一、BaseServlet的作用
我们在开发JavaWeb项目时,往往会在Sevlet体系中定义一个BaseServlet类,让我们自定义的Servlet都继承于BaseServlet。
那这是为什么呢?
BaseServlet是一个我们自己定义的一个Servlet基类,它不被直接调用而是用于被其它Servlet继承,因此不需要 @WebServlet("/XXXServlet") 注解,不需要在web.xml中声明。
目的是为了降低Servlet冗余,可以将多个方法写到同一个Servlet中,
因为一般一个Servlet只有一个方法(doGet或doPost),只能处理一个业务请求,如果项目大一些,那么Servlet的数量就会很惊人。
例如之前的一个文件上传下载功能,一个JSP页面对应3个Servlet类,Servlet类繁多。
为了避免这种情况,我们写一个BaseServlet。它的作用是让一个Servlet可以处理多种不同的请求,不同的请求去调用Servlet中的不同方法。
我们写好了BaseServlet后,让其他Servlet继承BaseServlet.
例如,UserServlet继承BaseServlet,然后在UserServlet中提供add()、update()、delete()、select()等方法,每个方法对应不同的请求,我们可以在每个方法最后,通过重定向或转发请求打开新的JSP页面;或者我们可以让每个方法返回一个字符串,指出它重定向或转发请求的路径,BaseServlet获得这个路径,再帮助子类转发请求或重定向到特定的页面。
这样,就可以减少Servlet的数量,一般来说,我们会让⼀个模块对应⼀个Servlet。相当于数据库中⼀张表对应⼀个Servlet,在Servlet中提供不同的⽅法,完成⽤户的请求。
二、BaseServlet的具体实现
编写⼀个BaseServlet继承HttpServlet来完成⽅法的分发。
再让其他的Servlet继承BaseServlet。
在BaseServlet中的service()⽅法中完成⽅法的分发。
import java.io.IOException; import java.lang.reflect.Method; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /* * init用于Servlet初始化时调用,只调用一次,后续再次请求将不会再次调用init * service:每次请求servlet时都会调用service * service方法会调用doGet、doPost方法(HttpServlet重写了service方法调用了doGet、doPost) * 重写了service方法就可以不重写doGet、doPost,直接在service中进行了处理 * 继承BaseServlet的子类Servlet会自动调用service方法 * */ public class BaseServlet extends HttpServlet { @Override public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=utf-8"); String method = req.getParameter("method"); // 获取传来的方法名字,知道需要使用哪个方法 System.out.println("BaseServlet.service()...method = " + method); if (null == method || "".equals(method) || method.trim().equals("")) { method = "execute"; } // 为页面请求匹配具体处理的方法 Class clazz = this.getClass(); try { /* * getMethod:获取方法对象(method类对象), * 需要的参数:需要获取的方法的方法名、HttpServletRequest.class、HttpServletResponse.class */ Method md = clazz.getMethod(method, HttpServletRequest.class, HttpServletResponse.class); if (null != md) { /* * this:当前类,使用service方法的类,这里是继承BaseServlet的类 * method.invoke:利用反射,在this代表的类中调用method方法 */ String jspPath = (String) md.invoke(this, req, resp); if (null != jspPath && !jspPath.trim().isEmpty()) { System.out.println("BaseServlet.service:jspPath = " + jspPath); req.getRequestDispatcher(jspPath).forward(req, resp); } else { System.out.println("BaseServlet.service:jspPath is null."); } } } catch (Exception e) { e.printStackTrace(); } } // 默认方法 public String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=utf-8"); System.out.println("BaseServlet.execute()..."); return null; } }