Метод @ExceptionHandler не вызывается при возникновении исключения - PullRequest
0 голосов
/ 27 мая 2019

У меня есть глобальный обработчик исключений, как показано ниже: -

@ControllerAdvice
@RestController
public class GlobalExceptionHandler {

@ExceptionHandler(value= {HttpMessageNotReadableException.class})
    public final ResponseEntity<ErrorDetails> validationException(HttpMessageNotReadableException ex, WebRequest request) {

        System.out.println("This was called.");
        if(ex.getCause() instanceof CsvRequiredFieldEmptyException){

            CsvRequiredFieldEmptyException csvExp = (CsvRequiredFieldEmptyException) ex.getCause();
            String exceptionDtls = csvExp.getMessage().concat(" ").concat(" at line number "+csvExp.getLineNumber()+ " in the csv filw.");
            ErrorDetails errorDetails = new ErrorDetails(LocalDate.now(),exceptionDtls, request.getDescription(false));
            return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
        }

        return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
    }
}

Я вызываю остальные API с помощью TestRestTemplate для интеграционного тестирования.

ResponseEntity<?> response = restTemplate.exchange(ITestUtils.createURLWithPort(postUrlCsv,
                host,port ), HttpMethod.POST,listingDocEnt, String.class);

@Test
    public void uploadListingCsvTest_Returns400BadReq_WhenCodeMissing() throws HttpMessageNotReadableException {

        // Step 1 : Create the Http entity object which contains the request body and headers.
        HttpEntity<ListingList> listingDocEnt = new HttpEntity<ListingList>(createTestDataForNewVehicleListingCodeMissing(),
                getHttpHeaderCsv());

        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));

        List<HttpMessageConverter<?>> csvMessgeonverter = new ArrayList<>();
        csvMessgeonverter.add(new CsvHttpMessageConverter<>());
        csvMessgeonverter.add(converter);
        TestRestTemplate restTemplate = new TestRestTemplate();
        restTemplate.getRestTemplate().setMessageConverters(csvMessgeonverter);

        ResponseEntity<?> response = restTemplate.exchange(ITestUtils.createURLWithPort(postUrlCsv,
                host,port ), HttpMethod.POST,listingDocEnt, String.class);

        // Check if the response is not null and the http status code is - 201 Created.
        Assert.assertNotNull(response);
        Assert.assertEquals(HttpStatus.BAD_REQUEST,response.getStatusCode());

    }

My rest APIимеет собственный HttpMessageConverter, который, как показано ниже, преобразует входной запрос csv в объект java в контроллере остатка.Этот пользовательский конвертер сообщений имеет метод readInternal, который генерирует исключение HttpMessageNotReadableException, но метод обработчика исключений 'validationException' все равно не вызывается.Джунит просто ломается и терпит неудачу.

public class CsvHttpMessageConverter<T, L extends ListParam<T>>
          extends AbstractHttpMessageConverter<L> {

    public CsvHttpMessageConverter () {
        super(new MediaType("text", "csv"));
    }

    @Override
    protected boolean supports (Class<?> clazz) {
        return ListParam.class.isAssignableFrom(clazz);
    }

    @Override
    protected L readInternal (Class<? extends L> clazz,HttpInputMessage inputMessage)
              throws IOException, HttpMessageNotReadableException {

        HeaderColumnNameMappingStrategy<T> strategy = new HeaderColumnNameMappingStrategy<>();
        Class<T> t = toBeanType(clazz.getGenericSuperclass());
        strategy.setType(t);

        CSVReader csv = new CSVReader(new InputStreamReader(inputMessage.getBody()));
        CsvToBean<T> csvToBean = new CsvToBean<>();

        List<T> beanList = null;

        try {
            beanList = csvToBean.parse(strategy, csv);

        } catch(Exception exception){
            throw new HttpMessageNotReadableException("Exception while parsing the CSV file.",exception.getCause());
        }

        try {
            L l = clazz.newInstance();
            l.setList(beanList);
            return l;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void writeInternal (L l, HttpOutputMessage outputMessage)
              throws IOException, HttpMessageNotWritableException {

        HeaderColumnNameMappingStrategy<T> strategy = new HeaderColumnNameMappingStrategy<>();
        strategy.setType(toBeanType(l.getClass().getGenericSuperclass()));

        OutputStreamWriter outputStream = new OutputStreamWriter(outputMessage.getBody());
        StatefulBeanToCsv<T> beanToCsv =
                  new StatefulBeanToCsvBuilder(outputStream)
                            .withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
                            .withMappingStrategy(strategy)
                            .build();

            try {
                beanToCsv.write(l.getList());
            } catch (CsvDataTypeMismatchException e) {
                throw new HttpMessageNotWritableException("Exception while parsing the CSV file.",e);
            } catch (CsvRequiredFieldEmptyException e) {
                throw new HttpMessageNotWritableException("Exception while parsing the CSV file.",e);
            }
            outputStream.close();

    }

    @SuppressWarnings("unchecked")
    private Class<T> toBeanType (Type type) {
        return (Class<T>) ((ParameterizedType) type).getActualTypeArguments()[0];
    }

Есть ли способ, что при вызове API покоя пружины с использованием TestRestTemplate мы можем вызывать метод обработчика исключения, когда есть исключение?

1 Ответ

0 голосов
/ 27 мая 2019

Я думаю, что проблема здесь в том, что HttpMessageNotReadableException не генерируется контроллером, а вместо этого подпружиненной инфраструктурой ДО вызова контроллера.

Но @ControllerAdvice обрабатывает только исключения, которые выдаетКонтроллер.

В весеннем DispatcherServlet также есть ErrorHandler, который вызывается в таких случаях.Может быть, это решение для вас?

Вот некоторые сведения об этом: https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc#going-deeper

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...