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

相关推荐
woshiabc11113 分钟前
windows安装Elasticsearch及增删改查操作
大数据·elasticsearch·搜索引擎
lucky_syq1 小时前
Saprk和Flink的区别
大数据·flink
lucky_syq1 小时前
流式处理,为什么Flink比Spark Streaming好?
大数据·flink·spark
袋鼠云数栈1 小时前
深入浅出Flink CEP丨如何通过Flink SQL作业动态更新Flink CEP作业
大数据
清平乐的技术专栏1 小时前
Hive SQL 查询所有函数
hive·hadoop·sql
小白学大数据2 小时前
如何使用Selenium处理JavaScript动态加载的内容?
大数据·javascript·爬虫·selenium·测试工具
15年网络推广青哥2 小时前
国际抖音TikTok矩阵运营的关键要素有哪些?
大数据·人工智能·矩阵
节点。csn3 小时前
Hadoop yarn安装
大数据·hadoop·分布式
不惑_3 小时前
小白入门 · 腾讯云轻量服务器部署 Hadoop 3.3.6
服务器·hadoop·腾讯云
csding113 小时前
写入hive metastore报问题Permission denied: user=hadoop,inode=“/user/hive”
数据仓库·hive·hadoop