Spring mvc 에서 시간의 전환 과 직렬 화 등 문 제 를 철저히 해결 하 다.

아 픈 점
Spring mvc 를 사용 하여 개발 할 때 우 리 는 전단 에서 들 려 오 는 특정한 형식의 시간 문자열 을 자주 만 나 자바 8 의 새로운 특성 인 자바.time 패키지 의 구체 적 인 유형 매개 변수 로 직접 받 을 수 없습니다.자바.time 패 키 징 형식 을 포함 하 는 매개 변 수 를 사용 하여 수신 하 는 것 도 역 직렬 화 문 제 를 보고 할 수 있 습 니 다.전단 으로 돌아 가 는 시간 유형 에 도 포맷 문제 가 발생 할 수 있 습 니 다.오늘 우 리 는 그들 을 철저히 해결 할 것 이다.
건의 하 다.
사실 가장 과학적 인 건 의 는 시간 표를 통일 적 으로 사용 하 는 것 이 시간 을 대표 한다.이것 은 가장 완벽 한 것 으로 전단 브 라 우 저의 호환성 문 제 를 피 하 는 동시에 다른 미들웨어 의 직렬 화/반 직렬 화 문 제 를 피 할 수 있 습 니 다.하지만 시간 으로 표현 하면 의미 화 될 수 있다.두 가지 방식 은 각각 천추 가 있 습 니 다.만약 우리 가 자바 8 의 시간 라 이브 러 리 를 꾸준히 사용한다 면 방법 이 없 는 것 은 아 닙 니 다.다음은 자바.time.LocalDateTime 을 예 로 들 어 하나씩 해결 하 겠 습 니 다.
국부 주해 방식
인터넷 상에 서 많은 글 들 이 이 주 해 는 전단 이 백 엔 드 를 가리 키 는 것 이 라 고 말 합 니 다.즉,전단 이 백 엔 드 에 전달 하 는 시간 매개 변 수 를 포맷 해서 사용 한 것 입 니 다.이것 은 잘못 이 없습니다!그러나 이 방식 은 반 서열 화 와 관련 이 없 는 상황 에서 만 적용 된다 는 작은 문제 가 있다.즉,다음 필드 에 만 적용:

 @GetMapping("/local")
 public Map<String, String> data(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime localDateTime) {
  Map<String, String> map = new HashMap<>(1);
  map.put("data", localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
  return map;
 }
만약 당신 이 아래 의 이 장면 에서 사용 하면 안 됩 니 다.

@Data
public class UserInfo {

 @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
 private LocalDateTime birthday;
 private String name;
 private Integer age;
}


 @PostMapping("/user")
 public Object postData(@RequestBody UserInfo userInfo) {
  System.out.println("userInfo = " + userInfo);
  return userInfo;
 }

post 요청 매개 변 수 는 body 에 있 기 때문에 반 직렬 화 대상 이 필요 합 니 다.기본 값 은 jackson 라 이브 러 리 로 역 직렬 화 되 며@DateTimeFormat 주석 체 제 를 실행 하지 않 습 니 다.이때 우 리 는 jackson 의 포맷 주 해 를 사용 해 야 합 니 다@JSonFormat.우 리 는 실체 류 User Info 를 아래 의 것 으로 개조 하면 된다.

@Data
public class UserInfo {

 @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
 private LocalDateTime birthday;
 private String name;
 private Integer age;
}

상기 두 개의 주 해 는 병존 할 수 있 지만 반드시 각자 의 사용 장면 을 잘 알 아야 한다.여기에 또 하나의 작은 세부 사항 이 있다.형식 은 반드시 시간 유형 에 잘 대응 해 야 한다.예 를 들 어 yyy-MM-dd 는 java.time.LocalDate 에 대응 합 니 다.좀 더 개성 화 하려 면@JSonFormat 은@JSonDeserialize 와@JSonSerialize 로 대체 할 수 있 습 니 다.그러나 이들 의 using 인 자 는 자신 이 대응 하 는 시간 유형 을 실현 해 야 합 니 다.@JSonFormat,@JSonDeserialize 와@JSonSerialize 가 동시에 존재 한다 면@JSonFormat 의 우선 순위 가 더 높 습 니 다.
국부 처리 의 이점
부분 처리 의 장점 은 여덟 글자 에 있다.백화제방,백가쟁명 이다.다양성 과 개성 을 유지 할 수 있다.그러나 부분 적 으로 새로운 문 제 를 가 져 왔 다.공 통 된 기준 이 없고 호 환 되 지 않 는 다.유지 하기 가 불편 합 니 다.그래서 가끔 은 업 무 를 바탕 으로 우리 의 글로벌 화 를 통 해 통일 적 으로 관리 할 수 있어 야 한다.다음은 전역 화 설정 을 어떻게 하 는 지 설명 하 겠 습 니 다.
전역 화 시간 형식 설정
전역 화 는 사실@DateTimeFormat 과@JSonFormat 두 가지 장면 을 바탕 으로 설정 합 니 다.@DateTimeFormat 의 장면 에 대해 저 희 는 Spring 이 제공 하 는 인 터 페 이 스 를 실현 합 니 다.

DateTimeFormatter :

  //      
 private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.CHINA);

