rest-assured的对象映射(序列化和反序列化)

rest-assured支持映射Java对象到Json和XML以及从Json和XML中映射到Java对象。Json映射需要在classpath 中有Jackson、Jackson 2或者是Gson,XML映射需要在classpath 中有JAXB。

一、序列化

序列化:序列化Java对象到Json或Xml

假设我们有这样一个Java Object:

 1 public class Message {
 2     private String message;
 3 
 4     public String getMessage() {
 5         return message;
 6     }
 7 
 8     public void setMessage(String message) {
 9         this.message = message;
10     }
11 }

我们想序列化这个对象为Json,并且将Json传递给request请求,这里有几种方法可以做到,比如说:

1.基于Content-Type的序列化

1 Message message = new Message();
2 message.setMessage("My messagee");
3 given().
4        contentType("application/json").
5        body(message).
6 when().
7       post("/message");

在这个例子中,因为请求的content-type被设置为“application/json”,所以rest-assured将序列化这个message对象为Json。rest-assured首先会尝试从classpath中寻找Jackson,如果Jackson没有找到的话,则会使用Gson。如果你将content-type被设置为“application/xml”,rest-assured将使用JAXB,序列化这个message对象为XML。如果content-type没有定义,那么rest-assured将会按照下列顺序序列化对象:

  1.使用Jackson 2将对象序列化为Json(Faster Jackson (databind),数据绑定的速度比Jackson快)

  2.使用Jackson将对象序列化为Json(databind)

  3.使用Gson将对象序列化为Json

  4.使用JAXB将对象序列化为XML

 

同时rest-assured也关心content-type的字符集,比如:

1 Message message = new Message();
2 message.setMessage("My messagee");
3 given().
4        contentType("application/json; charset=UTF-16").
5        body(message).
6 when().
7       post("/message");

你也可以将message对象序列化为表单参数:

1 Message message = new Message();
2 message.setMessage("My messagee");
3 given().
4        contentType("application/json; charset=UTF-16").
5        formParam("param1", message).
6 when().
7       post("/message");

这个message对象将会序列化为字符集为UTF-16的Json(使用Jackson 或者 Gson ,如果存在的话)。

2.通过HashMap来创建Json

你可以提供一个Map,rest-assured将会使用这个map创建Json文件

 1 Map<String,Object> map = new HashMap<String,Object>();
 2 map.put("firstName","lwj");
 3 map.put("lastName","nicole");
 4 
 5 given().
 6         contentType(JSON).
 7         body(map).
 8 when().
 9         post("/somewhere"").
10 then().
11         statusCode(200);

上面的例子会产生一个Json数据:

1 { "firstName" : "lwj", "lastName" : "nicole" }

3.使用显示序列化器

如果在你的classpath中同时存在多个Object Mappers(对象映射),或者你并不关心 content-type 的设置,那么你就可以指定一个显示序列化器来进行序列化:比如:

1 Message message = new Message();
2 message.setMessage("My messagee");
3 given().
4        body(message, ObjectMapperType.JAXB).
5 when().
6       post("/message");

在这个例子当中,rest-assured使用JAXB将Message对象序列化为XML。

 

二、反序列化

反序列化:将响应体反序列化为Java对象

假设我们有这样一个Java对象:

 1 public class Message {
 2     private String message;
 3 
 4     public String getMessage() {
 5         return message;
 6     }
 7 
 8     public void setMessage(String message) {
 9         this.message = message;
10     }
11 }

接下来我们想将响应体反序列化为Message 对象:

1.基于Content-Type的反序列化

假设服务端返回这样一个Json数据:

1 {"message":"My message"}

将这个json数据反序列化为Message对象,我们可以这样做:

1 Message message = get("/message").as("Message.class");

想要将上面的Json数据反序列化为Message对象,响应体(response)的content-type必须是"application/json"(或者是其他包含json的类型)。

假设服务端返回下面类型的数据(xml):

1 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2 <message>
3       <message>My message</message>
4 </message>

并且响应体的content-type是"application/xml",完全不用修改任何代码:

1 Message message = get("/message").as("Message.class");

1.1 自定义Content-Type反序列化

  如果服务端返回一个自定义的Conten-Type,比说:"application/something",你仍然想使用rest-assured的对象映射,那么这里有两个方法可以做到:你可以使用显示指定的方法,或者是为自定义的Content-Type注册一个解析器:

1 Message message = expect().parser("application/somthing",Parser.XML).when().get("/message").as(Message.class);

或者:

1 Message message = expect().defaultParser(Parser.XML).when().get("/message").as(Message.class);

当然你也可以注册一个默认解析器或者是静态自定义一个解析器,或者使用specification.

2.使用显示反序列化器

  如果在你的classpath中同时有多个对象映射,或者说你并不关心响应体的content-type,你可以指定一个显示的反序列化器,比如:

1 Message message = get("/message").as(Message.class,ObjectMapperType.GSON);

3.配置(ObjectMapperConfig)

  你可以使用ObjectMapperConfig来配置一个预定义的对象映射,并且将其传递到详细配置当中去(detailed configuration),比如:将GSON的命名策略改成LowerCaseWithUnderscores(一种策略,将大写字母改为小写字母并添加下划线),可以这样做:

1 RestAssured.config = RestAssuredConfig.config().objectMapperConfig(objectMapperConfig().gsonObjectMapperFactory(
2                 new GsonObjectMapperFactory() {
3                     public Gson create(Class cls, String charset) {
4                         return new GsonBuilder().setFieldNamingPolicy(LOWER_CASE_WITH_UNDERSCORES).create();
5                     }
6                 }
7         ));

这里为GSON, JAXB, Jackson和Faster Jackson都预定义了对象映射工厂。

4.自定义ObjectMapper

  默认情况下,rest-assured将会扫描classpath中各种各样的Object Mappers。如果你想集成一个Object Mappers,默认情况下rest-assured是不支持,或者你自己封装,你可以实现 io.restassured.mapper.ObjectMapper 接口。你需要告诉rest-assured使用你自定义的Object Mappers,或者是将自定义的Object Mappers作为第二个参数传递给body:

1 given().body(myJavaObject,myObjectMapper).when().post("....");

或者你可以静态定义:

1 RestAssured.config = RestAssuredConfig.config().objectMapperConfig(new ObjectMapperConfig(myObjectMapper));

 

三、自定义解析器

  rest-assured提供了预定义的解析器,例如HTML、XML、JSON。但是你可以通过注册一个预定义的解析器来解析一些现在不支持的内容类型,通过以下方法来注册:

1 RestAssured.registerParser(<content-type>, <parser>);

例如:注册一个可以解析"application/vnd.uoml+xml"类型的解析器,需要使用XML parser这样做:

1 RestAssured.registerParser("application/vnd.uoml+xml", Parser.XML);

你也可以通过下面的方法来注销解析器:

1 RestAssured.unregisterParser("application/vnd.uoml+xml");

解析器也可以指定于每一个请求中:

1 get("...").then().using().parser("application/vnd.uoml+xml", Parser.XML);

然后使用response specification

 

四、默认解析器

有时候指定一个默认的解析器非常有用,比如:当中响应体中不包含任何content-type的时候:

1 RestAssured.defaultParser = Parser.JSON;

当然,你也可以为某个请求指定默认解析器:

1 get("/x").then().using().defaultParser(Parser.JSON). ..

然后使用response specification

posted @ 2018-01-12 11:23  lwjnicole  阅读(1223)  评论(0编辑  收藏  举报