java连接mongodb生成接口调用日志
在开发中,我们会遇到使用mongodb生成接口调用日志的需求,那么如何解决的?废话少说,上代码:
1.导入pom依赖
<!--mongodb依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.10</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency>
2.在yml中加入mongodb连接
spring:
data:
mongodb:
uri: mongodb://[172.0.0.1:27013]/mongodb名称
3.建立实体类
这里建立的实体类名称即为mongodb表的名称
public class Log_Manager implements Serializable {
private Long id;
private String userName;
private String age;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public Log_Manager(Long id, String userName, String age) {
this.id = id;
this.userName = userName;
this.age = age;
}
public Log_Manager() {
}
}
4.创建MongoResponse
@Component
public interface MongoResponse extends MongoRepository<Log_Manager,Long> {
}
5.创建获取注解的工具类
public class Annotation implements Serializable {
/**
* @param scanPackage 需要扫描的包路径
*/
public static void getRequestMappingMethod(String scanPackage, Map map,String requestUrl) {
//设置扫描路径
Reflections reflections = new Reflections(new ConfigurationBuilder().setUrls(ClasspathHelper.forPackage(scanPackage)).setScanners(new MethodAnnotationsScanner()));
//扫描包内带有@ApiOperation注解的所有方法集合
Set<Method> methods = reflections.getMethodsAnnotatedWith(ApiOperation.class);
for (Method method : methods) {
if (method != null && method.getDeclaringClass() != null) {
//比对全部的RequestMapping的地址和传过来的地址是否一致
if (method.getDeclaringClass().getAnnotation(RequestMapping.class) != null && method.getAnnotation(RequestMapping.class) != null &&
method.getDeclaringClass().getAnnotation(RequestMapping.class).value() != null && method.getAnnotation(RequestMapping.class).value() != null
) {
try {
String url = method.getDeclaringClass().getAnnotation(RequestMapping.class).value()[0] + method.getAnnotation(RequestMapping.class).value()[0];
if (requestUrl.equals(url)) {
map.put("Function", method.getDeclaringClass().getAnnotation(Api.class).value());
map.put("Operation", method.getAnnotation(ApiOperation.class).value());
map.put("Message", method.getAnnotation(ApiOperation.class).value());
break;
}
}catch (Exception e){
System.out.println(method);
}
}
}
}
}
}
如代码所示,在所有想记录在mongodb的接口上须有@ApiOperation,其controller上须有@RequestMapping。注解的获取解决了,那么如何获取方法的返回值呢?别急
6.拦截返回值
@ControllerAdvice
public class ResponseBodyAnalysis implements ResponseBodyAdvice {
@Autowired
private MongoRepository mongoRepository;
@Override
public Object beforeBodyWrite(Object body, MethodParameter arg1, MediaType arg2, Class arg3, ServerHttpRequest arg4, ServerHttpResponse arg5) {
Annotation annotation = new Annotation();
try {
System.out.println(arg4.getBody());
} catch (IOException e) {
e.printStackTrace();
}
Map map = new HashMap();
//获取请求中的接口名称
String[] split = arg4.getURI().toString().split("/");
String requestUrl = "/"+split[split.length-2]+"/"+split[split.length-1];
//获得注解的内容
annotation.getRequestMappingMethod("com.sw.swbasicplatformupload.controller",map,requestUrl);
//body即为你返回值里的内容
System.out.println(body);
Date date = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String address = arg4.getRemoteAddress().toString();
String s = ip[0].substring(1);
map.put("DateTime", df.format(date));
//插入到mongodb中
Object o = mongoRepository.insert(map);
return body;
}
@Override
public boolean supports(MethodParameter arg0, Class arg1) {
return true;
}
}
只要有return,就会被拦截到此方法中,返回值的数据也拿到了。
mongodb中存储的值由实际需求决定,但现在我们获得注解的内容和返回值的数据,岂不是易如反掌。但这就要求了方法的返回值尽量不要为空。