在进行开发时会需要编写许多的 Servlet 来进行满足多种多样的业务需求,但是每一个 Servlet 都是需要部署在 Tomcat 或者其他的 Web 服务器上,如果 Servlet 的数量过多的话会占据大量的资源,因此我们可以考虑更优的方案来解决这个问题。
首先我们考虑在一个 Servlet 中编写多个方法,根据 request 携带过来的方法的名称的参数来进行方法的选取
但是当需要的方法的数量过多的时候就会导致 case 语句的数量繁多,因此我们就需要进一步的优化,这时我们可以想到可以利用反射的方式来进行 Servlet 的使用
从这其中我们又可以发现,当存在多个相同的类似基类,如:UserServlet , BrandServlet 等的时候,就会出现类似代码的冗余,每一个基类中都会写相同的代码,此时我们就可以考虑使用父类继承的方式来进行代码的优化,此时我们可以定义一个实现 HtppServlet 接口的类并在其中设置service 方法,而此时的 HttpServlet + service 的实现方式就是我们的 BaseServlet
package com.controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class BaseServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取方法名
String uri = req.getRequestURI();
int idx = uri.lastIndexOf('/');
String methodName = uri.substring(idx+1);
// 获取字节码文件 就是Servlet
Class<? extends BaseServlet> cls = this.getClass();
//使用方法
try {
//获取方法 Method 对象
Method method = cls.getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
//执行方法
method.invoke(this,req,resp);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
/**
* BaseServlet 实现过程是设计一个 BaseServlet 基础类来简化繁杂的Servlet
* 利用反射的基本原理 重写 HttpServlet 的 service 方法在其中获取方法名
* 与传统的 Servlet 的访问方式相比,这种方式可以减少 Servlet 的创建,减小了内存的占用,
* 在一个 Servlet 中构建多种的方法通过名称的不同来进入不同的方法,
* 在这其中可以使用 switch 来进行跳转,但是当方法的数量过多时,case 语句也会造成冗杂
* 所以说我们可以利用反射的原理来进行,从而避免了大量繁琐的判断语句
* 1、获取方法的标识符
* 2、根据方法名称调用相应的逻辑方法
*/
/**
* 在 html 页面中提交表单的发送位置的 Servlet ,然后根据 Servlet 的名称来去往相应的 Servlet,由于该 Servlet 继承自 BaseServlet
* 所以我们可以直接通过方法名称找到相对应的 Servlet 中的方法名称
*/
此时我们在进行 UserServlet 的调用时只需要继承 BaseServlet 并且编写相应的方法即可,可以通过地址栏输入 /brand/selectAll 的访问路径访问相应的 Servlet
最后,就是有关于原始的 doGet 和 doPost 的消失问题,我个人的理解是这样的,由于我们本来的 Servlet 是继承自 HttpServlet 所以是一种继承的关系,我们可以选择通过重写 doGet 和 doPost 的方式来进行请求方式不同的转发,而现在我们这种方式是通过对请求路径的不同来进行的转发,因此不用重写 doGet 和 doPost,在另外一方面,关于请求参数的获取问题,我们一般使用 json 进行数据的传输和接受,就算是有意外情况也会与前端开发人员进行沟通,所以这个问题不必要太纠结,因为我们前面只是在学习最初始版本的知识,所以会学到许多比较麻烦的知识。
@WebServlet("/brand/*")
public class BrandServlet extends BaseServlet{
private BrandService service = new BrandServiceImpl();
public void selectAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取数据
List<Brand> brands = service.selectAll();
//将List集合转为json
String jsonString = JSON.toJSONString(brands);
//响应
response.setContentType("text/json;charset=utf-8");
response.getWriter().write(jsonString);
}
public void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
BufferedReader br = request.getReader();
// 读取json数据 因为传入的形式和getParams形式不一样,所以需要使用 readLine的方法
String params = br.readLine();
Brand brand = (Brand) JSON.parseObject(params, Brand.class);
service.add(brand);
// 响应表示
response.getWriter().write("success");
}
public void selectById(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
BufferedReader br = request.getReader();
//获取json数据
String params = br.readLine();
//转为brand
int id= JSON.parseObject(params, int.class);
//调用方法传入id
Brand brand1 = service.selectById(id);
// 将数据转为json
String jsonString = JSON.toJSONString(brand1);
// 响应数据
response.setContentType("text/json;charset=utf-8");
response.getWriter().write(jsonString);
}
public void deleteById(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
BufferedReader br = request.getReader();
String params = br.readLine();
Integer id = JSON.parseObject(params, int.class);
service.deleteById(id);
response.getWriter().write("success");
}
public void deleteByIds(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
BufferedReader br = request.getReader();
String params = br.readLine();
int[] ids = JSON.parseObject(params,int[].class);
service.deleteByIds(ids);
//
response.getWriter().write("success");
}
public void updateInfo(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
BufferedReader br = request.getReader();
String params = br.readLine();
Brand brand = (Brand) JSON.parseObject(params, Brand.class);
service.updateInfo(brand);
//
response.setContentType("text/json;charset=utf-8");
response.getWriter().write("success");
}
public void selectByPage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
//读取参数 当前页码 每页展示条数
//下划线表示临时数据
String _currentPage = request.getParameter("currentPage");
String _pageSize = request.getParameter("pageSize");
int currentPage = Integer.parseInt(_currentPage);
int pageSize = Integer.parseInt(_pageSize);
//调用service
PageBean<Brand> pageBean = service.selectByPage(currentPage, pageSize);
//json
String jsonString = JSON.toJSONString(pageBean);
//响应
response.setContentType("text/json;charset=utf-8");
response.getWriter().write(jsonString);
}
public void selectByPageAndCondition(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
//读取参数 当前页码 每页展示条数
//下划线表示临时数据
String _currentPage = request.getParameter("currentPage");
String _pageSize = request.getParameter("pageSize");
int currentPage = Integer.parseInt(_currentPage);
int pageSize = Integer.parseInt(_pageSize);
//
BufferedReader br = request.getReader();
String params = br.readLine();
Brand brand = JSON.parseObject(params, Brand.class);
//调用service
PageBean<Brand> pageBean = service.selectByPageAndCondition(currentPage, pageSize,brand);
//json
String jsonString = JSON.toJSONString(pageBean);
//响应
response.setContentType("text/json;charset=utf-8");
response.getWriter().write(jsonString);
}
}