**对于restful API的使用可以查看我之前的文章SpringMVC开发restful API查询请求
本文将在restful API的基础上介绍@PathVariable和@JsonView注解的详细使用方式。**
一、@PathVariable注解的使用
在restful API中的URL地址一般传递的是资源,不同于传统的URL中传递的是用户行动信息。使用@PathVariable注解可以将URL中的片段映射到Java代码中,下面我们来举例说明。
1.使用MockMvc伪造客户端请求来测试
@Test
public void whenGetSuccess() throws Exception {
String result=mockMvc.perform(get("/user/1")
.contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(status().isOk())
.andExpect((ResultMatcher) jsonPath("$.username").value("shinelon"))
.andReturn().getResponse().getContentAsString();
System.out.println(result);
}
2.controller控制层方法代码:
@GetMapping("/user/{id}")
@JsonView(User.DetailJsonView.class)
public User get(@PathVariable String id) {
User user=new User();
user.setUsername("shinelon");
return user;
}
如上代码所示,在get方法参数上使用@PathVariable就会将路径中的参数id映射到String类型的方法的形参上,这个注解类似于@RequestParam注解,我们也可以在路径中使用正则表达式来限制传递参数,比如id必须为数字:
@GetMapping("/user/{id:\\d+}")
@PathVariable注解使用不难,很简单,这里就简单介绍一下,下面重点介绍@JsonView注解的使用。
@JsonView注解的使用
@JsonView注解有什么功能呢?首先我们在平时做项目的时候会有下面的场景,比如我们在查询的时候在不同方法上查询不同的字段,比如用户简单的信息只需要用户名称等,不需要用户密码,而有时候用户详情中就需要用户密码来展示出来。如果不使用@JsonView注解,我们可能需要多多查询字段或者封装实体类来解决。下面我们就依照上面讲解的场景来介绍一下该注解的使用方法。
下面说明如何使用@JsonView注解:
- 使用接口来声明多个视图
- 在值对象的get方法上指定视图
- 在controller方法上指定视图
1.我们在User实体类中声明两个接口,一个SimpleJsonView视图不展示用户密码,DetailJsonView展示用户密码,DetailJsonView继承SimpleJsonView就是说SimpleJsonView需要展示的信息DetailJsonView都会展示。
//1.声明接口
public interface SimpleJsonView{}
public interface DetailJsonView extends SimpleJsonView{}
2.在每一个字段的get方法上指定视图:
//2.在值对象的get方法上指定视图
@JsonView(SimpleJsonView.class)
public String getUsername() {
return username;
}
@JsonView(DetailJsonView.class) //因为DetailJsonView继承了SimpleJsonView接口,所以它既会显示密码还会显示username
public String getPassword() {
return password;
}
@JsonView(SimpleJsonView.class)
public Date getBirthday() {
return birthday;
}
3.在controller方法上指定视图:
@JsonView(User.SimpleJsonView.class) //3.在controller上指定视图
public List<User> query(UserQueryCondition condition,@PageableDefault(size=15,page=3,sort="username.asc") Pageable pageable){
System.out.println(ReflectionToStringBuilder.toString(condition,ToStringStyle.MULTI_LINE_STYLE));
List<User> list=new ArrayList<User>();
list.add(new User());
list.add(new User());
list.add(new User());
return list;
}
@GetMapping("/user/{id:\\d+}")
@JsonView(User.DetailJsonView.class)
public User get(@PathVariable String id) {
User user=new User();
user.setUsername("shinelon");
return user;
}
通过上面的三部我们已经完成了@JsonView注解的使用,下面是实体类和controller完整的代码:
User.java:
public class User {
//使用jsonview来显示视图
//1.声明接口
public interface SimpleJsonView{}
public interface DetailJsonView extends SimpleJsonView{}
private int id;
public String username;
public String password;
private Date birthday;
public void setUsername(String username) {
this.username = username;
}
//2.在值对象的get方法上指定视图
@JsonView(SimpleJsonView.class)
public String getUsername() {
return username;
}
public void setPassword(String password) {
this.password = password;
}
@JsonView(DetailJsonView.class) //因为DetailJsonView继承了SimpleJsonView接口,所以它既会显示密码还会显示username
public String getPassword() {
return password;
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@JsonView(SimpleJsonView.class)
public Date getBirthday() {
return birthday;
}
}
UserController.java:
@RestController
public class UserController {
@JsonView(User.SimpleJsonView.class) //3.在controller上指定视图
public List<User> query(UserQueryCondition condition,@PageableDefault(size=15,page=3,sort="username.asc") Pageable pageable){
System.out.println(ReflectionToStringBuilder.toString(condition,ToStringStyle.MULTI_LINE_STYLE));
List<User> list=new ArrayList<User>();
list.add(new User());
list.add(new User());
list.add(new User());
return list;
}
//\\d+这个正则表达式表示接受的参数是整型
@GetMapping("/user/{id:\\d+}")
@JsonView(User.DetailJsonView.class)
public User get(@PathVariable String id) {
User user=new User();
user.setUsername("shinelon");
return user;
}
}
下面使用MockMvc伪造请求进行测试:
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserControllerTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup() {
mockMvc=MockMvcBuilders.webAppContextSetup(wac).build();
}
@Test
public void whenQuery() throws Exception {
String result=mockMvc.perform(get("/user")
.contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(status().isOk())
.andExpect(jsonPath("$.length()").value(3))
.andReturn().getResponse().getContentAsString();
System.out.println(result);
}
@Test
public void whenGetSuccess() throws Exception {
String result=mockMvc.perform(get("/user/1")
.contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(status().isOk())
.andExpect((ResultMatcher) jsonPath("$.username").value("shinelon"))
.andReturn().getResponse().getContentAsString();
System.out.println(result);
}
}
当我们测试whenQuery方法的时候看到查询结果并没有显示密码,因为在controller的方法注解指定SimpleJsonView视图:
当我们测试whenGetSuccess方法时密码将会展示出来: