ChatGPT对话02
Q&A1
Q1:清理2023年,除了20230109目录外,保留近一个月的目录shell脚本
A1:以下是清理除20230109目录外,保留近一个月的目录的shell脚本:
1
2
3
4 复制代码#!/bin/bash
删除早于30天的目录
find /path/to/directory/* -type d ! -name "20230109" -ctime +30 -exec rm -rf {} \;将
/path/to/directory/
替换为要清理的目录的路径。这个脚本使用find
命令来查找除了名为20230109
的目录以外的所有目录,并删除它们,同时保留近30天内被修改过的目录。
学到了学到了,运维时就可以通过手动或定时任务清理一些不需要的文件了。
Q&A2
Q2:SpringBoot统一接口打印入参出参日志
A2:
在 Spring Boot 中,我们可以通过 AOP 实现统一打印接口的入参和出参日志。具体实现方式如下:
- 创建一个切面类 LogAspect,用来定义切点以及需要记录日志的方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
public class LogAspect {
private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
/**
* 定义切点,匹配所有controller包下面所有公共方法
*/
public void executionLog() {}
/**
* 通过环绕通知拦截请求参数与返回结果
* @param pjp 切点
*/
public Object around(ProceedingJoinPoint pjp) {
// 记录请求开始时间
long startTime = System.currentTimeMillis();
// 获取当前请求对象并记录请求参数
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
logRequestParams(request, pjp.getSignature().getName(), pjp.getArgs());
// 执行请求内容,并处理响应结果
Object result;
try {
result = pjp.proceed();
} catch (Throwable throwable) {
logger.error("error occurred while processing the request: {}", throwable.getMessage());
return Response.fail(ResponseCode.ERROR.getCode(), "系统繁忙,请稍候再试");
}
// 记录响应结果
logResponseResult(result);
// 记录请求结束时间
long endTime = System.currentTimeMillis();
// 输出耗时信息
logger.info("\n{} 请求处理结束,耗时:{}ms", pjp.getSignature(), (endTime - startTime));
return result;
}
/**
* 记录请求参数
*/
private void logRequestParams(HttpServletRequest request, String methodName, Object[] args) {
StringBuilder sb = new StringBuilder();
sb.append("\n╔------------------------------------------");
sb.append("\n║ Method Name : ").append(methodName);
sb.append("\n║ URL : ").append(request.getRequestURI());
sb.append("\n║ HTTP Method : ").append(request.getMethod());
if (args.length > 0) {
for (Object arg : args) {
// 参数为对象或Map类型时,转换为JSON字符串记录日志
if (arg != null && (arg instanceof JSONObject || arg.getClass().isAssignableFrom(Map.class))) {
sb.append("\n║ Request Parameters:");
sb.append(JSONObject.toJSONString(arg));
} else {
sb.append("\n║ Request Parameters:");
sb.append(arg);
}
}
}
sb.append("\n╚==========================================");
logger.info(sb.toString());
}
/**
* 记录响应结果
*/
private void logResponseResult(Object result) {
if (result == null) {
return;
}
// 将响应结果转换为 JSON 字符串,并打印
String resultJsonString = "";
if (result instanceof JSONObject) {
resultJsonString = JSONObject.toJSONString(result);
} else {
resultJsonString = JSONObject.toJSONString(Response.success(result));
}
logger.info("\n╔------------------------------------------" +
"\n║ Response :" + resultJsonString +
"\n╚==========================================");
}
}
- 在配置文件中开启 AOP 自动代理。
在 application.yml 或 application.properties 文件中添加以下配置:
1
2
3 spring:
aop:
auto: true
- 启动项目查看控制台日志。
现在,只要是位于 com.example.controller 包内的公共方法都会被 LogAspect 拦截,并在控制台输出请求参数和响应结果的日志信息。
这个回答还是挺好的,copy
下,修改就能用了,而且这个代码有意思的点是Response.fail(ResponseCode.ERROR.getCode(), "系统繁忙,请稍候再试");
,这个还是统一响应结果,有趣的勒。
Q&A3
Q3:springboot自定义拦截器
A3:在Spring Boot中自定义拦截器的步骤如下:
创建一个实现
HandlerInterceptor
接口的拦截器类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 public class MyInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 在请求处理之前进行调用(Controller方法调用之前)
// 返回true,则继续执行后续的Interceptor或Controller业务方法;返回false,则不再执行后续的Interceptor或Controller业务方法。
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
}
}注册拦截器 方法一:重写WebMvcConfigurerAdapter类
1
2
3
4
5
6
7
8
9
10
11
public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
private MyInterceptor myInterceptor;
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor).addPathPatterns("/**")
}
}方法二:实现WebMvcConfigurer接口
3. 若需要在拦截器中使用Bean 可以通过@Configuration,@Component等方式确保该Bean被Spring管理,然后通过@Autowired或@Resource注解引入。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class WebMvcConfig implements WebMvcConfigurer {
MyInterceptor getMyInterceptor(){
return new CorsInterceptor();
}
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(getMyInterceptor()).addPathPatterns("/**");
}
}注意:默认情况下,添加的拦截器将会应用到所有的请求路径上。如果有特殊需求,可以通过
addPathPatterns
、excludePathPatterns
方法来进行配置。除了以下实现HandlerInterceptor接口外,还支持使用@ControllerAdvice+AOP对控制器方法进行拦截处理;也可以使用Servlet Filter对HTTP请求与响应进行拦截处理。