Servlet 代码优化

以前我们写web层 servlet的时候格式如下:

需要一个一个写,Servlet个数比较多,以后不利于管理

一、优化前Servlet写法如下:

以添加商品为例

addServlet:

package com.itheima.web.servlet;
import com.alibaba.fastjson.JSON;
import com.itheima.pojo.Brand;
import com.itheima.service.BrandService;
import com.itheima.service.impl.BrandServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;

@WebServlet("/addServlet")
public class AddServlet extends HttpServlet {
    // 业务逻辑层类
    private BrandService brandService =new BrandServiceImpl();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 1. 通过抓包拿到前端请求过来的数据(演示的是前端的数据为JSON格式)
        BufferedReader bufferedReader =request.getReader();
        String rl =bufferedReader.readLine();   // 拿到前端请求的JSON数据

        // 2. 将JSON数据转换成Java数据 (也就是说将JSON数据转换成Brand对象类型,将数据封装到对象属性中了)
        Brand brand =JSON.parseObject(rl,Brand.class);

        // 3. 调用BrandService接口中的添加商品方法
        brandService.add(brand);

        // 4. 响应给前端success的标识信号
        response.getWriter().write("success");
        

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

打开服务器:访问该"addServlet"路径,前端的请求就会进入该Servlet层 然后做出相对应的逻辑:

 

二、优化后的Servlet层代码

总体思路:把增删改查的Servlet 转换成了BrandServlet类当中的方法了 ,然后调用就可以了

 BrandServlet:

1、因为该BrandServlet类继承了BaseServlet类,BaseServlet类又继承了HttpServlet并且重写了service()方法,所以就相当于BrandServlet类继承了HttpServlet又重写了service()方法【这就相当于上面的添加商品那一步 addServlet类继承HttpServlet了】

当前端访问路径@WebServlet("/brand/*") 格式的时候,相当于进入到了该BrandServlet类当中了,然后又因为该BrandServlet其实也重写了service()方法,所以服务器路径进来之后,会先调用该service()方法  然后基本上就是映射出该类调用该映射类的增删改查方法而已

注意:其实就是在BrandServlet类下跑程序调用增删改查方法而已,我们可以假想着BaseServlet类当中的service()方法是在BrandServlet类下跑的 (继承原因)

而且我们以后的增删改查商品问题等直接以方法的形式全写在该BrandServlet类当中即可,就不再一个一个创建增删改查的Servlet了,所以就容易管理了

package com.itheima.web.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 *  BrandServlet 继承父类BaseServlet
 *  父类中继承了HttpServlet 所以相当于BrandServlet继承了HttpServlet
 *
 *  父类BaseServlet中有service方法 (该方法当客户端访问相对应路径时自动调用该方法中)
 *  子类继承了父类 也就是说:这个BrandServlet中实际上也有个service方法 当访问该 @WebServlet("/brand/*")路径时
 *  其实调用的是BrandServlet类当中的service()方法
 *
 */

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

    /**
     *  1、 查询所有商品方法
     */
    public void selectAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        System.out.println("brand selectAll.....");
    }

    /**
     *  2、 添加商品方法
     */
    public void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        System.out.println("brand add.....");
    }

}

 BaseServlet:

package com.itheima.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
 *
 * 这个 BaseServlet类继承HttpServlet 重写 service方法
 */

public class BaseServlet extends HttpServlet {

    // 根据请求的最后一段路径来进行方法分发
    @Override   // 客户端请求过来会先进入service方法 req域当中封装了客户端请求的数据(和doGet doPost方法一样)
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        
        // 1. 获取请求路径
        String url =req.getRequestURI();
        // System.out.println(url);        // 格式: /brand-case/brand/selectAll

        //  获取最后一段路径(方法名)
        int index =url.lastIndexOf("/");    // 从路径后面数 第一次出现“/”的位置
        String methodName =url.substring(index+1);   // 获取到从“/”开始截取的后面的路径 (这里我们不要/ 所以+1)
        // System.out.println(methodName);   // selectAll


