文章目录
1.自定义拦截器
1.基本介绍
1.说明
2.自定义拦截器的三个方法
3.流程图
2.快速入门
1.Myinterceptor01.java
java
复制代码
package com.sun.web.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author 孙显圣
* @version 1.0
*/
@Component //注入容器
public class Myinterceptor01 implements HandlerInterceptor {
/**
* 在目标方法执行前被调用,如果返回false,目标方法不会被执行
*
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
return true;
}
/**
* 在目标方法执行后被调用,可以获取目标方法返回的ModelAndView,可以根据业务进行二次处理
*
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
/**
* 在渲染之后会被调用,可以进行资源清理工作
*
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
}
2.FurnHandler.java
java
复制代码
package com.sun.web.interceptor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author 孙显圣
* @version 1.0
*/
@Controller
public class FurnHandler {
@RequestMapping("/hi")
public String hi() {
System.out.println("hi方法被调用");
return "success";
}
@RequestMapping("/hello")
public String hello() {
System.out.println("hello方法被调用");
return "success";
}
}
3.springDispatcherServlet-servlet.xml配置拦截器
xml
复制代码
<!--配置拦截器-->
<mvc:interceptors>
<!--直接引用配置好的拦截器,这种配置方式会对所有的目标方法生效-->
<ref bean="myinterceptor01"/>
</mvc:interceptors>
4.单元测试
3.拦截特定路径
1.拦截指定路径
xml
复制代码
<!--配置拦截器-->
<mvc:interceptors>
<!--这样配置的拦截器可以指定路径-->
<mvc:interceptor>
<mvc:mapping path="/hi"/>
<ref bean="myinterceptor01"/>
</mvc:interceptor>
</mvc:interceptors>
2.通配符配置路径
xml
复制代码
<!--配置拦截器-->
<mvc:interceptors>
<!--拦截器可以使用通配符配置路径-->
<mvc:interceptor>
<!--匹配所有/h。。。的路径-->
<mvc:mapping path="/h*"/>
<!--排除掉/hi的路径-->
<mvc:exclude-mapping path="/hi"/>
<ref bean="myinterceptor01"/>
</mvc:interceptor>
</mvc:interceptors>
4.细节说明
5.多个拦截器
1.执行流程图
2.应用实例
1.FurnHandler.java目标方法
java
复制代码
@RequestMapping("/topic")
public String topic() {
System.out.println("topic执行!");
return "success";
}
2.拦截器
java
复制代码
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//只要参数中有topic是topic就直接响应
String topic = request.getParameter("topic");
if (topic.equals("topic")) {
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("<h1>请不要乱说话!!</h1>");
}
//后面的不再执行
return false;
}
3.结果展示
2.异常处理
1.基本介绍
2.局部异常处理器
1.需求分析
2.抛出问题
1.MyExceptionHandler.java
java
复制代码
package com.sun.web.exception;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author 孙显圣
* @version 1.0
*/
@Controller
public class MyExceptionHandler {
@RequestMapping("/getNum/{num}")
public String getNUm(@PathVariable("num") Integer num) {
//这里如果传进来的是0则会出现异常
System.out.println(10 / num);
return "success";
}
}
2.不处理异常则交给tomcat处理
3.局部异常实例
1.MyExceptionHandler.java
java
复制代码
package com.sun.web.exception;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
/**
* @author 孙显圣
* @version 1.0
*/
@Controller
public class MyExceptionHandler {
@RequestMapping("/getNum/{num}")
public String getNUm(@PathVariable("num") Integer num) {
//这里如果传进来的是0则会出现异常
System.out.println(10 / num);
return "success";
}
//处理异常
@ExceptionHandler({ArithmeticException.class, NullPointerException.class}) //参数是一个数组,可以接受多个异常类型
public String exceptionHandler(Exception ex, HttpServletRequest request) { //当出现异常时,异常会自动封装到ex中(数据绑定)
System.out.println("异常的信息=" + ex.getMessage());
//可以将异常信息请求转发给下一个页面
request.setAttribute("reason", ex.getMessage());
return "exception_mes";
}
}
2.exception_mes.jsp
jsp
复制代码
<%--
Date: 2024/3/1
Time: 8:47
User: 孙显圣
Version:1.0
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>出现异常</h3>
<h4>异常信息是${requestScope.reason}</h4>
</body>
</html>
3.结果展示
3.全局异常处理器
1.基本介绍
2.全局异常实例
1.MyGlobalException.java
java
复制代码
package com.sun.web.exception;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import javax.servlet.http.HttpServletRequest;
/**
* @author 孙显圣
* @version 1.0
*/
@ControllerAdvice //表示这个是处理全局异常的类
public class MyGlobalException {
@ExceptionHandler(ArithmeticException.class) //这个是处理算数异常的算数异常处理器
public String globalException(Exception ex, HttpServletRequest request) {
System.out.println("全局异常信息是=" + ex.getMessage());
//将全局异常信息请求转发
request.setAttribute("reason", ex.getMessage());
return "global_exception";
}
}
2.global_exception.jsp
jsp
复制代码
<%--
Date: 2024/3/1
Time: 9:02
User: 孙显圣
Version:1.0
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>出现异常</h3>
<h4>全局异常信息是${requestScope.reason}</h4>
</body>
</html>
3.结果展示
3.细节说明
1.局部异常优先级高于全局异常
2.处理异常机制
- 先从发生异常的方法所在的类中查找有
@ExceptionHandler
注解的方法,如果异常不匹配则进行下一步
- 从有
@ControllerAdvice
注解的类查找有@ExceptionHandler
注解的方法,如果匹配异常则处理,无法匹配则交给tomcat处理
4.自定义异常
1.基本介绍
2.自定义异常应用实例
1.SelfException.java
java
复制代码
package com.sun.web.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
/**
* @author 孙显圣
* @version 1.0
*/
//reason指的是返回的异常原因信息,value指的是返回的响应状态
@ResponseStatus(reason = "年龄需要在1-120之间", value = HttpStatus.BAD_REQUEST)
public class SelfException extends RuntimeException{
}
2.selfex.java
java
复制代码
package com.sun.web.exception;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author 孙显圣
* @version 1.0
*/
@Controller
public class selfex {
@RequestMapping("/selfex")
public void ex() {
throw new SelfException();
}
}
3.结果展示
3.可以使用有参构造,抛出异常交给异常处理器接管
1.SelfException.java
java
复制代码
package com.sun.web.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
/**
* @author 孙显圣
* @version 1.0
*/
//reason指的是返回的异常原因信息,value指的是返回的响应状态
@ResponseStatus(reason = "年龄需要在1-120之间", value = HttpStatus.BAD_REQUEST) //注意这个是给tomcat看的
public class SelfException extends RuntimeException{
public SelfException() {
}
//这样就可以从全局异常里获取message了
public SelfException(String message) {
super(message);
}
}
2.selfex.java抛出自定义异常并制定message
java
复制代码
package com.sun.web.exception;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author 孙显圣
* @version 1.0
*/
@Controller
public class selfex {
@RequestMapping("/selfex")
public void ex() {
throw new SelfException("年龄需要在1-100"); //指定message
}
}
3.MyGlobalException.java捕获自定义异常
java
复制代码
package com.sun.web.exception;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import javax.servlet.http.HttpServletRequest;
/**
* @author 孙显圣
* @version 1.0
*/
@ControllerAdvice //表示这个是处理全局异常的类
public class MyGlobalException {
//处理自定义异常
@ExceptionHandler(SelfException.class)
public String selfex(Exception ex, HttpServletRequest request) {
//将全局异常信息请求转发
request.setAttribute("reason", ex.getMessage());
return "global_exception";
}
}
4.结果展示
5.统一异常处理器
1.基本介绍
2.需求分析
3.具体实现
1.MyExceptionHandler.java抛出数组越界异常
java
复制代码
package com.sun.web.exception;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author 孙显圣
* @version 1.0
*/
@Controller
public class MyExceptionHandler {
//抛出数组越界异常,局部异常处理器和全局异常处理器都没有处理,则会交给统一异常处理器来处理
@RequestMapping("/arr")
public String array() {
int[] ints = {1, 2, 3};
System.out.println(ints[1222]); //交给统一异常处理器来处理
return "success";
}
}
2.springDispatcherServlet-servlet.xml配置统一异常处理器
xml
复制代码
<!--配置统一异常处理器-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" id="exceptionResolver">
<property name="exceptionMappings">
<props>
<!--这里的arrEx会返回给视图解析器,然后默认视图解析器进行前后缀拼接-->
<prop key="java.lang.ArrayIndexOutOfBoundsException">arrEx</prop>
</props>
</property>
</bean>
3.arrEx.jsp异常处理页面
jsp
复制代码
<%--
Date: 2024/3/1
Time: 10:02
User: 孙显圣
Version:1.0
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>数组越界异常</h1>
</body>
</html>
4.结果展示
6.对未知异常进行统一处理
1.具体实现
1.MyExceptionHandler.java抛出异常
java
复制代码
package com.sun.web.exception;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author 孙显圣
* @version 1.0
*/
@Controller
public class MyExceptionHandler {
//没有归类的异常
@RequestMapping("/test")
public String test() {
String str = "hello";
char c = str.charAt(10); //这里会抛出异常
return "success";
}
}
2.springDispatcherServlet-servlet.xml修改统一异常处理器
xml
复制代码
<!--配置统一异常处理器-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" id="exceptionResolver">
<property name="exceptionMappings">
<props>
<!--这里的arrEx会返回给视图解析器,然后默认视图解析器进行前后缀拼接-->
<prop key="java.lang.ArrayIndexOutOfBoundsException">arrEx</prop>
<prop key="java.lang.Exception">allEx</prop>
</props>
</property>
</bean>
3.allEx.jsp所有未知异常的处理
jsp
复制代码
<%--
Date: 2024/3/1
Time: 10:12
User: 孙显圣
Version:1.0
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>所有未知异常的处理界面</h1>
</body>
</html>
4.结果展示
7.异常处理的优先级
1.局部异常处理器
- 方法上加@ExceptionHandler({ArithmeticException.class, NullPointerException.class}) //参数是一个数组,可以接受多个异常类型
2.全局异常处理器
- 类上加@ControllerAdvice //表示这个是处理全局异常的类
- 方法上加@ExceptionHandler({ArithmeticException.class, NullPointerException.class}) //参数是一个数组,可以接受多个异常类型
3.统一异常处理器
- 匹配方式是匹配尽可能具体的类型,跟配置的顺序无关
- 在Spring配置文件中配置
xml
复制代码
<!--配置统一异常处理器-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" id="exceptionResolver">
<property name="exceptionMappings">
<props>
<!--这里的arrEx会返回给视图解析器,然后默认视图解析器进行前后缀拼接-->
<prop key="java.lang.ArrayIndexOutOfBoundsException">arrEx</prop>
<prop key="java.lang.Exception">allEx</prop>
</props>
</property>
</bean>
4.Tomcat默认机制
3.springMVC阶段的配置文件
1.springDispatcherServlet-servlet.xml
xml
复制代码
<?xml version="1.0" encoding="UTF-8"?>
<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: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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--容器扫描-->
<context:component-scan base-package="com.sun.web"/>
<!--配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!--配置前缀和后缀-->
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--配置国际化错误信息的资源处理bean-->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<!--这里是默认到src下的properties文件中去读取的basename配置的就是文件名,所以他会读取src的i18n.properties文件-->
<property name="basename" value="i18n"></property>
</bean>
<!--配置文件上传解析器,注意这里的id必须是接口首字母小写-->
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver"></bean>
<!--加入两个常规配置-->
<!--支持SpringMVC的高级功能,比如JSR303校验,映射动态请求-->
<mvc:annotation-driven></mvc:annotation-driven><!--注意:这个annotation-driven要选择mvc的那个-->
<!--springMVC不能处理的请求,交给tomcat处理,比如css,js-->
<mvc:default-servlet-handler/>
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/topic"/>
<ref bean="myinterceptor01"/>
</mvc:interceptor>
</mvc:interceptors>
<!--配置统一异常处理器-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" id="exceptionResolver">
<property name="exceptionMappings">
<props>
<!--这里的arrEx会返回给视图解析器,然后默认视图解析器进行前后缀拼接-->
<prop key="java.lang.ArrayIndexOutOfBoundsException">arrEx</prop>
<prop key="java.lang.Exception">allEx</prop>
</props>
</property>
</bean>
<!--视图解析器按照order的大小来决定优先级,默认的视图解析器是最低的优先级MAX_VALUE = 0x7fffffff-->
<!--配置自定义视图解析器-->
<!--<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">-->
<!-- <property name="order" value="99"/>-->
<!--</bean>-->
</beans>
2.web.xml
xml
复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--配置Spring自带的过滤器,解决乱码问题-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!--这里指定字符编码-->
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--<!–配置过滤器------放到最前面,因为这个应该是最先处理的–>-->
<!--<filter>-->
<!-- <filter-name>MyCharacterFilter</filter-name>-->
<!-- <filter-class>com.sun.web.filter.MyCharacterFilter</filter-class>-->
<!--</filter>-->
<!--<!–过滤所有请求–>-->
<!--<filter-mapping>-->
<!-- <filter-name>MyCharacterFilter</filter-name>-->
<!-- <url-pattern>/*</url-pattern>-->
<!--</filter-mapping>-->
<!--配置HiddenHttpMethodFilter-->
<!--把post方式提交的delete和put请求进行转换-->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<!--所有请求都经过这个过滤器-->
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--配置中央控制器-->
<!--只要服务器启动,这个servlet就调用init方法读取spring的配置文件,并且接收所有请求-->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--这里如果不配置init-param,则会按照springDispatcherServlet-servlet.xml在WEB-INF目录下找Spring的配置文件-->
<!--服务器启动就装载这个servlet,直接创建servlet实例,调用init方法-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<!--所有的请求都交给这servlet处理-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>