通过springboot中ResponseBodyAdvice接口拦截URL以及返回data的拦截

package com.huaN.listener;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import com.alibaba.fastjson.JSONObject;
import com.huaN.entity.OperateLog;
import com.huaN.mapper.QualityMapper;

@ControllerAdvice
public class HnLogAnalysis implements ResponseBodyAdvice{
	@Autowired
    private QualityMapper qualityMapper;
	   @Override
	    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
           //每次项目访问任何一个接口时都会被拦截到这来来
	        String requestPath = request.getURI().getPath();
	        String url = request.getURI().toString();
	       //获取指定访问接口的返回值
	        if(requestPath!=null){
				//通过RequestContextHolder获取request
	            HttpServletRequest httpServletRequest = 
	                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

	            HttpSession httpSession = httpServletRequest.getSession(true);
	            httpSession.setAttribute("body", body);
	           String body1 =  JSONObject.toJSON(body).toString();
	          //  requestPath = request.getQueryString() == null ? uri : (uri + "?" + request.getQueryString());
	            //System.out.println("请求URl::: "+url);
                //System.out.println("返回值JSON::: "+body);
               String usernum =  getTelnum(url);
                //System.out.println("使用user::: "+usernum);
                OperateLog log = new  OperateLog();
              String[] result =  body1.toString().split(",");
              try {
                  if(result.length>2) {
                	  JSONObject  json1 = JSONObject.parseObject(result[0]+"}");
                      log.setC_msg(json1.get("msg")!=null?json1.getString("msg"):"");
                      JSONObject  json2 = JSONObject.parseObject("{"+result[1]+"}");
                      log.setC_code(json2.get("code")!=null?json2.getString("code"):""); 
                      String a =    body1.toString().substring(body1.toString().indexOf(result[2]), body1.toString().length()) ;
                      String aplus = "{"+a;
                      log.setC_data(aplus);
                  }
                  
                  if(result.length==2) {
                	  JSONObject  json1 = JSONObject.parseObject(result[0]+"}");
                      log.setC_msg(json1.get("msg")!=null?json1.getString("msg"):"");
                      JSONObject  json2 = JSONObject.parseObject("{"+result[1]);
                      log.setC_code(json2.get("code")!=null?json2.getString("code"):""); 
                  }
			} catch (Exception e) {
				// TODO: handle exception
				log.setC_code("500");
				log.setC_msg("error");
			}
     
                log.setC_url(url);
                URI newurl =null ;
				try {
					newurl = new URI(url);
				} catch (URISyntaxException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
                log.setC_port(newurl.getPort()+"");
                log.setC_hostIp(newurl.getHost());
                log.setC_function(newurl.getPath());
                log.setC_user(usernum);
                if(!requestPath.contains("UrlList")) {
                	Integer i = qualityMapper.checkRepeatLog(log.getC_function());
                	if(i==0) {
                		 qualityMapper.insertOperateLog(log);
                	}
                	
                }
               
	            return body;
	        }
	        return body;
	    }

       //获取url中手机号(支持多个)
	   public String getTelnum(String sParam){

		   if(sParam.length()<=0)
		   return "";
		   Pattern pattern = Pattern.compile("(1|861)(3|5|8)\\d{9}$*");
		   Matcher matcher = pattern.matcher(sParam);
		   StringBuffer bf = new StringBuffer();
		   while (matcher.find()) {
		   bf.append(matcher.group()).append(",");
		   }
		   int len = bf.length();
		   if (len > 0) {
		   bf.deleteCharAt(len - 1);
		   }
		   return bf.toString();
		   }

	@Override
	public boolean supports(MethodParameter arg0, Class arg1) {
		// TODO Auto-generated method stub
		return true;
	}
	public static String getIP(String url) {
        //使用正则表达式过滤,
        String re = "((http|ftp|https)://)(([a-zA-Z0-9._-]+)|([0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}))(([a-zA-Z]{2,6})|(:[0-9]{1,4})?)";
        String str = "";
        // 编译正则表达式
        Pattern pattern = Pattern.compile(re);
        // 忽略大小写的写法
        // Pattern pat = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(url);
        //若url==http://127.0.0.1:9040或www.baidu.com的,正则表达式表示匹配
        if (matcher.matches()) {
            str = url;
        } else {
            String[] split2 = url.split(re);
            if (split2.length > 1) {
                String substring = url.substring(0, url.length() - split2[1].length());
                str = substring;
            } else {
                str = split2[0];
            }
        }
        return str;
    }

