@為什麼需要BaseServlet? 我們知道一個POST或者GET提交對應著一個Servlet, 無數的提交會讓Servlet頁面增加,我們希望一個Servlet就能處理很多提交的請求。 @BaseServlet 是一個繼承了HttpServlet的普通類,並不是Servlet類,所以不需要在we ...
@為什麼需要BaseServlet? 我們知道一個POST或者GET提交對應著一個Servlet, 無數的提交會讓Servlet頁面增加,我們希望一個Servlet就能處理很多提交的請求。
@BaseServlet 是一個繼承了HttpServlet的普通類,並不是Servlet類,所以不需要在web.xml中添加路徑。但是Servlet會繼承這個BaseServlet來實現一個Servlet處理多個提交請求 。
@一些要求 是: 客戶端發送請求時,必須提供一個參數(本文編寫的這個參數名字叫method,這個method和form中的那個method沒有半毛錢關係,只是一個變數名字而已),用來說明要調用Servlet中的那個處理方法; 其次,繼承了BaseServlet的Servlet中的處理請求的方法的原型必須與service方法相同,即返回值類型、參數都不需要和service方法相同。即如下的形式:
public String XXX(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { return null ; }
@POST和GET請求對於method參數的提供技巧 POST請求一般為表單形式,提供method參數的方式可以添加一個隱藏欄位 <input type="hidden" name="method" value="希望調用Servlet中的方法的名字"/> ; @GET請求一般為超鏈接,提供method參數的方式直接在路徑後面加 ?method=方法名
@POST和GET請求編碼處理 我們知道Servlet對POST請求和對GET請求的請求編碼不同,區別如下:
POST的請求 request.setCharacterEncoding("utf-8"); String name = request.getParameter("name"); GET的請求 String name = request.getParameter("name"); name = new String(name.getBytes("ISO-8859-1"),"utf-8"); POST和GET的響應編碼都是: response.setContentType("text/html;charset=UTF-8");
為了使得servlet中的代碼簡潔,我們可以把兩種編碼的代碼放到BaseServlet中,但是,像上傳下載這種請求不適合用BaseServlet,所以我們一般把這種代碼寫在過濾器中,過濾器不是本文主要內容,如果你不會的話,可以不用過濾器,把編碼的代碼直接寫在servlet中的請求處理方法中即可 。
@源碼
1 <%--get請求,傳遞過去method參數,指明調用TestServlet的fun2方法,並且傳遞一個參數param--%> 2 <a href="<c:url value='/TestServlet?method=fun2¶m=哈哈'/>"> 點擊這裡啊</a> 3 <%--post請求--%> 4 <form action="<c:url value='/TestServlet'/>" method="post"> 5 <input type="hidden" name="method" value="fun1"/> 6 <input type="text" name="param" value="我是表單參數" /> 7 <input type="submit" name="提交"/> 8 </form>請求jsp頁面
1 package cn.demo1.baseServlet; 2 3 import java.io.IOException; 4 5 import javax.servlet.ServletException; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 /** 9 * TestServlet 10 * 實現了一個Servlet中多個請求處理方法 11 * 方法的的參數必須和service方法相同 12 * 客戶端必須傳遞過來method參數,說明是調用哪一個請求處理方法 13 * @author ZHAOYUQIANG 14 * 15 */ 16 public class TestServlet extends BaseServlet { 17 /** 18 * 測試post傳遞過來的參數 19 * @param request 20 * @param response 21 * @return 22 * @throws ServletException 23 * @throws IOException 24 */ 25 public String fun1(HttpServletRequest request, HttpServletResponse response) 26 throws ServletException, IOException { 27 String param = request.getParameter("param"); 28 request.setAttribute("param", param); 29 return "f:/baseServlet/index.jsp" ; 30 } 31 /** 32 * 測試get請求傳遞過來的參數 33 * @param req 34 * @param resp 35 * @return 36 * @throws ServletException 37 * @throws IOException 38 */ 39 public String fun2(HttpServletRequest request, HttpServletResponse response) 40 throws ServletException, IOException { 41 String param = request.getParameter("param"); 42 request.setAttribute("param", param); 43 return "f:/baseServlet/index.jsp"; 44 } 45 }請求Servlet
1 package cn.demo1.baseServlet; 2 3 import java.io.IOException; 4 import java.lang.reflect.Method; 5 6 import javax.servlet.ServletException; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 /** 11 * BaseServlet[抽象類] 不需要在web.xml中添加路徑 12 * @功能 1. 13 * @author ZHAOYUQIANG 14 * 15 */ 16 public abstract class BaseServlet extends HttpServlet { 17 public void service(HttpServletRequest request, HttpServletResponse response) 18 throws ServletException, IOException { 19 // response.setContentType("text/html;charset=UTF-8");//處理響應編碼 20 /* 21 * 設置POST和GET請求編碼 22 */ 23 /* 24 * 1. 獲取參數,用來識別用戶想請求的方法 25 * method是用戶在瀏覽器地址欄中輸入的想要調用的方法,是個參數 26 */ 27 String methodName = request.getParameter("method"); 28 /* 29 * 2. 判斷用戶有沒有傳參數 30 */ 31 if(methodName == null || methodName.trim().isEmpty()){ 32 throw new RuntimeException("您沒有傳遞method參數! 無法確定您要調用的方法!"); 33 } 34 /** 35 * 3. 判斷是哪一個方法,是哪一個就調用哪一個 36 * 所用的技術是: 反射 37 * 需要得到本類Class,然後調用它的getMethod,通過傳遞過來的方法名字進行得到Method對象 38 * 這樣做的目的是: 以後像其他Servlet中的方法要修改或者添加新方法時,就不用在去修改這一塊代碼了 39 */ 40 /* 41 * 3.1. 得到當前類的對象 42 */ 43 Class c = this.getClass(); 44 /* 45 * 3.2. 通過傳遞過來的方法名(addUse等)得到Method對象 46 * 導包 :java.lang.reflect.Method; 47 */ 48 Method method = null ; 49 try { 50 method = c.getMethod(methodName, 51 HttpServletRequest.class,HttpServletResponse.class); 52 } catch (Exception e) { 53 throw new RuntimeException("您要調用的方法"+methodName+",它不存在"); 54 } 55 try { 56 /* 57 * 3.3. 調用method表示的方法,即: 調用繼承該類的類中的方法 58 * 反射調用: 用this來調用method表示的方法,並且傳遞參數req和resp 59 */ 60 String result =(String)method.invoke(this, request,response); 61 /** 62 * 4. 處理從繼承這個類的類中返回的字元串(重定向和轉發) 63 * return "r:/index.jsp"; 和 return "f:/index.jsp"; 64 * 返回的是字元串,需要解讀字元串 65 */ 66 /* 67 * 4.1. 如果用戶返回的字元串為null,或者"",那麼什麼都不做 68 */ 69 if(result == null || result.trim().isEmpty()){ 70 return ; 71 } 72 /* 73 * 4.2. 解讀字元串1:判斷字元串中有沒有冒號 74 * 沒有冒號預設表示轉發,反之再進行判斷 75 */ 76 if(result.contains(":")){ 77 /* 78 * 4.3. 解讀字元串2 : 先獲取冒號位置,然後截取首碼(操作,是重定向還是轉發)和尾碼(路徑) 79 */ 80 int index = result.indexOf(":"); 81 String operate = result.substring(0,index); 82 String path = result.substring(index+1); 83 /* 84 * 4.4. 進行處理,如果是r重定向,如果是f則轉發 85 */ 86 if(operate.equalsIgnoreCase("r")){ 87 response.sendRedirect(request.getContextPath()+path); 88 }else if(operate.equalsIgnoreCase("f")){ 89 request.getRequestDispatcher(path).forward(request, response); 90 }else{ 91 throw new RuntimeException("您指定的操作"+operate+ 92 "不支持,請正確填寫:r和f"); 93 } 94 }else{ 95 /* 96 * 沒有冒號預設轉發處理 97 */ 98 request.getRequestDispatcher(result).forward(request, response); 99 } 100 } catch (Exception e) { 101 System.out.println("您要調用的方法"+methodName+",它內部拋出了異常"); 102 throw new RuntimeException(e); 103 } 104 } 105 }BaseServlet
1 package cn.demo1.baseServlet; 2 3 import java.io.IOException; 4 import javax.servlet.Filter; 5 import javax.servlet.FilterChain; 6 import javax.servlet.FilterConfig; 7 import javax.servlet.ServletException; 8 import javax.servlet.ServletRequest; 9 import javax.servlet.ServletResponse; 10 import javax.servlet.http.HttpServletRequest; 11 12 /** 13 * 輔助Servlet簡化編碼代碼 14 */ 15 public class EncodingFilter implements Filter { 16 17 public void destroy() { 18 // TODO Auto-generated method stub 19 } 20 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 21 /* 22 * 處理post請求亂碼問題 23 */ 24 request.setCharacterEncoding("utf-8"); 25 /* 26 * 處理GET請求編碼問題 27 * String name1 = request.getParameter("name"); 28 * name2 = new String(name.getBytes("ISO-8859-1"),"utf-8"); 29 * GET不一樣,設置編碼後,servlet中獲取name,獲取應該是name2,都是如果如上寫的話, 30 * getParameter("name")獲取的是name1 . 31 * 掉包request 32 * 1. 寫一個request的裝飾類 33 * 2. 放行時,使用我們自己的request 34 * 3. 但是POST方式依然使用request 35 */ 36 HttpServletRequest req = (HttpServletRequest) request ; 37 if(req.getMethod().equals("GET")){ 38 EncodingRequest er = new EncodingRequest(req); 39 chain.doFilter(er, response); 40 }else if(req.getMethod().equals("POST")){ 41 chain.doFilter(request, response); 42 } 43 response.setContentType("text/html;charset=UTF-8"); 44 } 45 46 public void init(FilterConfig fConfig) throws ServletException { 47 // TODO Auto-generated method stub 48 } 49 50 }EncodingFilter類
package cn.demo1.baseServlet; import java.io.UnsupportedEncodingException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; /** * 輔助過濾器來處理GET編碼問題 * @author ZHAOYUQIANG * */ public class EncodingRequest extends HttpServletRequestWrapper{ private HttpServletRequest request ; public EncodingRequest(HttpServletRequest request) { super(request); this.request = request ; } /** * 處理編碼問題 */ public String getParameter(String name) { String value = request.getParameter(name); /* * 處理編碼問題 */ try { value = new String (value.getBytes("ISO-8859-1"),"utf-8"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block throw new RuntimeException(e); } return value; } }EncodingRequest類
1 <filter> 2 <display-name>EncodingFilter</display-name> 3 <filter-name>EncodingFilter</filter-name> 4 <filter-class>cn.demo1.baseServlet.EncodingFilter</filter-class> 5 </filter> 6 <filter-mapping> 7 <filter-name>EncodingFilter</filter-name> 8 <url-pattern>/TestServlet</url-pattern> 9 </filter-mapping>過濾器的攔截配置
@項目下載
http://files.cnblogs.com/files/zyuqiang/webBlogTest.rar