SpringMVC学习笔记(2021.6.2-2021.6.10)gstone

文章目录

  • SpringMVC概述
  • Tomcat中的大XML中,有两个默认配置好的Servlet
  • @RequestMapping
  • @PathVariable:映射URL绑定的占位符
  • REST风格的URL
  • SpringMVC中如何获取请求带来的各种信息?
  • 乱码问题的解决方案
  • Spring中如何给页面携带数据给浏览器?
  • SpringMVC源码分析(一个请求到得到响应的过程)
  • 视图解析器
  • 表单标签(一般不用)
  • 数据绑定的原理和思想
  • 使用SpringMVC来完成ajax请求
  • SpringMVC的文件下载(鸡肋功能)
  • 文件上传
  • SpringMVC的拦截器
  • SpringMVC异常机制
  • Spirng与SpringMVC的整合
  • 配置文件的一些常用的标签
  • 总结流程图

SpringMVC概述

  • 是Spring框架的web部分,是一个高性能的MVC架构模式下的框架。

Tomcat中的大XML中,有两个默认配置好的Servlet

  • DefaultServlet:路径的配置为"/"用来拦截所有非jsp文件的请求,处理静态资源文件的回送。

  • JspServlet:路径的配置为“ *.jsp 与 *.jspx”,用来拦截所有的jsp文件,处理解析Jsp文件并回送HTML文本。

@RequestMapping

  • 作用:注解在方法上,访问其对应的URI则调用被注解的方法。
  • 放置位置:
    • 写在类上:为当前类的方法添加一个基路径
    • 写在方法上:添加一个访问路径
  • 该注解属性
    • value:设置请求访问的URI路径值
    • method:规定请求方式
    • params:规定请求参数
    • headers:规定请求头(规定User-Agent可以达到规定指定的浏览器访问)
    • consumes:只接受内容类型是哪种的请求,规定请求头的Content-type
    • produces:告诉浏览器返回的内容类型是什么,给响应头中加上Content-type
  • 模糊匹配功能(ant风格的URL地址)
    • “?”:匹配哟个字符
    • “*” :匹配多个或零个字符
    • “**”:能替代多层路径

@PathVariable:映射URL绑定的占位符

//请求的URI:/User/goods
@RequestMapping("/User/{id}")
public String test(@PathVariable("id")Integer id){
    System.out.println(id);//goods
}

REST风格的URL

  • 概述:(资源)表现层状态转化,在REST的设计思想中,希望以非常简洁的URL地址来
    发送请求,用请求的方式来区分对资源的状态转化(即增删查改),请求的方式有:GET(查),
    POST(增),PUT(更新),DELETE(删除),并且将资源标识也作为路径传递,即/资源名/资源标
    识(book/1),若是Post资源标识还是写在?号后。
  • 问题:从页面上只能发起两种请求,GET与POST,其他的请求方式没法使用。
  • 解决:SpringMVC中有一个Filter:他可以把普通的请求转化为规定形式的请求。
  • 使用步骤
    • 配置Filter:…web.filter.HiddenHttpMethodFilter
    • 创建要给post类型的表单
    • 表单项中要携带名为_method的参数,其值表示需要转化的请求形式
  • 注意:高版本的Tomcat8.0以上版本中,若转发到JSP页面中,由于请求方式
    发生了改变,当在Tomcat不允许put,delete等等之类的请求,会抛出异常报错
    这个时候只需要在<%@ page 加个 isErrorPage=“true”%>处理这个异常即可。

