通过上文开发,系统已经能够进行初步的使用,但是需要进一步完善功能,
本篇介绍拦截器与过滤器还有关于异常的捕获的知识笔记
下面开始
过滤器Filter
-
入门程序
-
定义Filter类,实现Filter接口,并重写其所有方法
-
package com.testpeople.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; @WebFilter(urlPatterns = "/*")//拦截所有请求 public class demoFilter implements Filter { //初始化方法,调用一次 @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.printf("初始化方法被调用"); } //销毁方法,调用一次 @Override public void destroy() { Filter.super.destroy(); System.out.println("销毁方法被调用"); } //过滤方法,调用多次 @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.printf("拦截了请求"); filterChain.doFilter(servletRequest,servletResponse);//放行操作 } }
-
配置Filter类加上@WebFilter注解,配置拦截资源路径。引导类上加@ServeltComponentScan开启servlet组件支持。
- 效果
-
-
- 未拦截
-
详解
-
执行流程
-
放行后访问对应资源,资源访问完会回到过滤器中。
-
回到过滤器中,会执行放行后的逻辑。
-
-
拦截路径
-
- 过滤器链
-
登录校验
-
设计思路
-
-
开发
-
package com.testpeople.filter; import com.alibaba.fastjson.JSONObject; import com.testpeople.pojo.Result; import com.testpeople.utils.JwtUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.util.StringUtils; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Slf4j @WebFilter(urlPatterns = "/*") public class LoginFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { Filter.super.init(filterConfig); } @Override public void destroy() { Filter.super.destroy(); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //强制类型转换请求和响应、 HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; //1.获取请求url String url = request.getRequestURI(); log.info("请求的url:{}",url); //2.判断是否是登录操作 if (url.contains("login")){ log.info("此请求为登录,放行"); filterChain.doFilter(request,response); return; } //3.获取请求头中的token String twj = request.getHeader("token"); //4.判断令牌是否存在,若不存在,返回错误(未登录) if (!StringUtils.hasLength(twj)){ log.info("请求头中token为空,返回错误(未登录)"); Result error = Result.error("NOT_LOGIN"); //手动转换将对象转换成json————————阿里巴巴工具包fastjson String notLogin = JSONObject.toJSONString(error); response.getWriter().write(notLogin); return; } //5.解析令牌,若解析失败,返回错误(未登录) try { JwtUtils.parseJwt(twj); } catch (Exception e) {//解析失败 e.printStackTrace(); log.info("令牌解析失败,返回错误(未登录)"); Result error = Result.error("NOT_LOGIN"); //手动转换将对象转换成json————————阿里巴巴工具包fastjson String notLogin = JSONObject.toJSONString(error); response.getWriter().write(notLogin); return; } //6.放行 log.info("令牌合法,放行"); filterChain.doFilter(request,response); } }
-
测试
-
Postman
-
拦截器interceptor
-
简介
-
入门程序
-
定义拦截器,实现HandlerInterceptor接口,并重写其所有方法。(类)
-
注册拦截器(类)
-
//用于定义拦截器,实现拦截功能 package com.testpeople.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; @Component public class LoginCheckInterceptor implements HandlerInterceptor { @Override//目标方法资源运行前运行,返回值为true表示放行,false表示拦截 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle"); return true; } @Override//目标方法资源运行后运行 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle"); } @Override//视图渲染后运行,最后运行 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion"); } }
//用于注册拦截器,实现拦截的路径。 package com.testpeople.config; import com.testpeople.interceptor.LoginCheckInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration //配置类 public class WebConfig implements WebMvcConfigurer { @Autowired private LoginCheckInterceptor loginCheckInterceptor; @Override //注册拦截器 public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**"); } }
-
测试
-
不放行
-
-
-
放行
-
详解
-
拦截路径
-
@Override //注册拦截器
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
}
//addPathPatterns表示拦截什么,excludePatterns表示不拦截什么
//"/**"与"/*"的区别
-
执行流程
-
登录校验
-
思路
-
-
开发
-
package com.testpeople.interceptor; import com.alibaba.fastjson.JSONObject; import com.testpeople.pojo.Result; import com.testpeople.utils.JwtUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @Slf4j @Component public class LoginCheckInterceptor implements HandlerInterceptor { @Override//目标方法资源运行前运行,返回值为true表示放行,false表示拦截 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle"); //1.获取请求url String url = request.getRequestURI(); log.info("interceptor_请求的url:{}",url); //2.判断是否是登录操作 // 前面已经排除/login了 // if (url.contains("login")){ // log.info("interceptor_此请求为登录,放行"); // return true; // } //3.获取请求头中的token String twj = request.getHeader("token"); //4.判断令牌是否存在,若不存在,返回错误(未登录) if (!StringUtils.hasLength(twj)){ log.info("interceptor_请求头中token为空,返回错误(未登录)"); Result error = Result.error("NOT_LOGIN"); //手动转换将对象转换成json————————阿里巴巴工具包fastjson String notLogin = JSONObject.toJSONString(error); response.getWriter().write(notLogin); return false; } //5.解析令牌,若解析失败,返回错误(未登录) try { JwtUtils.parseJwt(twj); } catch (Exception e) {//解析失败 e.printStackTrace(); log.info("令牌解析失败,返回错误(未登录)"); Result error = Result.error("NOT_LOGIN"); //手动转换将对象转换成json————————阿里巴巴工具包fastjson String notLogin = JSONObject.toJSONString(error); response.getWriter().write(notLogin); return false; } //6.放行 log.info("令牌合法,放行"); return true; } @Override//目标方法资源运行后运行 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle"); } @Override//视图渲染后运行,最后运行 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion"); } }
-
测试
-
Postman
-
-
后端显示正常
-
登录功能没有被拦截,其他功能没有正确的token被拦截。
-
区别
异常处理
方案
-
在所有的Controller中加入try..catch(不推荐)
-
设置全局异常处理器(推荐)
-
package com.testpeople.exception; import com.testpeople.pojo.Result; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; /** * 全局异常处理类 */ @Slf4j @RestControllerAdvice public class GloablExceptionHandler { //捕获异常并返回 @ExceptionHandler(Exception.class)//捕获所有异常(类型) public Result handleException(Exception e) {//捕获异常 log.info("捕获异常:{}", e.getMessage()); e.printStackTrace();//堆栈信息 return Result.error("出现错误,请联系管理员"); } }
-
测试
拦截器和过滤器介绍完毕,也简单实现了异常的拦截
以上只是来自黑马程序员的课程,笔记为小编学习的笔记
项目地址