Spring MVC LocalDate 参数格式错误
Spring MVC LocalDate parameter has wrong format
我正在使用 Spring Boot 1.5.3,Spring Data REST,Spring JPA,Hibernate。
我在服务器中使用 java.time.* 在 UTC 中工作,我的客户也应该以 UTC 发回日期。
我自定义了一点我的 REST 配置:
@Configuration
public class RestConfig extends RepositoryRestConfigurerAdapter {
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return new Jackson2ObjectMapperBuilderCustomizer() {
@Override
public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
jacksonObjectMapperBuilder.serializers(InstantSerializer.INSTANCE);
jacksonObjectMapperBuilder.serializers(new ZonedDateTimeSerializer(ISO_FIXED_FORMAT));
jacksonObjectMapperBuilder
.serializers(new LocalDateSerializer(new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd").toFormatter()));
jacksonObjectMapperBuilder.serializers(new LocalDateTimeSerializer(
new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd'T'HH:mm:ss'Z'").toFormatter()));
}
};
}
}
我在存储库中创建了自定义方法:
@Transactional
@PreAuthorize("isAuthenticated()")
public interface DailyCodeRepository extends PagingAndSortingRepository<DailyCode, Long> {
@Query("SELECT d FROM DailyCode d WHERE (:code IS NULL OR code=:code) AND (:from IS NULL OR date>=:from) AND (:to IS NULL OR date<=:to)")
public Page<DailyCode> findAllWithParameter(@Param("code") @RequestParam(value = "code", required = false) String code,
@Param("from") @RequestParam(value = "from", required = false) @DateTimeFormat(iso=ISO.DATE) LocalDate from,
@Param("to") @RequestParam(value = "to", required = false) @DateTimeFormat(iso=ISO.DATE) LocalDate to, Pageable pageable);
}
第一个问题是方法接受ISO格式只有如果我放注释@DateTimeFormat(iso=ISO.DATE)
,否则它选择我的语言环境(意大利)的格式。我想将其全局设置为响应(请参阅我的 Jackson2ObjectMapperBuilderCustomizer)。
第二个问题是从客户端发送的日期参数被解释为 1 天前,所以这样的请求:
http://localhost:8080/api/v1/dailyCodes/search/findAllWithParameter?from=2017-07-07&to=2017-07-07
导致对数据库的查询:
select dailycode0_.`id` as id1_7_, dailycode0_.`created_by` as created_2_7_, dailycode0_.`created_date` as created_3_7_, dailycode0_.`last_modified_by` as last_mod4_7_, dailycode0_.`last_modified_date` as last_mod5_7_, dailycode0_.`sid` as sid6_7_, dailycode0_.`version` as version7_7_, dailycode0_.`code` as code8_7_, dailycode0_.`date` as date9_7_ from `daily_code` dailycode0_ where (null is null or dailycode0_.`code`=null) and ('2017-07-06' is null or dailycode0_.`date`>='2017-07-06') and ('2017-07-06' is null or dailycode0_.`date`<='2017-07-06') limit 20
所以它查询了 1 天前,它是错误的。我想这是一个时区问题,但我不知道如何解决。
这是我的属性文件的相关部分:
spring.mvc.date-format= `yyyy-MM-dd`
# REST
spring.data.rest.default-page-size= 20
spring.data.rest.base-path=/api/v1
spring.data.rest.enable-enum-translation=true
#Jackson
# to avoid an error loading lazy objects
spring.jackson.serialization.fail-on-empty-beans=false
spring.jackson.serialization.write-dates-as-timestamps=false
spring.jackson.mapper.infer-property-mutators=false
spring.jpa.properties.hibernate.jdbc.time_zone = UTC
您的代码中存在几个问题:
The first problem is that the method accept the ISO format only
你需要 OffsetDateTime
(不是 ZonedDateTime
,阅读 ) and custom converter. Read 。
date parameters sent from the client are interpreted like 1 day before
为什么?您将此日期解释为哪个时区?您的本地时区可能与服务器的不同,服务器的可能与客户端的不同。
Jackson2ObjectMapperBuilderCustomizer
这是做什么用的?
spring.mvc.date-format=yyyy-MM-dd
这应该不是必需的,而且我不认为对 Spring 数据有任何作用。
我正在使用 Spring Boot 1.5.3,Spring Data REST,Spring JPA,Hibernate。 我在服务器中使用 java.time.* 在 UTC 中工作,我的客户也应该以 UTC 发回日期。 我自定义了一点我的 REST 配置:
@Configuration
public class RestConfig extends RepositoryRestConfigurerAdapter {
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return new Jackson2ObjectMapperBuilderCustomizer() {
@Override
public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
jacksonObjectMapperBuilder.serializers(InstantSerializer.INSTANCE);
jacksonObjectMapperBuilder.serializers(new ZonedDateTimeSerializer(ISO_FIXED_FORMAT));
jacksonObjectMapperBuilder
.serializers(new LocalDateSerializer(new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd").toFormatter()));
jacksonObjectMapperBuilder.serializers(new LocalDateTimeSerializer(
new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd'T'HH:mm:ss'Z'").toFormatter()));
}
};
}
}
我在存储库中创建了自定义方法:
@Transactional
@PreAuthorize("isAuthenticated()")
public interface DailyCodeRepository extends PagingAndSortingRepository<DailyCode, Long> {
@Query("SELECT d FROM DailyCode d WHERE (:code IS NULL OR code=:code) AND (:from IS NULL OR date>=:from) AND (:to IS NULL OR date<=:to)")
public Page<DailyCode> findAllWithParameter(@Param("code") @RequestParam(value = "code", required = false) String code,
@Param("from") @RequestParam(value = "from", required = false) @DateTimeFormat(iso=ISO.DATE) LocalDate from,
@Param("to") @RequestParam(value = "to", required = false) @DateTimeFormat(iso=ISO.DATE) LocalDate to, Pageable pageable);
}
第一个问题是方法接受ISO格式只有如果我放注释@DateTimeFormat(iso=ISO.DATE)
,否则它选择我的语言环境(意大利)的格式。我想将其全局设置为响应(请参阅我的 Jackson2ObjectMapperBuilderCustomizer)。
第二个问题是从客户端发送的日期参数被解释为 1 天前,所以这样的请求:
http://localhost:8080/api/v1/dailyCodes/search/findAllWithParameter?from=2017-07-07&to=2017-07-07
导致对数据库的查询:
select dailycode0_.`id` as id1_7_, dailycode0_.`created_by` as created_2_7_, dailycode0_.`created_date` as created_3_7_, dailycode0_.`last_modified_by` as last_mod4_7_, dailycode0_.`last_modified_date` as last_mod5_7_, dailycode0_.`sid` as sid6_7_, dailycode0_.`version` as version7_7_, dailycode0_.`code` as code8_7_, dailycode0_.`date` as date9_7_ from `daily_code` dailycode0_ where (null is null or dailycode0_.`code`=null) and ('2017-07-06' is null or dailycode0_.`date`>='2017-07-06') and ('2017-07-06' is null or dailycode0_.`date`<='2017-07-06') limit 20
所以它查询了 1 天前,它是错误的。我想这是一个时区问题,但我不知道如何解决。
这是我的属性文件的相关部分:
spring.mvc.date-format= `yyyy-MM-dd`
# REST
spring.data.rest.default-page-size= 20
spring.data.rest.base-path=/api/v1
spring.data.rest.enable-enum-translation=true
#Jackson
# to avoid an error loading lazy objects
spring.jackson.serialization.fail-on-empty-beans=false
spring.jackson.serialization.write-dates-as-timestamps=false
spring.jackson.mapper.infer-property-mutators=false
spring.jpa.properties.hibernate.jdbc.time_zone = UTC
您的代码中存在几个问题:
The first problem is that the method accept the ISO format only
你需要 OffsetDateTime
(不是 ZonedDateTime
,阅读
date parameters sent from the client are interpreted like 1 day before
为什么?您将此日期解释为哪个时区?您的本地时区可能与服务器的不同,服务器的可能与客户端的不同。
Jackson2ObjectMapperBuilderCustomizer
这是做什么用的?
spring.mvc.date-format=yyyy-MM-dd
这应该不是必需的,而且我不认为对 Spring 数据有任何作用。