SpringMVC中如何获取请求带来的各种信息?

  • 默认方式:在方法中的形参添加一个变量名与请求的参数名一致的名称,若请求携带了改值
    ​则会为这个形参传递改值,若没带则为null。
  • @RequestParam注解方式
    • 使用方式:public String handle01(@RequestParam(“请求参数名”)String 自定义名)获得
    • 注解属性:
      • value:请求参数名
      • required:是否必须携带,默认是true,没带抛异常
      • defaultValue:默认值,若没有带,则设置默认值。
  • @RequestHeader:获取请求头中的某个key值
    • 使用方式:public String hand02(@RequestHeader(“User-Agent”)String userAgent);
    • 注解属性:
      • value:请求头参数名
      • required:是否必须携带,默认是true,没带抛异常
      • defaultValue:默认值,若没有带,则设置默认值。
  • @CookieValue:获取Cookie的值
    • 使用方式:public String hand02(@CookieValue(“JSONID”)String userAgent);
    • 注解属性:
      • value:Cookie的key值
      • required:是否必须携带,默认是true,没带抛异常
      • defaultValue:默认值,若没有带,则设置默认值。
  • 请求参数类型是一个对象,直接在方法的形参中写上该对象类型的形参,Spring会自动进行参数的注入,
    还可以级连封装(属性中有对象),要求级联对象属性对应的文本框的name=“级联对象名.级联对象属性名”
    ​,并且要求请求参数名要与属性名保持一致。
  • 方法的形参类型若是以下几种类型,SpringMVC会自动往里面传参,直接使用对象即可(即传入的是原生API)
    • HttpServletRequest
    • HttpServletResponse
    • HttpSessoin

乱码问题的解决方案

  • 请求乱码:
    • get请求:直接去tomcat的conf配置文件的server.xml,在这个标签中
    • post请求:直接使用SpringMVC提供的Filter过滤器
  • 响应乱码:被提供的Filter顺便解决了
  • 该Filter的配置编写
<filter>
    <filter-name>characterEncodingFilterfilter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
    
    <init-param>
        <param-name>encodingparam-name>
        <param-value>UTF-8param-value>
    init-param>
    
    <init-param>
        <param-name>foreEncodingparam-name>
        <param-value>trueparam-value>
    init-param>
