概述

  • 只要掌握了JavaSE的知识,以及B/S架构请求和响应的流程,就能够看懂,反射的部份占得比较多,还有注解
  • 使用环境:

    • JDK:1.8
    • Tomcat:9.0.3
    • 编译器:IDEA 2019

原生Servlet的问题

  • Servlet的作用:

    • Servlet的作用是处理浏览器发送过来的请求以及服务器响应回去的信息
    • 通过浏览器发送过来的资源请求,转发给对应的资源
  • 原生Servlet的写法

    • 1)在web.xml对一个Servlet进行配置
    • 2)实现Servlet接口/继承HttpServlet
    • 3)重写doPost/doGet/Service方法
  • 原生Servlet产生的问题

    • 1)配置信息多:每写一个Servlet类需要配置8行xml
    • 2)每个Servlet类都要实现/继承,增加耦合度
    • 3)一个Servlet类只对应了一个功能,当项目中的功能越来越多时,Servlet类也会越来越多

解决策略

  • 1)将多个Servlet的方法封装到一个Servlet中

    • 这样一个Servlet类就对应了多个功能
  • 2)封装一个DispatcherServlet类,这个类根据浏览器的资源请求,找到对应的Servlet,以及处理Servlet类的响应

    • 也就是这个DispatcherServlet类是唯一一个继承HttpServlet/实现Servlet接口,而之前写的Servlet类就是普通的类
    • 这样做降低了耦合度,web.xml配置文件中也只需要配置DispatcherServlet,减少了配置信息

封装后的组件

image

  • 如上图所示,主要封装了两个组件,分别是DispatcherServlet和Handler
  • DispatcherServlet的作用:

    • 1)接收浏览器发送过来的请求
    • 2)将请求交给Handler
  • Handler的作用:

    • 1)解析请求
    • 2)找到处理该请求的对象
    • 3)找到该对象具体处理该请求的方法
    • 4)解析执行对象执行方法后的结果
    • 5)将结果响应回给浏览器
  • ModelAndView:

    • 这个对象是用来存储服务器返回的转发/重定向路径,以及服务器要返回的参数
  • ApplicationContext.properties:

    • 这个配置文件是用来存储请求名字对应的处理对象的类路径

使用方法

@SessionAttributes("name")
public class AtmController {//需要管理这个Controller的单例机制
 private AtmService service = new AtmService();
 public ModelAndView login(User user){
        ModelAndView mv = new ModelAndView();
 String result = service.login(user);
 if("success".equals(result)){
 mv.addObject("name",user.getName());//如果存在session中 先放在mv容器里
 mv.setViewName("welcome.jsp");
 }else{
            mv.addObject("result",result);
 mv.setViewName("index.jsp");
 }
        return mv;
 }
    
 @ResponseBody
 public List<User> query(){
        List<User> userList = service.query();
 return userList;
 }
}
  • 比如如上代码:
  • 几个自定义注解的含义:

    • @SessionAttributes("参数名"):

      • 这个注解的作用是把参数存到session作用域里
      • 必须写在类名上面
      • 存入的参数必须是在request作用域里面存在的
    • @ResponseBody:

      • 写在方法上面
      • 如果返回的是实体对象、List对象、JSON对象、String字符串,则需要加上这个注解
    • @RequestParam("参数名"):

      • 写在方法携带的参数前面,注解里写的名字和方法的参数名一致
      • 如果浏览器发送的请求携带了参数,那么执行的对象不需要通过request对象就能拿到参数
    • 如果参数是一个实体对象/Map对象,那么就不需要写@RequestParam注解,框架会自动把请求携带的参数包装成一个对象

局限性

  • 因为时间不够充足,所以只是简单的封装,所以使用的时候也是有很多问题,比如对于方法参数处理以及响应信息的处理类型只能处理几个基本数据类型、实体对象以及Map、list集合和Json对象
  • 封装这个的意义主要是练习JavaSE的知识,以及了解真正的控制层的框架是怎么处理的,所以如果真的感兴趣的可以照着我这个思路继续写下去

代码地址:https://github.com/Cing-self/...


cing_self
18 声望3 粉丝