週末繼續學習jersey,測試了幾個get和post方式的webservice請求,並模擬客戶端測試調用情況。在google中找到了這麼一篇相關的文章:
REST: CRUD with JAX-RS (Jersey) 。 結果做到一半出了問題,服務端總是獲取不到客戶端請求的數據流內容!調試了一個下午未果,卻在第二天如夢方醒般的找到了原因。教訓1:學習下http協議;教訓2:老外的東西不一定是對的。
週末的測試主要還是基於jersey的webservice服務。對get和post兩種方式發送請求的幾種情況都做了簡單的示例(上傳文件的情況未測試,待續)。
service端:
- @Path("/hello")
- public class HelloService {
- @GET
- @Produces("text/plain")
- public String helloWorld(){
- return "hello world";
- }
- /*
- * post param test
- */
- @POST
- @Path("echo")
- @Consumes("application/x-www-form-urlencoded")
- public String echo(@FormParam("msg") String msg){
- return "are you say "+msg;
- }
- /*
- * get param test
- */
- @GET
- @Path("sex")
- @Produces("text/plain")
- public String getSex(@PathParam("name") String name){
- return "male";
- }
- /*
- * get {} request
- * http://houfeng:8080/jerseyWebServiceTest/services/hello/age/houfeng
- */
- @GET
- @Path("age/{name}")
- @Produces("text/plain")
- public String getAge(@PathParam("name") String name){
- return "18";
- }
- /*
- * get {} request
- * http://houfeng:8080/jerseyWebServiceTest/services/hello/223232323
- */
- @GET
- @Path ("{id}")
- @Produces ("application/xml")
- public StreamingOutput retrieveCustomer(@PathParam ("id") String customerId) {
- String customerDetails = "hou,feng,232";
- final String[] details = customerDetails.split(",");
- return new StreamingOutput() {
- public void write(OutputStream outputStream) {
- PrintWriter out = new PrintWriter(outputStream);
- out.println("<?xml version=/"1.0/" encoding=/"UTF-8/"?>");
- out.println("<customer>");
- out.println("<firstname>" + details[0] + "</firstname>");
- out.println("<lastname>" + details[1] + "</lastname>");
- out.println("<zipcode>" + details[2] + "</zipcode>");
- out.println("</customer>");
- out.close();
- }
- };
- }
- // get vs post
- @GET
- @Path("test_get")
- @Produces("text/plain")
- public String getTest1(@PathParam("name") String name, @Context HttpServletRequest request){
- System.out.println("name:"+name);// null
- String result;
- result = request.getParameter("name");
- System.out.println("name="+result); //houfeng
- result+= "--------"+request.getContextPath();
- return result;
- }
- /*
- * get 方式 正確的獲取參數方法 @QueryParam 或者 用 request; url裏有參數的用PathParam
- */
- @GET
- @Path("test_get2")
- @Produces("text/plain")
- public String getTest11(@QueryParam("name") String name, @Context HttpServletRequest request){
- System.out.println("name:"+name);// houfeng
- String result;
- result = request.getParameter("name");
- System.out.println("name="+result); //houfeng
- result+= "--------"+request.getContextPath();
- return result;
- }
- @POST
- @Path("test_post1")
- @Consumes("application/x-www-form-urlencoded")
- @Produces("text/plain")
- public String getTest2(@FormParam("name") String name){
- System.out.println(name);//houfeng
- String result=name;
- return result;
- }
- @POST
- @Path("test_post2")
- @Consumes("application/x-www-form-urlencoded")
- @Produces("text/plain")
- public String getTest22(@QueryParam("name") String name){
- System.out.println("name:"+name);//houfeng,但是有警告。提示用FormParam
- String result = name;
- return result;
- }
- @POST
- @Path("test_post3")
- @Produces("text/plain")
- public String getTest2222(String entity, @Context HttpServletRequest request){
- System.out.println("entity:"+entity);//hello 傳入方式:resource.entity("hello").post(String.class);
- String result;
- result= "--------"+request.getContextPath();
- return result;
- }
- @POST
- @Path("test_post4")
- //@Consumes("application/xml"),這樣就會出錯;@Consumes("application/x-www-form-urlencoded") 可以。
- @Produces("text/plain")
- public String getTest22222(InputStream is, @Context HttpServletRequest request) throws Exception{
- byte[] buf = new byte[is.available()];
- is.read(buf);
- System.out.println("buf:"+new String(buf));
- String result;
- result= "--------"+request.getContextPath();
- return result;
- }
客戶端可以採用兩種方式測試。
1,採用jersey實現的測試api:jersey-twitter-client-1.0-SNAPSHOT-jar-with-dependencies.jar
2,採用apache httpclient 模擬客戶端的各種請求。
上面提到的參考e文中是採用的第二種方式。在這裏我使用jersey測試api來實現。
- public void testHelloService() throws URISyntaxException {
- Client client = Client.create();
- URI u = new URI("http://houfeng:8080/jerseyWebServiceTest/services/hello");
- System.out.println(u);
- WebResource resource = client.resource(u);
- //get
- String result = resource.get(String.class);
- System.out.println(result);
- //get param
- u = new URI("http://houfeng:8080/jerseyWebServiceTest/services/hello/sex");
- System.out.println(u);
- resource = client.resource(u);
- MultivaluedMapImpl params = new MultivaluedMapImpl();
- params.add("name", "houfeng");
- result = resource.queryParams(params).get(String.class);
- System.out.println(result);
- u =new URI("http://houfeng:8080/jerseyWebServiceTest/services/hello/test_get");
- System.out.println(u);
- resource = client.resource(u);
- params = new MultivaluedMapImpl();
- params.add("name", "houfeng");
- result = resource.queryParams(params).get(String.class);
- System.out.println(result);
- u =new URI("http://houfeng:8080/jerseyWebServiceTest/services/hello/test_get2");
- System.out.println(u);
- resource = client.resource(u);
- params = new MultivaluedMapImpl();
- params.add("name", "houfeng");
- result = resource.queryParams(params).get(String.class);
- System.out.println(result);
- u =new URI("http://houfeng:8080/jerseyWebServiceTest/services/hello/test_post1");
- System.out.println(u);
- resource = client.resource(u);
- params = new MultivaluedMapImpl();
- params.add("name", "houfeng");
- result = resource.type(MediaType.APPLICATION_FORM_URLENCODED).post(String.class,params);
- System.out.println(result);
- u =new URI("http://houfeng:8080/jerseyWebServiceTest/services/hello/test_post2");
- System.out.println(u);
- resource = client.resource(u);
- params = new MultivaluedMapImpl();
- params.add("name", "houfeng");
- result = resource.queryParams(params).type(MediaType.APPLICATION_FORM_URLENCODED).post(String.class);
- System.out.println(result);
- u =new URI("http://houfeng:8080/jerseyWebServiceTest/services/hello/test_post3");
- System.out.println(u);
- resource = client.resource(u);
- result = resource.entity("hello").post(String.class);
- System.out.println(result);
- u =new URI("http://houfeng:8080/jerseyWebServiceTest/services/hello/test_post4");
- System.out.println(u);
- resource = client.resource(u);
- String buf = "inputstream content.";
- ByteArrayInputStream bais = new ByteArrayInputStream(buf.getBytes());
- result = resource.entity(bais).post(String.class);
- System.out.println(result);
- }
過程中遇到的問題就是提交流的時候,錯誤的參考了e文中 “@Consumes
(
"application/xml"
) ”的請求類型! 結果導致service 端 接受請求的方法參數InputStream
得不到內容。換作@Context HttpServeltRequest request 參數也無濟於事。於是在網上搜索,在一個國外論壇中有人提到相似的問題“上傳文件得不到流裏的內容,但是jetty裏可以,tomcat裏不可以。?”。好像沒有太大參考,但我也試了下,還是失敗。。。
今天修改提交類型註解爲:@Consumes("application/x-www-form-urlencoded") ,測試通過!終於才恍然大悟:application/xml是客戶端接受的內容類型。哎,是應該學習下http協議的相關知識,這樣的問題耽誤了大半天的時間!
另外,對於jax-ws中幾個註解,簡單總結下:
QueryParam--url ? 後面表示的參數 . get post 通用.
PathParam---url中的一部分,例如用{}表示的url中的一部分。get post 通用。
FormParam---post提交的form表單參數。 用於 post
( 其他幾個param稍後再學習)。