Spring MVCでリクエストパラメータをバインドする場合は@DateTimeFormat
でパターンを指定しますが、
和暦フォーマット(GGGGyy.MM.dd
など)を指定するとパースエラーが発生します。
和暦を扱う場合はパーサーにLocale
やChronology
を指定する必要があるのですが、
当然ながら日本用のものは指定されていないため、パースエラーとなります。
実はパーサーが使うLocale
やChronology
は、org.springframework.context.i18n.LocaleContextHolder
やorg.springframework.format.datetime.standard.DateTimeContextHolder
を使ってスレッドローカルに保存できます。
なのでFilterやInterceptorでこれを指定してやればOKです。
HandlerInterceptorAdapter
を使う例を以下に示します。
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.datetime.standard.DateTimeContext;
import org.springframework.format.datetime.standard.DateTimeContextHolder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDate;
import java.time.chrono.JapaneseChronology;
import java.util.Date;
import java.util.Locale;
@SpringBootApplication
@RestController
public class DemoWarekiApplication extends WebMvcConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(DemoWarekiApplication.class, args);
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
DateTimeContext context = new DateTimeContext();
context.setChronology(JapaneseChronology.INSTANCE);
Locale japan = new Locale("ja", "JP", "JP");
registry.addInterceptor(new HandlerInterceptorAdapter() {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
DateTimeContextHolder.setDateTimeContext(context); // for java.time.LocalDate
LocaleContextHolder.setLocale(japan); // for java.util.Date
return true;
}
});
}
@RequestMapping(path = "/jud")
Object jud(@DateTimeFormat(pattern = "GGGGyy.MM.dd") @RequestParam(name = "date") Date date) {
return date.toString();
}
@RequestMapping(path = "/jtl")
Object jtl(@DateTimeFormat(pattern = "GGGGyy.MM.dd") @RequestParam(name = "date") LocalDate date) {
return date.toString();
}
}
アクセス例
$ curl "localhost:8080/jud?date=平成28.03.03"
Thu Mar 03 00:00:00 JST 2016
$ curl "localhost:8080/jtl?date=平成28.03.03"
2016-03-03