filter>
<filter-mapping>
    <filter-name>characterEncodingFilterfilter-name>
    <url-pattern>/*url-pattern>
filter-mapping>

Spring中如何给页面携带数据给浏览器?

  • 通过原生API
  • 在形参中,写入Map(request域),Model(request域),ModelMap(request域)
    • *Map与Model与modelMap都是接口,spring来编写实现类,实现类为:BindingAwareModelMap,
      该实现类将数据放到request的域中保存。
    • 三者之间的关系是: 如绘图描述
      • SpringMVC学习笔记(2021.6.2-2021.6.10)gstone_第1张图片
  • 将返回值变成ModelAndView类型
    • 视图名就是转发到的页面
    • 即包含视图信息也包含模型数据
    • 也是将数据存放在request的作用域中保存
  • SpringMVC提供了两种注解来往作用域中放置数据(这两种注解现在都不常用)
    • @SessionAttributes可以往session中放入数据,但不推荐,推荐直接使用原生API来进行放置数据。
    • @ModelAttribute(将数据放置于request作用域中)比较复杂,现在基本上不用。
      • 解决业务问题是,在数据库修改语句中使用的是全数据更新语句,而实际在前端页面展现表单时,有些数据不能
        给用户修改,比如书名等等,而这个时候如果提交表单就会出现封装的数据为空,交予数据库的全更新语句执行
        时,数据丢失,一般这种问题的解决方法有两种,一种是将sql全更新语句改成类似于mybaits的动态sql样,另一
        种解决的方法的思想为:在springMVC将表单数据封装到book对象前,先将该id的book对象从数据库中查询出来,
        然后再交给SpringMVC进行数据的封装,这样就避免了某些不能修改字段数据为空的情况。
      • 使用的两种位置
        • 加在方法上,会提前于执行请求的方法执行,在其中可以将数据库的数据提前查出来,并且将数据保存在Model
          对象中(request作用域)中。并且该方法的返回值会保存在隐含模型(BingAwareModelMap)中,若是注解指定@ModelAttribute(“值”),则使用指定的值作为key值,若是没有指定则默认设为返回值类型的首字母小写值。
        • 用在形参属性上,可以将保存在Model对象的数据按key值取出来。

SpringMVC源码分析(一个请求到得到响应的过程)

  • SpringMVC的前台控制器(DispatcherServlet)的继承关系文字说明:

    • GenericServlet抽象类实现Servlet接口
    • HttpServlet抽象类继承GenericServlet抽象类
    • HttpServletBean抽象类继承HttpServlet抽象类
    • FrameworkServlet抽象类继承HttpServletBean抽象类
    • DispatcherServlet具体类继承FrameworkServlet
  • 请求得到相应的步骤流程:

    • 请求发送给服务器,Tomcat服务器调用FramworkServlet对于HttpServlet中doGet或doPost的覆盖的方法
    • FramworkServlet的doGet或doPost方法再调用本类的processRequest方法
    • processRequest方法再去调用DispatcherServlet类中对于本类doService抽象方法的实现的方法,
    • DispatcherServlet类中的doService方法再去调用,DispatcherServlet类中的doDispatch方法,该方法
      会利用反射机制去调用具体的业务实现方法。(最为重点的一步)
  • doDispath方法利用反射机制调用方法的简解:

    • mappedHandler = this.getHandler(processedRequest);
      //去路径映射信息找到对应的类对象,得到一个处理器对象

    • HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
      //利用该处理器对象得到一个处理器的适配器对象

    • mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

      //利用处理器的适配器对象去执行目标方法,返回值为ModelAndView,这说明了无论你在方法中返回了

      String也好ModelAndView也好,最后都是返回的值都是ModelAndView类型

    • this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
      //该语句负责响应数据给页面,渲染页面。

  • SpringMVC的九大组件:九大组件支持了SpringMVC的核心功能,且都是接口。

    • //文件上传解析器
      private MultipartResolver multipartResolver;
    • //区域信息解析器与国际化有关
      private LocaleResolver localeResolver;
    • //主题解析器(一般不用)
      private ThemeResolver themeResolver;
    • //Handle的映射信息处理器
      private List handlerMappings;
    • //Handle适配器的处理器
      private List handlerAdapters;
    • //异常解析器:Spring强大的异常解析处理器
      private List handlerExceptionResolvers;
    • //基本不用
      private RequestToViewNameTranslator viewNameTranslator;
    • //SpringMVC中运行重定向携带数据的功能
      private FlashMapManager flashMapManager
    • //视图解析器
      private List viewResolvers;
  • SpringMVC如何锁定具体方法并传入参数的执行详解步骤(最难的一步)

    • 标注解:保存注解的信息,最终会得到这个注解所对应解析的值。
    • 没标注解:
      • 看参数是否是原生API
      • 看是否是Model或者Map类型,或者其他类型
      • 看是否是简单类型(String,Interge)
      • 给attrName赋值,若是参数的属性标了@ModelAttribute(“xx”)就是指定的名字
        ,若是为空则为空串。
      • 确定自定义类型的参数的步骤:
        • 若是attrName为空则指定为其类型名的首字母小写名,若不为空则为注解标注的
        • 先看隐含模型(在所有调用方法执行前,创建的一个BindingAwareModelMap对象(request域))
          中是否有,名为attrName值对应的value,若有就从隐含模型中获取并且赋值
        • 再看是否是@SessionAttributes(“标注”),标注的属性值,若是就从Session域中拿,注意这里
          如果拿不到,则会抛出一个异常(这就是为什么不推荐使用SessionAttribute注解的原因,如果使用了
          就必须有与之对应的值,若是没有则会直接抛出一个异常)。
        • 若不是@SessionAttributes所标注的,则利用反射创建一个对象。
      • 拿到之前创建好的对象,使用数据绑定器(WebDateBinder)将请求中的数据绑定到这个对象中。

视图解析器

  • 首先要清楚一点,不管方法的返回值的类型为什么,在阅读了源码后,知道最终返回的类型都是ModelAndView类型的对象

  • 返回值为String类型或ModelAndView类型时转发与重定向的详解:

    • 若字符串或者setViewName()的内容为一个页面名,则在SpringMVC配置文件中配置的视图解析器会默认为该页面名进行拼串处理,然后转发到相应页面。
    • 若字符串或者setViewName()内容中有"forward:"与"redirect:"前缀开头,则配置的视图解析器不会为其拼串,而是会转发或者
      重定向到后面内容相对应的页面中或者servlet中去。
  • 视图渲染流程:(将域中的数据在页面显示,页面就是用来渲染数据的)

    • doDispath方法执行到这一行时:this.processDispatchResult(…)时,页面开始渲染
    • processDispatchResult()方法会调用render(mv,request,response)直译就是渲染方法,渲染页面
    • 进入render方法后,会利用==ViewResolver(视图解析器,九大组件)==得到一个View实现类对象
      • View(接口)与ViewResolver(接口)的关系:ViewResolver接口的唯一作用,就是根据视图名(方法的返回值)得到
        View实现类对象
    • View对象调用自身的render()方法,渲染页面
    • 进入View对象的render方法后,调用View实现类的renderMergedOutputModel()方法渲染要给页面输出的数据。
    • 该实现类的renderMergedOutputModel()方法会调用,exposeModelAsRequestAttributes()方法,该方法的作用:
      隐含模型的map中的值全部设置给request作用域map,所以隐含模型的值,可以请求域中取出来。
    • 得到路径后,再通过调用HttpServletRequest对象得到转发器或重定向器,抵达页面。
    • 一句话总结:视图解析器只是为了得到视图对象,视图对象才能真正的完成转发(将隐含模型数据全部放在请求域中)
      或重定向到页面
      (视图渲染)。
  • View(视图对象)与ViewResolver(视图解析器)

    • 视图对象:用于渲染页面,核心方法为render()。
    • 视图解析器:负责视图对象的实例化。
    • 不存在线程安全问题

表单标签(一般不用)

  • 表单标签是SpringMVC提供的一个用于简化浏览器从后端取数据对应到HTML页面的标签库。
  • 使用前需要导入SpringMVC表单标签库:<%@ taglib prefix=“form” uri=“http://www.springframework.org/tags/form” %>
  • 注意:使用表单标签,必须在request域中放置一个包含了表单所有内容的表单对象,且默认的key为"command",若不想为该key,必须在标签中声明。标签中使用path属性来代表普通标签的name属性,且这个path属性对应的request域中的对象的属性值,也会默认的取出来放置到改标签中。

数据绑定的原理和思想

  • 数据绑定:将前台通过超文本传输协议,传来的文本类型数据,转换为对应的Java数据类型,并对日期之类的数据进行格式化,与数据合法性的验证。

  • 绑定过程中必须处理的步骤

    • 数据转换
    • 数据格式化
    • 数据校验
  • 数据转换

    • 将前台发送过来的参数数据,转换为对应的Java类型的数据。SpringMVC默认对一些简单的数据类型都有对应的类型转换器。

    • 若是对于请求参数的值,为一个自定义类型,若要将其按照自己定义的类型转换,可以如下编写配置文件,

      • 实现Converter接口,做一个自定义类型的转换器
      • 将这个Converter配置在ConversionService中
      • 告诉SpringNMVC使用这个ConversionService
      <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
          
          <property name="converters">
               <set>
                    <bean class="com.atguigu.component.MyStringToEmployeeConverter">bean>
               set>
          property>
      bean>
      
          <mvc:annotation-driven conversion-service="conversionService">mvc:annotation-driven>
      
  • 数据格式化(主要是日期)

    • 在需要格式化的JavaBean的日期属性加上一个@DateTimeFromat(pattern=“需要格式化的值”)的注解,这样服务器就会把前端发送过来的日期数据,按照指定的日期格式,解析出来生成日期对象。
  • 数据校验

    • 概述:对于前端发送过来的数据,虽然有则前端验证帮我们检验数据,但前端校验主要是利用js进行校验的有太多的方式可以越过,在SpringMVC中可以使用 Hibernate Validator(第三方校验框架)来进行后台数据的校验,Hibernate Validator对Java中给出的一套后台检验数据规范,JSR303,进行了实现,类似于(JDBC的实现)。

    • 使用步骤

      • 添加pom依赖

        <dependency>
            <groupId>org.hibernate.validatorgroupId>
            <artifactId>hibernate-validatorartifactId>
            <version>6.1.7.Finalversion>
        dependency>
        
      • 在JavaBean中需要校验的属性上,添加相对应的校验注解

        • 常用的注解

          //注意以下每一个注解都有“message”,用于指定数据校验错误时的错误信息。
          @AssertFalse 验证注解的元素值是 false
          @AssertTrue 验证注解的元素值是 true
          @DecimalMax(value=x) 验证注解的元素值小于等于指定的十进制value 值
          @DecimalMin(value=x) 验证注解的元素值大于等于指定的十进制value 值
          @Digits(integer=整数位数, fraction=小数位数)验证注解的元素值的整数位数和小数位数上限
          @Future 验证注解的元素值(日期类型)比当前时间晚
          @Max(value=x) 验证注解的元素值小于等于指定的 value值
          @Min(value=x) 验证注解的元素值大于等于指定的 value值
          @NotNull 验证注解的元素值不是 null
          @Null 验证注解的元素值是 null
          @Past 验证注解的元素值(日期类型)比当前时间早
          @Pattern(regex=正则表达式) 验证注解的元素值不指定的正则表达式匹配
          @Size(min=最小值, max=最大值) 验证注解的元素值的在 min 和 max (包含)指定区间之内,如字符长度、集合大小
          @Valid 该注解主要用于字段为一个包含其他对象的集合或map或数组的字段,或该字段直接为一个其他对象的引用,这样在检查当前对象的同时也会检查该字段所引用的对象。
          @NotEmpty 验证注解的元素值不为 null 且不为空(字符串长度不为 0、集合大小不为 0)
          @Range(min=最小值, max=最大值)验证注解的元素值在最小值和最大值之间
          @NotBlank 验证注解的元素值不为空(不为 null、去
          除首位空格后长度为 0),不同于@NotEmpty, @NotBlank 只应用于字符串且在比较时会去除字符串的空格
          @Length(min=下限, max=上限) 验证注解的元素值长度在 min 和 max 区间内
          @Email 验证注解的元素值是 Email,也可以通过正则表达式和 flag 指定自定义的 email 格式
          

使用SpringMVC来完成ajax请求

  • 配置文件的导包

    <dependency>
        <groupId>com.fasterxml.jackson.coregroupId>
        <artifactId>jackson-databindartifactId>
        <version>2.12.3version>
    dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.coregroupId>
        <artifactId>jackson-coreartifactId>
        <version>2.12.3version>
    dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.coregroupId>
        <artifactId>jackson-annotationsartifactId>
        <version>2.12.3version>
    dependency>
    
  • 三个注解

    • @ResponseBody注解:返回Json数据
      • 写在路径映射注解之上
      • 当方法的返回值为domain层的实体类时,向网页发送Json格式该对象数据。
      • 本质上就是向浏览器写出数据,类似于“out”对象。
    • @RequestBody注解:获取请求体,必须是Post请求,接受JSON数据
      • 写在控制器方法封装的对象类型形参上:当接受的浏览器数据为Json格式的时候,会将该Json数据封装成对象。(高级用法)
      • 写在控制器方法的String类型的形参上,拿到请求体的数据
    • @RequestHeader注解与在控制器方法上直接写形参“HttpEntity str”的区别
      • 注解得到的是一个具体的某个请求头参数
      • 形参得到是全部的请求头参数

SpringMVC的文件下载(鸡肋功能)

@Controller
public class MyFisrController {
    //测试文件的(了解,MVC的做的烂)下载
    @RequestMapping("/download")
    public ResponseEntity<byte[]> download(HttpServletRequest request){
        ServletContext servletContext = request.getServletContext();
        String location="/JQuery/jquery-1.7.2.min.js";
        String realPath = servletContext.getRealPath(location);
        FileInputStream fileInputStream = null;
        byte[] bytes=null;
        try {
            fileInputStream = new FileInputStream(realPath);
            bytes = new byte[fileInputStream.available()];
            fileInputStream.read(bytes);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(fileInputStream!=null)
                    fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        HttpHeaders httpHeaders=new HttpHeaders();
        httpHeaders.set("Content-Disposition","attachment;filename="+"jquery-1.7.2.min.js");
        return  new ResponseEntity<byte[]>(bytes,httpHeaders, HttpStatus.OK);
    }
}

文件上传

  • pom依赖

<dependency>
    <groupId>commons-fileuploadgroupId>
    <artifactId>commons-fileuploadartifactId>
    <version>1.3.1version>
dependency>
<dependency>
    <groupId>commons-iogroupId>
    <artifactId>commons-ioartifactId>
    <version>2.4version>
dependency>
  • SpringMVC配置文件中注入九大组件的MultipartResover(文件上传解析器)实现类

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    
    <property name="maxUploadSize" value="#{20*1024*1024}"/>
    
    <property name="defaultEncoding" value="UTF-8"/>
bean>
  • Java文件的编写
//注意前端提交的表单属性必须设置这个:enctype="multipart/form-data"
//测试文件的上传
@RequestMapping("/upLoad")
public String upLoad(Map map,@RequestParam("userImag") MultipartFile multipartFile,String userName){
    System.out.println("文件上传表单的Id名"+multipartFile.getName());
    System.out.println("文件全名"+multipartFile.getOriginalFilename());
    System.out.println("用户名"+userName);
    try {
        multipartFile.transferTo(new File("D:\\suoying\\"+multipartFile.getOriginalFilename()));
        map.put("msg","文件上传成功");
    } catch (Exception e) {
        map.put("msg","文件上传失败"+e.getMessage());
    }
    return "forward:index.jsp";
}

SpringMVC的拦截器

  • 概述:拦截器就是过滤器的一个升级过滤器,拦截器的功能比过滤器的功能更为强大,SpringMVC的拦截器还提供了三个时机,分别是:方法执行前、方法执行后、页面渲染后。
  • SpringMVC配置文件的编写
//在配置文件中添加如下xml

<mvc:interceptors>
    
    
    <bean class="com.guolei.interceptor.MyfristInterceptor"/>
    
    <mvc:interceptor>
        <mvc:mapping path="/test01"/>
        <bean class="com.guolei.interceptor.MySecondInterceptor"/>
    mvc:interceptor>
mvc:interceptors>
  • 拦截器的编写
//注意:拦截器执行的顺序,与在SpringMVC配置文件中配置的顺序一致。
//拦截器一
public class MyfristInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("过滤器1:方法执行前");
        //注意:返回true控制器方法会执行,返回false控制器方法会执行
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("过滤器1:方法执行后");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("过滤器1:页面渲染后");
    }
}
//拦截器二
public class MySecondInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("过滤器2:方法执行前");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("过滤器2:方法执行后");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("过滤器2:页面渲染后");
    }
}
  • 控制器测试方法的编写
public class MyFisrController {
    //测试拦截器
    @RequestMapping("/test01")
    public String test01(){
        System.out.println("方法执行中!");
        return "success";
    }
}
/*
执行结果:
过滤器1:方法执行前
过滤器2:方法执行前
方法执行中!
过滤器2:方法执行后
过滤器1:方法执行后
你好,页面已得到响应!
过滤器2:页面渲染后
过滤器1:页面渲染后
*/
  • 拦截器的运行流程:
    • 正常运行流程:
      • 拦截器的preHandle------目标方法-----拦截器postHandle-----页面-------拦截器的afterCompletion
    • 异常运行流程
      • 若是目标方法执行异常,post不走,after走
      • 若是pre返回false,后面的所有都不走。
      • 在配置了多个拦截器后,遍历拦截器过程中,已经放行了的拦截器的afterCompletion总会执行。但只要有一个拦截器不放行,控制器方法就不会执行。
  • 什么时候用filter什么时候用拦截器:
    • 如果拦截的时候需要实现某些功能时,就用拦截器,否则其他情况就可以用filter。

