날짜와 시간 형식 처리의 요약에 대한 Springboot

프로젝트 시간 데이터 유형 DTO LocalDateTime 시리즈로 사용되지만, 항상 다음과 같은 방법을 시도, 세계 시간을 구성하는 매개 변수가 SpringMVC를받은 형식 변환을 주어지고.

참고 : 낮은 봄 버전 때문일 수 있습니다 적용 할 수없는 경우이 문서는, Springboot2.x 테스트를 기반으로합니다. PS : LOCALDATE에 컨트롤러 매개 변수 주석 (RequestParam, PathVariable 등) 증가하지 않는 어떤 종류의,뿐만 아니라 때문에 기본적으로 잘못 될 경우,이 매개 변수를 사용하여 구문 분석 ModelAttributeMethodProcessor처리하고,이 프로세서 반사를 통해 인스턴스화 객체에서, 다음 개체로 변환 개별 매개 변수,하지만 LOCALDATE 클래스 생성자 따라서 반사를 제공 인스턴스화 할 수 없습니다! ! !
소스 코드 분석 섹션에서 인용이 문서 LocalDateTime에 스프링을 사용하여이 같은 기준으로 LOCALDATE 매개 변수 , 원래 쓰기는 매우 흥미로운,주의 깊게 읽도록 권장합니다! ! !

완료 목표

  • 날짜 기준 요청 문자열 (지정된 형식), 지원하는 얻을로 전송됩니다 포스트 (콘텐츠 유형 = 응용 프로그램 / JSON)
  • 지정된 날짜 및 시간 형식 문자 레코드 유형 날짜로 반환 데이터
  • 같은 Java8 날짜 API 지원 LocalTime과 같이 , localDateLocalDateTime

날짜 문자열 형식 변환 POST와 GET 요청 양식

JSON 직렬화 잭슨 도구 (사용 후단 선회 JSON의 POJO 바닥의 전단 이후 JSON 문자열 등이 상황과 시간을 구별하는 HttpMessgeConverter) 정상적인 요청 파라미터 문자열 주었고, 시간, 변환 Converter, 두 접근 방식 다르다.

사용하는 사용자 정의 매개 변수 컨버터 (변환기)

다음과 같이 org.springframework.core.convert.converter.Converter, 사용자 정의 매개 변수 컨버터를 달성 :

@Configuration
public class DateConverterConfig {
    @Bean
    public Converter<String, LocalDate> localDateConverter() {
        return new Converter<>() {
            @Override
            public LocalDate convert(String source) {
                return LocalDate.parse(source, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            }
        };
    }

    @Bean
    public Converter<String, LocalDateTime> localDateTimeConverter() {
        return new Converter<>() {
            @Override
            public LocalDateTime convert(String source) {
                return LocalDateTime.parse(source, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            }
        };
    }

}

댓글 :이 콩 위의 파서 스프링 MVC의 매개 변수에 주입됩니다 (이 호출 될 것으로 보인다 ParameterConversionService들어오는 문자열이 LocalDateTime 클래스로 변환 할 때), 스프링 매개 변수에이를 변환하는 변환기를 호출합니다.

일치하도록 SS 등 : MM : SS, YYYY-MM-DD, HH : MM 또한 YYYY-MM-DD HH 같은 정규 일치 스트링의 말단에 전송 될 수있다. 다양한 시나리오를 수용합니다.

@Component
public class DateConverter implements Converter<String, Date> {

    private static final String dateFormat = "yyyy-MM-dd HH:mm:ss";

    @Override
    public Date convert(String value) {
        /**
         * 可对value进行正则匹配,支持日期、时间等多种类型转换
         * @param value
         * @return
         */
        SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
        try {
            return formatter.parse(value);
        } catch (Exception e) {
            throw new RuntimeException(String.format("parser %s to Date fail", value));
        }
    }
}

사용 봄 주석

스프링 @DateTimeFormat (패턴 = "YYYY-MM-DD는")에 따라 다음과 같은 자신의 주석 :

@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date startDate;

사용자 정의 매개 변수 개혁를 사용하는 경우, 봄, 즉 봄 주석이 적용되지 않습니다에 대처하기 위해이 방법을 사용하여 우선 순위를 부여합니다.

initBinder와 사용 ControllerAdvice

@ControllerAdvice
public class GlobalExceptionHandler {

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(LocalDate.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                setValue(LocalDate.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            }
        });
        binder.registerCustomEditor(LocalDateTime.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                setValue(LocalDateTime.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            }
        });
        binder.registerCustomEditor(LocalTime.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                setValue(LocalTime.parse(text, DateTimeFormatter.ofPattern("HH:mm:ss")));
            }
        });
    }
}

