Sprintboot的拦截器提供了精细的控制:在request被响应之前、request被响应之后、request全部结束之后至视图渲染之前 三个时间点,我们都可以通过编写他们的函数来控制。
首先新建一个拦截器passportInterpretor,这个拦截器类必须实现HandlerInterceptor接口,并重写三个成员函数。
然后注册拦截器。
下面举例,我在拦截器中做的事情是,从请求中拿到我想要的ticket,判断是否合法(过期、废弃等),如果合法就在视图中添加一个线程本地变量user,否则不做任何改变(放行请求),用于登录状态的页面显示。
package com.example.market1.Interceptor; import com.example.market1.DAO.TicketUserDAO; import com.example.market1.DAO.UserDAO; import com.example.market1.Model.HostHolder; import com.example.market1.Model.TicketLogin; import com.example.market1.Model.User; import com.example.market1.Utils.MarketUtils; import com.example.market1.Utils.MyTools; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Date; @Component public class PassportInterceptor implements HandlerInterceptor { @Autowired private UserDAO userDAO; @Autowired private TicketUserDAO ticketUserDAO; @Autowired private HostHolder hostHolder; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String ticket = MarketUtils.getTicketFromRequst(request); if(ticket != null){ TicketLogin ticketLogin = ticketUserDAO.getTicketLogin(ticket); if(ticketLogin == null || ticketLogin.getExpired().before(new Date()) || ticketLogin.getStatus() == 1){ return true; } User user = userDAO.getUserById(ticketLogin.getUserid()); MyTools.log("User got by ticket:" + user.getMail()); hostHolder.setUser(user); } return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { if(modelAndView != null && hostHolder.getUser() != null){ modelAndView.addObject("user", hostHolder.getUser()); } } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { hostHolder.clear(); } }
然后新建一个注册拦截器的配置类:
(这里有一点需要注意,新版本的springboot中该类需要实现的接口是WebMvcConfigurer,
旧版本要实现的接口是WebMvcConfigurerAdapter 并且此时registry.addInterceptor之后要super.addInterceptor(registry)。)
package com.example.market1.Configuration; import com.example.market1.Interceptor.PassportInterceptor; 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.WebMvcConfigurer; @Component public class MarketWebConfiguration implements WebMvcConfigurer { @Autowired PassportInterceptor passportInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(passportInterceptor); } }