springMVC笔记3

springmvc结合ajax:

在这里插入图片描述

在这里插入图片描述
@ResponseBody是jackon包将数据转为json格式的。

在这里插入图片描述

注解上是使用json:
1.@JsonFormat
在这里插入图片描述

此种方式返回的json日期不再是没注解(@JsonFormat)之前的时间毫秒数,而是一个类似于2019-03-03这样的格式。

2.使用json注解去忽略某些字段去转成json格式:@JsonIgnore
在这里插入图片描述

页面发送ajax请求:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

页面中利用ajax发送json数据:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

总结两个注解作用:

@RequestBody第一个作用:获取请求体湖区
@RequestBody第二个作用:接收前端的json数据,封装为对象。
在这里插入图片描述

HttpEntity:可以拿到请求头和请求体:
在这里插入图片描述

ResponBody将数据写出去到浏览器。浏览器收到响应体,然后解析即可。
在这里插入图片描述

在这里插入图片描述

springmvc的文件下载:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

springmvc文件上传/下载:

单文件上传:

第一步:环境:导包

<dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.2</version>
        </dependency>

或者手动添加这两个包到lib中:
在这里插入图片描述

第二步:写配置(springmvc.xml配置文件上传解析器):

<!--文件上传解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--设置请求编码格式-->
        <property name="defaultEncoding" value="utf-8"></property>
    </bean>

在这里插入图片描述

id="multipartResolver"必须为这个的原因:

在这里插入图片描述
第三步:上传的表单页面编写:

jsp页面写一个form表单:

在这里插入图片描述
此fileUpload.jsp在 WEB-INF下:

<%--
  Created by IntelliJ IDEA.
  User: fan
  Date: 2021/3/26
  Time: 22:46
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>xx</title>
</head>
<body>
${msg}
<form action="${pageContext.request.contextPath}/upload" method="post" enctype="multipart/form-data">
    用户头像:<input type="file" name="headerimg"><br>
    用户名:<input type="text" name="username"><br>
    <input type="submit" value="上传">
</form>
</body>
</html>

第四步,Controller逻辑:

Controller代码:

package com.fan.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

