복붙노트

[SPRING] Spring에서 JSON deserializer를 작성하거나 확장하는 올바른 방법

SPRING

Spring에서 JSON deserializer를 작성하거나 확장하는 올바른 방법

봄에 사용자 지정 JSON 디시리얼라이저를 작성하려고합니다. 대부분의 부분에 대해 기본 serializer를 사용하고 몇 가지 속성에 대해 사용자 지정 deserializer를 사용하려고합니다. 가능한가? 대부분의 속성 값이 값이기 때문에 이런 식으로 노력하고 있습니다. 따라서 Jackson에서는 기본 디시리얼라이저를 사용할 수 있습니다. 하지만 참조 속성이 거의 없으므로 사용자 지정 deserializer에서 데이터베이스에 대한 참조 이름을 쿼리하고 데이터베이스에서 참조 값을 가져와야합니다.

필요한 경우 몇 가지 코드를 보여 드리겠습니다.

해결법

  1. ==============================

    1.나는 많은 것을 수색했고, 내가 지금까지 찾은 최선의 방법은이 기사에있다.

    나는 많은 것을 수색했고, 내가 지금까지 찾은 최선의 방법은이 기사에있다.

    직렬화하는 클래스

    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의 새 버전을 사용하는이 기사를 살펴볼 수도 있습니다.

  2. ==============================

    2.내 Deserializer에 Spring 관리 서비스를 @Autowire하려고했습니다. 누군가가 serializer / deserializers를 호출 할 때 새로운 연산자를 사용하여 Jackson에게 저를 안내해주었습니다. 이것은 Jackson의 내 Deserializer 인스턴스의 자동 배선을 의미하지 않았습니다. 다음은 내가 서비스 클래스를 내 Deserializer에 @Autowire 할 수 있었던 방법입니다.

    내 Deserializer에 Spring 관리 서비스를 @Autowire하려고했습니다. 누군가가 serializer / deserializers를 호출 할 때 새로운 연산자를 사용하여 Jackson에게 저를 안내해주었습니다. 이것은 Jackson의 내 Deserializer 인스턴스의 자동 배선을 의미하지 않았습니다. 다음은 내가 서비스 클래스를 내 Deserializer에 @Autowire 할 수 있었던 방법입니다.

    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의 응답은 정확히 필요한 것입니다. 좋은 발견!

  3. ==============================

    3.Spring MVC 4.2.1.RELEASE를 사용하면 디시리얼라이저가 작동하려면 아래의 새로운 Jackson2 종속성을 사용해야합니다.

    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의 클래스가 아닌 역 직렬화를 사용하십시오.

  4. from https://stackoverflow.com/questions/11376304/right-way-to-write-json-deserializer-in-spring-or-extend-it by cc-by-sa and MIT license