当前位置: 首页 > wzjs >正文

营销型网站建设概述哈尔滨seo关键词优化

营销型网站建设概述,哈尔滨seo关键词优化,家装室内设计,tp框架做购物网站开发我的项目使用的是 SpringBoot 3。 要在 Spring Boot 3 项目中使用 AOP(面向切面编程)来打印接收和响应的参数,如 URL、参数、头部信息、请求体等,可以按照以下步骤操作: 步骤 1: 添加依赖 确保你的 pom.xml 文件中包…

我的项目使用的是 SpringBoot 3。
要在 Spring Boot 3 项目中使用 AOP(面向切面编程)来打印接收和响应的参数,如 URL、参数、头部信息、请求体等,可以按照以下步骤操作:

步骤 1: 添加依赖

确保你的 pom.xml 文件中包含 spring-boot-starter-aop 依赖。如果你创建的是一个标准的 Spring Boot 项目,这个依赖通常已经包含在内了。如果没有,请手动添加:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>

步骤 2: 创建切面类

创建一个新的类用于定义你的切面逻辑。例如,可以命名为 LoggingAspect.java

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import jakarta.servlet.http.HttpServletRequest;@Aspect
@Component
public class LoggingAspect {@Before("execution(* your.package.name.controller..*(..))")public void logRequest(JoinPoint joinPoint) {HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();// 打印URLSystem.out.println("URL : " + request.getRequestURL().toString());// 打印HTTP方法System.out.println("HTTP Method : " + request.getMethod());// 打印Header信息Enumeration<String> headerNames = request.getHeaderNames();while (headerNames.hasMoreElements()) {String headerName = headerNames.nextElement();System.out.println(headerName + " : " + request.getHeader(headerName));}// 打印请求参数System.out.println("Params : " + request.getQueryString());// 注意:直接从request对象获取body内容比较复杂,因为一旦读取就无法再次读取。// 对于需要读取body的情况,你可能需要使用HttpServletRequestWrapper或者Filter来实现。}@AfterReturning(pointcut = "execution(* your.package.name.controller..*(..))", returning = "result")public void logResponse(Object result) {System.out.println("Response Body : " + result);}
}

请注意,直接从 HttpServletRequest 中读取 body 内容可能会遇到挑战,因为一旦读取后,流将不可再次读取。对于需要访问 body 的场景,你可能需要使用 HttpServletRequestWrapper 或者 Filter 来缓存请求体,以便多次读取。

步骤 3: 配置类(如果需要)
对于某些高级需求,比如需要读取请求体,你可能还需要创建一个配置类或使用过滤器(Filter)来处理请求体的重复读取问题。

以上就是如何在 Spring Boot 3 项目中使用 AOP 打印接收和响应参数的基本步骤。根据实际需要调整包名和类名,并考虑是否需要处理请求体的特殊情形。


没了吗?
别急, 继续挑战 body 输出。接来下要做改造了。


为了在 Spring Boot 应用中使用 AOP 记录请求体(body),同时避免由于 InputStream 只能被读取一次而导致的问题,你可以通过创建一个自定义的 HttpServletRequestWrapper 来缓存请求体。这样,在你的切面逻辑中就可以多次访问请求体了。下面是一个具体的实现示例:

步骤 1: 创建 CachedBodyHttpServletRequest 类

首先,创建一个类继承 HttpServletRequestWrapper,用于缓存请求体。

import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;/*** 自定义 HttpServletRequestWrapper 来缓存请求体。*/
public class CachedBodyHttpServletRequest extends HttpServletRequestWrapper {private byte[] cachedBody;/*** 构造函数,读取并缓存原始请求体。*/public CachedBodyHttpServletRequest(HttpServletRequest request) throws IOException {super(request);InputStream requestInputStream = request.getInputStream();this.cachedBody = requestInputStream.readAllBytes();}/*** 获取缓存的请求体。*/public byte[] getCachedBody() {return cachedBody;}@Overridepublic BufferedReader getReader() {return new BufferedReader(new InputStreamReader(this.getInputStream()));}@Overridepublic ServletInputStream getInputStream() {return new CachedBodyServletInputStream(this.cachedBody);}
}

步骤 2: 创建 CachedBodyServletInputStream 类

然后,创建一个类来包装原始的 ServletInputStream,以便提供缓存的请求体数据。


import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;/*** 自定义 ServletInputStream 来包装缓存的请求体。*/
public class CachedBodyServletInputStream extends ServletInputStream {private final ByteArrayInputStream cachedBodyInputStream;/*** 使用缓存的请求体构造实例。*/public CachedBodyServletInputStream(byte[] cachedBody) {this.cachedBodyInputStream = new ByteArrayInputStream(cachedBody);}@Overridepublic boolean isFinished() {return this.cachedBodyInputStream.available() == 0;}@Overridepublic boolean isReady() {return true;}@Overridepublic void setReadListener(ReadListener listener) {throw new UnsupportedOperationException();}@Overridepublic int read() throws IOException {return this.cachedBodyInputStream.read();}
}

步骤 3: 创建并注册 Filter

接下来,创建一个过滤器来替换原始请求为你的 CachedBodyHttpServletRequest 实例。


import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;import java.io.IOException;/*** 过滤器用于将原始请求替换为自定义的 CachedBodyHttpServletRequest。*/
@Component
public class CachingRequestBodyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {HttpServletRequest httpRequest = (HttpServletRequest) request;CachedBodyHttpServletRequest cachedBodyRequest = new CachedBodyHttpServletRequest(httpRequest);chain.doFilter(cachedBodyRequest, response);}@Overridepublic void destroy() {}
}