이름에서 볼 수있는,이 (잡기 글로벌 예외도있다) 컨트롤러가 할례를 할 것입니다, 매개 변수 핸들러를 입력하기 전에 변환, 우리는 해당 개체를 변환합니다.

JSON 글로벌 과정에 매개 변수와 반환 값

요청 유형 : 포스트, 콘텐츠 유형 = 응용 프로그램 / JSON, 배경과 @RequestBody리셉션, 및 반환 값의 기본 형식을받습니다yyyy-MM-dd HH:mm:ss

application.yml 파일을 수정

application.propertities 파일에 다음을 추가합니다 :

spring:
    jackson:
        date-format: yyyy-MM-dd HH:mm:ss
        time-zone: GMT+8
  • 지원 (콘텐츠 유형 = 응용 프로그램 / JSON ) 요구 포맷의 yyyy-MM-dd HH:mm:ss배경을 가진 문자열을 @RequestBody수신하고, 값이 날짜 변환 반환 yyyy-MM-dd HH:mm:ss형식 문자열;
  • (콘텐츠 유형 = 응용 프로그램 / JSON)에서 지원되지 않음 YYYY-MM-DD 다른 종류의 요청 날짜에 문자열의;
  • 그것은 java8日期 API를 지원하지 않습니다;

JSON 직렬화 및 역 직렬화 잭슨의 사용

@Configuration
public class JacksonConfig {

    /** 默认日期时间格式 */
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    /** 默认日期格式 */
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    /** 默认时间格式 */
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        ObjectMapper objectMapper = new ObjectMapper();

        // 忽略json字符串中不识别的属性
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 忽略无法转换的对象 
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        // PrettyPrinter 格式化输出
        objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
        // NULL不参与序列化
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

        // 指定时区
        objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
        // 日期类型字符串处理
        objectMapper.setDateFormat(new SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT));

        // java8日期日期处理
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)));
        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
        javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)));
        javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
        objectMapper.registerModule(javaTimeModule);

        converter.setObjectMapper(objectMapper);
        return converter;
    }
}

요약 :

  • 지원 (콘텐츠 유형 = 응용 프로그램 / JSON ) 요구 포맷의 yyyy-MM-dd HH:mm:ss배경과 캐릭터 @RequestBody수신, 반환 값 스위치 날짜 yyyy-MM-dd HH:mm:ss형식 문자열;
  • java8日期 API를 지원;
  • (콘텐츠 유형 = 응용 프로그램 / JSON 지원되지 않음 ) 요청 yyyy-MM-dd과 날짜에 문자열의 다른 유형;

JSON 글로벌 처리 파라미터로서 상기 두 방법은 두 가지 용도, 특히 기본 패키지에 제공되는 글로벌 대규모 프로젝트 추천.

JSON 및 치료 로컬 차이가 기준값으로 복귀

장면 : 날짜 형식의 전체 처리 시간 인 경우 : yyyy-MM-dd HH:mm:ss하지만 필드가 수신하거나 반환 날짜합니다 yyyy-MM-dd.

사용은 자신의 주석을 springboot @JsonFormat(pattern = "yyyy-MM-dd")다음과 같이 :

@JsonFormat(pattern = "yyyy-MM-dd", timezone="GMT+8")
private Date releaseDate;

댓글 : 기본, 강력한 충족 일반적인 시나리오에 의해 제공 springboot 사용하고 시간대를 지정합니다.

