我使用Spring MVC Annotations创建一个JSON Rest API,其定义方法如下:
@RequestMapping(value = "/authenticate", method = RequestMethod.POST)
public @ResponseBody AuthenticationResponse authenticate(@RequestBody final DeviceInformation deviceInformation)
throws AuthenticationException {
return createAuthenticationResponse(deviceInformation, false);
}
为了处理不同的客户端版本,我想通过使用注释来排除或包含序列化bean的属性,如
class AuthenticationResponse {
@InterfaceVersion(max = 2)
String old;
@InterfaceVersion(min = 3)
String new;
}
因此,如果客户端使用InterfaceVersion 2调用,他将无法获得 new 属性,如果他使用3调用,则他将无法获得旧属性。
我已经发现Jackson库(Spring为JSON使用)提供了JsonView,JsonFilter等功能,但我无法弄清楚我在哪里以及如何配置这些东西。
答案 0 :(得分:1)
我使用@JsonFilter选择性地过滤掉同一个对象的属性,Spring当时没有(当然还没有?)支持这个,所以我注册了一个自定义MappingJackson2HttpMessageConverter来检查返回类型,如果是过滤器包装类型,我将过滤器取出并应用它。
public class JsonFilterAwareMappingJackson2HttpMessageConverter extends
MappingJackson2HttpMessageConverter {
private boolean prefixJson = false;
@Override
public void setPrefixJson(boolean prefixJson) {
this.prefixJson = prefixJson;
super.setPrefixJson(prefixJson);
}
@Override
protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException {
JavaType javaType = getJavaType(clazz);
try {
return this.getObjectMapper().readValue(inputMessage.getBody(), javaType);
}
catch (IOException ex) {
logger.error("Could not read JSON: " + ex.getMessage());
throw new HttpMessageNotReadableException("Could not read JSON: " + ex.getMessage(), ex);
}
}
@Override
protected void writeInternal(Object object, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
JsonEncoding encoding = getJsonEncoding(outputMessage.getHeaders().getContentType());
ObjectMapper objectMapper = getObjectMapper();
JsonGenerator jsonGenerator =
objectMapper.getJsonFactory().createJsonGenerator(outputMessage.getBody(), encoding);
// A workaround for JsonGenerators not applying serialization features
// https://github.com/FasterXML/jackson-databind/issues/12
if (objectMapper.isEnabled(SerializationFeature.INDENT_OUTPUT)) {
jsonGenerator.useDefaultPrettyPrinter();
}
try {
if (this.prefixJson) {
jsonGenerator.writeRaw("{} && ");
}
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
if (object instanceof FilterAppliedJsonObject) {
FilterAppliedJsonObject viewObject = FilterAppliedJsonObject.class.cast(object);
objectMapper.setFilters(viewObject.getFilters());
objectMapper.writeValue(jsonGenerator, viewObject.getObject());
} else if (object == null) {
jsonGenerator.writeNull();
} else {
objectMapper.writeValue(jsonGenerator, object);
}
}
catch (JsonProcessingException ex) {
logger.error("Could not write JSON: " + ex.getMessage());
throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getMessage(), ex);
}
}
}
我尽可能多地使用java @config而不是xml配置,所以我这样做:
@Override
public void configureMessageConverters(
List<HttpMessageConverter<?>> converters) {
converters.add(new JsonFilterAwareMappingJackson2HttpMessageConverter());
super.configureMessageConverters(converters);
}
如果你想在xml
中注册这种转换,我认为this post会对你有所帮助