1. 背景
VO用于API返回对象给调用者,由于不用场景,会有不同的需求,如果对每个API都定制一个VO对象,那么就会使得对象难以复用,造成代码的大量冗余。例如,都是返回用户信息,可能在查询列表时,只返回姓名;但是在查询用户详情时,需要返回用户的姓名和密码。
如果针对这两者分别编写一个VO就有点浪费,如果共用一个VO又无法满足需求。
2. 解决方案
使用@JsonView注解来解决该问题需要以下三个步骤:
(1)使用接口声明多个视图;
import com.fasterxml.jackson.annotation.JsonView;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
public interface UserSimpleView{}
public interface UserDetailView{}
private String username;
private String password;
}
也可以让UserDetailView接口继承UserSimpleView接口。
(2)在值对象的get方法上指定试图:
import com.fasterxml.jackson.annotation.JsonView;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
public interface UserSimpleView{}
public interface UserDetailView{}
@JsonView({UserSimpleView.class, UserDetailView.class})
private String username;
@JsonView(UserDetailView.class)
private String password;
}
(3) 在controller方法上指定试图:
import com.fasterxml.jackson.annotation.JsonView;
import com.john.security.dto.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@RestController
@Slf4j
public class UserController {
@RequestMapping(value = "/user", method = RequestMethod.GET)
@JsonView(User.UserSimpleView.class)
public List<User> query(@RequestParam(defaultValue = "hs") String username){
log.info("username: " + username);
List<User> users = new ArrayList<>();
users.add(new User("1", "111"));
return users;
}
@GetMapping(value = "/user/{id:\\d+}")
@JsonView(User.UserDetailView.class)
public User getInfo(@PathVariable String id){
return new User("tom", "1234");
}
}
3. 返回结果
query方法只返回name字段,getInfo接口返回了name字段和password字段。
网友评论