MockMvc는 더 이상 Spring Boot 2.2.0에서 UTF-8 문자를 처리하지 않습니다.


14

새로 출시 된 2.2.0.RELEASESpring Boot 버전으로 업그레이드 한 후 일부 테스트가 실패했습니다. MediaType.APPLICATION_JSON_UTF8은 더 이상 사용되지 않으며 컨텐츠 유형을 명시 적으로 지정하지 않은 컨트롤러 메소드에서 더 이상 기본 컨텐츠 유형으로 리턴되지 않는 것으로 보입니다 .

같은 테스트 코드

String content = mockMvc.perform(get("/some-api")
            .contentType(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
            .andReturn()
            .getResponse()
            .getContentAsString();

아래와 같이 콘텐츠 유형이 일치하지 않아 더 이상 갑자기 작동하지 않았습니다.

java.lang.AssertionError: Content type 
Expected :application/json;charset=UTF-8
Actual   :application/json

현재 코드를 변경하여 .andExpect(content().contentType(MediaType.APPLICATION_JSON))문제 를 해결했습니다.

그러나 이제 content직렬화 된 예상 객체와 비교할 때 객체에 특수 문자가 있으면 여전히 불일치가 있습니다. 이 .getContentAsString()방법은 기본적으로 UTF-8 문자 인코딩을 사용하지 않는 것으로 보입니다 (더 이상).

java.lang.AssertionError: Response content expected:<[{"description":"Er hörte leise Schritte hinter sich."}]> but was:<[{"description":"Er hörte leise Schritte hinter sich."}]>
Expected :[{"description":"Er hörte leise Schritte hinter sich."}]
Actual   :[{"description":"Er hörte leise Schritte hinter sich."}]

contentUTF-8 인코딩은 어떻게받을 수 있습니까?

답변:


7

예. 이것은 2.2.0 스프링 부트 문제입니다. 기본 문자셋 인코딩에 대한 지원 중단을 설정합니다.

.getContentAsString(StandardCharsets.UTF_8) -양호하지만 모든 응답에서 기본적으로 ISO 8859-1로 채워집니다.

내 프로젝트에서 현재 생성 된 변환기를 업데이트했습니다.

@Configuration
public class SpringConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.stream()
            .filter(converter -> converter instanceof MappingJackson2HttpMessageConverter)
            .findFirst()
            .ifPresent(converter -> ((MappingJackson2HttpMessageConverter) converter).setDefaultCharset(UTF_8));
    }
...

이것은 여기에서 권장되는 가장 쉬운 솔루션이었습니다!
Times

당신은 내 하루를 구했다!
Filomat


2

스프링의 5.2.0 버전 이후 기본 인코딩 문자는 더 이상 UTF-8이 아닙니다.

UTF-8을 계속 사용하려면 MockMvc 결과의 ServletResponse에서 UTF-8을 설정해야합니다. 기본 문자 인코딩을 UTF-8로 설정하려면 설정 방법에서 다음과 같이하십시오.

@Before
public void setUp() {
   mockMvc = webAppContextSetup(wac).addFilter(((request, response, chain) -> {
                response.setCharacterEncoding("UTF-8");
                chain.doFilter(request, response);
            })).build();
}

그런 다음 mockMvc 인스턴스를 사용하여 요청을 수행 할 수 있습니다.

이 도움을 바랍니다.


이 솔루션을 사용하면 모든 테스트 클래스에서 mockMvc를 구성해야합니다. 이것은 많은 테스트 수업에서 상당히 지루할 수 있습니다!
Times

0

스프링 개발자 의이 풀 요청 에 따르면 UTF-8 헤더는 더 이상 필요하지 않으므로 더 이상 사용되지 않습니다. 응용 프로그램에서 UTF-8 헤더를 사용하는 경우 테스트를 수정하는 대신 응용 프로그램에서 UTF-8 헤더를 제거하는 것이 좋습니다. Content-Type : application / json 헤더를 사용하고 있는지 확인하십시오 .


나는 당신이 문제를 이해하지 못한다고 생각합니다. 답변이 가치를 제공하는 경우 전체 질문을 읽은 다음 재평가하십시오. 내 응용 프로그램이 완벽하게 문제가 있으며 문제는 테스트와 관련이 있습니다.
Times

나는 전체 질문을 다시 읽고 내 대답을 재평가했다. 대답은 여전히 ​​동일하다. 귀하의 질문 에 헤더가 더 이상 사용되지 않는 이유를 설명하지 않고 귀하의 질문을 게시물로 풍부하게했습니다. 내가 연결 한 PR을 읽으면 헤더가 더 이상 사용되지 않는 이유를 이해할 수 있습니다. 이유를 이해하면 테스트가 Spring 2.1.X에서 기본 동작을 테스트하기 때문에 테스트 변경을 고려할 수 있지만 Spring 2.2.X의 동작을 올바르게 테스트하지는 않습니다. Spring 동작이 변경되었습니다. 새로운 Spring 동작을 수락하면 테스트가 적절히 변경됩니다.
scre_www 19

당신은 여기서 일관성이 없습니다. 당신의 대답에서 당신은 "테스트를 고치려고하지 말고"[...]라고 말합니다. 귀하의 의견에 "[...]라고 말하면 새로운 봄 행동을 받아들이면 시험이 적절히 변경되어야합니다."
Times

모든 프로그래머는 더 이상 사용되지 않는 값에 직면하게됩니다. 더 이상 사용되지 않는 항목이 더 이상 사용되지 않는지 조사하지 않고 어떻게 든 수정할 수 있습니다. 이 접근법은이 문제를 처리하는 방식 인 것 같습니다. 이제 더 자세히 살펴보고 더 이상 사용되지 않는지 조사해 보시기 바랍니다 . 이해하면 다음에 수행 할 작업을 더 잘 결정할 수 있습니다. 귀하의 질문에 당신 이 우리에게 연구가 열악한 가치가 더 이상 사용되지 않아 테스트가 실패했다고 말 했는지 에 대해서는 아무것도 없습니다 . 나는 당신이하지 않았고 Q를
찬성

0

Spring Boot 1.5.15.RELEASE를 사용하고 있으며 테스트를 작성할 때 동일한 문제가 발생했습니다.

나를 도와 준 첫 번째 해결책은 다음과 같이 .characterEncoding ( "UTF-8")을 추가하는 것이 었습니다.

String content = mockMvc.perform(get("/some-api")
            .contentType(MediaType.APPLICATION_JSON)
            .characterEncoding("UTF-8"))
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
            .andReturn()
            .getResponse()
            .getContentAsString();

내 테스트 클래스에서 StandaloneMockMvcBuilder를 사용하고 있으므로 두 번째 솔루션은 필터를 만드는 것입니다.

private static class Utf8Filter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {
        response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
        filterChain.doFilter(request, response);
    }
}

