找不到404的伪造且未声明的可抛出异常

时间:2019-03-13 17:47:01

标签: java spring spring-boot spring-cloud-feign feign

我正尝试捕获假响应并评估404未找到响应的异常,例如以下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)

可能会用undeclaredThrowable 404抛出responseCode

3 个答案:

答案 0 :(得分: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 :(得分:1)

您可以设置一个Cutom Error控制器,该控制器处理应用程序的所有错误并返回所需的消息类型。我将以下实现与ResponseBody一起用于网络应用。根据需要配置以下实现:

@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) {

    // ...

    }
}

答案 2 :(得分: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提出的