@Controller
public class FileUploadController {
    @RequestMapping("/upload")
    public String upload(Model model,
                         @RequestParam(value = "username",required = false) String username,
                         @RequestParam("headerimg") MultipartFile file){

        System.out.println("上传文件的信息:");
        System.out.println("文件项的name:"+file.getOriginalFilename());
        //文件保存
        try {
            file.transferTo(new File("G:\\BAWEI\\" +file.getOriginalFilename()));
            model.addAttribute("msg","文件上传成功");
        } catch (Exception e) {
            model.addAttribute("msg","文件上传失败"+e.getMessage());
        }
        return "forward:/WEB-INF/pages/fileUpload.jsp";//带前缀的不走拼串,要自己写路径
    }
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

多文件上传

Controller:

//测试多文件上传的
    @RequestMapping("/uploadMore")
    public String uploadMore(
            Model model,
            @RequestParam(value = "headerimg",required = false) MultipartFile[] files,
            @RequestParam(value = "username") String username
    ){
        for (MultipartFile file : files) {
            if(!file.isEmpty()){//为了安全,判断文件是否为空
                //保存文件,找一个位置
                try {
                    file.transferTo(new File("G:\\BAWEI\\" +file.getOriginalFilename()));
                    model.addAttribute("msg","多文件上传成功");
                } catch (Exception e) {
                   model.addAttribute("msg","多文件上传失败:"+e.getMessage());
                }
            }

        }
        return "forward:/WEB-INF/pages/fileUpload.jsp";
    }

在这里插入图片描述

jsp页面准备:
在这里插入图片描述

此fileUpload.jsp在 WEB-INF下:

<%--
  Created by IntelliJ IDEA.
  User: fan
  Date: 2021/3/26
  Time: 22:46
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>xx</title>
</head>
<body>
${msg}

<%--<form action="${pageContext.request.contextPath}/upload" method="post" enctype="multipart/form-data">
    用户头像:<input type="file" name="headerimg"><br>
    用户名:<input type="text" name="username"><br>
    <input type="submit" value="上传">
</form>--%>

<%--测试多文件上传的--%>
<form action="${pageContext.request.contextPath}/uploadMore" method="post" enctype="multipart/form-data">
    用户头像:<input type="file" name="headerimg"><br>
    用户头像:<input type="file" name="headerimg"><br>
    用户头像:<input type="file" name="headerimg"><br>
    用户名:<input type="text" name="username"><br>
    <input type="submit" value="上传">
</form>
</body>
</html>

springmvc的拦截器:

在这里插入图片描述

页面准备:

在这里插入图片描述

controller:

在这里插入图片描述

写配置:让拦截器放入容器工作:

在这里插入图片描述

单个拦截器:

在这里插入图片描述
总结流程:
在这里插入图片描述

多个拦截器:

配置多个拦截器的时候,谁靠前,谁优先。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

拦截器的源码解析:
(1)

在这里插入图片描述

(2)

在这里插入图片描述

(3)preHandle方法内部:

在这里插入图片描述
(4)然后根据返回值进行判断,是否需要继续执行目标方法。

在这里插入图片描述

在这里插入图片描述
目标方法执行后,执行postHandle:

在这里插入图片描述

然后来到目标页面渲染:
processDispatchResult(处理前端控制器的结果,即页面响应):

在这里插入图片描述

在这里插入图片描述

AfterCompletion执行逻辑代码:

在这里插入图片描述

总结所有拦截器都正常返回true(即放行让继续往下执行)的流程:

在这里插入图片描述

总结中间一个拦截器不放行的执行流程:

在这里插入图片描述

在这里插入图片描述

拦截器和Fileter的使用区别:

fileter属于tomcat的web组件,不能放到IOC容器中,如果想从IOC容器中拿到一些其他组件来注入,就不容易;filter能脱离springmvc使用。

拦截器属于springmvc的组件,可以放到IOC容器中,如果完成一些功能,想从IOC容器中拿取一些组件配合完成,就很容易@Autowire注入;拦截器不能脱离springmvc单独运行。

springmvc国际化:

第一种,基于浏览器请求的国际化实现:

这种方式不能自己更改的国际化,需要通过浏览器切换语言进行验证,很麻烦,不建议。

第一步:导包:

<!--jstl-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>

第二步,准备国际化文件

英文的国际化文件:

welcomeinfo=welcom my i18n page
username=USERNAME
password=PASSWORD
loginBtn=LOGIN_BTN

中文的国际化文件:

welcomeinfo=欢迎来到我的国际化页面
username=用户名
password=密码
loginBtn=登录

可以将国际化文件分类放在不同的文件夹下:

在这里插入图片描述

第三步:让springmvc管理国际化资源文件。

<!--让springmvc去管理国际化的资源文件-->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="i18n.login"></property>
    </bean>

在这里插入图片描述

第四步:直接去页面取值:

然后jsp页面导入标签库,并且通过fmt:message取资源文件中的值

<%--
  Created by IntelliJ IDEA.
  User: fan
  Date: 2021/3/28
  Time: 11:04
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<html>
<head>
    <title>Title</title>
</head>
<body>
<%--<fmt:bundle>标签将指定的资源束对出现在<fmt:bundle>标签中的<fmt:message>标签可用。
这可以使您省去为每个<fmt:message>标签指定资源束的很多步骤。--%>

<fmt:bundle basename="i18n.login">
    <%--如果页面出现???,就是不识别fmt标签问题,解决方案:<fmt:bundle  包裹所有的fmt:message
这里basename写resources下的 文件夹+基础名,--%>


<fmt:message key="welcomeinfo"></fmt:message>

<form action="">
<fmt:message key="username"></fmt:message>:<input type="text"><br>
<fmt:message key="password"></fmt:message>:<input type="text"><br>
<input type="submit" value="<fmt:message key="loginBtn"></fmt:message> ">
</form>

</fmt:bundle>
</body>
</html>

然后测试,手动切换浏览器语言测试:

在这里插入图片描述

在这里插入图片描述

国际化的第一种方式的源码分析:

springmvc自带一个默认的区域解析器:AcceptHeadLocalResover来解析国际化信息的。
而这个自带的解析器会从我们浏览器的请求头中拿区域信息进行解析,代码如下:
在这里插入图片描述

在这里插入图片描述

controller测试打印国际化的信息:注意这里是Locale,是java.util.Locale包。

package com.fan.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.Locale;

@Controller
public class Myi18nController {
    @RequestMapping("/toLoginPage")
    public String tologin(Locale locale){
        System.out.println("区域信息:"+locale);//区域信息:en_US
        return "login";
    }

