参考:https://blog.csdn.net/weixin_44676935/article/details/106649260
一、优化Servlet类
思路说明:
对于刚接触Servlet来说,在我们在处理,jsp+servlet增删改查时,需要建立多个Servlet来处理,不同功能中的请求。
其实,我们只需要一个Servlet就可以处理多个请求,这只需要我们在jsp页面向servlet发送请求时候,并传递一个参数,这个参数值是用来标记此请求,进入BeanServlet类我们只需要对这个参数值进行判断,然后创建对应的处理请求的方法即可!
具体实现
JSP页面
`<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%
// 把绝对路径封装成一个变量
String ctx = request.getContextPath();
pageContext.setAttribute("ctx", ctx);
%>
import java.io.IOException;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/beanServlet")
public class beanServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求标记
String action = req.getParameter("action");
String returns = null;
// 对比请求标记值
if(action.equals("add")) {
// 调用处理方法接受返回值
returns = add(req, resp);
}
// 对比请求标记值
if(action.equals("del")) {
// 调用处理方法接受返回值
returns = del(req, resp);
}
// 对比请求标记值
if(action.equals("update")) {
// 调用处理方法接受返回值
returns = update(req, resp);
}
// 将返回用请求值返回页面
req.setAttribute("returns",returns);
//这个做一个判空
if(returns!=null) {
req.getRequestDispatcher("/bean.jsp").forward(req, resp);
}
}
// 请求处理
public String add(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException{
return "添加成功!";
}
public String del(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException{
return "删除成功!";
}
public String update(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException{
return "更新成功!";
}
}
`
这样我们就实现了Servlet类的一个小小的优化,解决了需创建多个Servlet类的问题,但是这样还不是我们想要达到的目标,因为现在只有三个请求,当请求过多时,按照这种方法我们要写很多的if语句,这并不是我们理想的。
二、使用反射进行优化
思路说明:
提起反射就不得不提一下Java的类加载机制,什么是类加载机制,我在这就不阐述了,我找到了一个博主的详解,感兴趣的可以看一下。点击这里:Java类加载机制
使用反射进行优化,具体步骤就是,我们先要获取当前类的一个字节码文件,它返回的是这个类的字节码对象,然后运用getMethod()将从页面获取到的请求标志传入,并传入两个请求和响应类,
具体实现:
`package Test;
import java.io.IOException;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/beanServlet")
public class beanServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求标记
String action = req.getParameter("action");
try {
// 获取当前类的字节码文件
Class<? extends beanServlet> clazz = this.getClass();
/**
* clazz.getMethod();
* 查找当前类,有没有action值所对应的处理方法,它相当于:
* if(action.equals("add")){}
*/
Method method = clazz.getMethod(action,HttpServletRequest.class,HttpServletResponse.class);
// 判断是否为空!
if(method!=null) {
// method.invoke(this, req,resp);是去执行匹配的请求处理方法
String returns=(String) method.invoke(this, req,resp);
// 判空,传值,跳转
if(returns != null) {
req.setAttribute("returns", returns);
req.getRequestDispatcher("/bean.jsp").forward(req, resp);
}
}
} catch (Exception e) {
e.printStackTrace();
}
// 请求处理 注意:使用反射优化,这里的方法必须是 public 公有的
public String add(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException{
return "添加成功!";
}
public String del(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException{
return "删除成功!";
}
public String update(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException{
return "更新成功!";
}
}
`
三、进一步优化
我们可以将反射的方法进行分发处理这个模块封装成一个BeanServlet类,然后让其他Servlet继承此类,就可以进一步优化了。
beanServlet
`public class BaseServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求标记
String action = req.getParameter("action");
try {
// 获取当前类的字节码文件
Class<? extends beanServlet> clazz = this.getClass();
/**
* clazz.getMethod();
* 查找当前类,有没有action值所对应的处理方法,它相当于:
* if(action.equals("add")){}
*/
Method method = clazz.getMethod(action,HttpServletRequest.class,HttpServletResponse.class);
// 判断是否为空!
if(method!=null) {
// method.invoke(this, req,resp);是去执行匹配的请求处理方法
String returns=(String) method.invoke(this, req,resp);
// 判空,传值,跳转
if(returns != null) {
req.setAttribute("returns", returns);
req.getRequestDispatcher("/bean.jsp").forward(req, resp);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
`
Servlet
public class Servlet extends BeanServlet { private static final long serialVersionUID = 1L; // 请求处理 注意:使用反射优化,这里的方法必须是 public 公有的 public String add(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException{ return "添加成功!"; } public String del(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException{ return "删除成功!"; } public String update(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException{ return "更新成功!"; } }