SpringでカスタムJSONデシリアライザーを作成しようとしています。フィールドのほとんどの部分でデフォルトのシリアライザーを使用し、いくつかのプロパティではカスタムのデシリアライザーを使用します。出来ますか?プロパティの大部分が値であるため、私はこの方法を試しています。したがって、これらの場合、Jacksonにデフォルトのデシリアライザーを使用させることができます。しかし、いくつかのプロパティは参照であるため、カスタムデシリアライザーでは、データベースに参照名を照会し、データベースから参照値を取得する必要があります。
必要に応じていくつかのコードを示します。
私はよく検索しましたが、これまでに見つけた最良の方法はこれです 記事 :
シリアル化するクラス
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の新しいバージョンを使用する この記事 を見ることができます。
私は@Autowire
Spring管理のサービスをDeserializer
に追加します。誰かがシリアライザー/デシリアライザーを呼び出すときにnew
演算子を使用してジャクソンに私をだましました。これは、私のDeserializer
のJacksonのインスタンスの自動配線がないことを意味しました。 @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の応答はまさに必要なものです。素敵な発見!
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.JsonDeserializer
からのクラスではなく、com.fasterxml.jackson.databind.annotation.JsonDeserialize
およびorg.codehaus.jackson
を逆シリアル化に使用します