형식 변환 인터페이스:

org.springframework.core.convert.converter.Converter<S,T>
실현:

 @Bean
 public Converter<String, LocalDateTime> localDateConverter() {
  return new Converter<String, LocalDateTime>() {
   @Override
   public LocalDateTime convert(String source) {
    return LocalDateTime.parse(source, FORMATTER);
   }
  };
 }
또는 인터페이스 포맷:

org.springframework.format.Formatter<T>
실현:

@Bean
 public Formatter<LocalDateTime> localDateFormatter() {
  return new Formatter<LocalDateTime>() {
   @Override
   public LocalDateTime parse(String text, Locale locale) throws ParseException {
    return LocalDateTime.parse(text, FORMATTER);
   }

   @Override
   public String print(LocalDateTime object, Locale locale) {
    return object.format(FORMATTER);
   }
  };
 }

상기 두 인터페이스의 실현 은 모두 Spring Bean 으로 등록 해 야 합 니 다.설정 할 때 둘 중 하 나 를 선택 하면 됩 니 다.그 중에서 S 는 Source,즉 소스 입 니 다.사실은 전단 의 시간 문자열 입 니 다.T 즉 Target 즉 목표 입 니 다.전환 하거나 포맷 해 야 하 는 시간 자바 타 입 입 입 니 다.그러면 시간 서열 화 와 반 서열 화 에 대해 다음 과 같은 설정 을 하면 됩 니 다.(기본 잭 슨 을 바탕 으로 LocalDateTime 을 예 로 들 면)

 @Bean
 public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {

  return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder
     //     
    .deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(FORMATTER))
     //    
    .serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(FORMATTER));
 }

마찬가지 로 이 jsonMapper 사용자 정의 구축 기 는 Spring Bean 으로 등록 해 야 합 니 다.
전역 설정 요점
전역 배치 의 일부 장단 점 은 위 에서 이미 논술 하 였 으 니,여기 서 나 는 네가 구 덩이 를 밟 지 않도록 요점 을 말 해 야 한다.전역 설정 은 부분 설정 과 같 습 니 다.마찬가지 로 pattern 을 약속 해 야 합 니 다.이것 은 우리 전체 국면 이 일치 하도록 요구한다.우 리 는 LocalDate,OffsetDateTime 과 같은 여러 개의 전역 설정 을 실현 할 수 있 습 니 다.또한 만약 에 우리 가 다른 직렬 화/반 직렬 화 를 필요 로 하 는 중간 부품,예 를 들 어 redis,rabbitmq 에 접속 했다 면 우 리 는 적절 한 배합 에 주의해 야 한다.
총결산
이상 의 시간 형식의 국부 와 전역 처리 방식 에 대한 소 개 를 통 해 당신 을 괴 롭 히 는 Spring mvc 시간 문 제 는 더 이상 존재 하지 않 을 것 이 라 고 믿 습 니 다.여러분 의 학습 에 도움 이 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.
작자
원본:https://segmentfault.com/a/1190000020423352

좋은 웹페이지 즐겨찾기