404未找到的假装和未申报的可抛出异常

问题描述 投票:1回答:3

我正在尝试捕获Feign响应并评估404 Not Found响应的异常,如下面的REST模板:

try {
  response = restTemplate.exchange(url, HttpMethod.GET, request, Foo.class);

} catch (HttpClientErrorException ex) {
     if (ex.getStatusCode() != HttpStatus.NOT_FOUND) {
       throw ex;
     }
}

但对于

Foo response = feignClient.getFoo(foo)

这可能会引发undeclaredThrowableresponseCode 404。

java spring spring-boot spring-cloud-feign feign
3个回答
2
投票

您可以使用错误解码器并检查404状态代码。例如

public class MyErrorDecoder implements ErrorDecoder {

    @Override
    public Exception decode(String methodKey, Response response) {
        if (response.status() == 404) {
           ... 
           return new YourCustomException()

        }

        return errorStatus(methodKey, response);
    }
}

https://github.com/OpenFeign/feign/wiki/Custom-error-handling


1
投票

您可以设置cutom错误控制器,它可以处理应用程序的所有错误并返回所需的消息类型。我正在使用以下实现与ResponseBody为Web应用程序。根据您的需要配置以下实现:

@Controller
public class CustomErrorController implements ErrorController {

    @Override
    public String getErrorPath() {
        return "/error";
    }

    @ResponseBody
    @GetMapping("/error")
    public String handleError(HttpServletRequest request) {

        Enumeration<String> headerNames1 = request.getHeaderNames();
        Enumeration<String> headerNames2 = request.getHeaderNames();

        String headerJson = enumIterator(headerNames1, headerNames2, request);
        System.out.println(headerJson);

        Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);

        if (status != null) {
            Integer statusCode = Integer.valueOf(status.toString());

            if (statusCode == HttpStatus.NOT_FOUND.value()) {
                return "404 with other message";

            } else if (statusCode >= 500) {
                return "500  with other message";

            } else if (statusCode == HttpStatus.FORBIDDEN.value()) {
                return "403  with other message";
            }
        }
        return "miscellaneous error";
    }


    private String enumIterator(Enumeration<String> enumList1, Enumeration<String> enumList2, HttpServletRequest request) {

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("{");
        boolean status = false;

        while (enumList1.hasMoreElements()) {

            if (status) {
                stringBuilder.append(",");
            }
            status = true;

            stringBuilder
                    .append("\"").append(enumList1.nextElement()).append("\"")
                    .append(":")
                    .append("\"").append(request.getHeader(enumList2.nextElement())).append("\"");
        }
        stringBuilder.append("}");

        return stringBuilder.toString();
    }
}

或者你可以试试这个实现:

@Component
public class MyErrorController extends BasicErrorController {

    public MyErrorController(ErrorAttributes errorAttributes) {
        super(errorAttributes, new ErrorProperties());
    }

    @RequestMapping(produces = MediaType.APPLICATION_XML_VALUE)
    public ResponseEntity<Map<String, Object>> xmlError(HttpServletRequest request) {

    // ...

    }
}

0
投票

在我的情况下,我解决了如下

import java.lang.reflect.UndeclaredThrowableException;

    try {
      Foo response = feignClient.getFoo(foo)

    } catch (Exception ex) {
         if(((ServiceMethodException)((UndeclaredThrowableException) ex).getUndeclaredThrowable()).responseCode != 404){
           throw ex;
      }
    }

Vlovato提出了完美的解决方案

© www.soinside.com 2019 - 2024. All rights reserved.