首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Struts1 中文表單亂碼終極解決方案:Filter 編碼過濾器雙模式配置與安全過濾擴展實戰

     編輯:Java 綜合教學

前言

Struts1 時代的經典痛點:所有頁面、配置均設置為 UTF-8,提交中文表單到 ActionForm 仍出現亂碼。根因在於 Struts1 直接將請求參數填充到 FormBean,繞過了 HttpServletRequest.setCharacterEncoding(),導致容器按默認 ISO-8859-1 解碼。本文提供兩種 Filter 解決方案(硬編碼/參數化配置),並擴展演示安全關鍵字過濾 Filter與多 Filter 鏈順序控制,助你徹底攻克編碼與安全雙重難題。

一、亂碼根因深度剖析

  • Struts1 RequestProcessor 在 processPopulate() 階段調用 request.getParameter() 填充 FormBean。
  • Servlet 規範:getParameter() 首次調用時鎖定編碼,若在此之前未調用 setCharacterEncoding(),容器使用默認 ISO-8859-1 解碼 URL 和 Body 參數。
  • Struts1 無內置編碼設置點,必須在Filter 階段(早於 Servlet 處理)強制設置編碼。

二、方案一:硬編碼 Filter(最簡單有效)

1. MyFilter.java

package com.xidian.filter;

import javax.servlet.*;
import java.io.IOException;

public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        request.setCharacterEncoding("UTF-8");        // 設置請求解碼編碼
        response.setContentType("text/html;charset=UTF-8"); // 設置響應編碼
        chain.doFilter(request, response);            // 必須調用,否則鏈中斷
    }
    @Override public void init(FilterConfig config) {}
    @Override public void destroy() {}
}

2. web.xml 配置

<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>com.xidian.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

關鍵點: /* 攔截所有請求;chain.doFilter() 必須調用;Filter 必須配置在 Struts ActionServlet 之前(web.xml 順序決定)。

三、方案二:參數化配置 Filter(靈活復用)

1. MyFilter.java(支持 init-param)

package com.xidian.filter;

import javax.servlet.*;
import java.io.IOException;

public class MyFilter implements Filter {
    private String encoding = "UTF-8"; // 默認值

    @Override
    public void init(FilterConfig config) {
        String param = config.getInitParameter("encoding");
        if (param != null) encoding = param;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        request.setCharacterEncoding(encoding);
        chain.doFilter(request, response);
    }
    @Override public void destroy() {}
}

2. web.xml 配置

<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>com.xidian.filter.MyFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

優勢: 無需修改代碼即可切換編碼(如測試 GBK 環境),適合多環境部署。

四、擴展:安全關鍵字過濾 Filter(防注入/非法詞)

1. SafeFilter.java

package com.xidian.filter;

import javax.servlet.*;
import java.io.IOException;

public class SafeFilter implements Filter {
    private String[] keywords;

    @Override
    public void init(FilterConfig config) {
        String param = config.getInitParameter("keywords");
        keywords = (param != null) ? param.split(";") : new String[0];
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        String name = request.getParameter("name");
        if (name != null) {
            for (String kw : keywords) {
                if (kw.equals(name)) {
                    request.setAttribute("err", "您不允許登錄<font color='red'>" + name + "</font>");
                    request.getRequestDispatcher("/WEB-INF/ifo.jsp").forward(request, response);
                    return; // 直接返回,阻斷後續鏈
                }
            }
        }
        chain.doFilter(request, response); // 合法放行
    }
    @Override public void destroy() {}
}

五、多 Filter 鏈順序控制(web.xml 部署順序 = 執行順序)

<!-- 1. 首先執行編碼 Filter,確保後續 Filter 讀取到正確字符 -->
<filter>
    <filter-name>EncodingFilter</filter-name>
    <filter-class>com.xidian.filter.MyFilter</filter-class>
    <init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param>
</filter>
<filter-mapping>
    <filter-name>EncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<!-- 2. 其次執行安全 Filter,基於正確編碼做關鍵字匹配 -->
<filter>
    <filter-name>SafeFilter</filter-name>
    <filter-class>com.xidian.filter.SafeFilter</filter-class>
    <init-param><param-name>keywords</param-name><param-value>拉登;小明;鳳姐</param-value></init-param>
</filter>
<filter-mapping>
    <filter-name>SafeFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

鐵律: 編碼 Filter 必須在最前面,否則安全 Filter 讀取到的參數已是亂碼,關鍵字匹配失效。

六、Struts2 補充:更優雅的編碼處理

Struts2 內置 StrutsPrepareAndExecuteFilter 已在 prepare 階段調用 request.setCharacterEncoding(encoding),只需在 struts.xml 配置:

<constant name="struts.i18n.encoding" value="UTF-8"/>

無需手寫 Filter,框架級解決。

七、總結

  1. Struts1 中文亂碼本質:請求參數解碼早於 Struts 處理,必須用 Filter 搶在最前面設置編碼。
  2. 兩種 Filter 寫法:硬編碼簡單直接,參數化靈活復用,生產推薦參數化。
  3. 安全過濾 Filter 同理,務必在編碼 Filter 之後,基於正確字符做業務邏輯。
  4. Filter 鏈順序 = web.xml <filter-mapping> 聲明順序,切記「編碼優先」。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved