RESTEasy中JSON适配器Jackson & Jettision JAXB
前面的所有关于RESTEasy的JSON部分都使用了Jettision JAXB适配器。这里当运行时环境加入了Jackson相关的jar包,RESTEasy则会优先使用Jackson。
Jackson介绍(来自官方文档):
JSON适配器除了使用Jettision JAXB外,RESTEasy同样提供了Jackson项目的集成。很多用户发现Jackson的输出要远远好于Jettision所提供的一些方案( @BadgerFish或者@Mapped)。Jackson能让你很容易的将Java对象整理成JSON或者从JSON整理成Java对象。就像JAXB 一样,它同样基于JavaBean模型。Resteasy在Jackson 上做了一小点扩展。这个扩展是Resteasy添加了"application/*+json"支持。对于原生的Jackson则仅将"application/json" 和"text/json"当作有效的媒体类型。通过这个扩展,你可以创建基于JSON的媒体类型但同样让Jackson 来帮你整理。
Jackson生成JSON格式:
{"id":0,"firstName":"Bill","lastName":"Burke","street":"256 Clarendon Street中文呢"}
Jettision生成JSON格式:
{"mycustomer":{"firstName":"Bill","id":0,"lastName":"Burke","street":"256 Clarendon Street中文呢"}}
Jackson的使用
1, 依赖获取,推荐使用Maven方式。
Jackson的下载地址:https://github.com/FasterXML/
或者核心包所在地址:
https://github.com/FasterXML/jackson-core/releases
Jackson的Maven依赖。将其添加到项目的pom.xml中。
<dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jackson-provider</artifactId> <version>2.3.4.Final</version> </dependency>
2,添加相关的jar包到服务器环境。
3,相关代码:
服务器端:
@POST @Path("format/Jackson") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public MyCustomer Jackson(MyCustomer input) { System.out.println(input); return input; } @POST @Path("format/JacksonList") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public List<MyCustomer> JacksonList(List<MyCustomer> input) { System.out.println(input); return input; } @POST @Path("format/JacksonMap") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public Map<String,Object> JacksonMap(Map<String,Object> input) { System.out.println(input); return input; }
客户端:
@Test public void testJsonJackson() throws Exception { String newCustomer = "{\"id\":0,\"firstName\":\"Bill\",\"lastName\":\"Burke\",\"street\":\"256 Clarendon Street中文呢222\"}"; DefaultHttpClient client = new DefaultHttpClient(); HttpPost post = new HttpPost("http://localhost:8080/resteasy-json/form/format/Jackson"); StringEntity entity = new StringEntity(newCustomer, "UTF-8");// entity.setContentType("application/json"); post.setEntity(entity); HttpClientParams.setRedirecting(post.getParams(), false); HttpResponse response = client.execute(post); System.out.println("Content-Type: " + response.getEntity().getContentType()); HttpEntity entityReturn = response.getEntity(); BufferedReader reader = new BufferedReader(new InputStreamReader(entityReturn.getContent())); String line = reader.readLine(); while (line != null) { System.out.println(line); line = reader.readLine(); } } @Test public void testJsonJacksonList() throws Exception { String newCustomer = "[{\"id\":0,\"firstName\":\"Bill\",\"lastName\":\"Burke\",\"street\":\"256 Clarendon Street中文呢222\"},{\"id\":0,\"firstName\":\"Bill\",\"lastName\":\"Burke\",\"street\":\"256 Clarendon Street中文呢222\"}]"; DefaultHttpClient client = new DefaultHttpClient(); HttpPost post = new HttpPost("http://localhost:8080/resteasy-json/form/format/JacksonList"); StringEntity entity = new StringEntity(newCustomer, "UTF-8");// entity.setContentType("application/json"); post.setEntity(entity); HttpClientParams.setRedirecting(post.getParams(), false); HttpResponse response = client.execute(post); System.out.println("Content-Type: " + response.getEntity().getContentType()); HttpEntity entityReturn = response.getEntity(); BufferedReader reader = new BufferedReader(new InputStreamReader(entityReturn.getContent())); String line = reader.readLine(); while (line != null) { System.out.println(line); line = reader.readLine(); } } @Test public void testJsonJacksonList2() throws Exception { String url = "http://localhost:8080/resteasy-json/form/format/JacksonList"; ClientRequest request = new ClientRequest(url); List<MyCustomer> list = new ArrayList<MyCustomer>(); MyCustomer customer = new MyCustomer(); customer.setId(1); customer.setFirstName("Bill222"); customer.setLastName("Burke222"); customer.setStreet("263 Clarendon Street中文2"); list.add(customer); MyCustomer customer2 = new MyCustomer(); customer2.setId(2); customer2.setFirstName("Bill2228888"); customer2.setLastName("Burke222888"); customer2.setStreet("263 Clarendon Street中文28888"); list.add(customer2); request.body(MediaType.APPLICATION_JSON, list); List<MyCustomer> returnItem = request.postTarget(List.class); // MyCustomer[] returnItem = request.postTarget(MyCustomer[].class); //也可以使用数组接收返回的List数据。 System.out.println(returnItem); } @Test public void testJsonJacksonMap() throws Exception { String newCustomer = "{\"id\":0,\"firstName\":\"Bill\",\"lastName\":\"Burke\",\"street\":\"256 Clarendon Street中文呢222999\"}"; DefaultHttpClient client = new DefaultHttpClient(); HttpPost post = new HttpPost("http://localhost:8080/resteasy-json/form/format/JacksonMap"); StringEntity entity = new StringEntity(newCustomer, "UTF-8");// entity.setContentType("application/json"); post.setEntity(entity); HttpClientParams.setRedirecting(post.getParams(), false); HttpResponse response = client.execute(post); System.out.println("Content-Type: " + response.getEntity().getContentType()); HttpEntity entityReturn = response.getEntity(); BufferedReader reader = new BufferedReader(new InputStreamReader(entityReturn.getContent())); String line = reader.readLine(); while (line != null) { System.out.println(line); line = reader.readLine(); } } @Test public void testJsonJacksonMap2() throws Exception { String url = "http://localhost:8080/resteasy-json/form/format/JacksonMap"; ClientRequest request = new ClientRequest(url); MyCustomer customer = new MyCustomer(); customer.setId(1); customer.setFirstName("Bill222"); customer.setLastName("Burke222"); customer.setStreet("263 Clarendon Street中文2"); request.body(MediaType.APPLICATION_JSON, customer); MyCustomer returnItem = request.postTarget(MyCustomer.class); System.out.println(returnItem); }
实体类:
public class MyCustomer implements Serializable { /** * */ private static final long serialVersionUID = -5970656821565304922L; private int id; private String firstName; private String lastName; private String street; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } @Override public String toString() { return "MyCustomer [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", street=" + street + "]"; } }
此实体没有加入任何其它代码,包括注解,所以说使用Jackson对我们的原有实体或者PO没有任何侵入性。推荐使用Jackson。
Jettision JAXB的使用
注意:如果运行时环境中仅仅有Jettision JAXB相关的jar包而没有Jackson的包,那么则不需要对方法、方法参数或者相应的对象上加上注解:@NoJackson。这里的代码是两种环境都存在的情况。如果不存在Jackson的包,请相应去掉@NoJackson注解即可。
1, 依赖获取,这里使用Maven方式。
Jettision JAXB的Maven依赖。将其添加到项目的pom.xml中。
<dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jettison-provider</artifactId> <version>2.3.4.Final</version> <scope>provided</scope> </dependency>
2,添加相关的jar包到服务器环境。
3,相关代码:
服务器端:
@POST @Path("format/Jettision") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public MyCustomer Jettision(MyCustomer input) { System.out.println(input); return input; } @POST @Path("format/JettisionList") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public List<MyCustomer> JettisionList(List<MyCustomer> input) { System.out.println(input); return input; } @POST @Path("format/JettisionMap") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public Map<String,Object> JettisionMap(Map<String,Object> input) { System.out.println(input); return input; }
客户端:
@Test public void testJsonJettision() throws Exception { String newCustomer = "{\"mycustomer\":{\"firstName\":\"Bill222\",\"id\":1,\"lastName\":\"Burke222中文\",\"street\":\"263 Clarendon Street\"}}"; //下面这种JSON格式在Jettision单个实体的接收中是不能工作的。必需使用上面的方式。 // String newCustomer = "{\"id\":0,\"firstName\":\"Bill\",\"lastName\":\"Burke\",\"street\":\"256 Clarendon Street中文呢222\"}"; DefaultHttpClient client = new DefaultHttpClient(); HttpPost post = new HttpPost("http://localhost:8080/resteasy-json/form/format/Jettision"); StringEntity entity = new StringEntity(newCustomer, "UTF-8");// entity.setContentType("application/json"); post.setEntity(entity); HttpClientParams.setRedirecting(post.getParams(), false); HttpResponse response = client.execute(post); System.out.println("Content-Type: " + response.getEntity().getContentType()); HttpEntity entityReturn = response.getEntity(); BufferedReader reader = new BufferedReader(new InputStreamReader(entityReturn.getContent())); String line = reader.readLine(); while (line != null) { System.out.println(line); line = reader.readLine(); } } @Test public void testJsonJettisionList() throws Exception { //在服务器端使用List进行接收时,List里的实体对象可以不用在类上面写注解:@XmlRootElement。这里MyCustomer可以在此模式下省略注解@XmlRootElement(name = "mycustomer")。 String newCustomer = "[{\"id\":0,\"firstName\":\"Bill\",\"lastName\":\"Burke\",\"street\":\"256 Clarendon Street中文呢222\"},{\"id\":0,\"firstName\":\"Bill\",\"lastName\":\"Burke\",\"street\":\"256 Clarendon Street中文呢222\"}]"; DefaultHttpClient client = new DefaultHttpClient(); HttpPost post = new HttpPost("http://localhost:8080/resteasy-json/form/format/JettisionList"); StringEntity entity = new StringEntity(newCustomer, "UTF-8");// entity.setContentType("application/json"); post.setEntity(entity); HttpClientParams.setRedirecting(post.getParams(), false); HttpResponse response = client.execute(post); System.out.println("Content-Type: " + response.getEntity().getContentType()); HttpEntity entityReturn = response.getEntity(); BufferedReader reader = new BufferedReader(new InputStreamReader(entityReturn.getContent())); String line = reader.readLine(); while (line != null) { System.out.println(line); line = reader.readLine(); } } @Test public void testJsonJettisionList2() throws Exception { String url = "http://localhost:8080/resteasy-json/form/format/JettisionList"; ClientRequest request = new ClientRequest(url); List<MyCustomer> list = new ArrayList<MyCustomer>(); MyCustomer customer = new MyCustomer(); customer.setId(1); customer.setFirstName("Bill222"); customer.setLastName("Burke222"); customer.setStreet("263 Clarendon Street中文2"); list.add(customer); MyCustomer customer2 = new MyCustomer(); customer2.setId(2); customer2.setFirstName("Bill2228888"); customer2.setLastName("Burke222888"); customer2.setStreet("263 Clarendon Street中文28888"); list.add(customer2); request.body(MediaType.APPLICATION_JSON, list); List<MyCustomer> returnItem = request.postTarget(List.class); // MyCustomer[] returnItem = request.postTarget(MyCustomer[].class); //这里不可以使用数组接收返回的List数据。 System.out.println(returnItem); } @Test public void testJsonJettisionMap() throws Exception { // 以下三种JSON格式都能正确接收,只是第一种是根MAP里放了mycustomer,而mycustomer的值又是一个MAP,里面才是我们想到的值,这也和我们的JSON格式相对应。 String newCustomer = "{\"mycustomer\":{\"firstName\":\"Bill222\",\"id\":1,\"lastName\":\"Burke222中文\",\"street\":\"263 Clarendon Street\"}}"; // String newCustomer = "{\"id\":0,\"firstName\":\"Bill\",\"lastName\":\"Burke\",\"street\":\"256 Clarendon Street中文呢222999\"}"; // String newCustomer = "{\"firstName\":\"Bill222\",\"id\":1,\"lastName\":\"Burke222中文\",\"street\":\"263 Clarendon Street\"}"; DefaultHttpClient client = new DefaultHttpClient(); HttpPost post = new HttpPost("http://localhost:8080/resteasy-json/form/format/JettisionMap"); StringEntity entity = new StringEntity(newCustomer, "UTF-8");// entity.setContentType("application/json"); post.setEntity(entity); HttpClientParams.setRedirecting(post.getParams(), false); HttpResponse response = client.execute(post); System.out.println("Content-Type: " + response.getEntity().getContentType()); HttpEntity entityReturn = response.getEntity(); BufferedReader reader = new BufferedReader(new InputStreamReader(entityReturn.getContent())); String line = reader.readLine(); while (line != null) { System.out.println(line); line = reader.readLine(); } } @Test public void testJsonJettisionMap2() throws Exception { String url = "http://localhost:8080/resteasy-json/form/format/JettisionMap"; ClientRequest request = new ClientRequest(url); MyCustomer customer = new MyCustomer(); customer.setId(1); customer.setFirstName("Bill222"); customer.setLastName("Burke222"); customer.setStreet("263 Clarendon Street中文2"); request.body(MediaType.APPLICATION_JSON, customer); MyCustomer returnItem = request.postTarget(MyCustomer.class); System.out.println(returnItem); }
实体类:
@XmlRootElement(name = "mycustomer") @NoJackson public class MyCustomer implements Serializable { /** * */ private static final long serialVersionUID = -5970656821565304922L; private int id; private String firstName; private String lastName; private String street; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } @Override public String toString() { return "MyCustomer [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", street=" + street + "]"; } }
这里,也可以使用如下方法来分别控制服务器端接收和发送使用Jackson,还是Jettision。如:
@POST @Path("format/Jettision") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @NoJackson public MyCustomer Jettision(@NoJackson MyCustomer input) { System.out.println(input); return input; }
或者让发送的JSON为Jackson格式:
@POST @Path("format/Jettision") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) // @NoJackson public MyCustomer Jettision(@NoJackson MyCustomer input) { System.out.println(input); return input; }
注:在上面两种模式下,就不需要再对实体类上添加注解@NoJackson。实体类变为:
@XmlRootElement(name = "mycustomer") public class MyCustomer implements Serializable {