두 번째 방법

날짜 사용자 정의 직렬화 및 역 직렬화 등 다음 :

/**
 * 日期序列化
 */
public class DateJsonSerializer extends JsonSerializer<Date> {
    @Override
    public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws
            IOException {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        jsonGenerator.writeString(dateFormat.format(date));
    }
}

/**
 * 日期反序列化
 */
public class DateJsonDeserializer extends JsonDeserializer<Date> {

    @Override
    public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            return dateFormat.parse(jsonParser.getText());
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }
}

/**
 * 使用方式
 */
@JsonSerialize(using = DateJsonSerializer.class)
@JsonDeserialize(using = DateJsonDeserializer.class)
private Date releaseDate;

전체 구성을 처리 날짜 및 시간 형식

@Configuration
public class DateHandlerConfig {

    /** 默认日期时间格式 */
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    /** 默认日期格式 */
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    /** 默认时间格式 */
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

    /**
     * LocalDate转换器,用于转换RequestParam和PathVariable参数
     */
    @Bean
    public Converter<String, LocalDate> localDateConverter() {
        return new Converter<>() {
            @Override
            public LocalDate convert(String source) {
                return LocalDate.parse(source, DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT));
            }
        };
    }

    /**
     * LocalDateTime转换器,用于转换RequestParam和PathVariable参数
     */
    @Bean
    public Converter<String, LocalDateTime> localDateTimeConverter() {
        return new Converter<>() {
            @Override
            public LocalDateTime convert(String source) {
                return LocalDateTime.parse(source, DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT));
            }
        };
    }

    /**
     * LocalTime转换器,用于转换RequestParam和PathVariable参数
     */
    @Bean
    public Converter<String, LocalTime> localTimeConverter() {
        return new Converter<>() {
            @Override
            public LocalTime convert(String source) {
                return LocalTime.parse(source, DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT));
            }
        };
    }

    /**
     * Date转换器,用于转换RequestParam和PathVariable参数
     */
    @Bean
    public Converter<String, Date> dateConverter() {
        return new Converter<>() {
            @Override
            public Date convert(String source) {
                SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT);
                try {
                    return format.parse(source);
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
            }
        };
    }


    /**
     * Json序列化和反序列化转换器,用于转换Post请求体中的json以及将我们的对象序列化为返回响应的json
     */
    @Bean
    public ObjectMapper objectMapper(){
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);

        //LocalDateTime系列序列化和反序列化模块,继承自jsr310,我们在这里修改了日期格式
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class,new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
        javaTimeModule.addSerializer(LocalDate.class,new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)));
        javaTimeModule.addSerializer(LocalTime.class,new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
        javaTimeModule.addDeserializer(LocalDateTime.class,new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
        javaTimeModule.addDeserializer(LocalDate.class,new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)));
        javaTimeModule.addDeserializer(LocalTime.class,new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));


        //Date序列化和反序列化
        javaTimeModule.addSerializer(Date.class, new JsonSerializer<>() {
            @Override
            public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
                SimpleDateFormat formatter = new SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT);
                String formattedDate = formatter.format(date);
                jsonGenerator.writeString(formattedDate);
            }
        });
        javaTimeModule.addDeserializer(Date.class, new JsonDeserializer<>() {
            @Override
            public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
                SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT);
                String date = jsonParser.getText();
                try {
                    return format.parse(date);
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        objectMapper.registerModule(javaTimeModule);
        return objectMapper;
    }
}

확장 출처 : 심층 연구 데이터 바인딩 과정 SpringMVC

다음에, MVC 우리의 요구에 상원 콘트롤러 층에있어서의 파라미터를 바인딩하는 방법을 참조하는 디버그 모드로 들어간다;

간단한 컨트롤러를 쓰기 휴식을 확인 하 고 메소드 호출 스택을 참조하십시오

    @GetMapping("/getDate")
    public LocalDateTime getDate(@RequestParam LocalDate date,
                                 @RequestParam LocalDateTime dateTime,
                                 @RequestParam Date originalDate) {
        System.out.println(date);
        System.out.println(dateTime);
        System.out.println(originalDate);
        return LocalDateTime.now();
    }

호출 인터페이스 후, 우리는 중요한 방법 스택 메소드 호출의 일부를 보면 :

//进入DispatcherServlet
doService:942, DispatcherServlet
//处理请求
doDispatch:1038, DispatcherServlet
//生成调用链(前处理、实际调用方法、后处理)
handle:87, AbstractHandlerMethodAdapter
//反射获取到实际调用方法,准备开始调用
invokeHandlerMethod:895, RequestMappingHandlerAdapter
invokeAndHandle:102, ServletInvocableHandlerMethod
//这里是关键,参数从这里开始获取到
invokeForRequest:142, InvocableHandlerMethod
doInvoke:215, InvocableHandlerMethod
//这个是Java reflect调用,因此一定是在这之前获取到的参数
invoke:566, Method

위의 분석에 따르면, 발견 invokeForRequest:142, InvocableHandlerMethod여기에 사용되는 코드는 실제 매개 변수를 얻을 수 있습니다 :

    @Nullable
    public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
            Object... providedArgs) throws Exception {
        //这个方法是获取参数的,在这里下个断
        Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
        if (logger.isTraceEnabled()) {
            logger.trace("Arguments: " + Arrays.toString(args));
        }
        //这里开始调用方法
        return doInvoke(args);
    }

이 방법은 입력하고 무엇을 보는 것입니다 :

protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
    //获取方法参数数组,包含了入参信息,比如类型、泛型等等
    MethodParameter[] parameters = getMethodParameters();
    //这个用来存放一会从request parameter转换的参数
    Object[] args = new Object[parameters.length];
    for (int i = 0; i < parameters.length; i++) {
      MethodParameter parameter = parameters[i];
      parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
      //这里看起来没啥卵用(providedArgs为空)
      args[i] = resolveProvidedArgument(parameter, providedArgs);
      //这里开始获取到方法实际调用的参数,步进
      if (this.argumentResolvers.supportsParameter(parameter)) {
        //从名字就看出来:参数解析器解析参数
        args[i] = this.argumentResolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
        continue;
      }
    }
    return args;
}

resolveArgument을 살펴 입력 :

public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
                              NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
  //根据方法入参,获取对应的解析器
  HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
  //开始解析参数(把请求中的parameter转为方法的入参)
  return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
}

여기서, 대응하는 파라미터 분석기의 파라미터에 따른 내부 취득 방법 :

//遍历,调用supportParameter方法,跟进看看
for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) {
  if (methodArgumentResolver.supportsParameter(parameter)) {
    result = methodArgumentResolver;
    this.argumentResolverCache.put(parameter, result);
    break;
  }
}

여기서, 인수 파서에 더 적합한 파서를 찾기 없습니다! (I 26를 테스트 할 때) 그래서, 파서 매개 변수는 무엇인가? ? ? 나는 그것이 매우 익숙하지 않은, 몇 가지 중요한 참조를 나열했습니다! ! !

{RequestParamMethodArgumentResolver@7686} 
{PathVariableMethodArgumentResolver@8359} 
{RequestResponseBodyMethodProcessor@8366} 
{RequestPartMethodArgumentResolver@8367} 

우리는 자신의를 supportsParameter 방법은 해당 매개 변수를 주석 파서를 얻을 발견 볼 수있는 가장 일반적으로 사용되는 파서를 입력합니다.

    public boolean supportsParameter(MethodParameter parameter) {
        //如果参数拥有注解@RequestParam,则走这个分支(知道为什么上文要对RequestParam和Json两种数据区别对待了把)
        if (parameter.hasParameterAnnotation(RequestParam.class)) {
            //这个似乎是对Optional类型的参数进行处理的
            if (Map.class.isAssignableFrom(parameter.nestedIfOptional().getNestedParameterType())) {
                RequestParam requestParam = parameter.getParameterAnnotation(RequestParam.class);
                return (requestParam != null && StringUtils.hasText(requestParam.name()));
            }
            else {
                return true;
            }
        }
        //......
    }

