处理创建请求
在介绍 GET
请求之后,开始介绍如何使用 POST
请求。在 Restful
接口开发中,POST
请求的接口几乎是使用比较多的一种,因此在本章也会比较重要。在本小节中,将会说明 @RequestBody
注解的使用方法,然后,将对一些常用的知识点进行介绍。
@RequestBody注解
@RequestBody
注解:可以将请求体中的 JSON
字符串绑定到相应的 Bean
上,当然也可以将其分别绑定到对应的字符串上。这个注解常用来处理 content-type
不是默认的 application/x-www-form-urlencoded
编码的内容,比如,application/Json
或者 application/xml
等。一般情况下常用来处理 application/Json
类型。控制类代码如下所示。
@PostMapping("/user")
public User createInfo(@RequestBody User user) {
System.out.println(user.getUsername());
System.out.println(user.getPassword());
user.setUsername("Bob");
return user;
}
测试类代码如下所示。
@Test
public void whenCreateSuccess() throws Exception {
String content="{\"username\":\"tom\",\"password\":\"123\"}";
String result=mockMvc.perform(MockMvcRequestBuilders.post("/user")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(content))
.andExpect(MockMvcResultMatchers.status().isOk())
.andReturn().getResponse().getContentAsString();
System.out.println("result: "+result);
}
执行结果如图 3.8 所示。

程序使用了 @PostMapping
注解,这个注解是 @RequestMapping(method=RequestMeth od.POST)
的变体。同理还有 @GetMapping
、@PutMapping
、@DeleteMapping
,简化了注解。
从执行结果可以看出,content
中的 Json
值通过 @RequestBody
映射到 user
的 Bean
了,所以在控制类中可以通过对象 GET
属性值。同样可以使用 SET
对属性进行修改、返回,具体效果可以看测试类中 Result
的值。
日期类型的处理
后台交互时,对时间的处理总是不太方便,在这里建议使用时间戳进行传递,然后前后台分别对时间戳进行转换。可以在 User
类中添加时间类型的字段用于演示。User.java
中的代码如下所示。
public class User {
/*
创建两个接口
*/
public interface UserSimpleView{};
public interface UserDetailView extends UserSimpleView{};
private String username;
private String password;
private String id;
private Date birthday;
//Generate setters and getters//
//……
}
控制类代码如下所示。
/**
* @Desciption 测试日期类型
*/
@PostMapping("/user")
public User createInfo2(@RequestBody User user) {
System.out.println(user.getUsername());
System.out.println(user.getPassword());
System.out.println(user.getBirthday());
user.setUsername(“Bob”);
return user;
}
测试类代码如下所示。
/**
* @desciption 测试日期
* @throws Exception
*/
@Test
public void whenCreateSuccess2() throws Exception {
Date date=new Date();
System.out.println("dateTime: "+date.getTime());
String content="{\"username\":\"tom\",\"password\":\"123\",\"birthday\":"+date.getTime()+"}";
String result=mockMvc.perform(MockMvcRequestBuilders. post("/user")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(content))
.andExpect(MockMvcResultMatchers.status().isOk())
.andReturn().getResponse().getContentAsString();
System.out.println("result: "+result);
}
日期处理结果如图 3.9 所示。

@Valid注解
在开发业务时,需要满足校验,然后才会进行后台服务处理。校验的程序第一步,对校验字段进行校验要求;第二步,在服务上添加 @Valid
注解。首先在字段上添加校验代码如下所示。
public class User {
public interface UserSimpleView{};
public interface UserDetailView extends UserSimpleView{};
@NotBlank
private String username;
private String password;
private String id;
private Date birthday;
//generate setters and getters
//……
}
然后在控制类中添加校验,如下所示。
@PostMapping("/user")
public User createInfo3(@Valid @RequestBody User user) {
System.out.println(user.getUsername());
System.out.println(user.getPassword());
user.setUsername("Bob");
return user;
}
测试类代码如下所示。
@Test
public void whenCreateSuccess3() throws Exception {
String content="{\"username\":null,\"password\":\"123\"}";
String result=mockMvc.perform(MockMvcRequestBuilders.post("/user")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(content))
.andExpect(MockMvcResultMatchers.status().isOk())
.andReturn().getResponse().getContentAsString();
System.out.println("result: "+result);
}
执行结果如图 3.10 所示。

程序报错,说明没有通过校验。我们看到控制台没有输出任何和控制类有关的信息,说明程序没有进入控制类,所以 Valid
注解在没有通过校验时,不会进入后台服务。
BindingResult验证参数合法性
在上文的 @Valid
注解中,我们可以发现程序没有通过校验时,不会进入后台服务(就是获取不到效验错误消息),但在一些情况下需要进入后台进行一些操作,此时 BindingResult
就有用武之地了。
控制类代码如下所示。
@PostMapping("/user")
public User createInfo4(@Valid @RequestBody User user,BindingResult errors) {
if(errors.hasErrors()) {
errors.getAllErrors().stream().forEach(error->System.out. println("error message: "+error.getDefaultMessage()));
}
System.out.println(user.getUsername());
System.out.println(user.getPassword());
user.setUsername(“Bob”);
return user;
}
继续使用上面的测试类代码即可。执行结果如图 3.11 所示。

在控制类代码中,使用 JDK1.8
的新特性 lambda
表达式进行输出。根据控制台结果,可以看到这里不仅通过了校验,而且程序进入了后台服务,将报错信息存入 BindingResult
对象。