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

相关推荐
Hello.Reader40 分钟前
TopK算法在大数据重复数据分析中的应用与挑战
大数据·算法·数据分析
数据龙傲天1 小时前
1688商品API接口:电商数据自动化的新引擎
java·大数据·sql·mysql
Elastic 中国社区官方博客1 小时前
Elasticsearch:使用 LLM 实现传统搜索自动化
大数据·人工智能·elasticsearch·搜索引擎·ai·自动化·全文检索
Jason不在家3 小时前
Flink 本地 idea 调试开启 WebUI
大数据·flink·intellij-idea
Elastic 中国社区官方博客4 小时前
使用 Vertex AI Gemini 模型和 Elasticsearch Playground 快速创建 RAG 应用程序
大数据·人工智能·elasticsearch·搜索引擎·全文检索
CHICX12295 小时前
【Hadoop】改一下core-site.xml和hdfs-site.xml配置就可以访问Web UI
xml·大数据·hadoop
权^5 小时前
MySQL--聚合查询、联合查询、子查询、合并查询(上万字超详解!!!)
大数据·数据库·学习·mysql
bin915310 小时前
【EXCEL数据处理】000010 案列 EXCEL文本型和常规型转换。使用的软件是微软的Excel操作的。处理数据的目的是让数据更直观的显示出来,方便查看。
大数据·数据库·信息可视化·数据挖掘·数据分析·excel·数据可视化
极客先躯13 小时前
Hadoop krb5.conf 配置详解
大数据·hadoop·分布式·kerberos·krb5.conf·认证系统
2301_7869643615 小时前
3、练习常用的HBase Shell命令+HBase 常用的Java API 及应用实例
java·大数据·数据库·分布式·hbase