Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 数据库中的Springboot外部api调用请求和响应捕获_Java_Spring Boot_Design Patterns_Microservices_Software Design - Fatal编程技术网

Java 数据库中的Springboot外部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

从我的后端应用程序(springboot,java8)我将进行多个外部api调用。我需要将所有请求和响应数据(包括标题、请求和响应正文)记录到数据库中(MongoDB

下面是我的示例代码,这是我如何尝试捕获每个外部api调用的请求和响应。在异常情况下,我将存储状态为“失败”

在我的项目中,将在新的第三方api集成上添加多个模块,因此在每个模块中,对于每个不同的外部api调用,我必须捕获所有请求和响应,如下所示。我不满意下面的方法。请建议解决此问题的最佳方法

示例服务层方法

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

以下是有关记录请求和响应的教程:

干杯