春、ジャクソン、カスタマイズ(例:CustomDeSerializer)
-
01-10-2019 - |
解決
あなたは春にジャクソンをどのように使用しているのか言わないので、私はあなたがそれを使用していると思います <mvc:annotation-driven/>
そしてその @RequestBody
および/または @ResponseBody
注釈。
それの一つ <mvc:annotation-driven/>
登録することです AnnotationMethodHandlerAdapter
多くの事前に構成された豆が付属しています HttpMessageConverter
を含む豆 MappingJacksonHttpMessageConverter
, 、ジャクソンが解決したモデルクラスとの間でマーシャリングを処理します。
今 MappingJacksonHttpMessageConverter
があります setObjectMapper()
メソッドを使用すると、デフォルトをオーバーライドできます ObjectMapper
. 。しかしそれ以来 MappingJacksonHttpMessageConverter
舞台裏で作成されます <mvc:annotation-driven/>
, 、あなたはそれに到達することはできません。
でも、 <mvc:annotation-driven/>
便利なショートカットです。それはあなた自身を宣言するのが有効です AnnotationMethodHandlerAdapter
豆、あなた自身のものに注入します MappingJacksonHttpMessageConverter
Bean(経由 messageConverters
プロパティ)、および独自のカスタマイズを注入します ObjectMapper
それに。
その後、カスタムを構築する方法の問題があります ObjectMapper
, 、それはあまり春に優しいクラスではないので。私はあなたを書くことを提案します の単純な実装 FactoryBean
.
だからあなたはこのようなものになってしまうでしょう:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper">
<bean class="com.x.MyObjectMapperFactoryBean"/>
</property>
</bean>
</property>
</bean>
他のヒント
春3.1でこれを行う新しい方法:
http://magicmonster.com/kb/prg/java/spring/webmvc/mvc_spring_config_namespace.html
http://blog.springsource.org/2011/02/21/spring-3-1-m1-mvc-namespace-enhancements-anconfiguration/
このようなことをすることができます:
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper" ref="customObjectMapper"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
Rakeshが参照するソリューションは、Spring MVC 3.0で動作する可能性がありますが、MVCインフラストラクチャの一部では3.1で動作します 変更されました. 。その結果、あなたは持っていないかもしれません AnnotationMethodHandlerAdapter
アプリケーションのコンテキストで登録されているBeanで、あなたは BeanCreationException
初期化時に。
スプリングMVC 3.1の場合 mvc:annotation-driven
要素はaを作成します RequestMappingHandlerAdapter あなたのために、あなたは代わりにそのタイプを自動させるべきです。登録済みのhttpmessageconvertersのリストへのアクセスを提供し、ObjectMapperプロパティをに設定できるようにします。 MappingJacksonHttpMessageConverter
. 。これには、内部のわずかな変更も必要です init
. 。 httpmessageconvertersリファレンスのタイプへの方法。
更新されたクラスは次のように見えます:
@Component
public class JacksonFix {
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
private CustomObjectMapper objectMapper;
@PostConstruct
public void init() {
List<HttpMessageConverter<?>> messageConverters = requestMappingHandlerAdapter.getMessageConverters();
for (HttpMessageConverter<?> messageConverter : messageConverters) {
if (messageConverter instanceof MappingJacksonHttpMessageConverter) {
MappingJacksonHttpMessageConverter m = (MappingJacksonHttpMessageConverter) messageConverter;
m.setObjectMapper(objectMapper);
}
}
}
// this will exist due to the <mvc:annotation-driven/> bean
@Autowired
public void setRequestMappingHandlerAdapter(RequestMappingHandlerAdapter requestMappingHandlerAdapter) {
this.requestMappingHandlerAdapter = requestMappingHandlerAdapter;
}
@Autowired
public void setObjectMapper(CustomObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
}
アップデート: :Spring 3.1で最も簡単なことは、MVC構成に追加の構成を追加することです。
<mvc:annotation-driven conversion-service="applicationConversionService">
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper" ref="customObjectMapper" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
の新しいインスタンスが追加されます MappingJacksonHttpMessageConverter
デフォルトのhttpmessageconvertersのいずれかの前にカスタムObjectMapperを使用する register-defaults="true"
).
私の場合(スプリング3.2.4およびジャクソン2.3.1)、カスタムシリアイザー用のXML構成:
<mvc:annotation-driven>
<mvc:message-converters register-defaults="false">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="serializers">
<array>
<bean class="com.example.business.serializer.json.CustomObjectSerializer"/>
</array>
</property>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
原因不明の方法で、何かによってデフォルトに戻って上書きされました。
これは私のために働いた:
customobject.java
@JsonSerialize(using = CustomObjectSerializer.class)
public class CustomObject {
private Long value;
public Long getValue() {
return value;
}
public void setValue(Long value) {
this.value = value;
}
}
CustomObjectSerializer.java
public class CustomObjectSerializer extends JsonSerializer<CustomObject> {
@Override
public void serialize(CustomObject value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,JsonProcessingException {
jgen.writeStartObject();
jgen.writeNumberField("y", value.getValue());
jgen.writeEndObject();
}
@Override
public Class<CustomObject> handledType() {
return CustomObject.class;
}
}
XML構成はありません(<mvc:message-converters>(...)</mvc:message-converters>
)私のソリューションでは必要です。
Spring MVCをよりよく知っていたらいいのにと思いますが、Jax-RSの実装がJerseyやResteasyなどの実装を使用して、プロバイダーを登録しています。たぶん春は似たようなことをしますか?
Mappingjacksonhttpmessageconverter Stateのスプリングドキュメント:
2.4.5 mappingjacksonhttpmessageconverter
Jackson JSONプロセッサのObjectMapperを使用してJSONを読み書きできるHTTPMessageConverterの実装。 JSONマッピングは、Jacksonが提供された注釈を使用することにより、必要に応じてカスタマイズできます。さらなる制御が必要な場合は、カスタムJSONシリアイザー/脱介入剤を特定のタイプに提供する必要がある場合、オブジェクトマッパープロパティを介してカスタムオブジェクトマッパーを注入できます。デフォルトでは、このコンバーターがサポートしています(アプリケーション/JSON)。
その動作を変更するために、ObjectMapperへのAutowireアクセスだけではできませんか?