MockMvc artık Spring Boot 2.2.0 ile UTF-8 karakterlerini işlemiyor.


14

2.2.0.RELEASESpring Boot'un yeni sürümüne geçtikten sonra bazı testlerim başarısız oldu. Görünüşe göre, MediaType.APPLICATION_JSON_UTF8artık içerik türünü açıkça belirtmeyen denetleyici yöntemlerinden varsayılan içerik türü olarak döndürülmez.

Test kodu

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

içerik türü aşağıda gösterildiği gibi uyuşmadığından aniden çalışmadı

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

Kodun değiştirilmesi .andExpect(content().contentType(MediaType.APPLICATION_JSON))sorunu şimdilik çözdü.

Ancak şimdi contentbeklenen serileştirilmiş nesneyle karşılaştırıldığında , nesnede özel karakterler varsa hala bir uyumsuzluk var. .getContentAsString()Yöntemin varsayılan olarak UTF-8 karakter kodlamasını kullanmadığı anlaşılıyor (artık).

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 kodlamasına nasıl girebilirim ?

Yanıtlar:


7

Evet. Bu 2.2.0 yay önyükleme sorunudur. Varsayılan karakter kümesi kodlaması için kullanımdan kaldırmayı ayarlarlar.

.getContentAsString(StandardCharsets.UTF_8) - İyi ancak herhangi bir yanıtta varsayılan olarak ISO 8859-1 doldurulur.

Projemde mevcut oluşturulan dönüştürücüyü güncelledim:

@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));
    }
...

Burada önerilen en kolay çözüm buydu!
Times

günümü kurtardın!
Filomat


2

Yayının 5.2.0 sürümünden bu yana varsayılan kodlama karakteri artık UTF-8 değildir.

UTF-8'i kullanmaya devam etmek için MockMvc sonucunun ServletResponse'sinde ayarlamanız gerekir. Varsayılan karakter kodlamasını UTF-8 olarak ayarlamak için kurulum yönteminizde şöyle bir şey yapın:

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

Ardından, isteğinizi gerçekleştirmek için mockMvc örneğini kullanabilirsiniz.

Umarım bu yardım.


Bu çözümle her test sınıfında mockMvc'i yapılandırmam gerekir. Bu, birçok test sınıfı için oldukça sıkıcı olabilir!
Times

0

Yay geliştiricilerinden gelen bu çekme talebine göre artık UTF-8 başlığı gerekli değildir ve bu nedenle kullanımdan kaldırılmıştır. Uygulamanızda UTF-8 üstbilgisini kullanıyorsanız, testinizi düzeltmeyi denemek yerine bunu uygulamanızdan kaldırmayı düşünebilirsiniz. Content-Type: application / json üstbilgisini kullandığınızdan emin olun ve iyi olmalısınız.


Bence sorunu anlamıyorsun. Cevabınız herhangi bir değer veriyorsa, tüm soruyu okumanızı ve sonra yeniden değerlendirmenizi öneririz. Uygulamam mükemmel bir şekilde uyandı, sorun testlerle ilgili.
Times

Bütün soruyu tekrar okudum ve cevabımı tekrar değerlendirdim, cevap hala aynı. Sorunuzda, başlığın neden kullanımdan kaldırıldığını açıklamıyorsunuz, sorunuzu yazımla zenginleştirdim. Bağlantı verdiğim Halkla İlişkileri okumanızı öneririm, bu nedenle üstbilginin neden kullanımdan kaldırıldığını anlarsınız. Bunun nedenini anlarsanız, testiniz Bahar 2.1.X sürümünde varsayılan davranışı test ettiğinden, testinizi değiştirmeyi düşünebilirsiniz, ancak Bahar 2.2.X sürümündeki davranışı doğru bir şekilde test etmez. Bahar davranışı değişti, yeni Bahar davranışını kabul ederseniz testiniz buna göre değişmelidir.
scre_www

Burada çok tutarlı değilsiniz. Cevabınızda testinizi düzeltmek yerine "[...] dersiniz. Yorumunuzda "[...] yeni Bahar davranışını kabul ederseniz testinizin buna göre değişmesi gerektiğini söylüyorsunuz.
Times

Her programcı zaman zaman kullanımdan kaldırılmış değerlerle karşı karşıyadır. Bir şey kullanımdan kaldırıldığında, neden ilk başta kullanımdan kaldırıldığını araştırmadan bir şekilde düzeltebilirsiniz . Bu yaklaşım, bu sorunu ele alma şekliniz gibi görünüyor. Şimdi daha ileri bakmanızı ve neden kullanımdan kaldırıldığını araştırmanızı öneririm . Bunu anlarsanız, bundan sonra ne yapacağınız konusunda daha iyi bir karar verebilirsiniz. Sorunuzda, bize neden sadece araştırmanızın başarısız olduğunu söyleyen hiçbir şey yoktur . Soruyu, yapmadığınız bazı araştırmalarla zenginleştirdim VE Q'yu iptal ettim
scre_www

0

Spring Boot 1.5.15 kullanıyorum. BÜLTEN ve testleri yazarken aynı sorunla karşı karşıya.

Bana yardımcı olan ilk çözüm şöyle .characterEncoding ("UTF-8") eklemekti:

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();

Test sınıfımda bir StandaloneMockMvcBuilder kullanıyorum, bu yüzden bana yardımcı olan ikinci çözüm, örneğin bir filtre oluşturmak oldu:

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);
    }
}

ve daha sonra test sınıfımdaki standaloneSetup yöntemine şöyle ekleyin:

@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 için ek ayar .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();

Bu sorun Spring Boot değil, MockMvc'e özgü bir sorun. Bu nedenle, bir çözüm yalnızca MockMvc'e uygulanmalıdır. ( JSON, UTF-8 kullanılarak kodlanmalıdır .)

ilgili sorun: JSON yanıtı için MockMvc'de yanlış UTF-8 işleme · Sayı # 23622 · bahar projeleri / bahar çerçevesi

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.