SpringBoot引入了AOP和IOC概念,AOP(面向切面编程)和OOP(面向对象编程)差不多,在面向对象编程的过程中,我们很容易通过继承、多态来解决纵向扩展;但是对于横向的功能,比如事务、记录日志,面向对象的是无法解决的。所以AOP——面向切面编程其实是面向对象编程思想的一个补充。今天主题拦截器属于面向切面编程的具体实现,拦截器也有一个相似的兄弟过滤器(也是AOP的具体实现)。
过滤器Filter
Filter
对 用户请求 进行 预处理,接着将请求交给Servlet
进行 处理 并 生成响应,最后Filter
再对 服务器响应 进行 后处理。Filter
是可以复用的代码片段,常用来转换HTTP
请求、响应 和 头信息。Filter
不像Servlet
,它不能产生 响应,而是只 修改 对某一资源的 请求 或者 响应。拦截器Interceptor
类似 面向切面编程 中的 切面 和 通知,我们通过 动态代理 对一个
service()
方法添加 通知 进行功能增强。比如说在方法执行前进行 初始化处理,在方法执行后进行 后置处理。拦截器 的思想和AOP
类似,区别就是 拦截器 只能对Controller
的HTTP
请求进行拦截。
两者的区别
Filter 是基于 函数回调的,而 Interceptor 则是基于 Java反射 和 动态代理。
Filter 依赖于 Servlet 容器,而 Interceptor 不依赖于 Servlet 容器。
Filter 对几乎 所有的请求 起作用,而 Interceptor 只对 Controller 对请求起作用
以上是一些概念,毕竟就算你会配置,说不清楚也是没啥用的!!!
import com.alibaba.fastjson.JSONObject;
import com.xmjbq.officialwebsite.officialwebsite.mapper.OfwebVisitLogMapper;
import com.xmjbq.officialwebsite.officialwebsite.pojo.OfwebUser;
import com.xmjbq.officialwebsite.officialwebsite.pojo.OfwebVisitLog;
import com.xmjbq.officialwebsite.officialwebsite.util.Basejson;
import com.xmjbq.officialwebsite.officialwebsite.util.NetworkUtil;
import com.xmjbq.officialwebsite.officialwebsite.util.TextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Date;
@Component
public class LoginInterceptor implements HandlerInterceptor {
//请求日志标识
private static final String VisitLog = "_visit_log";
@Autowired
private OfwebVisitLogMapper ofwebVisitLogMapper ;
@Override
public @ResponseBody
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 获取请求的url
String url = request.getRequestURI();
//访问日志实体类
OfwebVisitLog ofwebVisitLog = new OfwebVisitLog();
ofwebVisitLog.setUrl(url);
ofwebVisitLog.setMenuName(url);
String ip = NetworkUtil.getIpAddress(request);
ofwebVisitLog.setUserIp(ip);
ofwebVisitLog.setUsername("用户");
ofwebVisitLog.setCreateTime(new Date());
//这里对不拦截请求进行处理
if (url.indexOf("/login/login") >= 0 || url.indexOf("/login/loginOut") >= 0 ){
ofwebVisitLog.setInformation("登录成功");
request.setAttribute(VisitLog,ofwebVisitLog);
return true;
}
// 判断session
HttpSession session = request.getSession();
// 从session中取出用户身份信息
OfwebUser user = (OfwebUser) session.getAttribute(TextUtils.XMJBQUSER);
if (user != null) {
ofwebVisitLog.setInformation("成功");
request.setAttribute(VisitLog,ofwebVisitLog);
return true;
}
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(JSONObject.toJSONString(Basejson.getNoLogin()));
response.getWriter().close();
ofwebVisitLog.setInformation("失败");
request.setAttribute(VisitLog,ofwebVisitLog);
return false;
}
/**
* 进入Handler方法之后,返回modelAndView之前执行
* 应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
/**
* 执行Handler完成执行此方法 应用场景:统一异常处理,统一日志处理
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
OfwebVisitLog ofwebVisitLog = (OfwebVisitLog) request.getAttribute(VisitLog);
ofwebVisitLogMapper.insertSelective(ofwebVisitLog);
}
}
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 LogInterceptorConfig implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
//配置拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor).addPathPatterns("/**");
}
}
第一段加了 @Autowired private OfwebVisitLogMapper ofwebVisitLogMapper ;
Mapper使用逆向工程生成,一些包装好的SQL方法