SpringMVC框架—知识总结(3)

拦截器

定义

拦截器( Interceptor )是一个用于在 请求 处理之前或之后 执行某些操作的组件,通常用于实现横切关注点(cross-cutting concerns ), 如日志记录、事务管理、安全认证、性能监控等。

作用

Web 应用程序中,拦截器可以拦截并处理来自客户端的请求和服务器返回给客户端的响应。

方法接口

拦截器通常用于框架(如 Spring MVC Struts2 等)中,以提供对请求和响应的集中处理。在 SpringMVC中, 拦截器通过实现 HandlerInterceptor 接口来定义 ,该接口包含三个方法:
  • preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) : 在请求处理之前被调用。可以在此方法中执行权限检查、记录日志、绑定用户数据等操作。如果该方法返回 false ,则请求将不会继续传递给后续的处理器(如Controller,而直接返回给客户端
  • postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) : 在请求处理完成后,但在视图渲染之前被调用。可以在此方法中执行一些清理工作,或者对模型数据进行修改。
  • afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) : 在整个请求处理完成后被调用,即在视图渲染之后。通常用于执行一些资源清理工作,如关闭数据库连接等。

 功能

拦截器通常被配置在框架的配置文件中,通过配置指定拦截器拦截哪些请求,以及拦截器的执行顺序。 这样,当请求到达时,框架会根据配置自动调用相应的拦截器,并在请求处理的不同阶段执行相应的操 作。

总结

通过使用拦截器,开发者可以将一些通用的、与业务逻辑无关的操作从控制器中分离出来,使控制器更加专注于处理业务逻辑。同时,拦截器也提供了一种灵活的方式来扩展框架的功能,而无需修改框架的源代码。

与过滤器的区别

过滤器和拦截器在 Web 开发中都是用于处理请求和响应的中间件,但它们之间存在明显的区别。以下是它们之间的主要差异点:
范围和执行位置
  • 过滤器(Filter):基于Servlet规范,作用于Servlet容器,可以拦截请求和响应的所有内容,包括静态资源和动态资源。过滤器在请求到达Servlet之前预处理请求,也可以在响应返回给客户端之前后处理响应。
  • 拦截器(Interceptor):基于Spring框架,只作用于Spring的上下文中。拦截器只能拦截请求到达Controller之前,或者响应返回视图之前的处理。拦截器主要针对框架提供的处理器(如控制器)进行拦截和处理。
实现方式
  • 过滤器:使用Servlet规范中的Filter接口进行实现。
  • 拦截器:使用Spring框架提供的HandlerInterceptor接口实现。
功能 
  • 过滤器:主要用于过滤请求和响应,例如字符编码处理、安全控制、日志记录等。过滤器在 请求到达Servlet之前进行预处理,但无法直接针对具体的控制器方法进行拦截和增强。
  • 拦截器:可以进行更复杂的业务逻辑处理,例如权限控制、日志记录、性能监控、事务控制 。拦截器在请求处理前后、异常处理等时机进行拦截和增强,且可以针对具体的控制器方 法进行拦截。拦截器是AOP思想的具体应用,可以通过配置和组合多个拦截器实现复杂的业 务逻辑处理。

过滤器过滤的是资源,拦截器拦截的是请求。 

拦截器链和过滤器链执行顺序

过滤器链:
  • 遵循先进入后放行;
  • 如果使用的是xml配置的过滤器链,进入的顺序和xml读取顺序有关,在xml中写在前面的过滤器先执行;
  • 如果使用到的是@WebFilter配置的过滤器链,执行顺序和类名有关,类名遵循字母和类名位数上的数字顺序;字母靠前先执行;位数上的数小先执行。
拦截器链:
  • xml配置中遵循先执行第一个拦截器的请求以前的方法,最后执行第一个拦截器的响应以前的方法,最后执行第一个拦截器响应完成的方法。

代码实现 

