javaWeb_BaseServlet --对于servlet的改写, 使得servlet更加优雅,类似于springmvc等
目的 : 实现BaseServlet, 实现对于servlet的优雅编写, 减少重复代码的出现
需要解决的问题 :
设计思路 : 继承HttpServlet, 重写service方法. 原本操作是:重写doGet与重写doPost(这两个函数原本由service调用)
实际代码 :
1. BaseServlet的实现 :
1 package com.theangryz.servlet; 2 3 import javax.servlet.ServletException; 4 import javax.servlet.http.HttpServlet; 5 import javax.servlet.http.HttpServletRequest; 6 import javax.servlet.http.HttpServletResponse; 7 import java.io.IOException; 8 import java.lang.reflect.Method; 9 10 public class BaseServlet extends HttpServlet { 11 @Override 12 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 13 Class clazz = this.getClass(); 14 String methodName = req.getParameter("method"); 15 if (methodName == null || methodName.trim().isEmpty()){ 16 throw new RuntimeException("没有输入method参数"); 17 } 18 Method method = null; 19 try{ 20 method = clazz.getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class); 21 }catch (Exception e){ 22 throw new RuntimeException("你调用的方法" + methodName + "不存在"); 23 } 24 String str = null; 25 try{ 26 str = (String) method.invoke(this, req, resp); 27 }catch(Exception e){ 28 throw new RuntimeException("方法执行出错"); 29 } 30 if (str == null || str.trim().isEmpty()){ 31 return ; 32 } 33 if (str.contains(":")){ 34 int index = str.indexOf(":"); 35 String prefix = str.substring(0, index); 36 String suffix = str.substring(index+1); 37 if (prefix.equalsIgnoreCase("f")){ //转发 38 req.getRequestDispatcher(suffix).forward(req, resp); 39 }else if (prefix.equalsIgnoreCase("r")){ //重定向 40 resp.sendRedirect(req.getContextPath() + suffix); 41 }else{ 42 throw new RuntimeException("当前版本不支持该前缀 : " + prefix); 43 } 44 }else{ //默认转发 45 req.getRequestDispatcher(str).forward(req, resp); 46 } 47 } 48 }
2. AServlet的实现(该AServlet用于测试BaseServlet)
1 package com.theangryz.servlet; 2 3 import javax.servlet.ServletException; 4 import javax.servlet.http.HttpServletRequest; 5 import javax.servlet.http.HttpServletResponse; 6 import java.io.IOException; 7 8 public class AServlet extends BaseServlet{ 9 protected String addUser(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 10 11 response.getWriter().print("addUser执行结束了"); 12 return "/show.jsp"; 13 } 14 protected String func1(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 15 System.out.println("func1"); 16 return "f:/show.jsp"; 17 } 18 protected String func2(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 19 System.out.println("func1"); 20 return "r:/show.jsp"; 21 } 22 protected String func3(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 23 System.out.println("func1"); 24 return null; 25 } 26 }
实际编写中遇到的问题 :
1. 程序在执行 clazz.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class)一直抛出异常(methodName是正确的前提下).
解决 : getMethod方法反射只能获取public的方法与继承得来的public方法. 但是在AServlet中方法的访问修饰为protected, 所以即使methodName是正确的, getMethod还是没有办法反射得到protected的方法. 所以程序使用了getDeclaredMethod()方法, 该方法可以得到除了继承得来的方法之外的所有方法.