通过
@JsonView
注解, 指定对应对象在对应控制器的不同返回内容.
JsonView以接口作为区分组, 不同的接口作为其参数可以针对不同类型进行分类区分.
我们有一个 User 对象, 它有username和password属性, 然后对应两个控制器userList和getUserInfo, 我想在在userList接口时只返回用户的名称列表, 在getUserInfo时,将用户名和密码一起返回。那么可以通过定义两个接口:UserSimpleView和UserDetailView, UserDetailView继承自UserSimpleView,根据Java的继承关系也不难理解,就是当有simple的时候, 是独立的, 当有detail的时候, 会将simple注解了的参数一并展示,描述的可能不是特别好,可以通过代码得到更好的展示。
首先,我们在User类中,定义两个接口。分别代表两种展示类别,然后再username字段加上simple接口参数,在password字段加上detail接口参数。
@Data
@Accessors(chain = true)
public class User implements Serializable {
public interface UserSimpleView {}
public interface UserDetailView extends UserSimpleView {}
@JsonView(UserSimpleView.class)
private String username;
@JsonView(UserDetailView.class)
private String password;
}
然后再对应的两个控制器,通过 @JsonView
注解,和对应对象的属性绑定起来。
可以看到,我们在getUserList方法上配置了simple接口,代表着它的参数返回中,只会包括usename字段属性值。
在getInfo方法上,通过配置detail接口,代表着它的返回值中可以包括 User
对象中的所有使用了 Detail
接口以及其父接口的参数.
@RestController
@RequestMapping("user")
public class UserController {
@GetMapping
@JsonView(User.UserSimpleView.class)
public List<User> getUserList(UserQueryCondition condition,
@PageableDefault(size = 20, page = 1, sort = "username,asc") Pageable pageable) {
System.out.println(ReflectionToStringBuilder.toString(condition, ToStringStyle.MULTI_LINE_STYLE));
System.out.println(pageable);
return Collections.singletonList(new User().setUsername("yzt").setPassword("xxx"));
}
@GetMapping("{id:\\d+}")
@JsonView(User.UserDetailView.class)
public User getInfo(@PathVariable String id) {
System.out.println(id);
User user = new User();
user.setUsername("tom").setPassword("xxx");
return user;
}
}
接下来通过单元测试的返回值,具体的来看一下效果。
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserControllerTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
@Test
public void whenQuerySuccess() throws Exception {
String contentAsString = mockMvc.perform(get("/user")
.param("username", "yzt")
.param("age", "20")
.param("ageTo", "30")
.param("page", "2")
.param("size", "10")
.param("sort", "age,desc")
.contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(status().isOk())
.andExpect(jsonPath("$.length()").value(1))
.andReturn()
.getResponse()
.getContentAsString();
System.out.println(contentAsString);
}
@Test
public void whenGetInfoSuccess() throws Exception {
String content = mockMvc.perform(get("/user/1")
.contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(status().isOk())
.andExpect(jsonPath("$.username").value("tom"))
.andReturn()
.getResponse()
.getContentAsString();
System.out.println(content);
}
}
对应的返回值如下:
whenQuerySuccess接口返回值, 只看到了username参数。
top.imyzt.learning.security.demo.dto.UserQueryCondition@67b560fe[
username=yzt
age=20
ageTo=30
]
Page request [number: 2, size 10, sort: age: DESC]
[{"username":"yzt"}]
whenGetInfoSuccess接口返回值,可以看到了password参数。
{"username":"tom","password":"xxx"}
至此,博客结束了。有多学了一个骚操作。