spring 切片打日志_为spring的controller做一个打印日志、验证参数、提供默认异常处理的切面...

@Aspect

@Component

@Slf4jpublic classRequestHelperAspect {

@AutowiredprivateSmartValidator validator;

@Around("@annotation(restRequestHelper)")publicObject process(ProceedingJoinPoint pjp, RestRequestHelper restRequestHelper) {

Class> targetClass =pjp.getTarget().getClass();

String className=targetClass.getSimpleName();

String methodName=pjp.getSignature().getName();

Object[] args=pjp.getArgs();

Object[] arguments= newObject[args.length];for (int i = 0; i < args.length; i++) {if (args[i] instanceof ServletRequest || args[i] instanceof ServletResponse || args[i] instanceofMultipartFile) {//ServletRequest不能序列化,从入参里排除,否则报异常:java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)//ServletResponse不能序列化 从入参里排除,否则报异常:java.lang.IllegalStateException: getOutputStream() has already been called for this response

continue;

}

arguments[i]=args[i];

}

log.info("processing request:{}.{} begin,params:{}", className, methodName, arguments);long startTime =System.currentTimeMillis();

Object proceed= null;if ((proceed = validParams(arguments,restRequestHelper.validGroups())) == null) {try{

proceed=pjp.proceed();

}catch(Throwable throwable) {

log.error("processing request error:", throwable);

//异常处理}

}long endTime =System.currentTimeMillis();//响应参数toString

String response = null;if (proceed instanceofResult) {

Result result=(Result) proceed;

response=result.toJson();

}else if (proceed!=null){

response=proceed.toString();

}

log.info("processing request:{}.{} end,params:{},response:{},use:{}ms", className, methodName, arguments, response, endTime -startTime);returnproceed;

}/*** 参数校验

*

*@paramargs

*@paramclasses

*@return

*/

privateResult validParams(Object[] args, Class[] classes) {

Result errorResult= null;for(Object arg : args) {if(arg==null){continue;

}

BindingResult bindingResult= newBeanPropertyBindingResult(arg, arg.getClass().getSimpleName());if(classes.length>0){

validator.validate(arg, bindingResult,classes);

}else{

validator.validate(arg, bindingResult);

}

StringBuilder errorMsg= null;

Map errorMap = null;if(bindingResult.hasErrors()) {

errorMsg= newStringBuilder();

errorMsg.append(//异常信息);final List fieldErrors =bindingResult.getFieldErrors();

errorMap= new HashMap<>(fieldErrors.size());for(FieldError fieldError : fieldErrors) {

errorMap.put(fieldError.getField(), fieldError.getDefaultMessage());

}

errorMsg.append(JSON.toJSON(errorMap));

errorResult= newResult(...异常);

}

}returnerrorResult;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的示例代码,用于实现Spring Boot中的日志切面: 首先,我们需要定义一个切面类,并在其中编写切面逻辑: ```java @Aspect @Component public class LoggingAspect { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Pointcut("execution(* com.example.controller..*.*(..))") public void controllerMethod() {} @Around("controllerMethod()") public Object logControllerMethodAccess(ProceedingJoinPoint joinPoint) throws Throwable { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String url = request.getRequestURL().toString(); String httpMethod = request.getMethod(); String remoteAddr = request.getRemoteAddr(); Object[] args = joinPoint.getArgs(); StringBuilder params = new StringBuilder(); for (Object arg : args) { params.append(arg.toString()).append(";"); } long startTime = System.currentTimeMillis(); Object result = joinPoint.proceed(); long endTime = System.currentTimeMillis(); logger.info("Request URL: {}, HTTP Method: {}, Remote Address: {}, Parameters: {}, Response Time: {} ms", url, httpMethod, remoteAddr, params.toString(), endTime - startTime); return result; } } ``` 上述代码中,我们使用了`@Aspect`注解来标识这是一个切面类,并使用`@Component`注解将其声明为Spring Bean。接着,我们定义了一个切点`controllerMethod()`,用于匹配所有Controller类中的方法。最后,我们在`controllerMethod()`切点上使用了`@Around`注解,表示这是一个环绕通知,即在Controller方法执行前后都会执行。 在`@Around`注解中,我们首先获取了请求的URL、HTTP Method和远程地址等信息,然后将请求参数转换为字符串,并在执行Controller方法前记录当前时间。在Controller方法执行完成后,我们再记录当前时间并计算出响应时间,最后将所有信息以日志的形式输出到控制台中。 最后,我们需要在Spring Boot的配置文件中开启AOP: ```yaml spring: application: name: demo aop: auto: true ``` 这样,当我们启动Spring Boot应用时,就能够看到所有Controller方法的访问信息被打印在控制台中了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值