Статьи

Улучшен быстрый запуск Spring MVC 4 Maven Archetype — больше возможностей Java 8

Для всех тех разработчиков, которые заинтересованы в быстрой загрузке приложения Spring 4 без Spring Boot, пожалуйста, проверьте мой Spring MVC 4 Quickstart Maven Archetype, который только что обновили. Archetype уже использует Java 8 в качестве целевой платформы уже некоторое время, но не поддерживаются конкретные функции Java 8. Недавние изменения включают (помимо исправления некоторых ошибок) поддержку Java 8 Data & Time API в Thymeleaf, Jackson и JPA.

Поддержка Thymeleaf JSR 310 (Java 8 Date & Time)

Если вам довелось работать с Spring MVC и Thymeleaf, и вам необходимо отформатировать объекты Java 8 Date & Time в ваших представлениях, вы можете теперь использовать thymeleaf-extras-java8time — модуль Thymeleaf для Java 8 Date & Time API.

POM был изменен, и была добавлена ​​новая зависимость:

1
2
3
4
5
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-java8time</artifactId>
    <version>2.1.0.RELEASE</version>
</dependency>

Кроме того, Java8TimeDialect был добавлен в TemplateEngine :

1
2
3
4
5
6
7
8
@Bean
public SpringTemplateEngine templateEngine() {
    SpringTemplateEngine templateEngine = new SpringTemplateEngine();
    templateEngine.setTemplateResolver(templateResolver());
    templateEngine.addDialect(new SpringSecurityDialect());
    templateEngine.addDialect(new Java8TimeDialect());
    return templateEngine;
}

Что делает Java8TimeDialect , он добавляет temporals объект в контекст как служебные объекты во время вычислений выражений. Это означает, что его можно использовать в вычислениях выражений OGNL или SpringEL:

1
2
3
4
<div th:fragment="footer" th:align="center">
    © <span th:text="${#temporals.format(#temporals.createNow(), 'yyyy')}">2016</span>,
    <span th:text="${@environment.getProperty('app.version')}"></span>
</div>

Поддержка Jackson JSR 310 (Java 8 Date & Time)

Чтобы иметь возможность сериализовать или десериализовать типы java.time с помощью Jackson, необходимо использовать внешний модуль типа данных. Этот модуль является jackson-datatype-jsr310 .

POM был изменен, и была добавлена ​​новая зависимость:

1
2
3
4
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

Нам не нужно предоставлять версию, так как в проекте используется платформа Spring IO. И если вы не знаете, главное преимущество Spring IO Platform заключается в том, что она упрощает управление зависимостями, предоставляя версии проектов Spring вместе с их зависимостями, которые были протестированы и работают совместно.

На данный момент никакая другая конфигурация не требуется, поскольку модуль будет автоматически зарегистрирован Spring. Это делается с помощью org.springframework.http.converter.json.Jackson2ObjectMapperBuilder .

Пример?

1
2
3
4
5
6
{
    "id": 2,
    "email": "admin",
    "role": "ROLE_ADMIN",
    "created": 1454017095.878
}

где created , который был сериализован до десятичного числа (по умолчанию).

Поддержка JPA JSR 310 (Java 8 Date & Time)

JPA 2.1 не поддерживает отображение типов java.time в допустимые типы SQL или типы отметок времени. К счастью, он предоставляет новый интерфейс AttributeConverter и «класс, который реализует этот интерфейс, может использоваться для преобразования состояния атрибута сущности в представление столбца базы данных и обратно». ,

Такие конвертеры являются частью проекта Spring Data JPA и доступны в классе Jsr310JpaConverters . Этот класс преобразует новые типы java.time в старые типы Date .

Активировать конвертеры можно, сделав пакет org.springframework.data.jpa.convert.threeten для проверки с помощью LocalContainerEntityManagerFactoryBean :

01
02
03
04
05
06
07
08
09
10
11
12
13
@Bean
public LocalContainerEntityManagerFactoryBean emf(DataSource dataSource) {
 
    [...]
 
    String entities = ClassUtils.getPackageName(Application.class);
    String converters = ClassUtils.getPackageName(Jsr310JpaConverters.class);
    entityManagerFactoryBean.setPackagesToScan(entities, converters);       
 
    [...]
 
    return entityManagerFactoryBean;
}

Если вы работаете с PostgreSQL, тип java.time.Instant теперь будет храниться как TIMESTAMP в PostgreSQL вместо BYTEA (как без конвертеров).

Узнайте больше о поддержке JPA 2.1 и JSR 310 здесь: http://www.viousts-on-java.org/persist-localdate-localdatetime-jpa/

Где это найти?

Я с нетерпением жду возможности услышать, что можно улучшить, чтобы сделать этот проект лучше. Если у вас есть идея или предложение, оставьте комментарий или создайте проблему.