你的位置:首页 > Java教程

[Java教程]关于BaseServlet那些事

@为什么需要BaseServlet?  我们知道一个POST或者GET提交对应着一个Servlet, 无数的提交会让Servlet页面增加,我们希望一个Servlet就能处理很多提交的请求。

@BaseServlet 是一个继承了HttpServlet的普通类,并不是Servlet类,所以不需要在web.

@一些要求 是: 客户端发送请求时,必须提供一个参数(本文编写的这个参数名字叫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&param=哈哈'/>"> 点击这里啊</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 ZHAOYUQIANG14  *15 */16 public class TestServlet extends BaseServlet {17  /**18   * 测试post传递过来的参数19   * @param request20   * @param response21   * @return22   * @throws ServletException23   * @throws IOException24  */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 req34   * @param resp35   * @return36   * @throws ServletException37   * @throws IOException38  */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. 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 stub19  }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    * 掉包request32    * 1. 写一个request的装饰类33    * 2. 放行时,使用我们自己的request34    * 3. 但是POST方式依然使用request35   */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 stub48  }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>
过滤器的拦截配置

@项目下载

湛江有什么旅游景点湛江二日游攻略大全惠州旅游景点大全清迈突突(Tuktuk)车怎么收费? 如何兑换泰铢最划算? 去马代旅游了,需要注意什么? 2015春节广东赏花时间地点一览表?广东春节看花有什么花开了? 2015华南植物园牡丹花开放了吗?广州华南植物园牡丹花盛花期? 2015春节广州赏花什么地方好?广州春节期间有什么花看? 惠州怡情谷漂流简介?怡情谷漂流时间? 2015小鸟天堂端午节活动?端午节新会小鸟天堂优惠活动? 龙虎山门票团购优惠多少?龙虎山在哪预定? 米兰大教堂—世界建筑和文明史上的奇迹 叹息桥—面对人生的永恒叹息 沙巴在哪里_马来西亚在什么地方 MAXIM MAX352CSEANALOGSW Datasheet MAXIM MAX352EPE Datasheet MAX6313UK43D2-T Datasheet MAX6313UK43D3-T Datasheet 深圳到岳阳三战三捷石刻旅游 深圳到岳阳三战三捷石刻旅游 深圳到岳阳三战三捷石刻旅游 深圳到岳阳四牌楼旅游 深圳到岳阳四牌楼旅游 深圳到岳阳四牌楼旅游