Spring BootでLocalDateTime(Java8日時API)を使う方法
Spring BootでJava8日時型である"LocalDate"、"LocalTime"、"LocalDateTime"を使う方法です。
Java8では、Date,Calendarクラスの代替として、
"Instant"、"LocalDateTime"、"ZonedDateTime"
が導入されました。中でもデータベースとの連携でよく使う"LocalDateTime"は「タイムゾーンなしの日時」で、不変の日付/時間オブジェクトです。
Spring BootはJava8での動作が対応されていますが、日時型についてはいくつか設定しないと動作しません。
ここでは Spring BootでJava8日時APIを使用する方法 について紹介します。
環境
今回のサンプルアプリの構築環境です。
- Spring Boot 1.4.1
- Thymeleaf 3.0.2
- Windows7
- Java8
- Eclipse 4.6 Neon
こちらのページを参考にサンプルアプリを作ってください。既にSpring Boot Webアプリがある場合は、読み飛ばして結構です。
Java8日時APIを使う方法
pom.xmlに、Thymeleafの設定を追加します。
<properties>
<java.version>1.8</java.version>
<thymeleaf-extras-java8time.version>3.0.0.RELEASE</thymeleaf-extras-java8time.version>
(・・・省略・・・)
</properties>
<dependencies>
(・・・省略・・・)
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
</dependencies>
テンプレートは「#dates」ではなく、「#temporals」を使用します。
<span id="testDateTime" th:text="${#temporals.format(testDateTime, 'yyyy-MM-dd HH:mm:ss')}" ></span>
次に、Java用のJSONパーサーライブラリである「Jackson」を利用する場合は、pom.xmlに下記を追加します。
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
これで "@RequestBody"、”@ResponseBody"でのJSON変換に対応できます。
"@JsonFormat"の"pattern"に書式を指定しましょう。
リクエストパラメータである"RequestParam"、"@PathValiable"への対応にも考慮しておきます。"@DateTimeFormat"を付与すれば受け取ることができます。
@JsonFormat(pattern = "yyyy/MM/dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy/MM/dd HH:mm:ss")
private LocalDateTime jsonLocalDateTime;
Java8日時APIを検証する
早速、検証してみましょう。
・Controller
@RequestMapping(value = "/", method = RequestMethod.GET)
public String index(Model model) {
model.addAttribute("ldt", LocalDateTime.now());
return "index";
}
・RestController
@RequestMapping(value = "/text-local-date-time", method = RequestMethod.POST)
public String textLocalDateTime() {
return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"));
}
@RequestMapping(value = "/json-local-date-time", method = RequestMethod.POST)
public List<DateBean> jsonLocalDateTime() {
List<DateBean> list = new ArrayList<DateBean>();
DateBean bean = new DateBean();
bean.setJsonLocalDateTime(LocalDateTime.now());
list.add(bean);
return list;
}
・Bean
package springbootapp;
import java.time.LocalDateTime;
import org.springframework.format.annotation.DateTimeFormat;
import com.fasterxml.jackson.annotation.JsonFormat;
public class DateBean {
@JsonFormat(pattern = "yyyy/MM/dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy/MM/dd HH:mm:ss")
private LocalDateTime jsonLocalDateTime;
public LocalDateTime getJsonLocalDateTime() {
return jsonLocalDateTime;
}
public void setJsonLocalDateTime(LocalDateTime jsonLocalDateTime) {
this.jsonLocalDateTime = jsonLocalDateTime;
}
}
・index.html
<p>Thymeleafの#temporals.format()を使った変換:<span th:text="${#temporals.format(ldt, 'yyyy/MM/dd HH:mm:ss')}"></span></p>
<p>DateTimeFormatterを使って変換:<span id="textLocalDateTime"></span></p>
<p>Jacksonを使ってJSON変換:<span id="jsonLocalDateTime"></span></p>
<script type="text/javascript" th:src="@{/webjars/jquery/1.12.4/jquery.min.js}"></script>
<script type="text/javascript">
$.ajax({
type: "post",
url: "/text-local-date-time",
success: function(otdata, dataType) {
$("#textLocalDateTime").html(otdata);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest + ":" + textStatus + ":" + errorThrown);
}
});
$.ajax({
type: "post",
url: "/json-local-date-time",
/*dataType: "json",
contentType: 'application/json',
scriptCharset: 'utf-8',*/
success: function(otdata, dataType) {
$("#jsonLocalDateTime").html(otdata[0].jsonLocalDateTime);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest + ":" + textStatus + ":" + errorThrown);
}
});
</script>
画面表示するとこんな感じになります。
おおお、ちゃんと変換されてますねー^^
まとめ
Spring BootでJava8日時APIを使用する方法を紹介しました。
昔からJavaの日付って扱いにいく印象でしたが、Java8になって更にひどくなった感があります。とはいえ、慣れるしかないのでしょうが、もう少しなんとかしてほしいところですね。もっと簡単に扱えるようになるはいつになるやら・・・。
ちなみに、Doma2では上記の設定だけで連携できました。特別な設定はいりません。助かりますね^^
皆さんも今のうちにJava8日時APIの"クセ"に慣れて、実務で利用できるようにしておくことをおすすめします。
おつかれさまでした。