Spring 3.1自定义JSON转换器

时间:2021-03-20 18:01:19

Im using Spring MVC 3.1 which by default uses Jackson for JSON-Java conversions.

我使用Spring MVC 3.1,它默认使用Jackson进行JSON-Java转换。

I need to create custom conversions for the following:

我需要为以下内容创建自定义转化:

  1. java.util.List (for all sorts of different types).
  2. java.util.List(适用于各种不同类型)。
  3. Enums to strings
  4. 枚举到字符串
  5. java.util.Calendar
  6. java.util.Calendar中

I have encountered a few different approaches for creating my custom converters:

我遇到了一些创建自定义转换器的不同方法:

  1. As described here more or less, create a custom ObjectMapper:

    如此处或多或少所述,创建一个自定义ObjectMapper:

    public class CustomObjectMapper extends ObjectMapper...

    公共类CustomObjectMapper扩展了ObjectMapper ...

Then adding MappingJacksonHttpMessageConverter to my servlet-context and register it with my custom ObjectMapper:

然后将MappingJacksonHttpMessageConverter添加到我的servlet-context并使用我的自定义ObjectMapper注册它:

Then i guess I need to have some specific implementations in my custom objectMapper (how should it look like?).

然后我想我需要在我的自定义objectMapper中有一些特定的实现(它应该如何?)。

  1. A second approach talks about extending FormattingConversionServiceFactoryBean and create my own converters (a class that implements org.springframework.core.convert.converter.Converter) as described here.
  2. 第二种方法讨论扩展FormattingConversionServiceFactoryBean并创建我自己的转换器(实现org.springframework.core.convert.converter.Converter的类),如此处所述。

UPDATE 1: Another approach I have seen is to subcalss MappingJacksonHttpMessageConverter and override getJavaType method, as described here. To do this I will have to add my custom converter to the list of converters:

更新1:我看到的另一种方法是subcalss MappingJacksonHttpMessageConverter并覆盖getJavaType方法,如此处所述。为此,我必须将我的自定义转换器添加到转换器列表:

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
    <list>
        <bean class="com.yl.app.CustomMappingJacksonHttpMessageConverter">
    </list>
</property>

Which approach is the recommended one? Are these the only ones, is there a better way of doing it?

推荐哪种方法?这些是唯一的,有更好的方法吗?

UPDATE 2:

更新2:

I still don't get it. In practice, suppose I have class A and class B.

我仍然没有得到它。在实践中,假设我有A级和B级。

Class A holds a list of B:

A类包含B的列表:

public class A {

   public List<B> list;

}

I would like to return an object of type A to my client. What should I do in my server besides adding the @ResponseBody annotation (which is not enough in this case as far as I get it)?

我想将A类型的对象返回给我的客户端。除了添加@ResponseBody注释之外,我应该在我的服务器中做什么(就我而言,在这种情况下还不够)?

2 个解决方案

#1


6  

Both approaches serve different purposes:

两种方法都有不同的用途:

The first approach that you have outlined is to customize Jackson ObjectMapper - say for eg, to show the date in a different format in the json or to register a custom serializer to handle mapping a class to a json a little differently.

您已经概述的第一种方法是自定义Jackson ObjectMapper - 例如,在json中以不同的格式显示日期或注册自定义序列化程序以处理将类映射到json的方式略有不同。

The second approach is to register converters - to transform one object to another, say for eg, to convert a String request parameter from the UI to an object or say if you get the entity id of a field and want to convert it to an entity.

第二种方法是注册转换器 - 将一个对象转换为另一个对象,例如,将String请求参数从UI转换为对象,或者说如果获得字段的实体ID并希望将其转换为实体。

So both have their place, to customize Jackson you would use the first approach, to create custom converters you would use the second approach.

所以两者都有自己的位置,为了定制杰克逊你将使用第一种方法,创建自定义转换器,你将使用第二种方法。

Update: Based on the new information that you have provided, I think what you are looking for is actually a HttpMessageConverter not a Converter.

更新:根据您提供的新信息,我认为您正在寻找的实际上是HttpMessageConverter而不是转换器。

When you say you want to return an object of type A to your client, you would serialize it some way over the wire - json or xml typically, but potentially other formats also - if you are going to convert it to json then you essentially customize ObjectMapper underlying MappingJacksonHttpMessageConverter(with Jackson 1.x) or MappingJackson2HttpMessageConverter(with Jackson2.x) you would typically do this:

当你说你想要将A类型的对象返回给你的客户端时,你会通过某种方式将它序列化 - 通常是json或xml,但也可能是其他格式 - 如果你要将它转换为json那么你实际上是自定义的ObjectMapper底层MappingJacksonHttpMessageConverter(使用Jackson 1.x)或MappingJackson2HttpMessageConverter(使用Jackson2.x)你通常会这样做:

