복붙노트

[SPRING] Joda DateTime을 ISO 8601 형식으로 자동 포맷

SPRING

Joda DateTime을 ISO 8601 형식으로 자동 포맷

http://wiki.fasterxml.com/JacksonFAQDateHandling에 따르면, "DateTime은 java.util.Date가 처리되는 것과 비슷하게 자동으로 직렬화 / 직렬화 해제 될 수 있습니다."그러나이 자동 기능을 수행 할 수는 없습니다. 이 주제와 관련된 StackOverflow 토론은 대부분 코드 기반 솔루션과 관련이 있지만 위의 견적에 기반하여 간단한 구성을 통해이를 수행 할 수 있어야합니다.

Per http://wiki.fasterxml.com/JacksonFAQDateHandling 시간 기록으로 날짜를 쓰는 것이 거짓이되도록 구성을 설정했습니다. 결과적으로 java.util.Date 형식은 ISO 8601 형식으로 serialize되지만 org.joda.time.DateTime 형식은 long 개체 표현으로 serialize됩니다.

내 환경은 다음과 같습니다.

잭슨 2.1 조다 시간 2.1 봄 3.2 Java 1.6

jsonMapper 빈에 대한 My Spring 구성은 다음과 같습니다.

@Bean
public ObjectMapper jsonMapper() {
    ObjectMapper objectMapper = new ObjectMapper();

    //Fully qualified path shows I am using latest enum
    ObjectMapper.configure(com.fasterxml.jackson.databind.SerializationFeature.
        WRITE_DATES_AS_TIMESTAMPS , false);

    return objectMapper;
}

내 테스트 코드 스 니펫은 다음과 같습니다.

Date d = new Date();
DateTime dt = new DateTime(d); //Joda time 
Map<String, Object> link = new LinkedHashMap<String, Object>();
link.put("date", d);
link.put("createdDateTime", dt);

결과 JSON 출력 스 니펫은 다음과 같습니다.

{"date":"2012-12-24T21:20:47.668+0000"}

{"createdDateTime": {"year":2012,"dayOfMonth":24,"dayOfWeek":1,"era":1,"dayOfYear":359,"centuryOfEra":20,"yearOfEra":2012,"yearOfCentury":12,"weekyear":2012,"monthOfYear":12 *... remainder snipped for brevity*}}

내 기대는 DateTime 개체 구성을 기준으로 Date 개체의 matche합니다. 내가 뭘 잘못하고 있니? 내가 뭘 잘못 생각하니? 잭슨 문서에서 자동으로 단어를 읽었으며 ISO 8601이 아니지만 문자열 표현이 생성되어 광고 된 자동 기능이 생성된다는 사실을 알고 있습니까?

