其實全站亂碼問題的難點就是處理GET請求參數的問題。如果只是處理POST請求的編碼問題,以及響應編碼問題,這個就很好解決了response.setContentType("text/html;charset=utf-8");和request.setCharacterEncoding("utf-8")...
其實全站亂碼問題的難點就是處理GET請求參數的問題。
如果只是處理POST請求的編碼問題,以及響應編碼問題,這個就很好解決了response.setContentType("text/html;charset=utf-8");和request.setCharacterEncoding("utf-8");就可以解決的
好了,這裡主要的就是解決GET請求參數的問題,我使用的方式是用過濾器(攔截器)Filter來解決,
我的思路是:
首先定義一過濾器allDecodingFilter的過濾器,這個過濾器是過濾全站的所有文件(<url-pattern>/*</url-pattern>),
1.要解決GET請求參數的問題,我們首先定義一個裝飾類(這裡涉及到了裝飾者模式),裝飾類通俗一點的說法就是把原有的類的方法或屬性進行再改造。我就定義一個名為DecodingRequest的裝飾類,這個類必須繼承HttpServletRequestWrapper類,因為這個類繼承了HttpServletRequest介面,並實現HttpServletRequest介面的所有方法,那麼只要我繼承了HttpServletRequestWrapper類就可以對該類裡面的方法再重寫了(有興趣的話可以去看看j2ee源碼)。這裡主要就是重寫getParameter(String name)方法。
2.回到過濾器中,我就可以把我自己定義的DecodingRequest類傳遞給Servlet的doget()和dopost()方法,那麼當需要獲取參數調用getParameter(String name)時,其實就是調用自己定義的getParameter(String name)方法,那麼就不會出現亂碼了。口述的可能不好,我還是通過代碼來說話吧
過濾器allDecodingFilter:
public class allDecodingFilter implements Filter { public void destroy() { } /** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; //處理響應編碼 HttpServletResponse reps = (HttpServletResponse) response; response.setContentType("text/html;charset=utf-8"); // 處理post請求參數的亂碼 request.setCharacterEncoding("utf-8"); // 若是Get請求方式就使用裝飾類的獲取的參數的方法 if (req.getMethod().equals("GET")) { HttpServletRequest newReq = new DecodingRequest(req);//這個類下一步會陳述 /* * 調包request 1. 自己定義的request的裝飾類 2. 在攔截通過時,使用我們自己定義request 3. * 在Servlet中 * ,只有你調用request.getParameter(name)方法本質就是執行自己定義的request.getParameter * (name)方法 */ chain.doFilter(newReq, response); } else { // 若是post方式就不使用裝飾類 chain.doFilter(request, response); } } public void init(FilterConfig fConfig) throws ServletException { } }
裝飾類DecodingRequest
/** *裝飾類(這是裝飾者模式) *HttpServletRequestWrapper:這個類幫我們實現了HttpServletRequest介面所有的方法, *那麼我們就可以根據自己的需求對其裡面的方法再進行實現 */ public class DecodingRequest extends HttpServletRequestWrapper { private HttpServletRequest req; public DecodingRequest(HttpServletRequest request) { super(request); this.req=request; } /** * 獲取到參數進而修改編碼方式,當用戶獲取參數的時候就是執行了這個方法了 */ @Override public String getParameter(String name) { try { //修改字元編碼方式 name=new String(req.getParameter(name).getBytes("iso-8859-1"),"utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return name; } }
Servlet測試類
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //這裡實質調用的是DecodingRequest類中的request.getParameter("uname");方法 String name = request.getParameter("uname"); System.out.println(name); response.getWriter().print(name); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("uname"); System.out.println(name); response.getWriter().print(name); }