한 번 의 구덩이 밟 기: springboot 2.0.2 설정 fastjson 이 유효 하지 않 습 니 다.
10745 단어 springbootfastjsonspring
가 벼 운 차 로 하 나 를 정 했다
SpringMvcConfigure
계승 WebMvcConfigurerAdapter
. 그리고 이것 WebMvcConfigurerAdapter
이 시대 에 뒤떨어 졌 다 는 것 을 알 게 되 었 다.what?입력 하여 원본 코드 보기:/**
* An implementation of {@link WebMvcConfigurer} with empty methods allowing
* subclasses to override only the methods they're interested in.
*
* @author Rossen Stoyanchev
* @since 3.1
* @deprecated as of 5.0 {@link WebMvcConfigurer} has default methods (made
* possible by a Java 8 baseline) and can be implemented directly without the
* need for this adapter
*/
@Deprecated
public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {}
spring 5.0 부터 @ Deprecated 를 볼 수 있 습 니 다. 자바 8 에서 지원 하 는 인터페이스 에 기본 적 인 방법 이 있 었 기 때문에 우 리 는 지금
WebMvcConfigurer
을 직접 실현 한 다음 에 선택 적 으로 어떤 방법 을 다시 쓸 수 있 습 니 다. 모든 방법 을 실현 하지 않 아 도 됩 니 다.그래서 실현 되 었 다
WebMvcConfigurer
.@Configuration
public class SpringMvcConfigure implements WebMvcConfigurer {
/**
*
* @param converters
*/
@Override
public void configureMessageConverters(List> converters) {
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
// ...
FastJsonConfig config = new FastJsonConfig();
config.setSerializerFeatures(SerializerFeature.QuoteFieldNames,
SerializerFeature.WriteEnumUsingToString,
/*SerializerFeature.WriteMapNullValue,*/
SerializerFeature.WriteDateUseDateFormat,
SerializerFeature.DisableCircularReferenceDetect);
fastJsonHttpMessageConverter.setFastJsonConfig(config);
converters.add(fastJsonHttpMessageConverter);
}
}
이렇게 설정 하면 끝 날 줄 알 았 는데 이상 한 일이 일 어 났 습 니 다. 저 는 분명히 주석
SerializerFeature.WriteMapNullValue
을 달 았 습 니 다. 그러나 돌아 온 제 이 슨 에는 아직도 위 null
필드 가 있 습 니 다. 그리고 저 는 com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter
중의 write
과 writeInternal
정지점 에 가서 다시 실 행 했 습 니 다. 아무 일 도 일어나 지 않 았 습 니 다. 이 두 가지 방법 을 전혀 가지 지 않 았 습 니 다. 그래서 사용자 정의 SpringMvcConfigure
에서 configureMessageConverters
방법 내 에 단점 을 쳤 습 니 다. 이 방법 파라미터 converters
안에 무엇이 있 는 지 보고 싶 습 니 다.여기 서 보 니 제 가 추가 한 fastjson 이 뒤에 있 기 때문에 효력 이 발생 하지 않 았 습 니 다. 그래서 다음 과 같은 코드 를 추 가 했 습 니 다.
@Override
public void configureMessageConverters(List> converters) {
converters = converters.stream()
.filter((converter)-> !(converter instanceof MappingJackson2HttpMessageConverter))
.collect(Collectors.toList());
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
// ...
FastJsonConfig config = new FastJsonConfig();
config.setSerializerFeatures(SerializerFeature.QuoteFieldNames,
SerializerFeature.WriteEnumUsingToString,
/*SerializerFeature.WriteMapNullValue,*/
SerializerFeature.WriteDateUseDateFormat,
SerializerFeature.DisableCircularReferenceDetect);
fastJsonHttpMessageConverter.setFastJsonConfig(config);
converters.add(fastJsonHttpMessageConverter);
}
아직 효력 이 발생 하지 않 았 습 니 다. 나중에 추적 을 시 작 했 습 니 다. 시작 방법 은
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport
류 중의 bean 설정 입 니 다.@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
RequestMappingHandlerAdapter adapter = createRequestMappingHandlerAdapter();
adapter.setContentNegotiationManager(mvcContentNegotiationManager());
// converters , .
adapter.setMessageConverters(getMessageConverters());
adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer());
adapter.setCustomArgumentResolvers(getArgumentResolvers());
adapter.setCustomReturnValueHandlers(getReturnValueHandlers());
if (jackson2Present) {
adapter.setRequestBodyAdvice(Collections.singletonList(new JsonViewRequestBodyAdvice()));
adapter.setResponseBodyAdvice(Collections.singletonList(new JsonViewResponseBodyAdvice()));
}
AsyncSupportConfigurer configurer = new AsyncSupportConfigurer();
configureAsyncSupport(configurer);
if (configurer.getTaskExecutor() != null) {
adapter.setTaskExecutor(configurer.getTaskExecutor());
}
if (configurer.getTimeout() != null) {
adapter.setAsyncRequestTimeout(configurer.getTimeout());
}
adapter.setCallableInterceptors(configurer.getCallableInterceptors());
adapter.setDeferredResultInterceptors(configurer.getDeferredResultInterceptors());
return adapter;
}
getMessageConverters()
방법:protected final List> getMessageConverters() {
if (this.messageConverters == null) {
this.messageConverters = new ArrayList<>();
configureMessageConverters(this.messageConverters);//
if (this.messageConverters.isEmpty()) {
addDefaultHttpMessageConverters(this.messageConverters);
}
extendMessageConverters(this.messageConverters);
}
return this.messageConverters;
}
org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration
: @Override
protected void configureMessageConverters(List> converters) {
this.configurers.configureMessageConverters(converters);
}
@Override
public void configureMessageConverters(List> converters) {
for (WebMvcConfigurer delegate : this.delegates) {
delegate.configureMessageConverters(converters);
}
}
this. delegates 는 springboot 의 기본 설정 클래스 를 포함 합 니 다.
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
안에 인자 가 있 습 니 다.private final HttpMessageConverters messageConverters;
for 순환 중의
delegate.configureMessageConverters(converters)
호출 WebMvcAutoConfiguration
중의 configureMessageConverters
방법:@Override
public void configureMessageConverters(List> converters) {
converters.addAll(this.messageConverters.getConverters());
}
이것 을 실행 한 후에
converters
에 10
개의 컨버터 를 추 가 했 습 니 다. 바로 위의 그림 에 있 는 10 개 입 니 다. this.delegates
중 하 나 는 우리 가 사용자 정의 한 것 입 니 다. 실행 한 후에 우리 가 사용자 정의 한 것 SpringMvcConfigure
에서 내 가 추가 한 fastjson 이 추 가 된 것 을 발 견 했 습 니 다. 그러나 org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.getMessageConverters()
converters 는 우리 가 추가 한 것 FastJsonHttpMessageConverter
을 발견 하지 못 했 습 니 다.이때 갑자기 생각 났 습 니 다. 자바 8 의 stream api 는 매번 새로운 대상 을 만 들 기 때문에 converters 는 이미 전 달 된 그 converters 의 인용 이 아 닙 니 다 (여기 서도 자바 가 값 전달 임 을 증명 합 니 다. 인용 전달 이 아 닙 니 다).그래서 그 lambda 표현 식 을 일반적인 증강 for 순환 으로 다시 바 꿉 니 다:
@Override
public void configureMessageConverters(List> converters) {
/*converters = converters.stream().
filter((converter)-> !(converter instanceof MappingJackson2HttpMessageConverter))
.collect(Collectors.toList());*/
for (HttpMessageConverter> converter : converters) {
if (converter instanceof MappingJackson2HttpMessageConverter){
converters.remove(converter);
}
}
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
// ...
FastJsonConfig config = new FastJsonConfig();
config.setSerializerFeatures(SerializerFeature.QuoteFieldNames,
SerializerFeature.WriteEnumUsingToString,
/*SerializerFeature.WriteMapNullValue,*/
SerializerFeature.WriteDateUseDateFormat,
SerializerFeature.DisableCircularReferenceDetect);
fastJsonHttpMessageConverter.setFastJsonConfig(config);
converters.add(fastJsonHttpMessageConverter);
}
다시 실행, wtf?오류 보고:
ConcurrentModificationException
원래 for 순환 을 사용 하 는 과정 에서 remove 작업 을 할 수 없 기 때문에 Iterator
로 바 꿉 니 다.@Override
public void configureMessageConverters(List> converters) {
/*converters = converters.stream()
.filter((converter)-> !(converter instanceof MappingJackson2HttpMessageConverter))
.collect(Collectors.toList());
for (HttpMessageConverter> converter : converters) {
if (converter instanceof MappingJackson2HttpMessageConverter){
converters.remove(converter);
}
}*/
Iterator> iterator = converters.iterator();
while(iterator.hasNext()){
HttpMessageConverter> converter = iterator.next();
if(converter instanceof MappingJackson2HttpMessageConverter){
iterator.remove();
}
}
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
// ...
FastJsonConfig config = new FastJsonConfig();
config.setSerializerFeatures(SerializerFeature.QuoteFieldNames,
SerializerFeature.WriteEnumUsingToString,
/*SerializerFeature.WriteMapNullValue,*/
SerializerFeature.WriteDateUseDateFormat,
SerializerFeature.DisableCircularReferenceDetect);
fastJsonHttpMessageConverter.setFastJsonConfig(config);
converters.add(fastJsonHttpMessageConverter);
}
다시 실행, 내 가 가서 드디어 해 결 했 습 니 다. 먼저 삭제
MappingJackson2HttpMessageConverter
한 다음 에 추가 FastJsonHttpMessageConverter
했 습 니 다. 그런데 왜 일련의 조작 에 들 어간 후에 MappingJackson2HttpMessageConverter
추가 되 었 습 니까? 그러나 FastJsonHttpMessageConverter
이전에 추가 되 었 기 때문에 결과 에 영향 을 주지 않 았 습 니 다. 이로써 이 문 제 를 해결 하 였 습 니 다.총결산
잘못된 점 이 있 으 면 지적 해 주세요. 감사합니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin Springboot -- 파트 14 사용 사례 REST로 전환하여 POST로 JSON으로 전환前回 前回 前回 記事 の は は で で で で で で を 使っ 使っ 使っ て て て て て リクエスト を を 受け取り 、 reqeustbody で 、 その リクエスト の ボディ ボディ を を 受け取り 、 関数 内部 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.