63

Spring でカスタム JSON デシリアライザーを作成しようとしています。ほとんどのフィールドにデフォルトのシリアライザーを使用し、いくつかのプロパティにはカスタム デシリアライザーを使用したいと考えています。出来ますか?プロパティのほとんどの部分は値であるため、この方法を試しています。これらについては、Jackson にデフォルトのデシリアライザーを使用させることができます。ただし、ほとんどのプロパティは参照ではないため、カスタム デシリアライザーでは、データベースに参照名を問い合わせ、データベースから参照値を取得する必要があります。

必要に応じて、いくつかのコードを示します。

4

4 に答える 4

95

私はたくさん検索しましたが、これまでに見つけた最良の方法は次の記事です。

シリアライズするクラス

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 を使用するこの記事を見ることができます。

于 2012-07-07T17:54:48.330 に答える
11

@AutowireSpring マネージド サービスを自分のDeserializer. newシリアライザー/デシリアライザーを呼び出すときにオペレーターを使用して、誰かが私をジャクソンに知らせました。これは、 my の Jackson のインスタンスの自動配線がないことを意味しましたDeserializer@Autowireサービスクラスを my に入れる方法は次の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>

myDeserializerが 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の回答はまさに必要なものです。いい発見!

于 2013-12-12T18:30:13.143 に答える
1

Spring MVC 4.2.1.RELEASE では、Deserializer が機能するために、以下のように新しい 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.JsonDeserializerにも and を使用しますcom.fasterxml.jackson.databind.annotation.JsonDeserializeorg.codehaus.jackson

于 2015-10-07T03:14:02.060 に答える