Обработка исключений, таких как ServletRequestBindingException в Spring, а не контейнера сервлетов - PullRequest
2 голосов
/ 15 марта 2011

Я использую springmvc для проекта REST, и всякий раз, когда клиент вызывает ресурс rest с неправильным методом HTTP, генерируется исключение servletrequestbindingexception. Я не могу обработать эти исключения с @ExceptionHandler в контроллере, так как это происходит не внутри метода обработчика, а на уровне отображения пружины.

В настоящее время я объявил обработку исключений web.xml, это работает:

<error-page>
    <exception-type>org.springframework.web.bind.ServletRequestBindingException</exception-type>
    <location>/servletRequestBindingException.jsp</location>
</error-page>
<error-page>
    <error-code>405</error-code>
    <location>/methodNotSupported.jsp</location>
</error-page>

Я бы предпочел использовать обработку исключений пружин. Например, я хотел бы создать динамический ответ, основанный на входящем заголовке Accept, поэтому либо выписываем json или xml для исключения rest, например. Лучше всего вернуть объект из этого обработчика, который будет автоматически преобразован в json или xml, как обычный dto, возвращаемый из обработчика.

Есть ли способ отловить эти исключения отображения нижнего уровня?

Ответы [ 2 ]

6 голосов
/ 17 марта 2011

Вы не можете использовать @ExceptionHandler (поскольку, как вы говорите, это для обработки исключений, выданных из внутри кода обработчика), но вы все равно можете использовать HandlerExceptionResolver framework для этого.

По умолчанию DispatcherServlet регистрирует экземпляр DefaultHandlerExceptionResolver:

Реализация по умолчанию интерфейса HandlerExceptionResolver, который разрешает стандартные исключения Spring и переводит их в соответствующие коды состояния HTTP.

Генерация HTTP 405 фактически обрабатывается в этом классе, перехватывая HttpRequestMethodNotSupportedException, генерируемый кодом отображения обработчика.

Так что, если вы хотите обработать это исключение по-другому, вы можете предоставить собственную реализацию HandlerExceptionResolver. Вероятно, проще всего создать подкласс DefaultHandlerExceptionResolver и переопределить метод handleHttpRequestMethodNotSupported, вернув оттуда ModelAndView.

2 голосов
/ 07 июня 2011

Будьте осторожны, чтобы включить средства разрешения исключений по умолчанию, если вы включаете свои собственные. Если вы используете аннотированные обработчики @Exception, вам необходимо явно загрузить их, иначе они больше не будут работать.

В этом случае FooBarHandlerExceptionResolver расширяет DefaultHandlerExceptionResolver и предоставляет метод, который распознаватель по умолчанию не охватывает. Это позволяет FooBarHandlerExceptionResolver обрабатывать исключения уровня класса, которые я не смог отловить с помощью аннотированных методов-обработчиков @Exception.

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver">
    <property name="order" value="1"/>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver" >
    <property name="order" value="2"/>
</bean>
<bean class="com.company.package.foo.FooBarHandlerExceptionResolver">
    <property name="order" value="3"/>
</bean>

Вот решатель исключений

public class FooBarHandlerExceptionResolver extends DefaultHandlerExceptionResolver {
    @Override
    protected ModelAndView doResolveException(HttpServletRequest request,
            HttpServletResponse response,
            Object handler,
            Exception ex) {
        try {
            if (ex instanceof UnsatisfiedServletRequestParameterException) {
                return handleUnsatisfiedServletRequestParameter((UnsatisfiedServletRequestParameterException) ex, request, response,
                        handler);
            }else {
                super.doResolveException(request,response,handler,ex);
            }
        }
        catch(Exception handlerException){
            logger.warn("Handling of [" + ex.getClass().getName() + "] resulted in Exception", handlerException);
        }
        return null;
    }

    protected ModelAndView handleUnsatisfiedServletRequestParameter(UnsatisfiedServletRequestParameterException ex,
            HttpServletRequest request,
            HttpServletResponse response,
            Object handler) throws Exception {

        logger.warn(ex.getMessage());
        return new ModelAndView("blank", new ModelMap("reason", ex.getMessage()));

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