新しくリリースされた_2.2.0.RELEASE
_バージョンのSpring 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."}]
_
UTF-8エンコードでcontent
を取得するにはどうすればよいですか?
はい。これは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()
を使用すると、問題が解決します。
Springの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への追加設定、.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
Spring開発者からの this プルリクエストによると、UTF-8ヘッダーは不要になり、非推奨になりました。アプリケーションでUTF-8ヘッダーを使用している場合は、テストを修正するのではなく、アプリケーションから削除することを検討してください。 Content-Type:application/jsonヘッダーを使用していることを確認してください。問題はありません。
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を使用しているので、私を助ける2番目の解決策はフィルターを作成することでした。
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();
}