    @RequestMapping("/toLoginPage2")
    public String tologin2(){
        return "login2";
    }
}

也可以这样使用:

在这里插入图片描述

第二种,基于自定义的国际化解析器实现国际化:

案例效果:实现中英文的切换按钮

在这里插入图片描述
准备工作:导包;和第一种方式导包一样。

然后第一步:

页面准备,login2.jsp:

<%--
  Created by IntelliJ IDEA.
  User: fan
  Date: 2021/3/28
  Time: 11:46
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
    <title>测试国际化</title>
</head>
<body>

<fmt:bundle basename="i18n.login"><%--这里写resources下的 文件夹+基础名--%>

    <fmt:message key="welcomeinfo"></fmt:message>

    <form action="">
        <fmt:message key="username"></fmt:message>:<input type="text"><br>
        <fmt:message key="password"></fmt:message>:<input type="text"><br>
        <input type="submit" value="<fmt:message key="loginBtn"></fmt:message>">
    </form>
    <a href="toLoginPage2?locale=zh_CN">中文</a>&nbsp;<a href="toLoginPage2?locale=en_US">English</a>
</fmt:bundle>
</body>
</html>

了解国家区域解析器的实现类:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

第二步:自定义的区域解析器编写:

需要实现一个接口org.springframework.web.servlet.LocaleResolver;并重写解析抽象方法。

package com.fan.utils;

import org.springframework.cglib.core.Local;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.LocaleResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;

/*自定义的区域解析器*/
public class MyLocaleResolver implements LocaleResolver {
    @Override
    public Locale resolveLocale(HttpServletRequest req) {
        Locale locale = null;
        //我们点击超链接发一个请求,会带来一个get形式的请求参数:local和值
        String localeStr = req.getParameter("locale");//根据强求参数得到en_US或者zh_CN
        if(localeStr != null && !"".equals(localeStr)){//请求携带的区域信息不为空也不是空串
            //我们自己封装一个Locale信息,Locale(String language, String country)
            //第一个参数是语言,第二个参数是国家,封装返回一个locale对象
            locale = new Locale(localeStr.split("_")[0],localeStr.split("_")[1]);
            System.out.println("这是我自定义的区域解析器。。。");
        }else{
            //如果前端的请求中没有携带任何的区域信息的参数和值,我们就默认用个浏览器请求头中的区域信息
            locale = req.getLocale();
        }
        return locale;//返回此区域信息
    }

    @Override
    public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {

    }
}

第三步:springmvc中写配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--注解扫描-->
    <context:component-scan base-package="com.fan"></context:component-scan>
    <!--注解驱动,动态资源有效和处理器映射器和处理器适配器-->
    <mvc:annotation-driven></mvc:annotation-driven>
    <!--静态资源的管理-->
    <mvc:default-servlet-handler></mvc:default-servlet-handler>

    <!--视图跳转的控制-->
    <!--<mvc:view-controller path="" view-name=""></mvc:view-controller>-->
    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--让springmvc去管理国际化的资源文件-->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="i18n.login"></property>
    </bean>

    <!--自定义的区域解析器的配置,让其替代系统默认提供的,如果不配置这个,系统默认提供一个AcceptHeaderLocalResolver-->
    <bean id="localeResolver" class="com.fan.utils.MyLocaleResolver">
    </bean>

</beans>

在这里插入图片描述

测试成功:
在这里插入图片描述

第三种,基于HttpSession的国际化实现:

springmvc配置换成这样:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--注解扫描-->
    <context:component-scan base-package="com.fan"></context:component-scan>
    <!--注解驱动,动态资源有效和处理器映射器和处理器适配器-->
    <mvc:annotation-driven></mvc:annotation-driven>
    <!--静态资源的管理-->
    <mvc:default-servlet-handler></mvc:default-servlet-handler>

    <!--视图跳转的控制-->
    <!--<mvc:view-controller path="" view-name=""></mvc:view-controller>-->
    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--让springmvc去管理国际化的资源文件-->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="i18n.login"></property>
    </bean>

    <!--使用系统提供的session区域解析器工作-->
    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean>

</beans>

页面我们用login3.jsp:session区域解析器就能从session中取区域信息值。

<%--
  Created by IntelliJ IDEA.
  User: fan
  Date: 2021/3/28
  Time: 11:46
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
    <title>测试国际化</title>
</head>
<body>

<fmt:bundle basename="i18n.login"><%--这里写resources下的 文件夹+基础名--%>

    <fmt:message key="welcomeinfo"></fmt:message>

