当您使用杰克逊的writerWithView
时,任何没有@JsonView
注释的属性仍会被序列化。但是,在Spring MVC操作上使用@JsonView
似乎需要@JsonView
在每个属性上。
如果说我们有以下型号:
public class User {
private String username;
private String emailAddress;
public String getUsername() { return username; }
@JsonView(DetailView.class)
public String getEmailAddress() { return emailAddress; }
}
DetailView
扩展BasicView
,当我使用基本视图进行序列化时,我希望序列化username
。当我们使用writerWithView
时会发生这种情况:
@RequestMapping(value = "/me", method = GET)
@ResponseBody
public String getMe() throws JsonProcessingException {
User user = getCurrentUser();
return objectMapper.writerWithView(BasicView.class).writeValueAsString(user);
}
但是,从Spring MVC 4.1开始,我们可以做以下事情:
@RequestMapping(value = "/me", method = GET)
@ResponseBody
@JsonView(BasicView.class)
public User getMe() throws JsonProcessingException {
return getCurrentUser();
}
后者导致回复为{}
而不是{username:"David"}
。如果我们将@JsonView(BasicView.class)
添加到getUsername()
,则按预期方式工作。
显然,我们可以选择前者或将@JsonView
添加到所有内容中,这两者都更加冗长且容易出错。
这看起来有点像MapperFeature.DEFAULT_VIEW_INCLUSION
已被关闭,但明确启用它似乎没有效果。
无论如何都要绕过这个?
答案 0 :(得分:0)
MapperFeature.DEFAULT_VIEW_INCLUSION
被禁用确实是问题,但不幸的是,Spring类没有提供一种简单的方法来配置或替换默认消息转换器使用的ObjectMapper。
我发现解决此问题的最佳方法是扩展DelegatingWebMvcConfiguration
并覆盖configureMessageConverters
以填充默认转换器,然后覆盖有问题的MappingJackson2HttpMessageConverter
:
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration;
import com.example.config.serialization.AllEncompassingFormHttpMessageConverterWithCustomObjectMapper;
import java.util.List;
@Configuration
@ComponentScan({/*...*/})
public class MyWebConfig extends DelegatingWebMvcConfiguration {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
//...
return objectMapper;
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
super.configureMessageConverters(messageConverters);
if (messageConverters.isEmpty()) {
addDefaultHttpMessageConverters(messageConverters);
}
messageConverters.replaceAll(converter -> {
if (converter instanceof MappingJackson2HttpMessageConverter) {
return new MappingJackson2HttpMessageConverter(objectMapper());
} else if (converter instanceof AllEncompassingFormHttpMessageConverter) {
return new AllEncompassingFormHttpMessageConverterWithCustomObjectMapper(objectMapper());
}
return converter;
});
}
}
为了完整起见,您可能还想将AllEncompassingFormHttpMessageConverter
替换为您自己的副本,如上所述,该副本还允许指定ObjectMapper
。我没有在此处添加AllEncompassingFormHttpMessageConverterWithCustomObjectMapper
课程 - 它是AllEncompassingFormHttpMessageConverter
的一个简单副本,它将ObjectMapper
构造函数参数转发给它创建的MappingJackson2HttpMessageConverter
。