3.AOP切面如下
package com.tjair.tjapi.config; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.tjair.common.log.TjapiLogVo; import com.tjair.common.util.IPUtil; import com.tjair.tjapi.feign.LogFeignService; import com.tjair.tjapi.util.HttpHelper; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; 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.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.Date; import java.util.Objects; /** • @description 拦截所有控制器的返回,记录响应报文 • @author unhejing • @date 2021-03-17 上午11:52:26 */ @Aspect @Configuration @Slf4j public class LogAspect { @Autowired private LogFeignService logFeignService; public LogAspect() { } @Pointcut(“execution(public * com.tjair.tjapi.controller..(…))”) public void pointCutMethod() { } // 声明环绕通知 @Around(“pointCutMethod()”) public Object doAround(ProceedingJoinPoint pjp) throws Throwable { Long startTime = System.currentTimeMillis(); ApiOperation apiOperation = ((MethodSignature)pjp.getSignature()).getMethod().getAnnotation(ApiOperation.class); // 获取request对象 RequestAttributes ra = RequestContextHolder.getRequestAttributes(); ServletRequestAttributes sra = (ServletRequestAttributes) ra; HttpServletRequest request = sra.getRequest(); Object ret = pjp.proceed(); Long endTime = System.currentTimeMillis(); TjapiLogVo tjapiLogVo = getTjapiLogVo(request,Objects.nonNull(apiOperation) ? apiOperation.value() : “”,endTime-startTime,JSON.toJSONString(ret)); // 添加日志 addLog(tjapiLogVo); log.info(“响应数据耗时{}:响应数据{}”,endTime-startTime,JSON.toJSONString(ret)); return ret; } public void addLog(TjapiLogVo tjapiLogVo) { log.info(“添加日志:{}”,JSON.toJSONString(tjapiLogVo)); Long startTime = System.currentTimeMillis(); logFeignService.addTjapiLog(tjapiLogVo); Long endtime = System.currentTimeMillis(); log.info(“添加日志耗时:{}”,endtime-startTime); } private TjapiLogVo getTjapiLogVo(HttpServletRequest request,String apiName,Long time,String response) throws IOException { TjapiLogVo tjapiLogVo = new TjapiLogVo(); String jsonBody = HttpHelper.getBodyString(request); log.info(“请求参数:{}”,jsonBody); JSONObject reqObj = Objects.nonNull(JSON.parseObject(jsonBody)) ? JSON.parseObject(jsonBody) : new JSONObject(); JSONObject resObj = Objects.nonNull(JSON.parseObject(response)) ? JSON.parseObject(response) : new JSONObject(); //设置请求参数 tjapiLogVo.setParams(jsonBody); tjapiLogVo.setPartnerid(Objects.nonNull(reqObj.getString(“partnerId”)) ? reqObj.getString(“partnerId”) : “-1”); // 设置IP地址 tjapiLogVo.setIp(IPUtil.getIpAddr(request)); // 设置位置 tjapiLogVo.setLocation(IPUtil.getCityInfo(tjapiLogVo.getIp())); //设置请求方法,GET,POST… tjapiLogVo.setMethod(request.getMethod()); //设置请求路径 tjapiLogVo.setUrl(request.getRequestURI()); // 设置请求方法名称 tjapiLogVo.setApiName(apiName); // 设置创建时间 tjapiLogVo.setCreateTime(new Date()); // 设置请求状态 Integer code = Objects.nonNull(resObj.getInteger(“code”)) ? resObj.getInteger(“code”) : 1; tjapiLogVo.setStatus(code); // 设置接口消耗时间 tjapiLogVo.setTime(time.intValue()); // 设置响应内容 tjapiLogVo.setResponse(response); return tjapiLogVo; } }
4.测试接口
package com.tjair.tjapi.controller; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.tjair.common.service.RedisUtils; import com.tjair.common.util.Result; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; /** • @author jingyujie • @create 2021-03-16 下午2:39 **/ @RestController @RequestMapping(“/test”) @Api(tags = “测试API控制器”) public class TestController { @Autowired private RedisUtils redisUtils; @PostMapping(“/apiTest”) @ApiOperation(“接口测试”) public Result apiTest(@RequestBody JSONObject obj){ return Result.returnSuccess(“接口已联通,请求入参:”+ JSON.toJSONString(obj)); } }
5.请求结果如下
备注说明:
1.LogFeignService是添加日志的service
2.IPUtil是获取IP和地址信息相关的工具类
3.HttpHelper是解析request中的请求参数的工具类
4.ApiOperation是获取接口的注解上面的接口描述
5.partnerId是我请求参数里面必传的用户编码
6.code是响应参数里面的状态码,用于判断接口是否请求成功
末尾附上工具类:
IPUtil.java
类中的/ip2region.db这个是一个地址库,可直接百度下载即可。
package com.tjair.common.util; import org.apache.commons.io.FileUtils; import org.lionsoul.ip2region.DataBlock; import org.lionsoul.ip2region.DbConfig; import org.lionsoul.ip2region.DbSearcher; import org.lionsoul.ip2region.Util; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.lang.reflect.Method; /** • ip操作相关工具类 • @author jingyujie • @create 2020-06-24 下午2:11 **/ public class IPUtil { public static String getCityInfo(String ip){ try { //db String dbPath = IPUtil.class.getResource(“/ip2region.db”).getPath(); System.out.println(“路径:”+dbPath); File file = new File(dbPath); if (file.exists() == false) { System.out.println(“Error: Invalid ip2region.db file”); String tmpDir = System.getProperties().getProperty(“java.io.tmpdir”); dbPath = tmpDir + “ip.db”; System.out.println(dbPath); file = new File(dbPath); FileUtils.copyInputStreamToFile(IPUtil.class.getClassLoader().getResourceAsStream(“classpath:ip2region.db”), file); } //查询算法 int algorithm = DbSearcher.BTREE_ALGORITHM; //B-tree //DbSearcher.BINARY_ALGORITHM //Binary //DbSearcher.MEMORY_ALGORITYM //Memory DbSearcher searcher = null; try { DbConfig config = new DbConfig(); searcher = new DbSearcher(config, dbPath);