在Spring中编写JSON反序列化器或扩展它的正确方法

时间:2012-07-07 15:36:21

标签: java json spring jackson deserialization

我正在尝试在Spring中编写自定义JSON反序列化程序。我想在大多数字段中使用默认序列化程序,并为少数属性使用自定义反序列化程序。可能吗? 我这样做是因为,大部分属性都是值,所以对于这些我可以让杰克逊使用默认的反序列化器;但是很少有属性是引用,所以在自定义反序列化器中,我必须查询数据库以获取引用名称并从数据库中获取引用值。

如果需要,我会展示一些代码。

3 个答案:

答案 0 :(得分:75)

我搜索了很多内容,到目前为止我找到的最佳方式是article

要序列化的类

package net.sghill.example;

import net.sghill.example.UserDeserializer
import net.sghill.example.UserSerializer
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.codehaus.jackson.map.annotate.JsonSerialize;

@JsonDeserialize(using = UserDeserializer.class)
public class User {
    private ObjectId id;
    private String   username;
    private String   password;

    public User(ObjectId id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }

    public ObjectId getId()       { return id; }
    public String   getUsername() { return username; }
    public String   getPassword() { return password; }
}

反序列化程序类

package net.sghill.example;

import net.sghill.example.User;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.ObjectCodec;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;

import java.io.IOException;

public class UserDeserializer extends JsonDeserializer<User> {

    @Override
    public User deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        ObjectCodec oc = jsonParser.getCodec();
        JsonNode node = oc.readTree(jsonParser);
        return new User(null, node.get("username").getTextValue(), node.get("password").getTextValue());
    }
}

编辑: 或者,您可以查看使用新版本com.fasterxml.jackson.databind.JsonDeserializer的this article

答案 1 :(得分:9)

我正在尝试将@Autowire Spring管理的服务加入Deserializer。在调用序列化程序/反序列化程序时,有人使用new运算符向我发送了许可证。这意味着杰克逊的Deserializer实例没有自动连线。以下是我能够将@Autowire我的服务类加入Deserializer

的方法

<强> context.xml中

<mvc:annotation-driven>
  <mvc:message-converters>
    <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
      <property name="objectMapper" ref="objectMapper" />
    </bean>
  </mvc:message-converters>
</mvc>
<bean id="objectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
    <!-- Add deserializers that require autowiring -->
    <property name="deserializersByType">
        <map key-type="java.lang.Class">
            <entry key="com.acme.Anchor">
                <bean class="com.acme.AnchorDeserializer" />
            </entry>
        </map>
    </property>
</bean>

既然我的Deserializer是一个Spring管理的bean,那么自动连线就可以了!

<强> AnchorDeserializer.java

public class AnchorDeserializer extends JsonDeserializer<Anchor> {
    @Autowired
    private AnchorService anchorService;
    public Anchor deserialize(JsonParser parser, DeserializationContext context)
             throws IOException, JsonProcessingException {
        // Do stuff
    }
}

<强> AnchorService.java

@Service
public class AnchorService {}

更新:当我写这篇文章时,我的原始答案对我有用,但@ xi.lin的回复正是我所需要的。很好找!

答案 2 :(得分:1)

使用Spring MVC 4.2.1.RELEASE,您需要使用下面的新Jackson2依赖项来使反序列化器工作。

不要使用此

<dependency>  
            <groupId>org.codehaus.jackson</groupId>  
            <artifactId>jackson-mapper-asl</artifactId>  
            <version>1.9.12</version>  
        </dependency>  

改为使用它。

<dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.2.2</version>
        </dependency>  

还可以使用com.fasterxml.jackson.databind.JsonDeserializercom.fasterxml.jackson.databind.annotation.JsonDeserialize进行反序列化,而不是org.codehaus.jackson

中的类