struts2中文亂碼解決辦法

根據filter的執行順序知,會先執行CharacterEncoding過濾器,再執行Struts2過濾器。
CharacterEncodingFilter的核心doFilterInternal方法如下:

view plaincopy to clipboardprint?
protected void doFilterInternal(  
            HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)  
            throws ServletException, IOException {  
 
if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) {  
            request.setCharacterEncoding(this.encoding);//設置字符集編碼  
            if (this.forceEncoding && responseSetCharacterEncodingAvailable) {  
                response.setCharacterEncoding(this.encoding);  
            }  
        }  
        filterChain.doFilter(request, response);//激活下一個過濾器  
    } 
protected void doFilterInternal(
   HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
   throws ServletException, IOException {

if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) {
   request.setCharacterEncoding(this.encoding);//設置字符集編碼
   if (this.forceEncoding && responseSetCharacterEncodingAvailable) {
    response.setCharacterEncoding(this.encoding);
   }
  }
  filterChain.doFilter(request, response);//激活下一個過濾器
 }

很簡潔,只要this.encoding != null就會設置request的字符集編碼,this.encoding就是web.xml中CharacterEncoding過濾器配置的encoding爲GBK。
到這裏我們已經執行了一個Filter(CharacterEncoding)已經把request的字符集設置爲GBK,然後執行filterChain.doFilter(request, response);//激活下一個過濾器即我們定義的Struts2過濾器。
到這裏request的字符集編碼還是GBK,但是我們在Action中取得的中文爲亂碼,使用request.getCharacterEncoding()獲取的編碼爲UTF-8,那麼我們可以肯定問題出在FilterDispatcher過濾器上。查看FilterDispatcher的源代碼,在其doFilter方法裏找到了prepareDispatcherAndWrapRequest方法,看其名字是對request進行預處理和封裝的方法。

view plaincopy to clipboardprint?
protected HttpServletRequest prepareDispatcherAndWrapRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException {  
 
        Dispatcher du = Dispatcher.getInstance();  
 
        if (du == null) {  
 
            Dispatcher.setInstance(dispatcher);  
            dispatcher.prepare(request, response);//設置編碼的關鍵地方  
        } else {  
            dispatcher = du;  
        }  
        //省略一些代碼  
 
        return request;  
    } 
protected HttpServletRequest prepareDispatcherAndWrapRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException {

        Dispatcher du = Dispatcher.getInstance();

        if (du == null) {

            Dispatcher.setInstance(dispatcher);
            dispatcher.prepare(request, response);//設置編碼的關鍵地方
        } else {
            dispatcher = du;
        }
        //省略一些代碼

        return request;
    }

展開dispatcher.prepare(request, response)發現:
view plaincopy to clipboardprint?
public void prepare(HttpServletRequest request, HttpServletResponse response) {  
        String encoding = null;  
        if (defaultEncoding != null) {  
            encoding = defaultEncoding;  
        }  
 
       //省略了一些代碼  
 
        if (encoding != null) {  
            try {  
                request.setCharacterEncoding(encoding);//設置了字符集編碼  
            } catch (Exception e) {  
                LOG.error("Error setting character encoding to '" + encoding + "' - ignoring.", e);  
            }  
        }  
    //省略了一些代碼  
    } 
public void prepare(HttpServletRequest request, HttpServletResponse response) {
        String encoding = null;
        if (defaultEncoding != null) {
            encoding = defaultEncoding;
        }

       //省略了一些代碼

        if (encoding != null) {
            try {
                request.setCharacterEncoding(encoding);//設置了字符集編碼
            } catch (Exception e) {
                LOG.error("Error setting character encoding to '" + encoding + "' - ignoring.", e);
            }
        }
    //省略了一些代碼
    }

可以發現FilterDispatcher過濾器設置了request的字符編碼,值來自defaultEncoding(看上面的代碼),而defaultEncoding則是通過struts的配置文件取得的,即struts.i18n.encoding的屬性值。view plaincopy to clipboardprint?
@Inject(StrutsConstants.STRUTS_I18N_ENCODING)  
   public static void setDefaultEncoding(String val) {  
       defaultEncoding = val;  
   } 
 @Inject(StrutsConstants.STRUTS_I18N_ENCODING)
    public static void setDefaultEncoding(String val) {
        defaultEncoding = val;
    }

如果沒有配置struts.i18n.encoding的值,默認是UTF-8.現在我們明白爲什麼中文是亂碼了,也明白了爲什麼在Action中獲取的編碼是UTF-8啦。解決方法也很簡單,在struts.xml文件中配置好struts.i18n.encoding的值爲GBK即可,可以選擇是否去掉spring的編碼過濾器。


<constant name="struts.i18n.encoding" value="gbk"></constant> 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章