Java 数据库中的Springboot外部api调用请求和响应捕获
从我的后端应用程序(springboot,java8)我将进行多个外部api调用。我需要将所有请求和响应数据(包括标题、请求和响应正文)记录到数据库中(MongoDB) 下面是我的示例代码,这是我如何尝试捕获每个外部api调用的请求和响应。在异常情况下,我将存储状态为“失败” 在我的项目中,将在新的第三方api集成上添加多个模块,因此在每个模块中,对于每个不同的外部api调用,我必须捕获所有请求和响应,如下所示。我不满意下面的方法。请建议解决此问题的最佳方法 示例服务层方法Java 数据库中的Springboot外部api调用请求和响应捕获,java,spring-boot,design-patterns,microservices,software-design,Java,Spring Boot,Design Patterns,Microservices,Software Design,从我的后端应用程序(springboot,java8)我将进行多个外部api调用。我需要将所有请求和响应数据(包括标题、请求和响应正文)记录到数据库中(MongoDB) 下面是我的示例代码,这是我如何尝试捕获每个外部api调用的请求和响应。在异常情况下,我将存储状态为“失败” 在我的项目中,将在新的第三方api集成上添加多个模块,因此在每个模块中,对于每个不同的外部api调用,我必须捕获所有请求和响应,如下所示。我不满意下面的方法。请建议解决此问题的最佳方法 示例服务层方法 public Res
public ResponseDTOFromExternalApi externalApiCallServiceMethod(String clientId, RequestDTO requestDTO) {
ExternalApiCallRequestObj externalApiCallRequestObj = prepareExternalApiRequestObjFromRequestDTO(requestDTO);
ApiCall apiCall = ApiCall.builder()
.clientId(clientId)
.status("SUBMITTED")
.requestPayload(externalApiCallRequestObj)
.build();
apiCall = apiCallRepository.save(apiCall);
ExternalApiCallReponseObj externalApiCallReponseObj = externalApiCallService.callExternalApi1(externalApiCallRequestObj);
apiCall = apiCallRepository.findById(apiCall.getId());
apiCall.setResponsePayload(externalApiCallReponseObj);
apiCall.setStatus("COMPLETED");
apiCallRepository.save(apiCall);
return toDTO(externalApiCallReponseObj);
}
api调用的示例域
@Document("api_calls")
@Builder
@Data
public class ApiCall {
@Id
private String id;
private String clientId;
private String status;
private Object requestPayload;
private Object responsePayload;
}
您可以使用SpringAOP来解决这个横切问题 假设
ExternalApiCallService
是一个spring管理的bean,下面的代码将截获所有callexternalapci1()
并将其记录到数据库中
@Component
@Aspect
public class ExternalCallLoggerAspect {
@Autowired
ApiCallRepository apiCallRepository;
@Pointcut("execution(* *..ExternalApiCallService.callExternalApi1(..))")
public void externalApiCallService(){}
@Around("externalApiCallService() && args(request)")
public ExternalApiCallReponseObj logCalls(ProceedingJoinPoint pjp,ExternalApiCallRequestObj request){
Object result=null;
String status = "COMPLETED";
ExternalApiCallReponseObj response = null;
// Build the apiCall from request
ApiCall apiCall = ApiCall.builder()
.clientId(clientId)
.status("SUBMITTED")
.requestPayload(request)
.build();
//save the same to db
apiCall = apiCallRepository.save(apiCall);
// Proceed to call the external Api and get the result
try {
result = pjp.proceed();
} catch (Throwable e) {
status = "FAILED";
}
//Update the response
apiCall = apiCallRepository.findById(apiCall.getId());
apiCall.setStatus(status);
apiCallRepository.save(apiCall);
if(result != null) {
response = (ExternalApiCallReponseObj)result;
apiCall.setResponsePayload(response);
}
//continue with response
return response;
}
}
注
1.名称为externalapicallreponsebj
2.方面代码已验证其工作正常,并且随后未测试逻辑。请做必要的更正
理想情况下,最初的方法应该简化为
public ResponseDTOFromExternalApi externalApiCallServiceMethod(String clientId, RequestDTO requestDTO) {
return toDTO(externalApiCallService.callExternalApi1(prepareExternalApiRequestObjFromRequestDTO(requestDTO)));
}
更多关于SpringAOP的信息
更新:再想想,如果所有外部api调用都是通过一个方法进行的,比如说
ExternalApiCallService.callExternalApi1()
,那么这个日志逻辑可以移动到那个公共点,不是吗 Spring的WebClient已经能够通过添加exchange筛选器来记录所有请求和响应数据
通过将其用于网络请求,剩下的唯一事情就是将此信息写入mongodb
以下是有关记录请求和响应的教程:
干杯