您好,登錄后才能下訂單哦!
Filter全局編碼過濾器
這篇來做一個Filter在全局編碼過濾器練習(xí),這篇新建一個web項目來做練習(xí)。
web項目創(chuàng)建
先創(chuàng)建一個叫GlobalFilter的web動態(tài)項目,把前面文章出現(xiàn)過的login.jsp復(fù)制過來,改成如下代碼。
<%@?page?language="java"?contentType="text/html; charset=UTF-8"
? ?pageEncoding="UTF-8"%>
<!DOCTYPE?html?PUBLIC?"-//W3C//DTD HTML 4.01 Transitional//EN"?"https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta?http-equiv="Content-Type"?content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
????<form?action="${pageContext.request.contextPath}/web/loginServlet"?method="post">
????????用戶名:<input?type="text"?name="username"?/><br/>
????????<input?type="submit"?value="登錄"?/><br/>
????</form>
</body>
</html>
因為我們這里做全局編碼的練習(xí),到時候登錄頁面輸入用戶名,我們會采用中文字符輸入。
Servlet創(chuàng)建
因為這里我們是模擬全局,實際中應(yīng)該有許多servlet和許多前端頁面,例如注冊,登錄,首頁搜索等。我們就來創(chuàng)建一個servlet來模擬下就好。創(chuàng)建一個LoginServlet.java。?url-pattern是/web/loginServlet。
package?com.kaigejava.web.servlet;
import?java.io.IOException;
import?javax.servlet.ServletException;
import?javax.servlet.annotation.WebServlet;
import?javax.servlet.http.HttpServlet;
import?javax.servlet.http.HttpServletRequest;
import?javax.servlet.http.HttpServletResponse;
@WebServlet("/loginServlet")
public class?LoginServlet?extends?HttpServlet?{? ??
????public void?doGet(HttpServletRequest?request,?HttpServletResponse?response) throws?ServletException,?IOException?{
????????//request.setCharacterEncoding("UTF-8");
????????String name =?request.getParameter("username");
????????System.out.println(name);
????}? ??
????public void?doPost(HttpServletRequest?request,?HttpServletResponse?response) throws?ServletException,?IOException?{
????????doGet(request, response);
????}
}
以前,我們是通過這個紅圈代碼來設(shè)置編碼,這樣拿到中文的username就不會是亂碼。
現(xiàn)實開發(fā)中有很多個servlet,如果都這樣寫這行代碼來設(shè)置編碼,這行代碼就冗余,我們可以把這行代碼放到Filter過濾器中去。
Filter類創(chuàng)建
創(chuàng)建一個MyFilter.java?實現(xiàn)Filter接口,代碼如下。
package?com.kaigejava.web.filter;
import?java.io.IOException;
import?javax.servlet.Filter;
import?javax.servlet.FilterChain;
import?javax.servlet.FilterConfig;
import?javax.servlet.ServletException;
import?javax.servlet.ServletRequest;
import?javax.servlet.ServletResponse;
import?javax.servlet.annotation.WebFilter;
import?javax.servlet.http.HttpServletRequest;
public class?MyFilter?implements Filter {
????public void?destroy() {
????????// TODO Auto-generated method stub
????}? ??
????public void?doFilter(ServletRequest?request,?ServletResponse?response,?FilterChain?chain) throws?IOException,?ServletException?{
????????// 轉(zhuǎn)換對象
????????HttpServletRequest?req = (HttpServletRequest) request;
????????// 設(shè)置編碼
????????req.setCharacterEncoding("UTF-8");
????????// 放行
????????chain.doFilter(request, response);
????}
????public void?init(FilterConfig?fConfig) throws?ServletException?{
????????// TODO Auto-generated method stub
????}
}
web.xml內(nèi)容如下
<?xml?version="1.0"?encoding="UTF-8"?>
<web-app?xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"?xmlns="https://java.sun.com/xml/ns/javaee"?xsi:schemaLocation="https://java.sun.com/xml/ns/javaee?https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"?id="WebApp_ID"?version="3.0">
?<display-name>GlobalFilter</display-name>
?<welcome-file-list>
? ?<welcome-file>index.html</welcome-file>
? ?<welcome-file>index.htm</welcome-file>
? ?<welcome-file>index.jsp</welcome-file>
? ?<welcome-file>default.html</welcome-file>
? ?<welcome-file>default.htm</welcome-file>
? ?<welcome-file>default.jsp</welcome-file>
?</welcome-file-list>
?
?<filter>
?????<filter-name>MyFilter</filter-name>
?????<filter-class>com.kaigejava.web.filter.MyFilter</filter-class>
?</filter>
?
?<filter-mapping>
?????<filter-name>MyFilter</filter-name>
?????<url-pattern>/*</url-pattern>
?</filter-mapping>
?
?<servlet>
? ?<servlet-name>LoginServlet</servlet-name>
? ?<servlet-class>com.anthony.web.servlet.LoginServlet</servlet-class>
?</servlet>
?<servlet-mapping>
? ?<servlet-name>LoginServlet</servlet-name>
? ?<url-pattern>/web/loginServlet</url-pattern>
?</servlet-mapping>
?
</web-app>
部署測試
現(xiàn)在部署到tomcat然后測試以下,前臺頁面用戶名輸入框輸入“張三”看看。
在Eclipse控制臺可以看到“張三”打印出來不亂碼,說明我們Filter中編碼設(shè)置起效果了。
Get方式提交表單問題
在login.jsp中我們表單提交是post方法,如果改成get呢,會出問題。
重新部署,再來測試下
如果是get方式傳過來,中文就很有可能顯示亂碼。這個問題怎么解決了,有兩種方式解決,第一種不要寫get,就是post表單提交?,F(xiàn)在我們來看看第二種方式如何解決。在MyFilter類中寫一個通用的方法,既能解決get也能解決post的編碼問題。
裝飾模式解決get和post編碼問題
我們在MyFilter.java代碼中添加一個MyRequest?class,里面寫我們的裝飾器代碼,只重寫了getParameter(String text)方法。
package?com.kaigejava.web.filter;
import?java.io.IOException;
import?java.io.UnsupportedEncodingException;
import?javax.servlet.Filter;
import?javax.servlet.FilterChain;
import?javax.servlet.FilterConfig;
import?javax.servlet.ServletException;
import?javax.servlet.ServletRequest;
import?javax.servlet.ServletResponse;
import?javax.servlet.http.HttpServletRequest;
import?javax.servlet.http.HttpServletRequestWrapper;
public?class?MyFilter?implements?Filter {
????public?void?destroy() {
????????//?TODO?Auto-generated method stub
????}? ??
????public?void?doFilter(ServletRequest?request,?ServletResponse?response,?FilterChain?chain)?throws?IOException,?ServletException?{
????????//?轉(zhuǎn)換對象
????????HttpServletRequest?req?= (HttpServletRequest)?request;
????????//?設(shè)置編碼
????????//req.setCharacterEncoding("UTF-8");
????????//?放行
????????req?=?new?MyRequest(req);
????????//?req這個對象是包裝之后的對象,把這個傳到servlet中的request
????????chain.doFilter(req,?response);
????}
????public?void?init(FilterConfig?fConfig)?throws?ServletException?{
????????//?TODO?Auto-generated method stub
????}
}
/**
* ?繼承HttpServlet的包裝類,實現(xiàn)裝飾模式,解決get和post亂碼問題
*
*/
class?MyRequest?extends?HttpServletRequestWrapper{? ??
????HttpServletRequest?request;? ??
????public?MyRequest(HttpServletRequest?request) {
????????super(request);
????????this.request?=?request;
????}? ??
????public?String?getParameter(String?name) {
????????name?=?request.getParameter(name);?//亂碼
????????try?{
????????????return?new?String(name.getBytes("iso-8859-1"),?"UTF-8");
????????}?catch?(UnsupportedEncodingException?e) {
????????????e.printStackTrace();
????????}
????????return?null;
????}
? ??}
部署到tomcat,login.jsp表單還是get提交,測試可以解決get和post亂碼。
重寫其他方法
在request對象中,還有其他方法,例如getParameters()?和getParameterMap(),這里我們把這兩個方法都重寫一下。
package?com.kaigejava.web.filter;
import?java.io.IOException;
import?java.io.UnsupportedEncodingException;
import?java.util.Map;
import?javax.servlet.Filter;
import?javax.servlet.FilterChain;
import?javax.servlet.FilterConfig;
import?javax.servlet.ServletException;
import?javax.servlet.ServletRequest;
import?javax.servlet.ServletResponse;
import?javax.servlet.http.HttpServletRequest;
import?javax.servlet.http.HttpServletRequestWrapper;
public?class?MyFilter?implements?Filter {
? ??public?void?destroy() {
????}
? ??public?void?doFilter(ServletRequest?request,?ServletResponse?response,?FilterChain?chain)?throws?IOException,?ServletException?{
????????//?轉(zhuǎn)換對象
????????HttpServletRequest?req?= (HttpServletRequest)?request;
????????//?放行
????????req?=?new?MyRequest(req);
????????//?req變成自己包裝的對象,然后傳遞給servlet中,servlet中的request就是調(diào)用包裝過的req
????????chain.doFilter(req,?response);
????}
? ??public?void?init(FilterConfig?fConfig)?throws?ServletException?{
????}
}
/**
*?繼承HttpServlet的包裝類,實現(xiàn)裝飾模式,解決get和post亂碼問題
*
*/
class?MyRequest?extends?HttpServletRequestWrapper?{
? ? ? ??HttpServletRequest?request;
? ? ? ??public?MyRequest(HttpServletRequest?request) {
????????super(request);
????????this.request?=?request;
????}
????
????/*@Override
????public String?getParameter(String name) {
????????name =?request.getParameter(name); //亂碼
????????try {
????????????return new String(name.getBytes("iso-8859-1"), "UTF-8");
????????} catch (UnsupportedEncodingException?e) {
????????????e.printStackTrace();
????????}
????????return null;
????}*/
????
????@Override
????public?String?getParameter(String?name) {
????????Map<String,?String[]>?map?=?getParameterMap();
????????return?map.get(name)[0];
????}
????
????@Override
????public?String[]?getParameterValues(String?name) {
????????Map<String,?String[]>?map?=?getParameterMap();
????????return?map.get(name);
????}
????
????public?boolean?flag?=?true;
????@Override
????public?Map<String,?String[]>?getParameterMap() {
????????Map<String,?String[]>?map?=?request.getParameterMap();?//?亂碼
????????if?(flag) {
????????????for?(Map.Entry<String,?String[]>?m?:?map.entrySet()) {
????????????????String[]?values?=?m.getValue();
????????????????for?(int?i?= 0;?i?<?values.length;?i++) {
????????????????????try?{
????????????????????????values[i] =?new?String(values[i].getBytes("iso-8859-1"),?"UTF-8");
????????????????????}?catch?(UnsupportedEncodingException?e) {
????????????????????????e.printStackTrace();
????????????????????}
????????????????}
????????????}
????????????flag?=?false;
????????}
????????return?map;
????}
}
由于最后三個方法,我們倒數(shù)第二個第三個都是調(diào)用倒數(shù)第一個,為了解決第一個調(diào)用亂碼好了,第二個再次調(diào)用又變成亂碼,所以這里在第三個方法添加了一個flag。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。