过滤器(Filter):可以拿到原始的http请求,但是拿不到你请求的控制器和请求控制器中的方法的信息。
拦截器(Interceptor):可以拿到你请求的控制器和方法,却拿不到请求方法的参数。
切片 (Aspect): 可以拿到方法的参数,但是却拿不到http请求和响应的对象
使用AOP处理请求或记录日志
- AOP面向切面 _编程范式(程序设计思想)
- 分离通用逻辑
1.引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.具体切面代码
/**
* 日志写入管理
* zjy
*/
@Aspect
@Component
public class ControllerAspect {
private final static Logger logger = LoggerFactory.getLogger(ControllerAspect.class);
@Autowired
@Qualifier("logServiceImpl")
private LogService logService;
@Autowired
private UserService userService;
@Pointcut("execution(* com.honghe.managerTool.controller.CommandController.*(..)) "
+ "|| execution(* com.honghe.managerTool.controller.UserController.*(..)) ")
public void aspect() {//拦截所有类下所有方法
}
//配置前置通知,使用在方法aspect()上注册的切入点
@Before("aspect()")
public void before(JoinPoint joinPoint) {
String[] paramNames = ((CodeSignature) joinPoint
.getSignature()).getParameterNames();
Object[] paramValues = joinPoint.getArgs();
String userIp = "127.0.0.1";
String oprationName = joinPoint.getSignature().getName();
switch (oprationName){
case "start":
oprationName=Operation.START.value;
break;
case "stop":
oprationName=Operation.STOP.value;
break;
case "restart":
oprationName=Operation.RESTART.value;
break;
default:
return;
}
if(paramValues.length>0){
if(paramValues[0] instanceof HttpServletRequest){
HttpServletRequest request = (HttpServletRequest)paramValues[0];
userIp = ParamUtil.getIpAddress(request);
}
}
Log log = new Log(oprationName,new Date(),userIp,1);
logService.saveLog(log);
}
//配置后置通知,使用在方法aspect()上注册的切入点
@After("aspect()")
public void after(JoinPoint joinPoint){
logger.info("after out successfully");
}
}
对http请求解析
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
/**
* @author: zhaojianyu
* @create: 2018-10-11 09:11
**/
@Aspect
@Component
public class HttpAspect {
private final static Logger logger = LoggerFactory.getLogger(HttpAspect.class);
/**
* 拦截所有类下所有方法
*/
@Pointcut("execution(* com.zjy.blog.blog_start.controller.HelloContraller.*(..)) ")
public void aspect() {
}
/**
* 配置前置通知,使用在方法aspect()上注册的切入点
*/
@Before("aspect()")
public void before(JoinPoint joinPoint) {
logger.info("方法开始执行"+new Date());
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//url
logger.info("url={}",request.getRequestURL());
logger.info("uri={}",request.getRequestURI());
//请求方法
logger.info("method={}",request.getMethod());
//请求ip地址
logger.info("ip={}",request.getRemoteAddr());
//类名 类方法
logger.info("class_method={}",joinPoint.getSignature().getDeclaringTypeName()+"="+joinPoint.getSignature().getName());
//参数
logger.info("args={}",joinPoint.getArgs());
}
@After("aspect()")
public void after() {
logger.info("方法执行完毕1"+new Date());
}
@AfterReturning(returning = "object",pointcut = "aspect()")
public void afterReturning(Object object) {
logger.info("方法执行完毕2"+new Date() + object);
}
}
filter处理
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;
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 javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import com.alibaba.fastjson.JSONObject;
import com.tinet.sqc.web.UserContext;
import com.tinet.sqc.web.controller.model.LoginEntity;
@WebFilter(urlPatterns = { "/api/*" })
public class LoginFilter implements Filter {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Value("${access.allow.origin}")
private String accessAllowOrigin;
private Set<String> excludeUrls = new HashSet<>();
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
HttpSession session = request.getSession(false);
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
if (accessAllowOrigin != null) {
response.addHeader("Access-Control-Allow-Origin", this.getProtocol(request) + accessAllowOrigin);
} else {
response.addHeader("Access-Control-Allow-Origin", "*");
}
response.addHeader("Access-Control-Allow-Credentials", "true");
response.addHeader("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept,X-Pagination");
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.addHeader("Access-Control-Expose-Headers", "X-Pagination");
// 解决跨域情况下 浏览器请求OPTIONS方法失败的问题
if (request.getMethod().equals("OPTIONS")) {
return;
}
if (isInclude(request.getServletPath())) {
if (session != null) {
LoginEntity loginEntity = (LoginEntity) session.getAttribute(UserContext.LOGINENTITY);
if (loginEntity != null) {
UserContext.set(loginEntity);
chain.doFilter(request, response);
return;
}
}
unLogin(response);
} else {
chain.doFilter(request, response);
}
}
/**
* 判断url是否需要身份认证
*
* @param servletPath
* @return
*/
private boolean isInclude(String servletPath) {
if (excludeUrls.contains(servletPath)) {
return false;
}
return true;
}
/**
* 用于提示用户未登录
*
* @param response
*/
private void unLogin(HttpServletResponse response) {
PrintWriter out = null;
try {
out = response.getWriter();
response.setContentType("application/json");
JSONObject result = new JSONObject();
result.put("status", 401);
result.put("error", "用户未登录");
out.print(result.toJSONString());
} catch (IOException e) {
logger.error("Filter异常!", e);
} finally {
if (out != null) {
out.close();
}
}
}
//添加不拦截的url
@Override
public void init(FilterConfig arg0) throws ServletException {
excludeUrls.add("/api/login");
excludeUrls.add("/api/logout");
}
@Override
public void destroy() {
}
/**
* 根据HttpServletRequest获取请求协议
*
* @param request
* @return http:// 或 https://
*/
private String getProtocol(HttpServletRequest request) {
String protocol = request.getHeader("X-Forwarded-Proto");
if (protocol == null || protocol.length() == 0 || "unknown".equalsIgnoreCase(protocol)) {
protocol = "http";
}
return protocol + "://";
}
}
https://blog.csdn.net/weixin_38704338/article/details/81285377
https://www.cnblogs.com/bingshu/p/7819932.html
https://www.imooc.com/video/16794