해결법

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

    1.잭슨 사용자 메일 링리스트에서 이에 대한 답변을 얻을 수 있었으며 초보자 용 문제이므로 나와 공유하고 싶었습니다. Jackson Date FAQ를 읽으면서, 나는 여분의 의존성과 등록이 필요하다는 것을 깨닫지 못했지만, 그렇습니다. git hub 프로젝트 페이지 (https://github.com/FasterXML/jackson-datatype-joda)에 문서화되어 있습니다.

    잭슨 사용자 메일 링리스트에서 이에 대한 답변을 얻을 수 있었으며 초보자 용 문제이므로 나와 공유하고 싶었습니다. Jackson Date FAQ를 읽으면서, 나는 여분의 의존성과 등록이 필요하다는 것을 깨닫지 못했지만, 그렇습니다. git hub 프로젝트 페이지 (https://github.com/FasterXML/jackson-datatype-joda)에 문서화되어 있습니다.

    본질적으로 Joda 데이터 유형에 특정한 Jackson jar 파일에 다른 종속성을 추가해야만했습니다. 그런 다음 객체 매퍼에 해당 모듈의 사용을 등록해야했습니다. 코드 스 니펫은 아래에 있습니다.

    내 Jackson Joda 데이터 형식 Maven 종속성 설정을 위해 나는 이것을 사용했다 :

    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-joda</artifactId>
        <version>${jackson.version}</version>
    </dependency>
    

    Joda 직렬화 / 직렬화 해제 기능을 등록하려면 다음을 사용했습니다.

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.registerModule(new JodaModule());
    objectMapper.configure(com.fasterxml.jackson.databind.SerializationFeature.
        WRITE_DATES_AS_TIMESTAMPS , false);
    
  2. ==============================

    2.스프링 부트 사용.

    스프링 부트 사용.

    Maven 설정에 추가 ...

    <dependency>
      <groupId>com.fasterxml.jackson.datatype</groupId>
      <artifactId>jackson-datatype-joda</artifactId>
      <version>2.7.5</version>
    </dependency>
    

    그렇다면 귀하의 WebConfiguration ...

    @Configuration
    public class WebConfiguration extends WebMvcConfigurerAdapter
    {
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters)
        {
          final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
          final ObjectMapper objectMapper = new ObjectMapper();
    
          //configure Joda serialization
          objectMapper.registerModule(new JodaModule());
          objectMapper.configure(
              com.fasterxml.jackson.databind.SerializationFeature.
                WRITE_DATES_AS_TIMESTAMPS , false);
    
          // Other options such as how to deal with nulls or identing...
          objectMapper.setSerializationInclusion (
             JsonInclude.Include.NON_NULL);
          objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
    
          converter.setObjectMapper(objectMapper);
          converters.add(converter);
          super.configureMessageConverters(converters);
        }
    }
    
  3. ==============================

    3.스프링 부트에서는 설정이 훨씬 간단합니다. 방금 Maven 의존성 선언

    스프링 부트에서는 설정이 훨씬 간단합니다. 방금 Maven 의존성 선언

        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-joda</artifactId>
        </dependency>
    

    application.yml / properties 파일에 구성 매개 변수를 추가하십시오.

    spring.jackson.serialization.write-dates-as-timestamps: false
    
  4. ==============================

    4.내가 사용하는 업데이트 된 작업 예제를 게시 할 줄 알았는데 : Spring 4.2.0.RELEASE, Jackson 2.6.1, Joda 2.8.2

    내가 사용하는 업데이트 된 작업 예제를 게시 할 줄 알았는데 : Spring 4.2.0.RELEASE, Jackson 2.6.1, Joda 2.8.2

    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/mvc"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
        xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
        xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/util  http://www.springframework.org/schema/util/spring-util.xsd
            ">
    
        <!-- DispatcherServlet Context: defines this servlet's request-processing 
            infrastructure -->
    
        <!-- Enables the Spring MVC @Controller programming model -->
        <annotation-driven>
            <message-converters>
                <beans:bean
                    class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                    <beans:property name="objectMapper" ref="objectMapper" />
                </beans:bean>
            </message-converters>
        </annotation-driven>
    
        <!-- Handles HTTP GET requests for /resources/** by efficiently serving 
            up static resources in the ${webappRoot}/resources directory -->
        <resources mapping="/resources/**" location="/resources/" />
    
        <!-- Resolves views selected for rendering by @Controllers to .jsp resources 
            in the /WEB-INF/views directory -->
        <beans:bean
            class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <beans:property name="prefix" value="/WEB-INF/views/" />
            <beans:property name="suffix" value=".jsp" />
        </beans:bean>
    
        <beans:bean id="objectMapper"
            class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
            <beans:property name="featuresToDisable">
                <beans:array>
                    <util:constant
                        static-field="com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS" />
                </beans:array>
            </beans:property>
            <beans:property name="modulesToInstall"
                value="com.fasterxml.jackson.datatype.joda.JodaModule" />
        </beans:bean>
    
        <beans:bean id="localeResolver"
            class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
            <beans:property name="defaultLocale" value="en" />
        </beans:bean>
    
        <!-- Configure the Message Locale Resources -->
        <beans:bean id="messageSource"
            class="org.springframework.context.support.ResourceBundleMessageSource">
            <beans:property name="basename" value="errors" />
        </beans:bean>
    
        <beans:bean id="versionSource"
            class="org.springframework.context.support.ResourceBundleMessageSource">
            <beans:property name="basename" value="version" />
        </beans:bean>
    
    
        <!-- DataSource -->
        <beans:bean id="dataSource"
            class="org.springframework.jndi.JndiObjectFactoryBean">
            <beans:property name="jndiName" value="java:comp/env/jdbc/TestDB" />
        </beans:bean>
    
    
        <!-- POJO: Configure the DAO Implementation -->
        <beans:bean id="publicationsDAO"
            class="com.test.api.publication.PublicationsDAOJdbcImpl">
            <beans:property name="dataSource" ref="dataSource" />
        </beans:bean>
    
    
        <!-- Things to auto-load -->
        <context:component-scan base-package="com.test.api" />
        <context:component-scan base-package="com.test.rest" />
    
    </beans:beans>
    

    API 코드

    package com.test.api.publication;
    
    import java.util.Map;
    
    import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
    import com.fasterxml.jackson.annotation.JsonProperty;
    import com.fasterxml.jackson.annotation.JsonRootName;
    
    @JsonRootName("event")
    @JsonIgnoreProperties(ignoreUnknown=true)
    public class Publication {
    
        private Map<String, Object> tokens;
        private String href;
        private String policy_path;
    
        @JsonProperty("tokens")
        public Map<String, Object> getTokens() {
            return tokens;
        }
    
        @JsonProperty("tokens")
        public void setTokens(Map<String, Object> tokens) {
            this.tokens = tokens;
        }
    
        @JsonProperty("href")
        public String getHref() {
            return href;
        }
    
        @JsonProperty("href")
        public void setHref(String href) {
            this.href = href;
        }
    
        @JsonProperty("policyPath")
        public String getPolicyPath() {
            return policy_path;
        }
    
        @JsonProperty("policyPath")
        public void setPolicyPath(String policy_path) {
            this.policy_path = policy_path;
        }
    
    
    }
    
    
    package com.test.api.publication;
    
    import javax.sql.DataSource;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class PublicationsDAOJdbcImpl implements PublicationsDAO{
    
        static final Logger logger = LoggerFactory.getLogger(PublicationsDAOJdbcImpl.class.getName());
        private DataSource _dataSource;
    
        @Override
        public void setDataSource(DataSource ds) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void close() {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public Publication getPublication(String policyPath) {
            Publication ret = new Publication();
            //TODO: do something
            return ret;
        }
    
    }
    
    
    
    package com.test.rest.publication;
    
    import java.util.HashMap;
    
    import org.joda.time.DateTime;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.test.api.publication.Publication;
    import com.test.api.publication.PublicationsDAO;
    import com.test.rest.error.UnknownResourceException;
    
    @RestController
    @RequestMapping("/pub")
    public class PublicationController {
    
            private static final Logger logger = LoggerFactory.getLogger(PublicationController.class);
    
            @Autowired
            @Qualifier("publicationsDAO")
            private PublicationsDAO publicationsDAO;
    
            /**********************************************************************************************************************
             * 
             * @param policyPath
             * @return
             * @throws UnknownResourceException
             */
            @RequestMapping(value = "/{policyPath}", method = RequestMethod.GET)
            public Publication getByPolicyPath(@PathVariable String policyPath) throws UnknownResourceException{
                logger.debug("policyPath=" + policyPath);
    
                Publication ret = publicationsDAO.getPublication(policyPath);
    
                HashMap<String, Object> map = new HashMap<String, Object>();
                map.put("TEST1", null);
                map.put("TEST2", new Integer(101));
                map.put("TEST3", "QuinnZilla");
                map.put("TEST4", new DateTime());
                ret.setTokens(map);
                return ret;
    
            }
    
    }
    

    그리고 출력 결과를 얻습니다.

    {
      "tokens": {
        "TEST2": 101,
        "TEST3": "QuinnZilla",
        "TEST4": "2015-10-06T16:59:35.120Z",
        "TEST1": null
      },
      "href": null,
      "policyPath": null
    }
    
  5. from https://stackoverflow.com/questions/14026081/jackson-automatic-formatting-of-joda-datetime-to-iso-8601-format by cc-by-sa and MIT license