【问题标题】:Changing a 404 response for REST API to a 200 empty response将 REST API 的 404 响应更改为 200 空响应
【发布时间】:2020-05-21 17:15:02
【问题描述】:

我有一个用 Java 编写的 Spring Boot 应用程序,它是一个 REST API。此服务 (Svc A) 调用 REST API 服务 (Svc B) 也是用 Java 编写的 Spring Boot 应用程序。未找到数据时,Svc B 返回 404 状态代码。我需要将此响应更改为 200 状态代码并返回一个空响应对象。我不确定是否或如何做到这一点。

我可以捕获错误并确定 404 是否是此未找到数据错误。但是,我不知道如何将响应更改为 200 空响应。 我正在使用 FeignClient 来调用服务。这是捕获 404 的错误代码:

@Component
public class FeignErrorDecoder implements ErrorDecoder {

    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public Exception decode(String methodKey, Response response) {
        Reader reader = null;
        String messageText = null;
        switch (response.status()){
            case 400:
                logger.error("Status code " + response.status() + ", methodKey = " + methodKey);
            case 404:
            {
                logger.error("Error took place when using Feign client to send HTTP Request. Status code " + response.status() + ", methodKey = " + methodKey);
                try {
                    reader = response.body().asReader();
                    //Easy way to read the stream and get a String object
                    String result = CharStreams.toString(reader);
                    logger.error("RESPONSE BODY: " + result);
                    ObjectMapper mapper = new ObjectMapper();
                    //just in case you missed an attribute in the Pojo
                    mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
                    //init the Pojo
                    ExceptionMessage exceptionMessage = mapper.readValue(result,
                            ExceptionMessage.class);

                    messageText = exceptionMessage.getMessage();
                    logger.info("message: " + messageText);

                } catch(IOException ex) {
                    logger.error(ex.getMessage());
                }
                finally {
                    try {

                        if (reader != null)
                            reader.close();

                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                return new ResponseStatusException(HttpStatus.valueOf(200), messageText);
            }
            default:
                return new Exception(response.reason());
        }
    }
}

我可以将状态码更改为 200,它会返回 200,但我需要响应有一个空的响应对象。 上面的代码会返回一个错误响应对象的响应体:

{
   "statusCd" : "200",
   "message" : "The Location not found for given Location Number and Facility Type Code",
   "detailDesc" : "The Location not found for given Location Number and Facility Type Code. Error Timestamp : 2020-01-31 18:19:13"
}

我需要它来返回这样的响应正文: 200 - 空响应

{
  "facilityNumber": "923",
  "facilityTimeZone": null,
  "facilityAbbr": null,
  "scheduledOperations": []
}

【问题讨论】:

  • 如果你的身体是空的,为什么不使用状态码 204?
  • 刚刚添加了我得到的和我需要的。如果响应对象为空,则调用此服务的服务需要 200 代码

标签: java spring-boot http-status-codes


【解决方案1】:

如果是 404 试试

return new ResponseStatusException(HttpStatus.valueOf(200));

【讨论】:

  • 确实返回 200 状态码,但在错误响应正文的响应对象中:它返回此响应:404 - 错误响应 { "statusCd" : "200", "message" : "The找不到给定位置编号和设施类型代码的位置”,“detailDesc”:“找不到给定位置编号和设施类型代码的位置。错误时间戳:2020-01-31 18:19:13”} 我需要它返回: 200 - 空响应 { "facilityNumber": "923", "facilityTimeZone": null, "facilityAbbr": null, "scheduledOperations": [] }
  • 在没有找到数据的情况下,你不能改变 svc B 响应发送 200 OK
  • 这是我的团队建议的,但管理层拒绝了。我们必须捕获这个错误并将其更改为 200。调用我们的服务也无法处理它。
【解决方案2】:

对于必须做如此疯狂的事情的任何人......这是我的解决方案: 删除了 FeignErrorCode 文件。 向 ControllerAdvice 类添加了一个例外,如下所示:

@ExceptionHandler(FeignException.class)
    public ResponseEntity<?> handleFeignException(FeignException fe, WebRequest request) {
        ErrorDetails errorDetails = new ErrorDetails(new Date(), HttpStatus.valueOf(fe.status()), fe.getMessage(), request.getDescription(false));
        String response = fe.contentUTF8();

        if(response != null) {
            ScheduledOperationsViewResponse scheduledOperationsViewResponse = new ScheduledOperationsViewResponse();
            if (response.contains("Scheduled") || response.contains("Location")) {
                HttpHeaders headers = new HttpHeaders();
                scheduledOperationsViewResponse.setFacilityNumber(request.getParameter("facilityNumber"));
                return new ResponseEntity<ScheduledOperationsViewResponse>(scheduledOperationsViewResponse, headers, HttpStatus.OK);
            }
        }
        return new ResponseEntity<>(errorDetails, errorDetails.getStatus());
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-24
    • 1970-01-01
    相关资源
    最近更新 更多