利用spring 拦截器批量解决多个请求共有的业务: 以低耦合度完成多个问题
目标当登录状态不同时页面的显示不同:
登录与否,头部有区别
使得每个静态页面都含有登录信息
拦截器示例:
定义拦截器: HandlerInterceptor
新建controller
package com.nowcoder.community.Controller.inteceptor;
import org.mybatis.logging.LoggerFactory;
import org.slf4j.Logger;
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 AlphaInterceptor implements HandlerInterceptor {
private static final Logger logger= (Logger) LoggerFactory.getLogger(AlphaInterceptor.class);
//在controller之前执行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handle) throws Exception{
logger.debug("preHandle"+handle.toString());
return true;
}
//在controller 之后
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView) throws Exception{
logger.debug("preHandle"+handle.toString());
}
//在templteengine 之后执行
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle,Exception ex)throws Exception{
logger.debug("preHandle"+handle.toString());
}
}
对其进行配置类
需要实现WebMvcConfigurer 接口
新建配置类WebMvcConfigurer
注入
@Autowired
private AlphaInterceptor alphaInterceptor;
public voidaddInterceptors(InterceptorRegistry registry){
registry.addInterceptor(alphaInterceptor).excludePathPatterns("")
这个方法spring 在实现时会将对象registry 传进来然后用registry 去注册interceptor 拦截器
registry.addInterceptor(alphaInterceptor) ; 指这个拦截器会拦截一切请求
所以用.exclude — 去去除一些.add 加入想要拦截的
1 静态资源的访问排除掉
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(alphaInterceptor)
.excludePathPatterns("/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg", "/**/*.jpeg")
.addPathPatterns("/register", "/login");
}
拦截器应用
1 在请求开始时 查询登录用户
2.在本次请求中持有用户数据
- 在模板视图上显示用户数据
- 在请求结束时清理用户数据
逻辑如下:
浏览器 服务器之间
用户已经登录: 浏览器里有cookie (登录的ticket)此时浏览器向服务器发送cookie (里面有ticket 凭证)。
服务器通过凭证的到当前用户是谁 :(从login——ticket 表中获得user )
最终将信息应用到模板上
模版像浏览器响应生成html
加入 loginTicketInterceptor类
@Component 注解
实现接口HandlerInterceptor
请求的一开始获取ticket 因为在请求的过程中需要获取用户
所以先通过cookie 获得ticket ;考虑到可能会复用我们封装一个工具类: CookietUtil包
public class CookietUtil {
public static String getValue(HttpServletRequest request,String name){
if (request==null||name==null) {
throw new IllegalArgumentException("参数为空");}
Cookie[] cookies=request.getCookies();
if (cookies!=null){
for (Cookie cookie:cookies){
if (cookie.getName().equals(name)){
return cookie.getValue();
}
}
}
return null;
}
}
在userservice 层 写入 通过ticket 获取loging ticket 的方法
public LoginTicket findLoginTicket(String ticket){
return loginTicketMapper.selectByTicket(ticket);
}
写如util
package com.nowcoder.community.util;
import com.nowcoder.community.entity.User;
import org.springframework.stereotype.Component;
@Component
public class HostHolder
{
/**
持用用户信息 用于替代session 对象*/
private ThreadLocal <User> users= new ThreadLocal<>();
public void setUsers (User user){
users.set(user);
}
public User getUser(){
return users.get();
}
public void clear(){
users.remove();
}
}
package com.nowcoder.community.Controller.inteceptor;