#spring-boot #spring-mvc #error-handling #resttemplate #spring-restcontroller
Вопрос:
Недавно я написал простое приложение Spring Boot, которое позволяет выполнять один вызов удаленного API для восстановления. При обработке любых потенциальных исключений с самим вызовом я создал реализацию ResponseErrorHandler
, подобную приведенной ниже (где фактическое имя службы изменилось на «Удаленная служба»).:
@Component public class RemoteServiceOneResponseErrorHandler implements ResponseErrorHandler { public static final String ERR_MSG_401 = "Authentication issue with remote service one"; public static final String ERR_MSG_404 = "No match for remote service one"; public static final String ERR_MSG_422 = "Unprocessable Entity. Incorrect parameters provided to remote service one"; public static final String ERR_MSG_503 = "Service Unavailable"; public static final String ERR_MSG_CATCH_ALL = "Unparseable response returned from remote service one"; @Override public boolean hasError(ClientHttpResponse response) throws IOException { return response.getStatusCode().isError(); } @Override public void handleError(ClientHttpResponse response) throws IOException { throw new ProblemDetailsException(response.getStatusCode(), getProblemDetails(response)); } private ProblemDetails getProblemDetails(ClientHttpResponse response) throws IOException { ProblemDetails pd = new ProblemDetails(); pd.setType(ProblemDetails.TYPE_SCHEMA); pd.setTitle(HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()); pd.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); if (response.getRawStatusCode() == 401) { pd.setDetail(ERR_MSG_401); } else if (response.getRawStatusCode() == 404) { pd.setDetail(ERR_MSG_404); pd.setTitle(HttpStatus.NOT_FOUND.getReasonPhrase()); pd.setStatus(HttpStatus.NOT_FOUND.value()); } else if (response.getRawStatusCode() == 422) { pd.setDetail(ERR_MSG_422); } else { pd.setDetail(ERR_MSG_CATCH_ALL); } return pd; } }
Это было назначено обработчику RestTemplate
ошибок, как показано ниже:
@Bean RestTemplate restTemplate(@Autowired RemoteServiceOneResponseErrorHandler serviceOneResponseErrorHandler) { HttpClientBuilder builder = baseClientBuilder(); HttpClient client = builder.build(); HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(client); RestTemplate restTemplate = new RestTemplate(factory); restTemplate.setErrorHandler(serviceOneResponseErrorHandler); return restTemplate; }
Для справки, ProblemDetailsException
это пользовательский проверенный класс исключений, который мы используем в компании.
Теперь я получил новое требование, которое теперь означает, что приложение Spring Boot также вызывает другую службу (которую я буду называть удаленной службой Два), и это произойдет в классе службы, но для того же контроллера, в котором RemoteServiceOneResponseErrorHandler
был установлен обработчик ошибок. Требования к тому, как обрабатываются ошибки, отличаются от приведенных выше, поскольку некоторые фактические сообщения об ошибках будут отличаться для обеих служб, и в некоторых случаях сопоставление кодов состояния HTTP из ClientHttpResponse
экземпляра в status
поле в пользовательском ProblemDetailsException
также будет отличаться.
До сих пор я могу думать только о том, чтобы разбить приложение Spring Boot на два или более контроллеров, каждый из которых имеет свой собственный экземпляр ResponseErrorHandler
, но это нежелательно, так как приложение должно иметь только один маршрут, а переделка выходит за рамки.
Итак, я пытаюсь найти наилучший способ обработки ошибок таким образом, чтобы я все еще ResponseErrorHandler
мог использовать экземпляр ClientHttpResponse
, который он использует, но через два разных удаленных вызова API. Любая помощь будет признательна.
Cheers Rich