ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

基于反射抽取父类Servlet实现请求处理

2022-06-24 11:03:55  阅读:136  来源: 互联网

标签:抽取 请求 resp req 父类 Servlet method Constants


基于反射抽取父类Servlet实现请求处理

学习于:https://www.bilibili.com/video/BV1Dh41197mE?share_source=copy_web

背景:

​ 由于在web项目中,Servlet会对于前端传过来的请求携带的method参数(有可能叫其他名字),进行if...else if ...的判断,实现Servlet复用,但是如果每个模块的Servlet都先获得参数,再多轮判断,就会产生很多冗余的代码,于是想到提取出一个父类,来简化代码。至此,我们再创建新的Servlet模块的时候,只需要继承这个父类,然后实现对应的方法就可以完整请求的处理。

分析:

  • Servlet层的共同点:
    • 都会获取前端请求来的路径中的参数,以判断请求方法名;
    • 在处理完请求之后,都会进行相应的后续处理,可以大致分为4种:
      • 1、请求转发----forward
      • 2、重定向----redirect
      • 3、向页面输出内容----write/print;(例如与ajax进行交互)
      • 4、没有任何的处理,这种情形下,可以默认重新回到首页

分析得到这些控制层的共同点之后,就可以根据这些共同点,抽取出方法,由于具体的很多参数都是在实例化的具体Servlet类中才能够得知要调用什么方法,所以利用反射机制,动态的获取处理方法!

父类代码实例:BaseController

package com.wxy.servlet;

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;

import com.wxy.util.Constants;

/**
 * @Description: 基于反射实现的父类Servlet,动态的执行子类的处理方法;
 */
public class BaseController extends HttpServlet {

    /**
     * 子类中,只需要重写doGet/doPost 方法,不重写service方法,所以子类会自动调用父类的方法,也就是下面的方法;
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     * @Description: 内容详细介绍;
     * 1、获取方法名:前端提交的url请求中携带着关于请求处理的参数,例如---> url: "/user?method=check...";
     * 2、判断方法名:此时无法得知具体的  method  等于什么,所以对method进行判断;
     * 3、通过反射机制获得当前类的字节码;
     * 4、获得方法对象,执行方法,invoke(执行对象,传入参数)  执行对象:this --->就是当前调用的子类;
     * 5、统一规定方法返回一个String类型的result;供判断处理后的输出或跳转方法;
     * 6、根据方法的返回值,分别处理:请求转发、重定向、向页面输出内容  3种响应方式;
     * 7、在catch异常的时候,向页面携带一个信息,告诉客户出错了,并且让网页自动跳转会首页;
     * 8、在此类中,另外专门写一个index() 方法,专门处理前端传递过来的没有携带method参数的请求;
     */
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //req.setCharacterEncoding("utf-8");

        //获取一个方法名,method="check/login/register.....(req,resp)
        String methodName = req.getParameter(Constants.TAG);//  常量类中定义:Constants.TAG="method"
        //此时无法得知具体的  method  等于什么,所以对method进行判断
        if (methodName == null && "".equals(methodName)) {
            //若前端没有传回method参数,默认前往index页面,
            methodName = Constants.INDEX;   //  Constants.INDEX="index"
        }
        try {
            //获得当前类的字节码
            Class<? extends BaseController> clazz = this.getClass();
            //check(req,resp)
            Method method = clazz.getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            //result=this.check(req,resp)
            Object result = method.invoke(this, req, resp);
            if (result != null) {
                //返回值:要么带"forward:xxxx",或者"redirect:xxxx",要么是其他
                String str = (String) result;

                //请求转发的请求地址
                String path = str.substring(str.indexOf(Constants.FLAG) + 1);   //  Constants.FLAG=":"
                if (str.startsWith(Constants.FOWARD)) {
                    req.getRequestDispatcher(path).forward(req, resp);
                } else if (str.startsWith(Constants.REDIRECT)) {
                    resp.sendRedirect(path);
                } else {
                    //若不请求也不转发,就向页面输出返回值str
                    resp.getWriter().print(str);
                }
            }
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            e.printStackTrace();
            //加入出现异常,就传回一个msg值
            req.setAttribute("msg", "网络异常,请检查自己的网络");
            req.getRequestDispatcher("/message.jsp").forward(req, resp);
        }

    }

    /*
     * 跳转到首页
     *  为默认情况设置方法,如果method=index   就走当前类的这个方法
     */
    public String index(HttpServletRequest req, HttpServletResponse resp) {
        return Constants.FOWARD + "/index.jsp";
    }

}

标签:抽取,请求,resp,req,父类,Servlet,method,Constants
来源: https://www.cnblogs.com/lemonaaa/p/16407980.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有