    <form action="">
        <fmt:message key="username"></fmt:message>:<input type="text"><br>
        <fmt:message key="password"></fmt:message>:<input type="text"><br>
        <input type="submit" value="<fmt:message key="loginBtn"></fmt:message>">
    </form>
    <a href="toLoginPage3?locale=zh_CN">中文</a>&nbsp;<a href="toLoginPage3?locale=en_US">English</a>
</fmt:bundle>
</body>
</html>

Conreoller测试:

package com.fan.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

import javax.servlet.http.HttpSession;
import java.util.Locale;

@Controller
public class Myi18nController {
    //1.测试系统自带的区域解析器
    @RequestMapping("/toLoginPage")
    public String tologin(Locale locale){
        System.out.println("区域信息:"+locale);//区域信息:en_US
        return "login";
    }

    //2.测试自定义的区域解析器
    @RequestMapping("/toLoginPage2")
    public String tologin2(){
        return "login2";
    }

    //3.测试session的区域解析器
    /*defaultValue = "zh_CN"不设置可能发生400,请求数据异常,就是你刚进浏览器没发请求切换前要用默认的*/
    @RequestMapping("/toLoginPage3")//toLoginPage3
    public String tologin3(
            @RequestParam(value = "locale",defaultValue = "zh_CN") String localeStr,
            Locale locale,
            HttpSession session
    ){
        System.out.println("参数上的locale:"+locale.getClass());
        Locale l = null;
        //进行区域字符串的拆分和包装local对象
        if(localeStr != null && !"".equals(localeStr)){
            //拆分
            l = new Locale(localeStr.split("_")[0],
                    localeStr.split("_")[1]);
        }else{
            l = locale;//将浏览器的locale赋值给l
        }
        System.out.println("包装后的locale:"+l.getClass());
        session.setAttribute(SessionLocaleResolver.class.getName()+".LOCALE",l);
        return "login3";
    }

}

启动服务器进行测试:

session区域解析器再次简化后的代码:

springmvc中配置一个拦截器:

 <!--让springmvc去管理国际化的资源文件-->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="i18n.login"></property>
    </bean>

    <!--使用系统提供的session区域解析器工作-->
    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean>

    <!--配置一个拦截器,拦截session的区域设置信息,自动帮我们把区域信息设置进去session-->
    <mvc:interceptors>
        <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>
    </mvc:interceptors>

controller代码测试;

package com.fan.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

import javax.servlet.http.HttpSession;
import java.util.Locale;

@Controller
public class Myi18nController {
  
    //3.测试session的区域解析器和配置了拦截器后的简化代码
    /*defaultValue = "zh_CN"不设置可能发生400,请求数据异常,就是你刚进浏览器没发请求切换前要用默认的*/
    @RequestMapping("/toLoginPage3")//toLoginPage3
    public String tologin3(
            @RequestParam(value = "locale",defaultValue = "zh_CN") String localeStr,
            HttpSession session
    ){
        return "login3";
    }

}

也可以这样:

@Controller
public class LoginController {
    @RequestMapping(value = "/toLoginPage")//toLoginPage
    public String toLoginPage(@RequestParam(value = "locale",defaultValue = "zh_CN")Locale locale){
        return "login";
    }
}

然后测试成功;

在这里插入图片描述

springMVC异常处理:

页面准备:

<%--
  Created by IntelliJ IDEA.
  User: fan
  Date: 2021/3/29
  Time: 9:15
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  
  <a href="${pageContext.request.contextPath}/ex01?i=10">ex01</a><br>
  </body>
</html>

Controller:

package com.fan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class MyExceptionController {
    @RequestMapping("/ex01")
    public String ex01(Integer i){
        System.out.println("ex01---");
        System.out.println(10/i);
        return "success";
    }
}

测试:发一个正常的数据:
在这里插入图片描述

结果,success页面跳转运行正常,控制台打印:
ex01—
1

常见的异常解析器:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

本类的异常注解处理本类发生的异常:

使用注解:@ExceptionHandler

Controller中的异常方法:

package com.fan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class MyExceptionController {
    //测试方法
    @RequestMapping("/ex01")
    public String ex01(Integer i){
        System.out.println("ex01---");
        System.out.println(10/i);
        return "success";
    }

    /*
    * 告诉springmvc这个方法专门处理这个类发生的异常
    * 1.给方法上随便写一个Exception,用来接收发生的异常
    * 2.要携带异常信息不能给参数位置写Model
    * 3.返回ModelAndView就行了。
    * 4.如果有多个@ExceptionHandler都能处理这个异常,精确优先。
    */
    @ExceptionHandler(value = {ArithmeticException.class})
    public ModelAndView handleException01(Exception exception){
        System.out.println("handleException01--"+exception);
        //有参构造,传递一个视图名
        ModelAndView mv = new ModelAndView("myerror");
        //将异常信息放进隐含模型中
        mv.addObject("ex",exception);
        //视图解析器拼串
        return mv;
    }
}

在index.jsp页面发送异常数据:

<%--
  Created by IntelliJ IDEA.
  User: fan
  Date: 2021/3/29
  Time: 9:15
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>