        // 2. 执行BrandServlet对象中的selectAll方法

        // 2.1 获取BrandServlet 字节码对象 Class (映射)

        Class<? extends BaseServlet> cls =this.getClass();
        // System.out.println(cls);    // com.itheima.web.servlet.BrandServlet@24ad61c6
        /**
         *  特别注意: 这个 this 代表的是谁?
         *      因为BrandServlet类继承了BaseServlet,当客户端访问路径到BrandServlet类下时,因为BaseServlet
         *      重写了Service方法 所以BrandServlet类当中也有该service方法 (可以看作:BaseServlet类当中的service方法
         *      在BrandServlet类当中,当访问该BrandServlet路径下时 会自动调用service()方法, 所以该this表示BrandServlet
         *      对象,【也就是说,谁调用这个this所在的方法中,这个this就代表是谁】
         *
         *      这里的service()方法 其实是BrandServlet对象调用的 所以this表示BrandServlet对象)
         */

        // 2.2 获取方法 Method对象(映射)
        try {
            // 这里直接把methodName传入, 表示该映射类调用methodName方法
            // 上面假设拿到客户端发送的selectAll请求,这里我们就表示该映射类BrandServlet调用的是methodName(selectAll方法) )
            Method method =cls.getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);

            // 2.3 调用该方法 (映射)
            method.invoke(this,req,resp); // 往映射出来的方法中传客户端请求的数据(传参):把req域和resp域传过去

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }


    }
}

开启服务器访问路径 以(/brand/selectAll为例 【刚好相当于调用BrandServlet的查询所有selectAll的方法】):

 

因此优化后写商品增删改查逻辑的时候 直接在BrandServlet类当中写成增删改查的方法即可了,不用动BaseServlet类 也不用再一个一个创建增删改查的Servlet了, 增删改查代码如下:

package com.itheima.web.servlet;
import com.alibaba.fastjson.JSON;
import com.itheima.pojo.Brand;
import com.itheima.service.BrandService;
import com.itheima.service.impl.BrandServiceImpl;
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;

/**
 *  BrandServlet 继承父类BaseServlet
 *  父类中继承了HttpServlet 所以还是相当于BrandServlet继承了HttpServlet
 *
 *  父类BaseServlet中有service方法 (该方法当客户端访问相对应路径时自动调用该方法中)
 *  子类继承了父类 也就是说:这个BrandServlet中实际上也有个service方法 当访问该 @WebServlet("/brand/*")路径时
 *  其实调用的是BrandServlet类当中的service()方法
 *
 */

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

    private BrandService brandService =new BrandServiceImpl();
    /**
     *  1、 查询所有商品方法
     *
     *  这下面逻辑和以前没优化的时候在doGet() doPost()方法当中的逻辑一样
     */
    public void selectAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{

        // 1. 调用BrandServiceImpl完成查询所有功能
        List<Brand> brands =brandService.selectAll();

        // 2. 将Java对象数据转换成JSON格式数据,响应给前端
        response.setContentType("text/json;charset=utf-8"); // 中文乱码问题
        String toString = JSON.toJSONString(brands);

        // 3. 响应给前端数据
        response.getWriter().write(toString);

    }

    /**
     *  2、 添加商品方法
     */
    public void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{

        // 1. 通过抓包拿到前端请求过来的数据(演示的是前端的数据为JSON格式)
        BufferedReader bufferedReader =request.getReader();
        String rl =bufferedReader.readLine();   // 拿到前端请求的JSON数据

        // 2. 将JSON数据转换成Java数据 (也就是说将JSON数据转换成Brand对象类型,将数据封装到对象属性中了)
        Brand brand =JSON.parseObject(rl,Brand.class);

        // 3. 调用BrandService接口中的添加商品方法
        brandService.add(brand);

        // 4. 响应给前端success的标识信号
        response.getWriter().write("success");

    }




}

开启服务器访问该查询所有商品,调用该查询所有方法时结果如下:

 最后把数据用前端页面处理一下即可~

开启服务器访问 brand.html:

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值