SpringMVC异常机制

  • SpringMVC处理异常的解析器为九大组件之一的:handlerExceptionResolvers,默认解析三种内置的异常解析器的实现类。

    • ExceptionHandlerExceptionResolver
    • ResponseStatusExceptionResolver
    • DefaultHandlerExceptionResolver(默认的异常)
    • 使用配置装配的自定义异常(没有装配则没有):SimpleMappingExceptionResolver
    • 从上到下的异常解析的流程,如果异常解析器都不能处理就直接抛出去给Tomcat处理
  • ExceptionHandlerExceptionResolver的使用

    • 在控制器方法中,自定义异常处理方法

      @Controller
      public class MyFisrController {
          //测试默认异常解析器ExceptionHandlerExceptionResolver
          @RequestMapping("/test01")
          public String test01(int num){
              System.out.println(10/num);
              return "success";
          }
      
          //自定义异常处理方法
          //value属性指定处理什么异常,在本控制器中,所有的数学的异常都会交给这个方法执行。
          //传入参数类型为Exception,则自动会将引起的异常对象传入形参,但注意!!!
          //这里不能写map等等隐含模型,若要携带错误信息给页面,直接将返回值设置为ModelAndView
          @ExceptionHandler(value = {ArithmeticException.class})
          public ModelAndView HanderException(Exception exception){
              ModelAndView modelAndView = new ModelAndView();
              modelAndView.setViewName("errorPage");
              modelAndView.addObject("ex",exception.getMessage());
              return modelAndView;
          }
      }
      
    • 创建全局异常处理类的处理方法

      //该注解表明,这是个异常处理类,会将该类对象装配到IOC容器中
      @ControllerAdvice
      public class MyException {
          //这里定义的异常处理方法,会处理本项目中抛出的所有对应异常
          @ExceptionHandler(value = {NullPointerException.class,ArithmeticException.class})
          public ModelAndView HanderException(Exception exception){
              ModelAndView modelAndView = new ModelAndView();
              modelAndView.setViewName("errorPage");
              System.out.println("全局异常处理方法已执行"+exception.toString());
              modelAndView.addObject("ex",exception.toString());
              return modelAndView;
          }
      }
      
    • 注意:优先调用异常处理方法为本类定义的。本类无定义再使用全局异常处理方法。

  • ResponseStatusExceptionResolver的使用

    //在方法中抛出该异常类,会展现一个SpringMVC中指定的异常页,并将注解的信息写入异常页
    @ResponseStatus(reason = "用户不存在", value = HttpStatus.NOT_EXTENDED)
    public class MyHttpException extends RuntimeException{
    }
    

