JAVA进阶之——继承的妙处与灵活性处理JAVAWeb中Servlet代码优化的问题

在学习专业课JAVAWeb的时候,听老师讲解有些费劲,于是自己去b站上找了网课自行学习,在学到做最终案例的时候,如下,在写Servlet的对应代码时,面对老师提出的问题以及对现书写的Servlet代码优缺点时,因为一个项目中会有很多对应的实体类 我在编写的为  brand(品牌实体类),web层的Servlet个数太多了,下面还会有 user(用户实体类).....等等很多的实体类,这样一来,不利于管理和编写。所以老师给出的解决方案是 将Servlet进行归类,对同一个实体的操作方法写到一个Servlet中,对于同一个实体类的操作方法写到一个Servlet中。如BrandServlet、UserServlet。

    

下面给出Servlet优化之后的代码 以及继承思想的体现

如下图  左边是优化前  右边是优化后  明显清爽且方便管理 

这里最大的不同之处就是在于 访问的路径发生了变化  之前的是通过注解@WebServlet("访问的servlet路径");   

优化之后要做到很多的路径都要访问到Servlet,接收很多的资源访问路径,明显之前的单个的servlet做不到,具体是怎么实现的呢?我们往下看  之前我们写的Servlet写的路径是写死了的

 这里后面我们采用通配符的方法

 

只要路径是以/brand/*的路径  后面都可以映射到写的Brand Servlet中去

   

 如上图 灰色部分是项目访问的路径,后面从"/brand/"后面开始就是开始访问资源了,是可以映射到

 "/brand/*"上去的,然后一一访问对应的方法 可以和url parttern 匹配上 所以上述的selectAll方法add方法   都会访问到 "/brand/*" 中去  那么如何去实现分别调用"selectAll" 和 "add"方法呢?

 如上图,将访问路径的名称的最后一段  写成与所调用的方法一致即可  我们现在要做的就是获取最后一段的路径,也就是方法名称。 有了方法名称之后自然就可以执行对应的方法了,我们首先通过获取BrandServlet的字节码文件 获取对应方法的method对象  最后通过Method.invoke();把方法进行调用(这里我们要通过反射区获取对象方法,执行方法)。

继承

上面我们说到,要创建一个BrandServlet 这时我们如果直接去继承HttpServlet,HttpServlet里面干了很重要的一件事 在对应的service里面获取了请求的方式(doGet doPost

 HttpServlet里面做的事就是通过 请求方式完成方法的分发。如果将来我们写的BrandServlet 直接继承HttpServlet 那么就只能用里面的doGet doPost方法 并不能自己在里面写自己所需要的方法   selectAll add.....等方法  这个时候就不能去直接继承HttpServlet(不用其根据请求方式进行方法的分发的功能)  自定义Servlet,使用请求路径进行方法的分发 替换 HttpServlet的根据请求方式进行方法分发。  首先定义一个BaseServlet(名字自定义,将来的BrandServlet继承它),

BaseServlet作用:替换HttpServlet 根据请求的最后一段路径来进行方法的分发(这里之所以会调用父类的方法,其实是因为子类没有重写,web的访问,都会由tomcat自动调用service方法,子类继承了父类的service方法!)  重写HttpServlet 里面的doGet doPost方法  下面为具体的实现代码  看注释

BaseServlet:

package com.yzh.web.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;

/*
* 替换HttpServlet,数据请求的最后一段来进行方法分发
*
* */
public class BaseServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取请求的路径
        String uri = req.getRequestURI();  // /brand-case/brand/selectAll
      //  System.out.println(uri);
        //2.获取最后一段路径  方法名
        int index = uri.lastIndexOf('/');
        String methodName = uri.substring(index + 1);   //
     //   System.out.println(methodName);

        //3.执行方法
         //3.1 获取BrandServlet/ UserServlet 字节码对象
        //谁调用我(this  所在的方法)
        //System.out.println(this);
        Class<? extends BaseServlet> cls = this.getClass();
        //3.2获取方法 method对象
        try {
            Method method = cls.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            //3.3执行方法
            method.invoke(this,req,resp);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }
}

 BrandServlet:

package com.yzh.web.servlet;

import com.alibaba.fastjson.JSON;
import com.yzh.pojo.Brand;
import com.yzh.service.BrandService;
import com.yzh.service.impl.BrandServiceImpl;
import com.yzh.web.servlet.BaseServlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.List;

//@WebServlet("/brand/*")
public class BrandServlet extends BaseServlet {

    //设置成员变量
    private BrandService brandService = new BrandServiceImpl();

      public void selectAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          //1.调用service查询
          List<Brand> brands = brandService.selectAll();

          //2.转为json数据
          String jsonString = JSON.toJSONString(brands);

          //3.写数据  且输出的为中文
          response.setContentType("text/json;charset=utf-8");
          response.getWriter().write(jsonString);
      }

      public void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
          //1.提交品牌数据
          BufferedReader br = request.getReader();
          String params = br.readLine(); //json字符串

          //转为Brand对象
          Brand brand = JSON.parseObject(params, Brand.class);


          //2.调用service 添加
          brandService.add(brand);

          //3.响应成功的标识
          response.getWriter().write("success");
      }

}

然后展示页面中  前后端交互中的ajax中的url代码也进行修改 

    axios({
                    method:"get",
                    url:"http://localhost:8080/brand-case/brand/selectAll"

 优化后的Servlet代码从代码量上来说和之前差别不大,主要是方便管理和阅读,后期维护起来会更加的方便。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值