Spring、Jackson 和定制(例如 CustomDeserializer)
由于对 Spring 还是有点不熟悉,我遇到了一个 问题 这使得有必要为 Jackson 实现一个自定义解串器。该过程在一个小教程中进行了描述,但是,我坚持使用Spring。我不明白,
ObjectMapper mapper = new ObjectMapper();
当通过控制器类的方法反序列化 json 时,Spring MVC 中是在哪里执行的。所以我不知道该怎么做才能用自定义解串器替换默认解串器。
任何建议都非常欢迎。
Being still a little unfamiliar with Spring, I have encountered a problem that makes it necessary implementing my a custom deserialzer for Jackson. The procedure is described in a small tutorial, however, I am stuck with Spring. I do not understand, where
ObjectMapper mapper = new ObjectMapper();
in Spring MVC is carried out when json is deserializes by a method of a controller class. So I do not know, what to do in order to replace the default deserializer by a custom deserialiser.
Any suggestions most welcome.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您没有说明如何在 Spring 中使用 Jackson,所以我假设您通过
和@RequestBody< 使用它/code> 和/或
@ResponseBody
注释。
所做的事情之一是注册一个AnnotationMethodHandlerAdapter
bean,它带有许多预配置的HttpMessageConverter< /code> beans,包括 MappingJacksonHttpMessageConverter,它处理与 Jackson 注解的模型类之间的编组。
现在,
MappingJacksonHttpMessageConverter
有一个setObjectMapper()
方法,它允许您覆盖默认的ObjectMapper
。但由于MappingJacksonHttpMessageConverter
是由
在幕后创建的,因此您无法访问它。然而,
只是一个方便的捷径。声明您自己的AnnotationMethodHandlerAdapter
bean,将您自己的MappingJacksonHttpMessageConverter
bean 注入其中(通过messageConverters
属性),然后注入您的自己定制的ObjectMapper
到其中。然后,您会遇到如何构建自定义
ObjectMapper
的问题,因为它不是一个对 Spring 非常友好的类。我建议写你的 自己的FactoryBean
的简单实现。所以你最终会得到这样的结果:
You don't say how you're using Jackson in Spring, so I'll assume you're using it through
<mvc:annotation-driven/>
and the@RequestBody
and/or@ResponseBody
annotations.One of the things that
<mvc:annotation-driven/>
does is to register aAnnotationMethodHandlerAdapter
bean which comes with a number of pre-configuredHttpMessageConverter
beans, includingMappingJacksonHttpMessageConverter
, which handles marshalling to and from Jackson-annotated model classes.Now
MappingJacksonHttpMessageConverter
has asetObjectMapper()
method, which allows you to override the defaultObjectMapper
. But sinceMappingJacksonHttpMessageConverter
is created behind the scenes by<mvc:annotation-driven/>
, you can't get to it.However,
<mvc:annotation-driven/>
is just a convenient short-cut. It's just as a valid to declare your ownAnnotationMethodHandlerAdapter
bean, injecting into it your ownMappingJacksonHttpMessageConverter
bean (via themessageConverters
property), and injecting your own customizedObjectMapper
into that.You then have the problem of how to build a custom
ObjectMapper
, since it's not a very Spring-friendly class. I suggest writing your own simple implementation ofFactoryBean
.So you'd end up with something like this:
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/
允许您执行以下操作:
New way to do this in 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/
Allows you to do something like this:
Rakesh 引用的解决方案可能适用于 Spring MVC 3.0,但适用于 3.1 的一些 MVC 基础设施已更改。因此,您可能没有在应用程序上下文中注册
AnnotationMethodHandlerAdapter
bean,并且最终会在初始化时出现BeanCreationException
。对于 Spring MVC 3.1,
mvc:annotation-driven
元素将创建一个 RequestMappingHandlerAdapter 适合您,因此您应该自动装配该类型。它仍然提供对已注册 HttpMessageConverter 列表的访问,并允许您在MappingJacksonHttpMessageConverter
上设置 ObjectMapper 属性。这还需要在init
中进行一些细微的更改。方法到 HttpMessageConverters 引用的类型。更新后的类如下所示:
更新:事实证明,使用 Spring 3.1 做的最简单的事情就是向 MVC 配置添加一些额外的配置:
这将添加
MappingJacksonHttpMessageConverter< 的新实例/code> 与任何默认 HttpMessageConverters 之前的自定义 ObjectMapper(由于
register-defaults="true"
而仍然存在)。The solution referenced by Rakesh likely works with Spring MVC 3.0 but with 3.1 some of the MVC infrastructure has changed. As a result you may not have an
AnnotationMethodHandlerAdapter
bean registered in your application context and you'll end up with aBeanCreationException
at initialization time.For Spring MVC 3.1 the
mvc:annotation-driven
element will create a RequestMappingHandlerAdapter for you, so you should autowire that type instead. It will still provide access to the list of registered HttpMessageConverters and allow you to set the ObjectMapper property on theMappingJacksonHttpMessageConverter
. This also requires a slight change within theinit
. method to the type of the HttpMessageConverters reference.The updated class looks like:
UPDATE: It turns out the absolute easiest thing to do with Spring 3.1 is to add some additional configuration to your MVC configuration:
That will add a new instance of
MappingJacksonHttpMessageConverter
with the custom ObjectMapper before any of the default HttpMessageConverters (which are still present due toregister-defaults="true"
).就我而言(Spring 3.2.4 和 Jackson 2.3.1),自定义序列化器的 XML 配置:
以无法解释的方式被某些东西覆盖回默认值。
这对我有用:
CustomObject.java
CustomObjectSerializer.java
我的解决方案中不需要 XML 配置 (
(...)
) 。In my case (Spring 3.2.4 and Jackson 2.3.1), XML configuration for custom serializer:
was in unexplained way overwritten back to default by something.
This worked for me:
CustomObject.java
CustomObjectSerializer.java
No XML configuration (
<mvc:message-converters>(...)</mvc:message-converters>
) is needed in my solution.我希望我能更好地了解 Spring MVC,但是对于像 Jersey 和 RESTeasy 这样的 Jax-RS 实现,需要注册提供者。也许 Spring 也做了类似的事情?
I wish I knew Spring MVC better, but with Jax-RS implementations like Jersey and RESTeasy, one registers providers. Maybe Spring does something similar?
MappingJacksonHttpMessageConverter 的 spring 文档状态:
2.4.5 MappingJacksonHttpMessageConverter
一个 HttpMessageConverter 实现,可以使用 Jackson JSON Processor 的 ObjectMapper 读取和写入 JSON。 JSON 映射可以根据需要通过使用 Jackson 提供的注释进行自定义。当需要进一步控制时,可以通过 ObjectMapper 属性注入自定义 ObjectMapper,以应对需要为特定类型提供自定义 JSON 序列化器/反序列化器的情况。默认情况下,此转换器支持 (application/json)。
难道您不能自动连接对 ObjectMapper 的访问以修改它的行为吗?
The spring docs for MappingJacksonHttpMessageConverter state:
2.4.5 MappingJacksonHttpMessageConverter
An HttpMessageConverter implementation that can read and write JSON using Jackson JSON Processor's ObjectMapper. JSON mapping can be customized as needed through the use of Jackson's provided annotations. When further control is needed, a custom ObjectMapper can be injected through the ObjectMapper property for cases where custom JSON serializers/deserializers need to be provided for specific types. By default this converter supports (application/json).
Couldn't you just autowire access to the ObjectMapper in order to modify it's behaviour?