즉 들면, @RequestParam@RequestBody뿐만 아니라 같은 @PathVariable매개 변수 주석, SpringMVC 파서는 데이터 바인딩에 대해 서로 다른 매개 변수를 사용합니다!
그래서, 그것을 사용하는 세 가지 파서 변환기 분석 매개 변수는 무엇인가? 우리는 세 파서로 각 엔트리에서 보면 :
제 모습 RequestParamMethodArgumentResolverWebDataBinder 내부 데이터 인 ConversionService 바닥 사용 결합 실측치 (즉, 현지 주사 변환기)

WebDataBinder binder = binderFactory.createBinder(webRequest, null, namedValueInfo.name);
//通过DataBinder进行数据绑定的
arg = binder.convertIfNecessary(arg, parameter.getParameterType(), parameter);
//跟进convertIfNecessary()
public <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType,
                                @Nullable MethodParameter methodParam) throws TypeMismatchException {

  return getTypeConverter().convertIfNecessary(value, requiredType, methodParam);
}
//继续跟进,看到了把
ConversionService conversionService = this.propertyEditorRegistry.getConversionService();
if (editor == null && conversionService != null && newValue != null && typeDescriptor != null) {
  TypeDescriptor sourceTypeDesc = TypeDescriptor.forObject(newValue);
  if (conversionService.canConvert(sourceTypeDesc, typeDescriptor)) {
    try {
      return (T) conversionService.convert(newValue, sourceTypeDesc, typeDescriptor);
    }
    catch (ConversionFailedException ex) {
      // fallback to default conversion logic below
      conversionAttemptEx = ex;
    }
  }
}

그런 모습은 RequestResponseBodyMethodProcessorHttpMessageConverter 변환 유형이 사용됩니다 발견

//resolveArgument方法内部调用下面进行参数解析
Object arg = readWithMessageConverters(webRequest, parameter, parameter.getNestedGenericParameterType());

//step into readWithMessageConverters(),我们看到这里的Converter是HttpMessageConverter
for (HttpMessageConverter<?> converter : this.messageConverters) {
  Class<HttpMessageConverter<?>> converterType = (Class<HttpMessageConverter<?>>) converter.getClass();
  GenericHttpMessageConverter<?> genericConverter =
    (converter instanceof GenericHttpMessageConverter ? (GenericHttpMessageConverter<?>) converter : null);
  if (genericConverter != null ? genericConverter.canRead(targetType, contextClass, contentType) :
      (targetClass != null && converter.canRead(targetClass, contentType))) {
    if (message.hasBody()) {
      HttpInputMessage msgToUse =
        getAdvice().beforeBodyRead(message, parameter, targetType, converterType);
      body = (genericConverter != null ? genericConverter.read(targetType, contextClass, msgToUse) :
              ((HttpMessageConverter<T>) converter).read(targetClass, msgToUse));
      body = getAdvice().afterBodyRead(body, msgToUse, parameter, targetType, converterType);
    }
    else {
      body = getAdvice().handleEmptyBody(null, message, parameter, targetType, converterType);
    }
    break;
  }
}

마지막으로,보기는 PathVariableMethodArgumentResolver코드가 게시되지 않도록, 일관성 및 (AbstractNamedValueMethodArgumentResolver 파서에서 상속 둘 다) RequestParam 실행 경로를 이동하는 것으로.

개요

변환 할 경우 매개 변수 요청을 구별하는 상원 노트에 따라 유형을 지정하기 위해 우리에게왔다 :

  • 다음 ObjectMapper 배치함으로써 requestBody 경우 (이 점은 HttpMessagConverter 잭슨 내부, 즉 주입한다 MappingJackson2HttpMessageConverter직렬화 및 역 직렬화 JSON 데이터 형식을 구현에서);
  • RequestParam 또는 PathVariable 타입 파라미터, 파라미터 변환 컨버터를 배치함으로써 달성하는 경우 (이는 ConversionService 변환기에 주입 함).

추천

출처www.cnblogs.com/christopherchan/p/12404804.html