<mvc:annotation-driven conversion-service="conversionService"> 
   <mvc:message-converters register-defaults="true">
       <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
           <property name="objectMapper">
               <bean class="org.bk.lmt.web.spring.CustomObjectMapper"/>
           </property>
       </bean>
   </mvc:message-converters>
</mvc:annotation-driven>

and in the Custom Object Mapper, register the appropriate serializers/deserializers IF you want to customize the Json representation.

在自定义对象映射器中,如果要自定义Json表示,请注册相应的序列化器/反序列化器。

Similarly with XML, you would typically not write your own converter(Jaxb2RootElementHttpMessageConverter), but use XmlJavaAdapters to customize how some of the elements are serialized.

与XML类似,您通常不会编写自己的转换器(Jaxb2RootElementHttpMessageConverter),而是使用XmlJavaAdapters来自定义某些元素的序列化方式。

If you have some new serialization format (not xml, json), then yes, you can attempt writing a HttpMessageConverter from scratch.

如果您有一些新的序列化格式(不是xml,json),那么是的,您可以尝试从头开始编写HttpMessageConverter。

#2


-2  

After trying it myself, non of the listed approaches is required. Jackson (as is) is capable of handling nested Collections just fine, no customization required.

在自己尝试之后,不需要列出的方法。 Jackson(按原样)能够很好地处理嵌套集合,无需定制。

#1


6  

Both approaches serve different purposes:

两种方法都有不同的用途:

The first approach that you have outlined is to customize Jackson ObjectMapper - say for eg, to show the date in a different format in the json or to register a custom serializer to handle mapping a class to a json a little differently.

您已经概述的第一种方法是自定义Jackson ObjectMapper - 例如,在json中以不同的格式显示日期或注册自定义序列化程序以处理将类映射到json的方式略有不同。

The second approach is to register converters - to transform one object to another, say for eg, to convert a String request parameter from the UI to an object or say if you get the entity id of a field and want to convert it to an entity.

第二种方法是注册转换器 - 将一个对象转换为另一个对象,例如,将String请求参数从UI转换为对象,或者说如果获得字段的实体ID并希望将其转换为实体。

So both have their place, to customize Jackson you would use the first approach, to create custom converters you would use the second approach.

所以两者都有自己的位置,为了定制杰克逊你将使用第一种方法,创建自定义转换器,你将使用第二种方法。

Update: Based on the new information that you have provided, I think what you are looking for is actually a HttpMessageConverter not a Converter.

更新:根据您提供的新信息,我认为您正在寻找的实际上是HttpMessageConverter而不是转换器。

When you say you want to return an object of type A to your client, you would serialize it some way over the wire - json or xml typically, but potentially other formats also - if you are going to convert it to json then you essentially customize ObjectMapper underlying MappingJacksonHttpMessageConverter(with Jackson 1.x) or MappingJackson2HttpMessageConverter(with Jackson2.x) you would typically do this:

当你说你想要将A类型的对象返回给你的客户端时,你会通过某种方式将它序列化 - 通常是json或xml,但也可能是其他格式 - 如果你要将它转换为json那么你实际上是自定义的ObjectMapper底层MappingJacksonHttpMessageConverter(使用Jackson 1.x)或MappingJackson2HttpMessageConverter(使用Jackson2.x)你通常会这样做:

<mvc:annotation-driven conversion-service="conversionService"> 
   <mvc:message-converters register-defaults="true">
       <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
           <property name="objectMapper">
               <bean class="org.bk.lmt.web.spring.CustomObjectMapper"/>
           </property>
       </bean>
   </mvc:message-converters>
</mvc:annotation-driven>

and in the Custom Object Mapper, register the appropriate serializers/deserializers IF you want to customize the Json representation.

在自定义对象映射器中,如果要自定义Json表示,请注册相应的序列化器/反序列化器。

Similarly with XML, you would typically not write your own converter(Jaxb2RootElementHttpMessageConverter), but use XmlJavaAdapters to customize how some of the elements are serialized.

与XML类似,您通常不会编写自己的转换器(Jaxb2RootElementHttpMessageConverter),而是使用XmlJavaAdapters来自定义某些元素的序列化方式。

If you have some new serialization format (not xml, json), then yes, you can attempt writing a HttpMessageConverter from scratch.

如果您有一些新的序列化格式(不是xml,json),那么是的,您可以尝试从头开始编写HttpMessageConverter。

#2


-2  

After trying it myself, non of the listed approaches is required. Jackson (as is) is capable of handling nested Collections just fine, no customization required.

在自己尝试之后,不需要列出的方法。 Jackson(按原样)能够很好地处理嵌套集合,无需定制。