注意:确保你在 Spring Boot 配置中注册这个过滤器,例如通过添加 @Component 注解或者在配置类中进行注册。

步骤 4: 修改 LoggingAspect 类

最后,修改你的 LoggingAspect 类以利用缓存请求体的功能:


import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import jakarta.servlet.http.HttpServletRequest;import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;/*** 使用 AOP 记录请求的 URL、参数、头部信息以及 body 内容。*/
@Aspect
@Component
@Slf4j
public class LoggingAspect {@Before("execution(* com.tylerzhong.web.controller..*(..))")public void logRequest(JoinPoint joinPoint) throws Exception {log.info("=======================请求数据start=======================");// 获取当前请求属性ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();if (attributes != null) {// 从请求属性中获取 HttpServletRequestHttpServletRequest request = attributes.getRequest();if (request instanceof CachedBodyHttpServletRequest) {CachedBodyHttpServletRequest cachedBodyRequest = (CachedBodyHttpServletRequest) request;// 打印URLlog.info("请求地址:{}", request.getRequestURL().toString());// 打印HTTP方法log.info("请求方式:{}", request.getMethod());// 打印Header信息var headerNames = request.getHeaderNames();log.info("请求头:");while (headerNames.hasMoreElements()) {String headerName = headerNames.nextElement();System.out.println(headerName + ":" + request.getHeader(headerName));}// 打印请求参数String queryString = request.getQueryString();// 此处进行解码处理String decodedQueryString = URLDecoder.decode(queryString, StandardCharsets.UTF_8);log.info("请求参数:{}", decodedQueryString);// 获取请求体字节数组byte[] requestBodyBytes = cachedBodyRequest.getCachedBody();String rawRequestBody = new String(requestBodyBytes, StandardCharsets.UTF_8);log.info("请求体:{}", rawRequestBody);log.info("=======================请求数据end=======================");}}}@AfterReturning(pointcut = "execution(* com.tylerzhong.web.controller..*(..))", returning = "result")public void logResponse(Object result) {log.info("-----------------------响应数据start-----------------------");log.info("响应体:{}", result);log.info("-----------------------响应数据end-----------------------");}
}

代码中的下面这段代码进行解码打印是因为请求参数在传输过程中被进行了 URL 编码(也称为百分号编码)。URL 编码是一种用于将字符转换为可以在 URL 中安全传输的格式的编码方式。例如,中文字符“姓名”和“年龄”会被编码为 %E5%A7%93%E5%90%8D 和 %E5%B9%B4%E9%BE%84。
如果你希望打印出原始的、未经过 URL 编码的请求参数,你需要对这些参数进行解码。Java 提供了 java.net.URLDecoder 类来帮助你完成这个任务。

String queryString = request.getQueryString();
// 此处进行解码处理
String decodedQueryString = URLDecoder.decode(queryString, StandardCharsets.UTF_8);

到上面为止,基本可以说完成了AOP切面打印日志的所有内容。
但是我的项目中会上传大量的文件,并且是通过二进制流传递的,所以打印出来的都是二进制数据,输出到控制台会很长,所以我这里需要对它进行 base64 编码输出,但是如果传的 json 数据,我需要输出原始数据,即不进行编码。所以我就想了一个折中的办法,一般上传文件的话,字节数据大小都是几百KB,所以我就判断,如果字节数据的大于100KB就进行 base64 编码输出,小于 100KB 就输出原始数据。这样既可以节省空间,也简化了的输出内容。

所以再进行改造一下:


import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import jakarta.servlet.http.HttpServletRequest;import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;/*** 使用 AOP 记录请求的 URL、参数、头部信息以及 body 内容。*/
@Aspect
@Component
@Slf4j
public class LoggingAspect {private static final int MAX_RAW_BODY_SIZE = 102400; // 100KB@Before("execution(* com.tylerzhong.web.controller..*(..))")public void logRequest(JoinPoint joinPoint) throws Exception {log.info("=======================请求数据start=======================");// 获取当前请求属性ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();if (attributes != null) {// 从请求属性中获取 HttpServletRequestHttpServletRequest request = attributes.getRequest();if (request instanceof CachedBodyHttpServletRequest) {CachedBodyHttpServletRequest cachedBodyRequest = (CachedBodyHttpServletRequest) request;// 打印URLlog.info("请求地址:{}", request.getRequestURL().toString());// 打印HTTP方法log.info("请求方式:{}", request.getMethod());// 打印Header信息var headerNames = request.getHeaderNames();log.info("请求头:");while (headerNames.hasMoreElements()) {String headerName = headerNames.nextElement();System.out.println(headerName + ":" + request.getHeader(headerName));}// 打印请求参数String queryString = request.getQueryString();String decodedQueryString = URLDecoder.decode(queryString, StandardCharsets.UTF_8);log.info("请求参数:{}", decodedQueryString);// 获取请求体字节数组byte[] requestBodyBytes = cachedBodyRequest.getCachedBody();if (requestBodyBytes.length > MAX_RAW_BODY_SIZE) {// 如果字节数组长度超过阈值,进行Base64编码并打印String base64EncodedRequestBody = Base64.getEncoder().encodeToString(requestBodyBytes);log.info("请求体:{}", base64EncodedRequestBody);} else {// 否则直接打印原始内容String rawRequestBody = new String(requestBodyBytes, StandardCharsets.UTF_8);log.info("请求体:{}", rawRequestBody);}log.info("=======================请求数据end=======================");}}}@AfterReturning(pointcut = "execution(* com.tylerzhong.web.controller..*(..))", returning = "result")public void logResponse(Object result) {log.info("-----------------------响应数据start-----------------------");log.info("响应体:{}", result);log.info("-----------------------响应数据end-----------------------");}
}

请确保替换 com.tylerzhong.web 和 com.tylerzhong.web.controller 为你实际的应用包名和控制器所在的包路径。

以上代码段提供了一个完整的解决方案,用于在 Spring Boot 3 应用中使用 AOP 来记录请求的详细信息,包括 URL、参数、头部信息以及 body 内容。注意,这里假设你已经在项目中正确配置了 Spring AOP 相关依赖,并且你的应用是基于 Spring Boot 构建的。

http://www.dtcms.com/wzjs/316135.html

相关文章:

