创建BaseServlet的必要性
如果不创建BaseServlet,现在我们只要实现一个功能,我们就需要创建一个servlet!
例如:用户模块(登录,注册,退出录,激活,发送邮件等等功能) 也就是说,我们必须要创建一些系列的Servlet:UserLoginServlet - 登录功能! UserRegisterServlet ->注册功能!
总之,只要你实现一个功能,你就得创建-个servlet!
这种情况会有两个弊端!
1.创建大量的servlet!servet实例-> web容器(tomcat)管理!有大量的servlet实例必然会占有更大的
运行内存!会间接的拖慢web容器的速度!
2.servlet 他的service(dogel/dopost)方法是一个多线程方法!也就说理论上说!一个servlel可以处理很多次请求,也可以并发的 处理请求,一个servlel能力很强! 但是只对应一个功能!你不觉得浪费么?
Baseservlet我们想解决的问题就是!简化和优化servlet的创建和数量!
Baseservlet的实现思路
1.为什么一个servlet只对应一个功能!
一个serviet被访问以后,只会有一个方法被调用,通常我们习惯一个方法中写一个套业务逻辑!
一个servlet对应一个方法对应一个业务功能!
2.分析Baseservlet实现的思路
1.让一个servet对应多个方法就好了! 每个方法都实现一个业务逻辑!
2.具体的实现思路
步骤1:在一个servlel声明多个处理业务逻方法!
步骤2:在每次访问servlet的时候在路径上添加一个标识! 标识(method)用于判断要访问具体业务逻辑方法!
步骤3:当每次请求到 doget/dopost/service方法的时候,判断参数的标识,调用对应的业务逻辑方
法即可!
Baseservlet的实现
1.实现基本的Baseservlet
步骤1:Baseservlet继承httpservlet类,重写其service方法
步骤2:在service方法中获得具体要执行的方法如(登录,注册等),在执行
2.优化方法调用
利用标识符的字符串和方法名相同!
我们可以利用反射的技术!调用对应的执行方法!
避免了大量的if或switch判断!
当有新的方法出现的时候!也不需要额外的添加判断方法!
3.优化多Servlet实现
实现思路:
我们创建一个BascServlet类,让他去继承HttpServlet!BaseServlet中写service方法!
在service写 1.获取标识 2.反射调用业务逻辑
每个模块对应的Controller只需要集成Baseservlet即可!
HttpServlet->BaseServlet->模块的Controller
4.优化返回值问题
每个方法都要进行响应
响应的方式固定: 转发 重定向 返回字符串 返回字节流
如果在每个方法写转发和重定向和返回字符串的语法比较繁琐!
我们可以统一在Baseservlet进行处理!
操作:
步骤1:将方法的返回值改成字符串即可!
步骤2: 根据约定的内容,添加特殊的标识!
例如:转发“forward: 路径”
步骤3:BaseServlet集中处理
执行方法!获取返回值!进行非空判断!
截取标识!进行转发重定向或者写回字符串处理!
好处:简化方法的响应的操作!
注意:没有管返回字节!
返回字节!我们只需要将方法的返回值改成void!
整体实现代码样例
BaseServlet代码
package 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.Method;
import static utils.Constants.*;
public class BaseServlet extends HttpServlet {
@Override
public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
try {
//防止乱码
req.setCharacterEncoding("UTF-8");
res.setCharacterEncoding("UTF-8");
res.setContentType("text/html;charset=utf-8");
//得到方法的名称
String m=req.getParameter(TAG);
if(m==null||m.isEmpty()){
m=INDEX;
}
Class<? extends BaseServlet>clazz=this.getClass();
//获取要执行的方法
Method method = clazz.getDeclaredMethod(m, HttpServletRequest.class, HttpServletResponse.class);
method.setAccessible(true);
//得到返回值再进行判断是什么操作:转发 重定向 字符串(json)
Object result = method.invoke(this, req, res);
if(result!=null){
String path=(String) result;
if(path.startsWith(FORWARD)){ //转发
System.out.println("执行了转发");
path=path.replace(FORWARD,"");
req.getRequestDispatcher(path).forward(req,res);
}
else if(path.startsWith(REDIRECT)){ //重定向
System.out.println("执行了重定向");
path=path.replace(REDIRECT,"");
res.sendRedirect(path);
}
else{ //字符串(json)
res.getWriter().println(path);
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("BaseServlet异常处理");
}
}
//方法为空
public String index(HttpServletRequest req, HttpServletResponse res){
return FORWARD+"路径";
}
}
Usercontroller类代码
package controller;
import com.google.gson.Gson;
import pojo.Result;
import pojo.student;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/Login")
public class UserController extends BaseServlet {
//登录功能
public String login(HttpServletRequest req,HttpServletResponse res) throws IOException {
String account = req.getParameter("account");
String password = req.getParameter("password");
System.out.println(account);
System.out.println(password);
//设置响应格式为json
res.setContentType("application/json");
// 创建一个示例对象
Result dataObject = new Result(1,"json请求测试",new student("张三",14));
// 将对象转换为 JSON 字符串
Gson gson = new Gson();
String json = gson.toJson(dataObject);
System.out.println(json);
return json;
}
}
工具类
package utils;
public class Constants {
public static final String TAG="method";
public static final String FORWARD="forward:";
public static final String REDIRECT="redirect:";
public static final String INDEX="index";
}
测试
前端发送请求:
后端响应数据:
前端响应数据:
json格式字符串