Springboot之拦截器Interceptor
1、Interceptor定义
Interceptor类似于Servlet中的过滤器,但是Interceptor是Spring boot所带的,它主要用于拦截用户请求并做出相应的处理。例如通过拦截器可以进行登录校正。
首先当用户登录成功时,需要生成令牌,并分发令牌。代码如下:
package yuyanan.controller;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import yuyanan.pojo.Emp;
import yuyanan.pojo.Result;
import yuyanan.service.EmpService;
import yuyanan.utils.JwtUtils;import java.util.HashMap;
import java.util.Map;@Slf4j
@RestController
public class LoginController {@Autowiredprivate EmpService empService;@PostMapping("/login")public Result login(@RequestBody Emp emp){log.info("员工登录:{}", emp);Emp e = empService.login(emp);//登录成功,生成令牌,下发令牌if (e != null){Map<String, Object> claims = new HashMap<>();claims.put("id", e.getId());claims.put("name", e.getName());claims.put("username", e.getUsername());String jwt = JwtUtils.generateJwt(claims); //jwt包含了当前登录的员工信息return Result.success(jwt);}//登录失败,返回错误信息return Result.error("用户名或者密码错误");}
}
在设置拦截器时需要注意,拦截器LoginCheckInterceptor需要实现HandlerInterceptor接口,并在preHandle方法中编写相应的代码,若该方法返回true,则放行;否则不放行。相应代码如下:
package yuyanan.Interceptor;import com.alibaba.fastjson.JSONObject;
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 yuyanan.pojo.Result;
import yuyanan.utils.JwtUtils;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@Slf4j
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {@Override //目标资源方法运行前运行,返回true,放行;返回false,拦截public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {//1、获取请求urlString url = req.getRequestURL().toString();log.info("请求的url:{}", url);//2、判断请求url中是否包含login,如果包含,说明是登录操作,放行if (url.contains("login")){log.info("登录操作,放行...");return true;}//3、获取请求头中的令牌(token)String jwt = req.getHeader("token");//4、判断令牌是否存在,如果不存在,返回错误结果(未登录)if(!StringUtils.hasLength(jwt)){log.info("请求头token为空,返回未登录的信息");Result error = Result.error("NOT_LOGIN");//手动转换 对象--json ---------》阿里巴巴的fastJsonString jsonString = JSONObject.toJSONString(error);resp.getWriter().write(jsonString);return false;}//5、解析token,如果解析失败,返回错误结果(未登录)try {JwtUtils.parseJWT(jwt);}catch (Exception e){ //jwt令牌解析失败e.printStackTrace();log.info("请求头token为空,返回未登录的信息");Result error = Result.error("NOT_LOGIN");//手动转换 对象--json ---------》阿里巴巴的fastJsonString jsonString = JSONObject.toJSONString(error);resp.getWriter().write(jsonString);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...");}
}
由于需要将该类放入到容器中进行管理,因此在上面添加@Component注解。紧接着还需要添加一个配置类WebConfig,该配置类实现WebMvcConfigurer接口,并重写添加拦截器addInterceptors方法,在该方法中指出我们要添加的拦截器名字以及作用范围。代码如下:
package yuyanan.config;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;
import yuyanan.Interceptor.LoginCheckInterceptor;@Configuration //代表当前类是一个配置类
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate LoginCheckInterceptor loginCheckInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**");}
}
值得注意的是该类是一个配置类,因此在类上面添加@Configuration注解。
总结:
1、编写自己的拦截器类LoginCheckInterceptor并实现HandlerInterceptor接口,给该类添加注解@Component将其注入到容器中,重写preHandle方法。
2、编写配置类WebConfig并实现WebMvcConfigurer接口,添加@Configuration注解表明该类是一个配置类,在该类中重写addInterceptors方法,并将我们自己编写的拦截器类加入即可。