나중에 다음과 같이 테스트 클래스의 standaloneSetup 메소드에 추가하십시오.

@Before
public void setup() {
    MockitoAnnotations.initMocks(this);
    final SomeResource someResource = new SomeResource(someService);
    this.restLankMockMvc = MockMvcBuilders.standaloneSetup(someResource)
        .setCustomArgumentResolvers(pageableArgumentResolver)
        .setControllerAdvice(exceptionTranslator)
        .setConversionService(createFormattingConversionService())
        .setMessageConverters(jacksonMessageConverter)
        .addFilter(new Utf8Filter())
        .build();
}

0

MockMvc에 대한 추가 설정 .accept(MediaType.APPLICATION_JSON_UTF8_VALUE):

    String content = mockMvc.perform(get("/some-api")
        .contentType(MediaType.APPLICATION_JSON)
        .accept(MediaType.APPLICATION_JSON_UTF8_VALUE))
        .andExpect(status().isOk())
        .andExpect(content().contentType(MediaType.APPLICATION_JSON))
        .andReturn()
        .getResponse()
        .getContentAsString();

이 문제는 Spring Boot가 아니지만 MockMvc 관련 문제입니다. 따라서 해결 방법은 MockMvc에만 적용해야합니다. ( JSON은 UTF-8을 사용하여 부호화한다 .)

관련 문제 : JSON 응답을 위해 MockMvc에서 부적절한 UTF-8 처리 · 문제 # 23622 · 스프링 프로젝트 / 스프링 프레임 워크

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.