Jersey+Jacksonで日付のフォーマットを変更する

Jeysey の JSON 変換に Jackson を使っている場合で、日付のフォーマットを任意のフォーマットに変更する方法。

ちなみに、デフォルトでサポートされている日付フォーマットは以下。

- `yyyy-MM-dd'T'HH:mm:ss.SSSZ`
- `yyyy-MM-dd'T'HH:mm:ss.SSS'Z'`
- `EEE, dd MMM yyyy HH:mm:ss zzz`
- `yyyy-MM-dd`

#環境
##アプリケーションサーバー
Tomcat 7.0.50

##Jersey
2.10.1

#実装
```groovy:build.gradle
dependencies {
    providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
    compile'org.glassfish.jersey.containers:jersey-container-servlet:2.10.1'
    compile 'org.glassfish.jersey.media:jersey-media-json-jackson:2.10.1'
}
```

```java:MyConfig.java
package sample.jersey;

import javax.ws.rs.ApplicationPath;

import org.glassfish.jersey.server.ResourceConfig;

@ApplicationPath("rest")
public class MyConfig extends ResourceConfig {
    
    public MyConfig() {
        packages(this.getClass().getPackage().getName());
    }
}
```

```java:JacksonConfigurator.java
package sample.jersey;

import java.text.SimpleDateFormat;

import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;

import com.fasterxml.jackson.databind.ObjectMapper;

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class JacksonConfigurator implements ContextResolver<ObjectMapper> {

    private ObjectMapper mapper = new ObjectMapper();

    public JacksonConfigurator() {
        mapper.setDateFormat(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"));
    }

    @Override
    public ObjectMapper getContext(Class<?> arg0) {
        return mapper;
    }
}
```

`ContextResolver` を実装したクラスを用意し、 `getContext()` で日付フォーマットを設定した `ObjectMapper` を返却する。

```java:SampleResource.java
package sample.jersey.resource;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;

@Path("sample")
public class SampleResource {
    
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public void post(Form form) {
        System.out.println(form);
    }
}
```

```java:Form.java
package sample.jersey.resource;

import java.text.SimpleDateFormat;
import java.util.Date;

public class Form {

    private Date date;
    
    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    @Override
    public String toString() {
        return new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(this.date);
    }
}
```

```html:index.html
<html>
  <head>
    <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
    <script>
      $(function() {
        $.ajax({
          type: 'POST',
          contentType: 'application/json',
          url: 'rest/sample',
          data: '{"date": "2014/01/01 11:12:13"}',
          complete: function(xhr) {
            $('body').empty().html(xhr.responseText);
          }
        });
      });
    </script>
  </head>
  <body>
  </body>
</html>
```

#動作確認
ブラウザを開いて `index.html` を開く。

```text:サーバー側コンソール出力
2014/01/01 11:12:13
```

#参考
- [8.1.4. Jackson | Chapter 8. Support for Common Media Type Representations](https://jersey.java.net/documentation/latest/media.html#json.jackson)
- [Jackson - JSON Processor | GitHub Gist](https://gist.github.com/wtokuno/1996260)
- [java - Jersey + Jackson JSON date serialization format problem - how to change the format or use custom JacksonJsonProvider - Stack Overflow](http://stackoverflow.com/questions/4428109/jersey-jackson-json-date-serialization-format-problem-how-to-change-the-form)