  • 武汉本地最大的社区网站市场营销策划书范文5篇精选
  • 厦门律师网站建设seo关键词快速排名
  • 汕头制作网站推荐怎样能在百度上搜索到自己的店铺
  • 英文设计网站徐州做网站的公司
  • 做彩妆发哪个网站浏览量高成都网站建设方案服务
  • wordpress登录微信插件下载海洋seo
  • 杭州做网站seo百度云盘登录入口
  • 网页设计在大学属于什么专业seo点击排名工具有用吗
  • 重庆金融公司网站建设中国seo谁最厉害
  • 石家庄住房和城乡建设局网站网络营销的五大优势
  • web网站开发工作经验互联网创业项目
  • 找网站有中文字目的免费私人网站建设软件
  • 郑州做网站好的公司百度竞价排名背后的伦理问题
  • app开发人员网站北京网站优化步骤
  • 做销售网站公司做网站推广
  • 购物网站的页面设计sem推广是什么意思呢
  • 网站开发相关期刊广告网络推广
  • 软路由系统如何做网站高级搜索百度
  • 河北住房与城乡建设部网站企业快速建站
  • 驻马店标准网站建设全网关键词指数查询
  • 东莞专业网站建设平台seo排名推广工具
  • 富阳区建设局网站首页海南网站制作公司
  • 领地网建的网站百度自然搜索排名优化
  • 淄博网站建设费用报个电脑培训班要多少钱
  • 外贸营销网站网络搜索优化
  • 网站百度不到验证码怎么办啊互联网线上推广
  • 做试玩网站b2b平台免费推广网站
  • 顺义做网站个人网站设计毕业论文
  • 甘孜州住房城乡建设局网站推广员是干什么的
  • 广州品牌seo网站推广谷歌排名优化入门教程