springboot的兩種實現攔截器的方法
阿新 • • 發佈:2018-12-16
一、使用Interceptor攔截器
1.首先新建一個攔截器實現HandlerInterceptor介面
以一個簡單的token驗證為例,驗證通過,將使用者資訊放入作用域,返回true
不通過返回false
- @Service
- public class UserTokenInterceptor implements HandlerInterceptor {
- @Autowired
- private SysusertokenMapper sysusertokenMapper;
- @Autowired
- private SysloginuserMapper sysloginuserMapper;
- @Autowired
- private SysuserMapper sysuserMapper;
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
- throws Exception {
- // 在請求處理之前進行呼叫(Controller方法呼叫之前),返回true才會繼續往下執行,返回false取消當前請求
- boolean isAccess = false;
- String tokenCode = request.getHeader("Token"
); - if (tokenCode != null && !"".equals(tokenCode)) {
- //查詢未過期的
- Sysusertoken sysusertoken = sysusertokenMapper.selectByTokenCode(tokenCode);
- if (sysusertoken != null) {
- Sysloginuser sysloginuser = sysloginuserMapper.selectByPrimaryKey(sysusertoken.getLoginid());
- Sysuser sysuser = sysuserMapper.selectByPrimaryKey(sysloginuser.getUserid());
- request.getSession().setAttribute("user",sysuser);
- request.getSession().setAttribute("token",tokenCode);
- isAccess = true;
- }
- }
- return isAccess;
- }
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
- ModelAndView modelAndView) throws Exception {
- }
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
- throws Exception {
- }
- }
2.新建一個配置類來管理攔截器,將你之前新建的攔截器注入進來
addPathPatterns("/**")是攔截所有請求
excludePathPatterns("","",...)配置無需攔截的請求
- package com.gcexe.monitor.filter;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Component;
- import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
- import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
- @Component
- public class UserTokenAppConfigurer extends WebMvcConfigurationSupport{
- @Autowired
- private UserTokenInterceptor userTokenInterceptor;
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- // 多個攔截器組成一個攔截器鏈
- // addPathPatterns 用於新增攔截規則
- // excludePathPatterns 使用者排除攔截
- registry.addInterceptor(userTokenInterceptor).addPathPatterns("/**")
- .excludePathPatterns("/account/login","/account/register");
- super.addInterceptors(registry);
- }
- }
注意加上@Component註解,使其可以被掃描到
二、使用servlet的filter攔截器
新建一個類實現javax.servlet.Filter介面,通過@WebFilter註解來配置要攔截的請求,doFilter方法是要進行的操作。
- package com.gcexe.monitor.filter;
- import java.io.IOException;
- import java.util.Arrays;
- import javax.servlet.Filter;
- import javax.servlet.FilterChain;
- import javax.servlet.FilterConfig;
- import javax.servlet.ServletException;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- import javax.servlet.annotation.WebFilter;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Component;
- import com.gcexe.monitor.persistence.dao.SysloginuserMapper;
- import com.gcexe.monitor.persistence.dao.SysuserMapper;
- import com.gcexe.monitor.persistence.dao.SysusertokenMapper;
- import com.gcexe.monitor.persistence.entity.Sysloginuser;
- import com.gcexe.monitor.persistence.entity.Sysuser;
- import com.gcexe.monitor.persistence.entity.Sysusertoken;
- @Component
- @WebFilter(urlPatterns = "/**", filterName = "monitorFilter")
- public class TokenAuthorFilter implements Filter {
- @Autowired
- private SysusertokenMapper sysusertokenMapper;
- @Autowired
- private SysloginuserMapper sysloginuserMapper;
- @Autowired
- private SysuserMapper sysuserMapper;
- private static final String[] excludePathPatterns = { "/monitor/account/login", "/monitor/account/register" };
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- // TODO Auto-generated method stub
- }
- @Override
- public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
- throws IOException, ServletException {
- // 在請求處理之前進行呼叫(Controller方法呼叫之前),返回true才會繼續往下執行,返回false取消當前請求
- boolean isFilter = false;
- HttpServletRequest request = (HttpServletRequest) req;
- HttpServletResponse response = (HttpServletResponse) resp;
- // 不攔截登陸和註冊
- String url = request.getRequestURI();
- if (Arrays.asList(excludePathPatterns).contains(url)) {
- chain.doFilter(request, response);
- return;
- }
- String tokenCode = request.getHeader("Token");
- if (tokenCode != null && !"".equals(tokenCode)) {
- // 查詢未過期的
- Sysusertoken sysusertoken = sysusertokenMapper.selectByTokenCode(tokenCode);
- if (sysusertoken != null) {
- Sysloginuser sysloginuser = sysloginuserMapper.selectByPrimaryKey(sysusertoken.getLoginid());
- Sysuser sysuser = sysuserMapper.selectByPrimaryKey(sysloginuser.getUserid());
- request.getSession().setAttribute("user", sysuser);
- request.getSession().setAttribute("token", tokenCode);
- isFilter = true;
- }
- }
- if (isFilter) {
- chain.doFilter(request, response);
- }
- }
- @Override
- public void destroy() {
- // TODO Auto-generated method stub
- }
- }
執行chain.doFilter(request,response)方法類似於上面的返回true,讓程式繼續往下執行
可以自己配置返回內容,無需攔截的請求,我這裡是定義了一個數組,自行判斷,對應地址直接執行chain.doFilter(reuqest.response),同樣注意加上@Component註解
兩種方式均可以使用,相比較而言,第一種方式較為方便,我一開始也是使用的這種,但是後來需要整合Spring Boot Validator框架時,發現驗證資料一直不生效,後來發現是和Inteceptor有衝突,去掉攔截就可以驗證了,暫時還沒找到解決的辦法,所以改為使用第二種方法。