使用拦截器获取请求信息和返回信息

一、要使用拦截器获取请求信息和返回信息,而不是使用切面。
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();
    }
}

 

你可能感兴趣的:(使用拦截器获取请求信息和返回信息)