まだSpringに少し慣れていないので、 問題 に遭遇したため、Jackson用のカスタムデシリアライザーを実装する必要があります。手順は小さな チュートリアル で説明されていますが、私はSpringで立ち往生しています。わからない、どこ
ObjectMapper mapper = new ObjectMapper();
springでは、MVCは、jsonがコントローラークラスのメソッドによって逆シリアル化されるときに実行されます。したがって、デフォルトのデシリアライザーをカスタムデシリアライザーに置き換えるにはどうすればよいかわかりません。
どんな提案でも大歓迎です。
春にジャクソンをどのように使用しているかは言わないので、_<mvc:annotation-driven/>
_と_@RequestBody
_および/または_@ResponseBody
_アノテーションを使用していると仮定します。
_<mvc:annotation-driven/>
_が行うことの1つは、マーシャリングを処理するAnnotationMethodHandlerAdapter
を含む多数の事前構成されたHttpMessageConverter
Beanが付属するMappingJacksonHttpMessageConverter
Beanを登録することです。ジャクソン注釈付きモデルクラスとの間。
現在、MappingJacksonHttpMessageConverter
にはsetObjectMapper()
メソッドがあり、デフォルトのObjectMapper
をオーバーライドできます。ただし、MappingJacksonHttpMessageConverter
は_<mvc:annotation-driven/>
_によって舞台裏で作成されるため、アクセスできません。
ただし、_<mvc:annotation-driven/>
_は便利なショートカットです。独自のAnnotationMethodHandlerAdapter
Beanを宣言し、(MappingJacksonHttpMessageConverter
プロパティを介して)独自のmessageConverters
Beanを注入し、独自にカスタマイズしたObjectMapper
それに。
次に、カスタムObjectMapper
を作成する方法に問題があります。これは、Springにあまり適したクラスではないためです。 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>
_
Spring 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-and-configuration/
次のようなことができます。
<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で機能する可能性がありますが、3.1ではMVCインフラストラクチャの一部が機能します 変更されています 。その結果、アプリケーションコンテキストにAnnotationMethodHandlerAdapter
Beanが登録されていない可能性があり、初期化時にBeanCreationException
になってしまいます。
Spring MVC 3.1の場合、mvc:annotation-driven
要素は RequestMappingHandlerAdapter を作成するため、代わりにそのタイプを自動配線する必要があります。登録されたHttpMessageConvertersのリストへのアクセスを引き続き提供し、MappingJacksonHttpMessageConverter
でObjectMapperプロパティを設定できるようにします。これには、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;
}
}
[〜#〜] update [〜#〜]: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>
これにより、デフォルトのHttpMessageConverters(register-defaults="true"
のためにまだ存在している)の前に、カスタムObjectMapperを使用してMappingJacksonHttpMessageConverter
の新しいインスタンスが追加されます。
私の場合(Spring3.2.4およびJackson2.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>
_
説明のつかない方法で、何かによってデフォルトに上書きされました。
これは私のために働いた:
_@JsonSerialize(using = CustomObjectSerializer.class)
public class CustomObject {
private Long value;
public Long getValue() {
return value;
}
public void setValue(Long value) {
this.value = value;
}
}
_
_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>
)は必要ありません。
MappingJacksonHttpMessageConverter状態の春のドキュメント:
2.4.5 MappingJacksonHttpMessageConverter
JacksonJSONプロセッサのObjectMapperを使用してJSONを読み書きできるHttpMessageConverter実装。 JSONマッピングは、Jacksonが提供する注釈を使用して、必要に応じてカスタマイズできます。さらに制御が必要な場合は、特定のタイプにカスタムJSONシリアライザー/デシリアライザーを提供する必要がある場合に備えて、ObjectMapperプロパティを介してカスタムObjectMapperを挿入できます。デフォルトでは、このコンバーターは(application/json)をサポートします。
ObjectMapperへのアクセスを自動配線して、その動作を変更することはできませんか?
Spring MVCをもっとよく知っていればいいのですが、JerseyやRESTeasyのようなJax-RS実装では、プロバイダーを登録します。多分春は似たようなことをしますか?