Web中文亂碼——1、SpringMVC+Jetty編解碼基礎
阿新 • • 發佈:2019-02-09
我們部門的web專案常用的是spring+jetty。在編解碼過程中,spring本身不會進行干預,而jetty也干預減少。因此,我們從瀏覽器和Servlet之間的互動入手,來看Spring+jetty專案的編解碼過程。
瀏覽器和Servlet之間的互動過程如下圖所示,主要分成4個部分。
一、瀏覽器傳送請求
瀏覽器傳送的請求引數會進行URL encode。URL encode區別於encode的主要特點是:前者對中文編碼後會帶百分號。詳細的請各位google吧。1、表單遞交
表單遞交時,瀏覽器採用的編碼由header中的Content-type決定,例如在快門中是:
當沒有指定Content-type時,瀏覽器預設採用ISO-8859-1進行URL encode。
2、Javascript
IE總是採用作業系統的預設編碼來進行編碼,而Firefox/chrome總是採用utf-8編碼。二、Servlet接收請求
Servlet收到請求時,會對其中的引數進行URL decode。Serlvet的行為是受應用伺服器影響的,在使用Jetty時如下。1、Get請求
2、Post請求
和Jetty無關。在獲取引數值之前,通過HttpServletRequest.setCharacterEncoding(charset)來設定字符集,但必須在第一次呼叫request.getParameter()前設定。若沒設定,則預設ISO-8859-1。三、Servlet傳送響應
Servlet傳送的響應時,響應內容自然是java自己定製的,可以是任意字符集。但無論如何,它需要把自己的編碼方式告訴瀏覽器,以便對方正確解析。
3.1、html
那麼,對於html頁面響應,只需要設定頁面header中的Content-type,預設為ISO-8859-1。<metacharset="Content-type: application/x-www-form-urlencoded;charset=UTF-8" />
3.2、VM
velociy頁面最終也相當於是一個html頁面。因此首先也需要設定正確的Content-type,方法和上面一致。
除此之外,還需要注意velocity本身的編碼設定。
<bean id="velocityConfig"
class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<property name="resourceLoaderPath">
<value>WEB-INF/view</value>
</property>
<property name="velocityProperties">
<props>
<prop key="input.encoding">utf-8</prop>
<prop key="output.encoding">utf-8</prop>
<!--<prop key="eventhandler.referenceinsertion.class">org.apache.velocity.app.event.implement.EscapeHtmlReference</prop>-->
</props>
</property>
</bean>
如上所示,input.encoding用於指定Java讀取vm時採用的字符集;而output.encoding用於指定Java將vm輸出到瀏覽器時採用的字符集。
3.3、Java write
如果直接用HttpServletResponse.getWriter.write(),那就需要採用如下方式來設值
HttpServletResponse.setContentType(“text/html; charset=GBK”)
在Servlet2.4以後,還可以採用如下方式HttpServletResponse.setCharacterEncoding(charset)
四、瀏覽器接收響應
瀏覽器收到響應時,會根據header中的Content-type來decode,預設為ISO-8859-1五、推薦配置
當然是推薦在上述可配置的地方全部配置成相同的編碼,比如:UTF-8。但即使如此,亂碼還是有可能發生。發生亂碼的各種情形請參考下一篇《Web中文亂碼——2、SpringMVC+Jetty 亂碼》
參考:http://www.ruanyifeng.com/blog/2010/02/url_encoding.html
http://blog.csdn.net/chenyongsuda/article/details/5393458