  <a href="${pageContext.request.contextPath}/ex01?i=0">ex01</a><br>
  </body>
</html>

pages下的myerror自定义异常页面:

<%--
  Created by IntelliJ IDEA.
  User: fan
  Date: 2021/3/29
  Time: 9:57
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>出错了</h1>
<h2>错误信息:${ex}</h2>
</body>
</html>

测试结果:

在这里插入图片描述

全局的处理异常的类处理所有的异常:

使用注解:@ControllerAdvice和 @ExceptionHandler

我们在controller包下创建一个全局的处理异常的类MyAllException:

package com.fan.controller;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

@ControllerAdvice
public class MyAllException {

    //全局异常处理与本类同时存在时,本类优先。
    @ExceptionHandler(value = {Exception.class})
    public ModelAndView handleException01(Exception exception){
        System.out.println("全局的:handleException01--"+exception);
        //有参构造,传递一个视图名
        ModelAndView mv = new ModelAndView("myerror");
        //将异常信息放进隐含模型中
        mv.addObject("ex",exception);
        //视图解析器拼串
        return mv;
    }
}

注意:全局异常处理与本类同时存在时,本类优先
我们定义的全局的异常处理类,需要把此类加入到ioc容器中,通过注解@ControllerAdvice,来声明此类是专门处理异常的类。

在这里插入图片描述

测试:当本类的和全局的异常处理都存在的时候,本类优先:

打印的结果:
ex01—
本类的:handleException01–java.lang.ArithmeticException: / by zero
视图跳转到myerror:
在这里插入图片描述

总结:以上两种都是属于ExceptionHandleExceptionResolver来解析处理的

自定义异常的注解(@ResponseStatusExceptionResolver解析器解析):

处理顺序从上到下依次进行,一旦一个能处理,则后面处理器就失效
在这里插入图片描述

在这里插入图片描述

发送请求的页面准备:

<%--
  Created by IntelliJ IDEA.
  User: fan
  Date: 2021/3/29
  Time: 9:15
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>

  <a href="${pageContext.request.contextPath}/ex01?i=0">ex01</a><br>
  <a href="${pageContext.request.contextPath}/ex02?username=admin">ex02测试@ResponseStatus注解</a><br>
  </body>
</html>

自定义异常类UserNotFoundException:

package com.fan.controller;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

//要继承可以抛出的异常RuntimeException
//此种方式一般是,当我们懒的自己做页面的时候,用这种@ResponseStatus异常处理方式
@ResponseStatus(reason = "拒绝用户登录",value = HttpStatus.NOT_ACCEPTABLE)
public class UserNotFoundException extends RuntimeException{
}

控制器方法抛出一个自定义异常:

package com.fan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class MyExceptionController {
    //测试方法
    @RequestMapping("/ex01")
    public String ex01(Integer i){
        System.out.println("ex01---");
        System.out.println(10/i);
        return "success";
    }

   //测试@ResponseStatus注解的
    @RequestMapping("/ex02")
    public String ex02(@RequestParam("username")String username){
        //如果前端参数的用户名不是admin,则抛出异常
        if(!"admin".equals(username)){
            System.out.println("登录失败!!!");
            throw new UserNotFoundException();
        }else{
            System.out.println("登录成功");
        }

        return "success";
    }
}

运行测试:

在这里插入图片描述

默认异常处理器处理方式(DefaultHandleExceptionResolver):

处理顺序从上到下,上面的能处理,则下面的失效。

在这里插入图片描述
我们在index.jsp发送一个请求,但是此请求没有对应的处理器方法来处理:
此处发送get请求,我们使用post出来方式来处理:

<a href="${pageContext.request.contextPath}/ex03">ex03测试默认的异常处理器</a><br>

controller中的目标方法(method = RequestMethod.POST):

@RequestMapping(value = "/ex03",method = RequestMethod.GET)
    public String ex03(){
        return "success";
    }

当controller不能处理的时候弹出的页面:
在这里插入图片描述
或者这样
在这里插入图片描述
如果我们让全局异常处理器处理,则出现以下页面:
在这里插入图片描述

在这里插入图片描述

通过配置的方式来处理异常(SimpleMappingExceptionResolver):

SimpleMappingExceptionResolver

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

自己配一个key取错误消息的值:

在这里插入图片描述
测试:

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值