Spring mvc 返回亂碼 和方法返回型別探討

Spring mvc 返回亂碼 和方法返回型別探討

今天寫程式碼有個方法返回的值是亂碼

這樣的亂碼,當時很奇怪,都設定的是utf-8.為什麼是亂碼.用postman看,返回的值裡headers的頭裡

有個content-Type屬性裡面的值是   text/plain;charset=ISO-8859-1

這裡亂碼原因就很明顯了 我的utf-8的編碼格式用iso-8859解碼很明顯就會出現亂碼.

接著我就在思考為什麼瀏覽器的會用iso編碼格式去解碼的.

這裡返回的值是spring,我在httpservletrequest裡面是沒有找到contentType這個屬性的,也就是說這個值不是瀏覽器決定的.

我將返回值改為Map<String,String> 而不用spring的時候,就沒有了亂碼,很神奇

我當時的理解是認為可能要用spring的map轉換json就會是對的,但是我決定debug看下是不是這樣.

springmvc裡面有這樣的類

AbstractMessageConverterMethodProcessor

這個方法就是用來設定對應的編碼的格式

this.getProducibleMediaTypes(servletRequest, returnValueClass);

這個方法會遍歷出編譯器(我以前以為只有一個就是StringHttpMessageConverter)原來有七個,這裡的方法canWrite會根據你的返回型別比如String HashMap去對比哪些編譯器HttpMessageConverter可以用.

String型別裡面可以用的編譯器有4個converter.上面的方法會排序然後選擇第一個使用他的編碼型別,String這個類很不幸第一就是iso.而Map對應的只有兩個,都是utf-8.所以在這裡map返回的值不會亂碼的原因就找到了.

七個編譯器合影

當然我們可以不用他的預設的編碼格式而用utf-8,在spring裡面配置一下就好了

這樣即使返回的值用的型別是string,編碼格式也是對的.在這裡不得不佩服這些編寫spring的人