BaseServlet的封装

创建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格式字符串

相关推荐
JessieZeng aaa1 小时前
CSV文件数据导入hive
数据仓库·hive·hadoop
Java 第一深情3 小时前
零基础入门Flink,掌握基本使用方法
大数据·flink·实时计算
MXsoft6183 小时前
华为服务器(iBMC)硬件监控指标解读
大数据·运维·数据库
PersistJiao3 小时前
Spark 分布式计算中网络传输和序列化的关系(二)
大数据·网络·spark·序列化·分布式计算
九河云4 小时前
如何对AWS进行节省
大数据·云计算·aws
FreeIPCC4 小时前
谈一下开源生态对 AI人工智能大模型的促进作用
大数据·人工智能·机器人·开源
梦幻通灵4 小时前
ES分词环境实战
大数据·elasticsearch·搜索引擎
Elastic 中国社区官方博客4 小时前
Elasticsearch 中的热点以及如何使用 AutoOps 解决它们
大数据·运维·elasticsearch·搜索引擎·全文检索
天冬忘忧5 小时前
Kafka 工作流程解析:从 Broker 工作原理、节点的服役、退役、副本的生成到数据存储与读写优化
大数据·分布式·kafka
sevevty-seven6 小时前
幻读是什么?用什么隔离级别可以防止幻读
大数据·sql