Jersey系列文章:
Jersey框架一:Jersey RESTful WebService框架簡介
Jersey提供3種基本方式來使用JSON格式
無論使用何種方式,在原有包的基礎上,都需要在客戶端和服務端Maven配置文件中添加jersey-json包以支持JSON格式
<dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-json</artifactId> <version>1.18</version> </dependency>
一,基於POJO
Request類和Response類(服務端和客戶端都需要)都是基本的POJO:
package com.sean; public class Request { private String query; public String getQuery() { return query; } public void setQuery(String query) { this.query = query; } }
package com.sean; public class Response { private int respCode; private String respDesc; public int getRespCode() { return respCode; } public void setRespCode(int respCode) { this.respCode = respCode; } public String getRespDesc() { return respDesc; } public void setRespDesc(String respDesc) { this.respDesc = respDesc; } }
服務端代碼:
package com.sean; import java.io.IOException; import java.net.URI; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriBuilder; import org.glassfish.grizzly.http.server.HttpServer; import com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory; import com.sun.jersey.api.core.PackagesResourceConfig; import com.sun.jersey.api.core.ResourceConfig; import com.sun.jersey.api.json.JSONConfiguration; @Path("query") public class MyResource { @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response query(Request req) { System.out.println(req.getQuery()); Response resp = new Response(); resp.setRespCode(0); resp.setRespDesc(req.getQuery()); return resp; } public static void main(String[] args) { URI uri = UriBuilder.fromUri("http://127.0.0.1").port(10000).build(); ResourceConfig rc = new PackagesResourceConfig("com.sean"); //使用Jersey對POJO的支持,必須設置為true rc.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, true); try { HttpServer server = GrizzlyServerFactory.createHttpServer(uri, rc); server.start(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (NullPointerException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { Thread.sleep(1000*1000); } catch (InterruptedException e) { e.printStackTrace(); } } }
客戶端代碼:
package com.sean; import javax.ws.rs.core.MediaType; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.WebResource; import com.sun.jersey.api.client.config.ClientConfig; import com.sun.jersey.api.client.config.DefaultClientConfig; import com.sun.jersey.api.json.JSONConfiguration; public class JerseyClient { public static void main(String[] args) { ClientConfig cc = new DefaultClientConfig(); //使用Jersey對POJO的支持,必須設置為true cc.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE); Client client = Client.create(cc); WebResource resource = client.resource("http://127.0.0.1:10000/query"); Request req = new Request(); req.setQuery("name"); ClientResponse response = resource .accept(MediaType.APPLICATION_JSON) .type(MediaType.APPLICATION_JSON) .post(ClientResponse.class, req); Response resp = response.getEntity(Response.class); System.out.println(resp.getRespCode() + " " + resp.getRespDesc()); } }
二,基於JAXB
使用JAXB的優點在於,無論使用XML格式還是JSON格式數據,都可以使用統一的Java模型
缺點很難找到一個合適的方式來生成特殊的JSON格式,這也是Jersey提供很多控制選項的原因
將Request類和Response類進行修改:
package com.sean; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Request { private String query; public String getQuery() { return query; } public void setQuery(String query) { this.query = query; } }
package com.sean; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Response { private int respCode; private String respDesc; public int getRespCode() { return respCode; } public void setRespCode(int respCode) { this.respCode = respCode; } public String getRespDesc() { return respDesc; } public void setRespDesc(String respDesc) { this.respDesc = respDesc; } }
服務端代碼去掉下面的配置
// rc.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, true);
客戶端代碼去掉下面的配置
// cc.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
Jersey提供很多控制選項以便更精細的控制JSON的解析、組裝過程,但是就我個人來看,JAXB提供的標簽足夠使用了
三,基於底層JSONObject/JSONArray
最大的優勢在於可以完全控制JSON的解析、組裝過程,相應的,在處理數據對象時也要更復雜
服務端代碼如下:
package com.sean; import java.io.IOException; import java.net.URI; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriBuilder; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import org.glassfish.grizzly.http.server.HttpServer; import com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory; import com.sun.jersey.api.core.PackagesResourceConfig; import com.sun.jersey.api.core.ResourceConfig; @Path("query") public class MyResource { @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public JSONObject query(JSONObject query) { //{"query":"name"} System.out.println(query.toString()); JSONObject resp = new JSONObject(); try { resp.put("respCode", 0); resp.put("respDesc", query.get("query")); } catch (JSONException e) { e.printStackTrace(); } return resp; } public static void main(String[] args) { URI uri = UriBuilder.fromUri("http://127.0.0.1").port(10000).build(); ResourceConfig rc = new PackagesResourceConfig("com.sean"); try { HttpServer server = GrizzlyServerFactory.createHttpServer(uri, rc); server.start(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (NullPointerException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { Thread.sleep(1000*1000); } catch (InterruptedException e) { e.printStackTrace(); } } }
客戶端代碼如下:
package com.sean; import javax.ws.rs.core.MediaType; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.WebResource; import com.sun.jersey.api.client.config.ClientConfig; import com.sun.jersey.api.client.config.DefaultClientConfig; public class JerseyClient { public static void main(String[] args) { ClientConfig cc = new DefaultClientConfig(); Client client = Client.create(cc); WebResource resource = client.resource("http://127.0.0.1:10000/query"); JSONObject req = new JSONObject(); try { req.put("query", "name"); } catch (JSONException e) { e.printStackTrace(); } ClientResponse response = resource .accept(MediaType.APPLICATION_JSON) .type(MediaType.APPLICATION_JSON) .post(ClientResponse.class, req); JSONObject resp = response.getEntity(JSONObject.class); //{"respCode":0,"respDesc":"name"} System.out.println(resp.toString()); } }
與JAXB相比,結果是相同的,但是處理過程(主要是組裝JSON對象)要復雜
對於上面3種方式,均可使用String類代替Request類、Response類或JSONObject類,Jersey會自動將對象轉換為JSON串
當然,如果客戶端修改為String,服務端也要相應的修改為String類型
修改客戶端代碼:
public class JerseyClient { public static void main(String[] args) { ClientConfig cc = new DefaultClientConfig(); Client client = Client.create(cc); WebResource resource = client.resource("http://127.0.0.1:10000/query"); JSONObject req = new JSONObject(); try { req.put("query", "name"); } catch (JSONException e) { e.printStackTrace(); } String response = resource .accept(MediaType.APPLICATION_JSON) .type(MediaType.APPLICATION_JSON) .post(String.class, req.toString()); } }