Spirng与SpringMVC的整合

  • 整合的目的:分工明确

    • SpringMVC的配置文件就来配置和网站转发逻辑以及网站功能有关的(视图解析器,文件上传解析器,支持ajax,xxx)
    • Spring的配置文件来配置和业务有关的(事务控制,数据源,xxx)
  • 方案:SpringMVC和Spring分容器

    • 默认行为:Spring默认是父容器,SpringMVC默认是子容器;子容器可以引用父容器的组件;父容器不能引用子容器的组件;

    • web.xml文件配置两个容器

      DOCTYPE web-app PUBLIC
       "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
       "http://java.sun.com/dtd/web-app_2_3.dtd" >
      
      <web-app>
          
          <filter>
              <filter-name>characterEncodingFilterfilter-name>
              <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
              
              <init-param>
                  <param-name>encodingparam-name>
                  <param-value>UTF-8param-value>
              init-param>
              
              <init-param>
                  <param-name>foreEncodingparam-name>
                  <param-value>trueparam-value>
              init-param>
          filter>
          <filter-mapping>
              <filter-name>characterEncodingFilterfilter-name>
              <url-pattern>/*url-pattern>
          filter-mapping>
          
          <context-param>
              <param-name>contextConfigLocationparam-name>
              <param-value>
                  classpath:applicationContext.xml
              param-value>
          context-param>
          <listener>
              <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
          listener>
          
          <servlet>
              <servlet-name>springmvcservlet-name>
              <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
              <init-param>
                  <param-name>contextConfigLocationparam-name>
                  <param-value>classpath:springmvc.xmlparam-value>
              init-param>
              <load-on-startup>1load-on-startup>
          servlet>
          
          <servlet-mapping>
              <servlet-name>springmvcservlet-name>
              <url-pattern>/url-pattern>
          servlet-mapping>
      
      web-app>
      
      
    • Spring配置文件的编写

      
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:aop="http://www.springframework.org/schema/aop"
             xmlns:tx="http://www.springframework.org/schema/tx"
             xmlns:mvc="http://www.springframework.org/schema/mvc"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/context
              http://www.springframework.org/schema/context/spring-context.xsd
              http://www.springframework.org/schema/aop
              http://www.springframework.org/schema/aop/spring-aop.xsd
              http://www.springframework.org/schema/tx
              http://www.springframework.org/schema/tx/spring-tx.xsd
              http://www.springframework.org/schema/mvc
              http://www.springframework.org/schema/mvc/spring-mvc.xsd
      http://www.springframework.org/schema/tx ">
          
          <context:component-scan base-package="com.guolei">
              <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
              <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
          context:component-scan>
      beans>
      
    • SpringMVC配置文件的书写

      
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:aop="http://www.springframework.org/schema/aop"
             xmlns:tx="http://www.springframework.org/schema/tx"
             xmlns:mvc="http://www.springframework.org/schema/mvc"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/context
              http://www.springframework.org/schema/context/spring-context.xsd
              http://www.springframework.org/schema/aop
              http://www.springframework.org/schema/aop/spring-aop.xsd
              http://www.springframework.org/schema/tx
              http://www.springframework.org/schema/tx/spring-tx.xsd
              http://www.springframework.org/schema/mvc
              http://www.springframework.org/schema/mvc/spring-mvc.xsd
      http://www.springframework.org/schema/tx ">
          
          <context:component-scan base-package="com.guolei" use-default-filters="false">
              <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
              <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
          context:component-scan>
          <mvc:default-servlet-handler/>
          
          <mvc:annotation-driven/>
      beans>
      

配置文件的一些常用的标签


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx ">
    
    <context:component-scan base-package="com.guolei.controller"/>
    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        
        <property name="prefix" value="/JspPages/"/>
        
        <property name="suffix" value=".jsp"/>
    bean>
    
    
    
    <mvc:default-servlet-handler/>
    
    <mvc:annotation-driven/>
    
beans>
  • ==< mvc:annotation-driven/>==标签的详解
    • 会自动注册三个bean对象
      • RequestMappingHandlerMapping对象:该对象用于保存SpringMVC扫描注解,解析路径对应的类。
      • RequestMappingHandleAdapter对象:该对象用于生成对应处理类的适配器。
      • ExceptionHandleExceptionResolver对象
    • 还将提供以下支持:
      • 支持使用ConversionsService实例对表单参数进行类型转换
      • 支持使用@NumberFormatannotation、@DateTimeFormat注解完成数据类型的格式化。
      • 支持使用@Valid注解对JavaBean实例进行JSR303验证
      • 支持使用@RequestBody和@ResponseBody注解
  • < mvc:annotation-driven/> 与==< mvc:default-servlet-handler/>==这两个标签配置后,功能的实现
    • 都没有配置:(前提:前端适配器的路径过滤为“/”),动态资源可以访问,但是静态资源不可以访问。
    • 加上< mvc:default-servlet-handler/>标签后,不加==< mvc:annotation-driven/>== ,静态资源可以访问,但动态资源不可以访问。
    • 两个都加上去后,静态资源和动态资源就都能访问。

总结流程图

SpringMVC学习笔记(2021.6.2-2021.6.10)gstone_第2张图片

你可能感兴趣的:(Spring框架,java,spring,mvc,jdk1.8)