一、要使用拦截器获取请求信息和返回信息,而不是使用切面。
1、使用拦截器一开始使用的是spring的HandlerIntercepter。但是使用这个无法获取到response和request请求体内容。因为两者通过流来读取,而只能读取一次。因为要Controller读取。所以获取不到。
代码如下:
1、Config
package com.sinosoft.app.platform.interceptor.config;
import com.sinosoft.app.platform.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Bean;
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 LoginLogInterceptorConfig implements WebMvcConfigurer {
/**
* 为了让拦截器添加到spring容器中
* @return
*/
@Bean
public LoginInterceptor loginInterceptor(){
return new LoginInterceptor();
}
//添加自定义拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
// registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/sys/auth/login/app");
registry.addInterceptor(loginInterceptor()).addPathPatterns("/sys/auth/login/app1");
}
}
2、Intercepter
package com.sinosoft.app.platform.interceptor;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sinosoft.app.base.activemq.util.ActivemqUtil;
import com.sinosoft.app.platform.interceptor.entity.CustTerminalInfo;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource;
import javax.jms.Queue;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//@Component
public class LoginInterceptor implements HandlerInterceptor {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(LoginInterceptor.class);
// //注入存放消息的队列
// @Resource
// private Queue queue;
// //注入springboot封装的工具类
// @Resource
// private JmsMessagingTemplate jmsMessagingTemplate;
@Override
public void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
String type = request.getHeader("x-ss-from");
//财富端或企业端登录
if (!StringUtils.isEmpty(type)){
//获取设备型号
String deviceInfor = request.getHeader("deviceInfor");
if (!StringUtils.isEmpty(deviceInfor)){
CustTerminalInfo custTerminalInfo = JSONObject.parseObject(deviceInfor, CustTerminalInfo.class);
custTerminalInfo.setType(type);
//发送消息给business存入设备型号
ActivemqUtil.sender("terminal_info_",JSON.toJSONString(custTerminalInfo));
// jmsMessagingTemplate.convertAndSend(queue, custTerminalInfo);
}
}
}
}
2、再次使用的是Spring的ResponseBodyAdvice。该方法可以完美的获取到想要的信息。需要注意的是获取到的params都是自动带着个 [] 。
代码:
package com.sinosoft.app.platform.interceptor;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sinosoft.app.base.activemq.util.ActivemqUtil;
import com.sinosoft.app.base.utils.Result;
import com.sinosoft.app.base.utils.TokenUser;
import com.sinosoft.app.base.utils.WebUtil;
import com.sinosoft.app.base.vo.ReturnInfoVo;
import com.sinosoft.app.platform.interceptor.LoginInterceptor;
import com.sinosoft.app.platform.interceptor.entity.CustTerminalInfo;
import com.sinosoft.app.platform.interceptor.entity.LoginLog;
import net.sf.json.JSONString;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Parameter;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @author JYJ
* @since 2021-6-18 16:09:59
* @apiNote 落库设备信息和登录日志
*/
@ControllerAdvice
public class LoginResponseBodyAdvice implements ResponseBodyAdvice {
private static final org.slf4j.Logger log = LoggerFactory.getLogger(LoginInterceptor.class);
/**
* 参数返回给前端之前进行,可以进行相关的处理例如,记录请求参数,响应参数,封装统一响应参数等操作
*/
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType,
MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request,
ServerHttpResponse response) {
try {
if(request.getURI().toASCIIString().indexOf("/login/app")>0){
//获取到返回内容
String bodyStr = JSON.toJSONString(body);
ReturnInfoVo result = JSONObject.parseObject(bodyStr, ReturnInfoVo.class);
if (result.isSuccess()){
//获取到请求头
HttpHeaders headers = request.getHeaders();
String type = String.valueOf(headers.get("x-ss-from"));
//财富端或企业端登录
if (!StringUtils.isEmpty(type)){
type = type.replace("[","");
type = type.replace("]","");
//获取设备型号
String deviceInfor = String.valueOf(headers.get("deviceInfor"));
if (!StringUtils.isEmpty(deviceInfor)){
// String jsonString = JSON.toJSONString(deviceInfor);
deviceInfor = deviceInfor.replace("[","");
deviceInfor = deviceInfor.replace("]","");
CustTerminalInfo custTerminalInfo = JSONObject.parseObject(deviceInfor,CustTerminalInfo.class);
// CustTerminalInfo custTerminalInfo = custTerminalInfos.get(0);
custTerminalInfo.setType(type);
String userCode = String.valueOf(result.getResult());
custTerminalInfo.setCustCode(userCode);
//发送消息给business存入设备型号
ActivemqUtil.sender("user_terminal_info_",JSON.toJSONString(custTerminalInfo));
//发送登录日志
//只有企业端和财富端进行落库
if ("1".equals(type)||"2".equals(type)) {
LoginLog loginLog = new LoginLog();
loginLog.setUserType(type);
loginLog.setUserCode(userCode);
loginLog.setOperateDate(new Date());
loginLog.setTerminalInfo(deviceInfor);
// try {
// TokenUser user = WebUtil.getUser();
// log.info(JSON.toJSONString(user));
loginLog.setUserName(user.getUserName());
// }catch (Exception e){
// log.info("NULLLLLLL");
// }
//发送登录日志
ActivemqUtil.sender("user_login_log_", JSON.toJSONString(loginLog));
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return body;
}
/**
* 如果要beforeBodyWrite方法生效,必须返回true
* @param arg0
* @param arg1
* @return
*/
@Override
public boolean supports(MethodParameter arg0, Class arg1) {
return true;
}
/**
* 将inputStream里的数据读取出来并转换成字符串
*
* @param inputStream inputStream
* @return String
*/
private String inputStream2String(InputStream inputStream) {
StringBuilder sb = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
log.error(e.getMessage());
throw new RuntimeException(e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
log.error(e.getMessage());
}
}
}
return sb.toString();
}
}