Spring Boot aop 获取HttpResponse的状态码方法如下:
HttpServletResponse httpServletResponse = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
int status = httpServletResponse.getStatus();
Spring Boot 项目中,@Around、@AfterReturning、@After注解的Pointcut不能获取到程序异常时返回的HTTPServletResponse的状态码,因为这几个注解执行的条件均是在你调用的接口执行完成之后再执行(不论你的接口调用会不会抛异常)。如果你的接口没问题,正常返回,则上述方法获取到的status为200正常值;如果你的接口抛异常,则该status仍为200,此时时错误的。
原因(个人理解):
当你发送HTTPServletRequest服务器接收到之后,会生成一个HTTPServletResponse对象,这个response对象默认的status初始值为200,如果你的程序内部抛异常了,Java内部会根据你的异常原因给status赋值(比如null空指针异常,status会被赋值为500)。
而使用@Around、@AfterReturning、@After注解时,无论你接口的程序代码是否正常执行,都会被认为该接口调用已经执行完成,你的接口代码出错时会被认为返回一个null,由于调用接口是在你aop代码的@Around或@AfterReturning或@After注解中执行完成的,所以初始化的HTTPServletResponse对象的status值并未做修改(因为你的接口正常调用完成后,Java内部会根据实际情况给status赋值,而上述几个注解加入后,感觉像是跳过了异常(或者说用接口返回的 null处理了异常),status貌似未被赋上错误代码值)。
所以HTTPServletResponse的status值始终为200,即Http的请求与返回总是正常执行完(程序中的异常在aop代码中被捕获到,但未处理)。
最后强调一下:Http请求与返回是否正常执行 与 你的接口代码是否正常执行,这是两个概念。
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
@Aspect
@Component
public class SysLoggerAspect {
@A