java
package cn.ry.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
//创建拦截器:
public class CustomerInterceptor implements HandlerInterceptor{
/**
* Object handler: 请求;
* 返回值: true放行;false:拦截;
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse
response, Object handler)
throws Exception {
// TODO Auto-generated method stub
System.out.println("请求以前进入拦截器-----------");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse
response, Object handler,
ModelAndView mav) throws Exception {
// TODO Auto-generated method stub
System.out.println("进入请求后,响应完成前执行---"+mav.getViewName());
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse
response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub
System.out.println("响应完成后执行--------------");
}
}

 xml

<!-- 配置拦截器: -->
<!-- 将当前拦截器交给spring容器管理 -->
<bean id="ci" class="cn.ry.interceptor.CustomerInterceptor"></bean>
<bean id="ci2" class="cn.ry.interceptor.CustomerInterceptor2"></bean>
<!-- 配置mvc中拦截器的标签: -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 需要拦截的请求: -->
<mvc:mapping path="/**"/>
<!-- 可以直接放行的请求有哪些 -->
<mvc:exclude-mapping path="/login/**"/>
<ref bean="ci"/>
</mvc:interceptor>
<mvc:interceptor>
<!-- 需要拦截的请求: -->
<mvc:mapping path="/**"/>
<!-- 可以直接放行的请求有哪些 -->
<mvc:exclude-mapping path="/login/**"/>
<ref bean="ci2"/>
</mvc:interceptor>
</mvc:interceptors>

异常处理

  • 全局异常处理器、自定义异常处理器。
  • 异常操作要求要求在控制层处理异常,选择将dao层和service层的异常进行抛出。
  • 全局异常处理器是在处理器中对异常处理,不需要每个controller中的每个请求中进行trycatch操作。
  • 全局异常处理器经常搭配自定义异常处理器使用。

全局异常处理

  • 创建的类必须实现HandlerExceptionResolver 接口,表示当前类是异常处理器;
  • 将被创建的类交给spring容器管理;
  • 搭配自定义异常处理器一起使用。
package cn.ry.exception;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
@Component
public class GlobalException implements HandlerExceptionResolver{
/**
* Exception: 异常对象:指的是当前抛出的异常;
* handler:指:当前执行的请求对象;
* 返回值: 要求返回的是modelandview;返回的是视图;
*/
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler,
Exception ex) {
// TODO Auto-generated method stub
//返回结果视图:
ModelAndView mv = new ModelAndView();
//跳转到异常页面;
mv.setViewName("forward:/error.jsp");
//返回异常信息;
//如果是空指针异常就返回5001状态码,异常信息定义为"空指针异常";
if(ex instanceof NumberFormatException) {
mv.addObject("code", "5001");
mv.addObject("message", "数值类型异常");
}
if(ex instanceof CustomerException) {
//将当前的ex转换成自定义异常对象,从而调用自定义异常中的信息:
CustomerException ce = (CustomerException)ex;
mv.addObject("code", ce.getCode());
mv.addObject("message", ce.getMessage());
mv.addObject("htmlMessage", ce.getHtmlMessage());
}
return mv;
}
}

 自定义异常

package cn.ry.exception;
/**
*
* <p>Title: CustomerException</p>
* <p>Description: 自定义异常类:</p>
* @author dzc
* @date 2024年6月20日
*/
public class CustomerException extends Exception{
//定义状态码:
private String code;
//定义异常信息:
private String message;
//定义页面信息:
private String htmlMessage;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getHtmlMessage() {
return htmlMessage;
}
public void setHtmlMessage(String htmlMessage) {
this.htmlMessage = htmlMessage;
}
使用:
过滤器
//无参构造:
public CustomerException() {
}
public CustomerException(String code, String message) {
super();
this.code = code;
this.message = message;
}
public CustomerException(String code, String message, String
htmlMessage) {
super();
this.code = code;
this.message = message;
this.htmlMessage = htmlMessage;
}
}

使用

//异常使用:
@GetMapping("/ceshi")
public String ceshi(String id) throws Exception {
Integer id1 =Integer.valueOf(id);
System.out.println(id1+2);
int i = service.deleteU();
if(i!=1) throw new CustomerException("5002","➗错了");
if(i==1) throw new CustomerException("5003","正确操作");
return "";
}

 过滤器配置

<!-- 过滤器过滤编码 设置编码 解决请求信息和响应信息中文乱码-->
<filter>
<filter-name>filter01</filter-name>
<!-- spring-web包中的; -->
<filterclass>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
MAVEN
概念
Apache Maven 是一个软件项目管理和理解工具。基于项目对象模型的概念 (POM),Maven 可以从
中心信息中管理项目的构建、报告和文档 。maven就是构建工具。最直接接触到的是代替之前下载lib
导入的功能,以及打包的操作。
下载和配置
https://archive.apache.org/dist/maven/
下载后进行解压,解压以后,conf目录如下,
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>filter01</filter-name>
<!-- 表示对所有资源都过滤 -->
<url-pattern>/*</url-pattern>
</filter-mapping>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值