BaseServlet
知识铺垫
在以往的Test ServletDemo中,我们可以知道,Servlet是作为客户端和服务器连接的一个工具,当需要处理请求和页面跳转的时候,大多数情况下都是每一个请求和转发我们都需要一个单独的Servlet程序去处理,并且其中的架构大多相同doGet(params),doPost(params),这大大增加了代码的冗余,通过以往的学习我们可以知道,Servlet都继承自类HttpServlet,并执行其中的service()方法。
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String method = req.getMethod();
if (method.equals(METHOD_GET)) {
long lastModified = getLastModified(req);
if (lastModified == -1) {
// servlet doesn't support if-modified-since, no reason
// to go through further expensive logic
doGet(req, resp);
} else {
long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
if (ifModifiedSince < lastModified) {
// If the servlet mod time is later, call doGet()
// Round down to the nearest second for a proper compare
// A ifModifiedSince of -1 will always be less
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
}
} else if (method.equals(METHOD_HEAD)) {
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp);
} else if (method.equals(METHOD_POST)) {
doPost(req, resp);
} else if (method.equals(METHOD_PUT)) {
doPut(req, resp);
} else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp);
} else if (method.equals(METHOD_OPTIONS)) {
doOptions(req,resp);
} else if (method.equals(METHOD_TRACE)) {
doTrace(req,resp);
} else {
//
// Note that this means NO servlet supports whatever
// method was requested, anywhere on this server.
//
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
}
}
通过继承我们可以了解到:父类引用子类对象,在继承的过程中有以下的情况:
1、如果子类没有重写父类方法,在创建子类对象调用该方法的时候,调用的是父类中的方法
2、如果子类重写了父类方法,在子类对象调用该方法的时候,实现的是子类的方法。根据这个思想,我们可以将servlet进行一定的整合。即创建一个BaseServlet类(用于实现某一个特定实体的servlet,如:user),继承自HttpServlet并重写service方法。
public class BaseServlet extends HttpServlet {
//重写父类德Service方法就会优先执行, 其他类继承该类会直接访问该类的service方法
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
实现步骤
由于页面请求Servlet程序时都只会执行service方法,所以我们可以将页面中需要访问的servlet的@WebServlet(“”)功能在此实现;主要方法如下:
1、找到页面请求的Servlet路径
String road = req.getRequestURI();
2、获得方法名
在上述获得路径中,包含了项目相对路径,如://test,但我们需要得到的应该是最后的名称,即test,这样就可以通过该名称在servlet方法库中找到对应的方法名,并执行相关操作。
String methodName = road.substring(road.lastIndexof("/") + 1);
3、使用反射的方式获取该方法
//在继承关系中,那个类实现了方法,this就代表哪个类
Class<? extends BaseServletL> clazz = this.getClass();
//在实现方法中,有doGET,和doPost他们包含了HttpServletRequest,HttpServletResponse对象参数
method = clazz.getDeclaredMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
method.setAccessible(true);
method.invoke(this, req, resp);
示例
BaseServlet
public class BaseServletL extends HttpServlet {
//调用HttpServlet第一使用的就是service, 使用该类的作用是将所有的Servlet功能实现在同一个类下,在前端调用的时候,使用方法名的调用方式
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//继承中, 函数调用的方式是,如果子类没有重写相关的方法,在使用子类的对象去调用的时候会调取父类的该方法,如果子类重写了该方法,则调用实现的是子类实现的方法
/*想要实现上述的方法,我们就需要获得获取资源的路径,但需要注意的是,在获得路径中,我们需要得到的方法应该是最后的名称*/
String road = req.getRequestURI();// /test
//需要获得路径下的最后一个名称,该内容就是需要调用的方法
String methodName = road.substring(road.lastIndexOf("/") + 1);
//使用反射的方式获取该方法,在继承关系中,那个类实现了方法,this就代表哪个类
Class<? extends BaseServletL> clazz = this.getClass();
//getDeclaredMethod表示
Method method = null;
try {
method = clazz.getDeclaredMethod(methodName);
method.setAccessible(true);
method.invoke(this, req, resp);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
实现类
package com.louis.rigester.web.extract;
import com.louis.rigester.pojo.Employee;
import com.louis.rigester.service.EmployeeService;
import com.louis.rigester.service.impl.EmployeeServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* @author XRY
* @date 2023年05月13日14:47
*/
//该类用于书写关于User所有servlet功能
@WebServlet("/user/*")
public class UserServlet extends BaseServlet {
private EmployeeService employeeService = new EmployeeServiceImpl();
protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html; charset = UTF-8");
//获取用户名和密码
String username = req.getParameter("username");
String password = req.getParameter("password");
String remember = req.getParameter("remember");
Employee employee = new Employee();
employee.setUsername(username);
employee.setPassword(password);
Employee result= employeeService.findByPwdAndUsername(employee);
System.out.println(result);
if(employeeService.findByPwdAndUsername(employee) != null){
//用户存在,登录成功之后,跳转到查看所有信息的页面
if(true){
}
//判断记住选矿
if("1".equals(remember)){
Cookie uname = new Cookie("username", username);
Cookie pwd = new Cookie("password", password);
//cookie发送数据只能在当前路径下资源访问才有效,
/*如username这个cookie存在*/
uname.setPath(req.getContextPath());
pwd.setPath(req.getContextPath());
uname.setMaxAge(60*60*24*7);
pwd.setMaxAge(60*60*24*7);
resp.addCookie(uname);
resp.addCookie(pwd);
}
//将登陆成功后的数据存储到Session中
HttpSession session = req.getSession();
session.setAttribute("username", employee);
req.getRequestDispatcher("/findAll").forward(req, resp);
}else{
//失败
//跳转到login.jsp
req.setAttribute("tip_msg", "用户名或密码错误");
String contextPath = req.getContextPath();
req.getRequestDispatcher(contextPath + "/login.jsp").forward(req, resp);
}
}
protected void register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset = UTF-8");
Employee employee = new Employee();
String username = request.getParameter("username");
String password = request.getParameter("password");
String checkCode = request.getParameter("checkCode");
employee.setUsername(username);
//判断用户名是否存在
if(employeeService.findByUsername(employee) == null){
//说明用户名不存在
//判断验证码
//获取程序生成的验证码进行比对
HttpSession session = request.getSession();
//获取存储在session中的验证码
String codeGen = (String)session.getAttribute("codeGen");
if(!codeGen.equalsIgnoreCase(checkCode)){
//允许注册
request.setAttribute("tip_msg", "验证码错误!");
request.getRequestDispatcher("/register.jsp").forward(request, response);
return;
}
employee.setPassword(password);
employeeService.add(employee);
request.setAttribute("tip_msg", "注册成功,请登录!");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}else{
//用户名存在,跳转到注册页面
request.setAttribute("tip_msg", "用户名已存在");
request.getRequestDispatcher("/register.jsp").forward(request, response);
}
}
}