버전 의존성
Spring boot | Spring core | Spring integration | Jackson core |
2.1.6 | 5.1.8 | 5.1.6 | 2.9.0 |
2.2.0 | 5.2.0 | 5.2.0 | 2.10.0 |
2.2.4 | 5.2.3 | 5.2.3 | 2.10.2 |
2.2.5 | 5.2.4 | 5.2.4 | 2.10.2 |
TCP 통신을 하는 것을 만들고 있는데, 아직 상대방 방화벽이 닫혀있는지 긴 타임아웃이 발생하였다.
기본 연결 대기 시간 이전에 timeout이 발생하게 하고 싶었다.
AbstractClientConnectionFactory 에 정의되어 있는 기본 연결 타임아웃은 60초이다.
구현체에서 소켓을 만들때 getConnectTimeout() 이라는 메서드를 통해 값을 구해온다.
이 값은 TcpConnectionFactoryFactoryBean 의 connectTimeout의 프로퍼티가 null일 아닐 경우에 설정이 된다.
TcpClientConnectionFactorySpec 의 connectTimeout 을 통해서도 설정이 가능하다.
문제는 내가 사용하고 있는 스프링 부트 버전이 2.1.6인데 spring-integration 5.1.6에 의존을 하고 있었다.
connectTimeout 은 주석에도 써있지만 5.2부터 생겼다.
현재 스프링 부트 버전은 2.2.4인데 spring-integration 는 5.2.3로 올라갔다.
스프링부트 버전을 2.1.6에서 2.2.4로 올렸더니 Jackson 도 버전이 올라가서 테스트코드가 깨진다.
1) Jackson - readValue - TypeReference
컴파일 에러: Error:(61, 26) java: incompatible types: java.lang.Object cannot be converted to T
readValue(String content, TypeReference valueTypeRef) 가
readValue(String content, TypeReference<T> valueTypeRef) 로 바뀌었다.
2) Jackson - IllegalArgumentException <- NullPointerException
NullPointerException 예외를 던지던 것이 IllegalArgumentException 로 바뀌었다.
이것은 ObjectMapper의 내부에 _assertNotNull가 추가되었기 때문이다.
public <T> T readValue(String content, Class<T> valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(content), _typeFactory.constructType(valueType));
}
가
public <T> T readValue(String content, Class<T> valueType)
throws IOException, JsonParseException, JsonMappingException
{
_assertNotNull("content", content);
DefaultDeserializationContext ctxt = _deserializationContext();
return (T) _readMapAndClose(ctxt,
_streamFactory.createParser(ctxt, content), _typeFactory.constructType(valueType));
}
기존에는 내부의 ByteSourceJsonBootstrapper에서 readUnsignedByte() 메서드가 호출 될때 까지 call stack 안으로 들어갔다.
at com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper.skipUTF8BOM(ByteSourceJsonBootstrapper.java:187)
at com.fasterxml.jackson.core.JsonFactory._createParser(JsonFactory.java:1378)
at com.fasterxml.jackson.core.JsonFactory.createParser(JsonFactory.java:937)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3135)
3) Jackson - 인코딩 깨짐 (한글이 깨진다) Issue
5.1.8에서는 MockMvc의 servletResponse의 characterEncoding이 처음에는 ISO-8859-1였다가 나중에 UTF-8로 바뀌었다.
org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#writeInternal
사실 이것은 아래 4번의 MediaType을 APPLICATION_JSON_UTF8_* 에서 APPLICATION_JSON 로 바꾸면서 발생하는 이슈이다.
https://namocom.tistory.com/832 참고.
이것은 테스트 비교를 할 때 string 이 아닌 byte[]로 비교를 하면 된다.
ContentResultMatchers: string('') -> bytes(''.getBytes(StandardCharsets.UTF_8))
4) Deprecated : MediaType
org.springframework.http.MediaType#APPLICATION_JSON_UTF8_VALUE
/**
* A String equivalent of {@link MediaType#APPLICATION_JSON_UTF8}.
* @deprecated as of 5.2 in favor of {@link #APPLICATION_JSON_VALUE}
* since major browsers like Chrome
* <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=438464">
* now comply with the specification</a> and interpret correctly UTF-8 special
* characters without requiring a {@code charset=UTF-8} parameter.
*/
@Deprecated
public static final String APPLICATION_JSON_UTF8_VALUE = "application/json;charset=UTF-8";
5) MockMvc 인코딩 깨짐
org.springframework.test.web.servlet 패키지의 MockMvc 으로 수행하던 테스트 코드가 인코딩 깨진다.
GitHub 에도MockMvc no longer handles UTF-8 characters 와 같이 이슈가 올라온 적이 있다.
답변은 String 대신 bytes 배열을 래핑해서 쓰라는 것..
MockHtpServletResponse: getContentAsString() -> getContentAsString(StandardCharsets.UTF_8)
단점은 ...Sonarqube는 지표가 엄청 깨짐.
'Programing > Framework' 카테고리의 다른 글
[Spring] spring-retry 재시도 및 백오프 정책 정리 (0) | 2020.04.17 |
---|---|
[spring boot] 2.1.6 -> 2.2.0 테스트 깨짐(인코딩) (0) | 2020.02.18 |
[Spring] mvc - DispatcherServlet 1부 (1) | 2020.02.09 |
[Spring] SSE vs WebFlux (0) | 2020.02.08 |
[Spring] mvc 예외처리 (0) | 2020.02.07 |