    private static URI getIP1(URI uri) {
        URI effectiveURI = null;
        try {
            effectiveURI = new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(), null, null, null);
        } catch (Throwable var4) {
            effectiveURI = null;
        }
        return effectiveURI;
    }

}

```java
在这里插入代码片

### 关于Spring Boot中Swagger切面不生效的解决方案 在Spring Boot项目中,如果发现Swagger相关的切面未正常执行,通常是因为某些配置或逻辑干扰了AOP机制的工作流程。以下是针对此问题的具体分析与解决方法: #### 1. AOP代理模式的影响 Spring默认支持两种代理模式:基于JDK动态代理和CGLIB代理。如果目标类没有实现任何接口,则会使用CGLIB代理;如果有接口则优先采用JDK动态代理[^1]。然而,Swagger的相关功能可能会依赖特定的请求路径或者注解来触发,而这些路径可能并未被正确纳入AOP代理范围。 为了确保AOP能够覆盖所有必要的组件,请确认以下设置: - **启用AspectJ模式**:可以通过`@EnableAspectJAutoProxy(proxyTargetClass=true)`显式指定强制使用CGLIB代理。 ```java @Configuration @EnableAspectJAutoProxy(proxyTargetClass = true) public class AspectConfig { } ``` #### 2. 排除Swagger相关路径 有时统一响应处理逻辑会对Swagger API文档生成造成影响。例如,通过实现`ResponseBodyAdvice`接口并结合`@RestControllerAdvice`注解的方式对返回值进行封装时,可能导致Swagger无法识别原始的数据结构[^4]。 因此,在自定义全局响应处理器中需特别注意排除Swagger相关路径,避免对其产生副作用。具体做法是在`beforeBodyWrite`方法内加入条件判断: ```java @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> converterType, ServerHttpRequest request, ServerHttpResponse response) { String path = request.getURI().getPath(); if (path.contains("/v3/api-docs") || path.contains("/swagger-ui")) { return body; } // 继续其他业务逻辑... return new ResponseData<>(body); } ``` 上述代码片段的作用在于跳过对于Swagger资源文件的操作,从而保留其原有的行为特性而不受额外包装层的影响。 #### 3. 检查过滤器链顺序 当存在多个拦截器或过滤器共同作用时,它们之间的调用次序也至关重要。假如某个自定义的安全认证或其他类型的前置检查提前终止了请求流转过程,那么后续涉及Swagger的部分自然也就得不到执行机会[^3]。 一种可行的办法是调整Filter注册时机以及赋予恰当的优先级数值,比如让跨域支持(CORS)始终处于最前端位置以便兼容外部访问需求的同时允许内部工具正常使用: ```java @Bean public FilterRegistrationBean<CorsFilter> corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); // 允许携带Cookie凭证 config.addAllowedOriginPattern("*"); // 支持任意来源站点发起连接尝试 config.setMaxAge(3600L); // 缓存预检结果有效期设为1小时 source.registerCorsConfiguration("/**", config); FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(); bean.setFilter(new CorsFilter(source)); bean.setOrder(Ordered.HIGHEST_PRECEDENCE); // 设置最高优先级 return bean; } ``` 另外还需留意是否存在重复声明相同名称/URL映射关系的情况,这同样容易引发冲突现象。 --- ### 总结 综上所述,要彻底解决Spring Boot环境下Swagger切面失效的问题可以从以下几个方面入手: 1. 明确选用合适的AOP代理策略; 2. 对特殊场景下的例外情况进行妥善处理(如绕开Swagger专属路由); 3. 合理规划整个应用内的各类中间件排列布局以减少不必要的相互制约情况发生。 希望以上建议能帮助您快速定位根源所在并顺利完成修复工作! ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值