MockMvc는 더 이상 스프링 부트 2.2.0에서 UTF-8 문자를 처리하지 않습니다.풀어주다
새로 출시된 제품으로 업그레이드한 후2.2.0.RELEASE일부 테스트에 불합격했습니다.보아하니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 인코딩으로요?
네, 이것은 2.2.0 spring-boot부터의 문제입니다.디폴트 문자 집합 부호화에 대해서는 폐지 설정을 실시합니다.
.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));
}
...
사용..getContentAsString(StandardCharsets.UTF_8)대신.getContentAsString()이 문제를 해결합니다.
스프링 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 인스턴스를 사용하여 요청을 수행할 수 있습니다.
이게 도움이 됐으면 좋겠다.
Spring Boot 1.5.15를 사용하고 있습니다.릴리스되어 쓰기 테스트에서도 같은 문제가 발생하였습니다.
처음에 도움이 된 솔루션은 .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();
}
원래 동작을 복원하려면(Content-Type=application/json;charset=)UTF-8)를 사용하여 테스트에 그대로 합격할 수 있도록 다음 작업을 수행할 수 있습니다.
@Configuration
public class MyWebConfig implements WebMvcConfigurer {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_JSON_UTF8);
}
...
단, APPLICATION_JSON_UTF8은 권장되지 않으며 Spring의 의도는 문자 집합을 포함하지 않는 것이므로 테스트를 변경하는 것이 좋을지도 모릅니다.black4bird의 솔루션은 나에게 효과가 있었습니다.
black4bird의 답변에 따라 다음 항목을 입력하여 모든 테스트에서 문자 인코딩을 덮어쓸 수 있습니다.MockMvcBuilderCustomizer「 」 「 」 、 「 」 。
@Component
class MockMvcCharacterEncodingCustomizer implements MockMvcBuilderCustomizer {
@Override
public void customize(ConfigurableMockMvcBuilder<?> builder) {
builder.alwaysDo(result -> result.response.characterEncoding = "UTF-8");
}
}
MockMvc를 MockMvc를 이 될 수 .@AutoconfigureMockMvc.
스프링 개발자의 이 풀 요청에 따라 UTF-8 헤더는 더 이상 필요하지 않으므로 더 이상 사용되지 않습니다.응용 프로그램에서 UTF-8 헤더를 사용하는 경우 테스트를 수정하는 대신 해당 헤더를 응용 프로그램에서 제거하는 것이 좋습니다.Content-Type: application/json 헤더를 사용하고 있는지 확인하기만 하면 됩니다.
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 · spring - projects / spring - framework
maven을 사용하는 경우 maven-surefire-plugin을 사용하여 다음과 같이 UTF-8 인코딩을 활성화할 수 있습니다.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Dfile.encoding=UTF-8</argLine>
</configuration>
</plugin>
언급URL : https://stackoverflow.com/questions/58525387/mockmvc-no-longer-handles-utf-8-characters-with-spring-boot-2-2-0-release
'sourcecode' 카테고리의 다른 글
| module.config 내부 값의 AngularJS 의존성 주입 (0) | 2023.03.19 |
|---|---|
| Spring Webflux + JPA :사후 대응 리포지토리는 JPA에서 지원되지 않습니다. (0) | 2023.03.19 |
| Jest 테스트 실패: TypeError: window.matchMedia가 함수가 아닙니다. (0) | 2023.03.19 |
| 스프링 부트 셧다운 훅 (0) | 2023.03.19 |
| mongodb에서 여러 어레이 요소를 업데이트하는 방법 (0) | 2023.03.19 |