Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Jackson JSON筛选属性_Json_Spring Mvc_Jackson - Fatal编程技术网

从Jackson JSON筛选属性

从Jackson JSON筛选属性,json,spring-mvc,jackson,Json,Spring Mvc,Jackson,我正在使用Spring MVC注释创建一个JSON Rest API,其方法定义如下: @RequestMapping(value = "/authenticate", method = RequestMethod.POST) public @ResponseBody AuthenticationResponse authenticate(@RequestBody final DeviceInformation deviceInformation) throws Auth

我正在使用Spring MVC注释创建一个JSON Rest API,其方法定义如下:

@RequestMapping(value = "/authenticate", method = RequestMethod.POST)
public @ResponseBody AuthenticationResponse authenticate(@RequestBody final DeviceInformation deviceInformation)
            throws AuthenticationException {
    return createAuthenticationResponse(deviceInformation, false);
}
为了处理不同的客户机版本,我想通过使用类似

class AuthenticationResponse {
    @InterfaceVersion(max = 2) 
    String old;

    @InterfaceVersion(min = 3)
    String new;
}
因此,如果客户使用InterfaceVersion 2调用,他将无法获得新的属性,如果使用3调用,他将无法获得旧的属性

我已经发现Jackson库(Spring用于JSON)提供了JsonView、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);
    }
}

}
公共类jsonfilterawremappingjackson2httpmessageconverter扩展
映射Jackson2HttpMessageConverter{
私有布尔前缀xjson=false;
@凌驾
public void setPrefixJson(布尔前缀JSON){
this.prefixJson=prefixJson;
super.setPrefixJson(prefixJson);
}
@凌驾
受保护对象readInternal(类clazz,HttpInputMessage inputMessage)
抛出IOException、HttpMessageNodeReadableException{
JavaType JavaType=getJavaType(clazz);
试一试{
返回此.getObjectMapper().readValue(inputMessage.getBody(),javaType);
}
捕获(IOEX异常){
logger.error(“无法读取JSON:+ex.getMessage());
抛出新的HttpMessageNodeReadableException(“无法读取JSON:+ex.getMessage(),ex”);
}
}
@凌驾
受保护的void writeInternal(对象对象,HttpOutputMessage outputMessage)
抛出IOException、HttpMessageNotWritableException{
JsonEncoding encoding=getJsonEncoding(outputMessage.getHeaders().getContentType());
ObjectMapper ObjectMapper=getObjectMapper();
JsonGenerator JsonGenerator=
objectMapper.getJsonFactory().createJsonGenerator(outputMessage.getBody(),编码);
//JsonGenerators不应用序列化功能的解决方法
// https://github.com/FasterXML/jackson-databind/issues/12
if(objectMapper.isEnabled(SerializationFeature.INDENT_输出)){
jsongGenerator.useDefaultPrettyPrinter();
}
试一试{
if(this.prefixJson){
jsonGenerator.writeRaw(“{}&”);
}
configure(SerializationFeature.WRITE_DATES_作为时间戳,false);
if(FilterAppliedJsonObject的对象实例){
FilterAppliedJsonObject viewObject=FilterAppliedJsonObject.class.cast(对象);
setFilters(viewObject.getFilters());
writeValue(jsonGenerator,viewObject.getObject());
}else if(object==null){
jsonggenerator.writeNull();
}否则{
writeValue(jsonGenerator,object);
}
}
捕获(JsonProcessingException ex){
logger.error(“无法写入JSON:+ex.getMessage());
抛出新的HttpMessageNotWritableException(“无法写入JSON:+ex.getMessage(),ex”);
}
}
}
我尽可能多地使用java@config而不是xml配置,所以我做到了:

@Override
public void configureMessageConverters(
        List<HttpMessageConverter<?>> converters) {
    converters.add(new JsonFilterAwareMappingJackson2HttpMessageConverter());
    super.configureMessageConverters(converters);
}
@覆盖
公共无效配置MessageConverters(
List我用来选择性地过滤掉同一对象上的属性,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);
    }
}

}
公共类jsonfilterawremappingjackson2httpmessageconverter扩展
映射Jackson2HttpMessageConverter{
私有布尔前缀xjson=false;
@凌驾
public void setPrefixJson(布尔前缀JSON){
this.prefixJson=prefixJson;
super.setPrefixJson(prefixJson);
}
@凌驾
受保护对象readInternal(类clazz,HttpInputMessage inputMessage)
抛出IOException、HttpMessageNodeReadableException{
JavaType JavaType=getJavaType(clazz);
试一试{
返回此.getObjectMapper().readValue(inputMessage.getBody(),javaType);
}
捕获(IOEX异常){
logger.error(“无法读取JSON:+ex.getMessage());
抛出新的HttpMessageNodeReadableException(“无法读取JSON:+ex.getMessage(),ex”);
}
}
@凌驾
受保护的void writeInternal(对象对象,HttpOutputMessage outputMessage)
抛出IOException、HttpMessageNotWritableException{
JsonEncoding encoding=getJsonEncoding(outputMessage.getHeaders().getContentType());
ObjectMapper ObjectMapper=getObjectMapper();
JsonGenerator JsonGenerator=
objectMapper.getJsonFactory().createJsonGenerator(outputMessage.getBody(),编码);
//JsonGenerators不应用序列化功能的解决方法
// https://github.com/FasterXML/jackson-databind/issues/12
if(objectMapper.isEnabled(SerializationFeature.INDENT_输出)){
jsongGenerator.useDefaultPrettyPrinter();
}
试一试{
if(this.prefixJson){
jsonGenerator.writeRaw(“{}&”);
}
configure(SerializationFeature.WRITE_DATES_作为时间戳,false);
if(FilterAppliedJsonObject的对象实例){
FilterAppliedJsonObject viewObject=FilterAppliedJsonObject.class.cast(对象);
setFilters(viewObject.getFilters());
writeValue(jsonGenerator,viewObject.getObject());
}else if(object==null){
jsonggenerator.writeNull();
}否则{
writeValue(jsonGenerator,object);
}
}
捕获(JsonProcessingException ex){
logger.error(“无法写入JSON:+ex.getMessage());
抛出新的HttpMessageNotWritableException