对于其他从 Laravel(PHP)、Django(Python)、Rails(Ruby) 迁移的人:
我创建了一个包serializers,其中我的每个模型都有一个序列化程序类。
public class UserSerializer {
// Default user values
public interface User {}
// User values with users posts
public interface UserWithPosts extends User {}
}
现在在您的模型中,您要做的是注释它们所属的序列化器的字段:
@Entity
class User {
@Id
@GeneratedValue
@JsonView(UserSerializer.User.class)
private Long id;
@JsonView(UserSerializer.User.class)
private String username;
@JsonView(UserSerializer.User.class)
private String email;
@OneToMany(mappedBy = "user")
@JsonManagedReference // This prevents infinite loop
@JsonView(UserSerializer.UserWithPosts.class)
private List<Post> posts;
// .. getters and setters bellow
}
在您的控制器中,您可以使用 @JsonView(..) 注释您的方法,以确定您要使用哪个序列化程序。
@RestController
@RequestMapping("users")
public class UsersController {
private UserRepository userRepository;
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
/**
* In list method we only want users default values to keep the payload smaller.
*/
@GetMapping("list")
@JsonView(UserSerializer.User.class)
public @ResponseBody ArrayList<User> list() {
ArrayList<User> users = new ArrayList<>();
for (User user : userRepository.findAll()) {
users.add(user);
}
return users;
}
/**
* In this method we are only fetching a single user so payload is smaller so we can add the users posts as well. You could also toggle this with a url filter/parameter.
*/
@GetMapping("show")
@JsonView(UserSerializer.UserWithPosts.class)
public @ResponseBody ArrayList<User> show(@RequestParam(name = "id", required = true) Long id) {
return userRepository.findOne(id):
}
}
配置!这很容易理解,但是当我第一次这样做时,没有任何示例/教程告诉/显示您也需要更新配置。如果你不这样做,那么序列化你的关系就会出现问题,序列化器仍然可以工作,但是你会在 JSON 响应中得到类似的东西:
...
"posts": [
{},
{},
{},..
]
...
所以它会为每个用户返回一个 JSON 对象,但没有值来解决这个问题我创建了 config 包添加了一个 WebConfiguration 类:
@Configuration
@EnableWebMvc
public class WebConfiguration extends WebMvcConfigurerAdapter {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
ObjectMapper mapper = Jackson2ObjectMapperBuilder.json().defaultViewInclusion(true).build();
converters.add(new MappingJackson2HttpMessageConverter(mapper));
}
}
您也可以在 XML 配置中执行此操作。但我个人更喜欢使用基于 Java 类的配置。如果 Spring 文档为新手提供更好的解释,那就太好了。