1

Spring MVCアノテーションを使用して、次のように定義されたメソッドを持つJSONRestAPIを作成しています。

@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で呼び出した場合、新しいプロパティを取得せず、3で呼び出した場合、古いプロパティを取得しません。

Jacksonライブラリ(Spring for JSONで使用される)がJsonView、JsonFilterなどの機能を提供していることはすでにわかりましたが、これらをどこでどのように構成する必要があるのか​​わかりませんでした。

4

1 に答える 1

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);
    }
}

}

可能な限りxml構成の代わりにjava @configを使用するので、次のようにします。

@Override
public void configureMessageConverters(
        List<HttpMessageConverter<?>> converters) {
    converters.add(new JsonFilterAwareMappingJackson2HttpMessageConverter());
    super.configureMessageConverters(converters);
}

この種の変換をxmlに登録したい場合は、この投稿が役立つと思います

于 2012-08-21T17:29:10.610 に答える