我有几个微服务,我用openfeign来调用不同的微服务。全局应用程序的入口点名为dispatcher-ws。他的作用是根据有效载荷分派呼叫。
作为条目,我确实有以下有效载荷:
{
"operation": "signature",
"clientId": "abcdef",
...
"pdfDocument": "JVBERi0xLjMNCiXi48/TDQoNCjEg..."
}我有一个名为签名-ws的微服务,可以处理pdf签名。到现在为止还好。我用这种方式实现了我的客户:
@FeignClient(name="signature-ws", decode404 = true, url = "http://localhost:8080/signature-ws/api")
public interface SignatureClient {
@PostMapping("/signature")
Map<String, Object> signDocument(RequestDto request) throws AppServiceException;
}在我的服务层中,我尝试根据操作值进行调用:
@Service
public class RequestServiceImpl implements DispatchService {
private final RequestRepository requestRepository;
private final SignatureClient signatureClient;
private final Resilience4JCircuitBreakerFactory circuitBreakerFactory;
@Autowired
public DispatchServiceImpl(RequestRepository requestRepository,
SignatureClient signatureClient,
Resilience4JCircuitBreakerFactory circuitBreakerFactory) {
this.requestRepository = requestRepository;
this.signatureClient = signatureClient;
this.circuitBreakerFactory = circuitBreakerFactory;
}
@Override
public RequestDto handleRequest(RequestDto request) {
RequestDto returnValue = new RequestDto();
// if not initialized, throw null pointer exception...
returnValue.setPayloads(new ArrayList<>());
if(request.getOperation().equals("signature") {
Resilience4JCircuitBreaker circuitBreaker = circuitBreakerFactory.create("signature");
Supplier<Map<String, Object>> signatureResponseSupplier =
() -> signatureClient.signDocument(request);
Map<String, Object> signatureResponse = circuitBreaker.run(
signatureResponseSupplier,
throwable -> handleException()
);
...
returnValue.getResponses().add(signatureResponse)
}
return retunValue;
}
...
private Map<String, Object> handleException() {
Map<String, Object> returnValue = new HashMap<>();
returnValue.put("Error", "Error rmessage ... ");
returnValue.put("status", "Failure");
return returnValue;
}如果我没有在签名don服务中传递pdfDocument,我就会检索一个异常。
{
"errorId": "Qe99DwntFrMPCAfuZfDQW1ucwNh5BK",
"status": "ERROR",
"operations": "signature",
"profile": "client123456",
"errorMessage": "PDF is missing",
"createdAt": 1647354022127
}我想检索异常响应,并将键值传递给handleException方法中的映射。在这个阶段,它没有返回任何东西,更糟糕的是,我确实返回了200状态。
我实现了一个管理响应返回的controllerAdvice。这个类在我的所有web服务中是相同的(我应该考虑创建一个处理所有异常的微服务.)
@ControllerAdvice(basePackages = { "com.company.app" })
public class AppExceptionsHandler {
private final RequestContext requestContext;
@Autowired
public AppExceptionsHandler(RequestContext requestContext) {
this.requestContext = requestContext;
}
@ExceptionHandler(value = {AppServiceException.class})
public ResponseEntity<Object> handleAppException(AppServiceException ex,
WebRequest request) {
// récupérer le body
DispatchDto response = requestContext.getResponse();
ErrorMessage errorMessage = ErrorMessage.builder()
.errorId(response.getId())
.status(RequestOperationStatus.ERROR.name())
.operations(response.getOperations())
.profile(response.getProfile())
.errorMessage(ex.getMessage())
.createdAt(new Date())
.build();
}
return new ResponseEntity<>(errorMessage, new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}我所期望的是在我的调度器微服务中返回相同的异常。
发布于 2022-03-16 09:28:43
我找到了解决这个问题的办法。首先,我被一次尝试抓住了我的假装请求:
try {
...
Map<String, Object> facturxResponse =
facturXClient.createFacturX(dispatchDto);
...
} catch(FeignException e) {
System.out.println(e.getMessage());
throw new AppServiceException(e.getMessage());
}我注意到e.getMessage返回一个具有以下模式的字符串:
[500 Internal Server Error] during [POST] to [http://localhost:8080/my-ws/api/ws]
[FacturXClient#createFacturX(DispatchDto)]: [{"errorId":"z3o1bE8SJrm8WGrxlpIIWe6TNf0NzR","status":"ERROR","operations":"facturx","profile":"client123456","errorMessage":"PDF is missing","createdAt":1647422337344}]我抛出这个异常并拦截响应。
@ExceptionHandler(value = {AppServiceException.class})
public ResponseEntity<Object> handleUserServiceException(AppServiceException ex,
WebRequest request) throws JsonProcessingException {
String input = ex.getMessage();
String[] splitResponse = input.split(":", 4);
ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
String response = splitResponse[3].trim().substring(1, splitResponse[3].trim().length() -1);
ErrorMessage errorMessage = mapper.readValue(response, ErrorMessage.class);
System.out.println(errorMessage.toString());
return new ResponseEntity<>(errorMessage, new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
}我终于得到了预期的回应:
{
"errorId": "z3o1bE8SJrm8WGrxlpIIWe6TNf0NzR",
"status": "ERROR",
"operations": "facturx",
"profile": "client123456",
"errorMessage": "PDF is missing",
"createdAt": "2022-03-16T09:18:57.344+00:00"
}https://stackoverflow.com/questions/71484642
复制相似问题