2017-07-07 12 views
0

私はSpringブート1.5.3、SpringデータREST、Spring JPA、Hibernateを使用しています。 私はサーバでjava.time。*を使用してUTCで作業しています。クライアントはUTCでも日付を返すことになっています。Spring MVC LocalDateパラメータの形式が間違っています

@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形式を受け入れることである最初の問題:私は、リポジトリ内のカスタムメソッドを作成し

@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())); 
     } 

    }; 
} 

}

: 私は少し私のRESTの設定をカスタマイズしました注釈を付けると@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 

答えて

1

これは私の性質の関連する部分であるが、ファイル

を第一の問題は、この方法は、ISO形式のみ

を受け入れるということです

OffsetDateTimeZonedDateTimeではなく、this)とカスタムコンバータが必要です。 thisを読んでください。クライアントから送信され

日付パラメータは

なぜ前に、1日のように解釈されていますか?この日付を解釈するのはどのタイムゾーンですか?あなたのローカルタイムゾーンは、クライアントのものと異なる場合があるサーバーと異なる場合があります。

Jackson2ObjectMapperBuilderCustomizer

これがために使われていますか?

spring.mvc.dateフォーマット= YYYY-MM-DD

これは必要ではないはず、と私はとにかく春データのために何をするとは思いません。

+0

このメソッドは、時刻情報のない日付のみを受け入れる必要があります。この場合、私はそれを必要としません。私はSpring Data REST機能を使用しているので、そのメソッドの実装はありません。サーバーのタイムゾーンはEurope/Romeですが、表示された設定のおかげで、DBにUTC形式の日付を保存しています。 Jackson2ObjectMapperBuilderCustomizerについて私は、https://github.com/spring-projects/spring-boot/issues/4217に従って、クラスを追加して私の質問を編集しました – drenda

+0

@drenda明らかに、クライアントから送られた文字列を日付時刻に変換する必要があります。あなたが 'findAllWithParameter'に送るものにかかわらず。あなたが盲目的にクライアントから送られた文字列をメソッドに渡すと、すべてのクライアントが同じ場所から来ていると見なされますが、これは間違いです。次に、 'findAllWithParameter'とDB時間との間の変換の問題があります。これはUTCと言います。 Springデータメソッドに必要な場合はボディを持つことができます。その場合、カスタムリポジトリが必要になります。 –

+0

Use UTCはベストプラクティスであるため、クライアント(この場合はAngularアプリケーション)はすべての日付をUTC形式で送信します。だから私は、標準でなければならないことのための定型コードをたくさん用意する必要はないと思う。ありがとう – drenda

関連する問題