2016-06-02 2 views
0

Я работаю над обработкой исключений с помощью Spring MVC. Я использую @ControllerAdvice и @ExceptionHandler. Чтобы вернуть JSON, я пробовал оба случая: @ResponseBody и ResponseEntity.@ExceptionHandler ответ не работает в Tomcat

Вот мой контроллер:

@ControllerAdvice 
public class GlobalExceptionController { 

@ExceptionHandler(CustomGenericException.class) 
@ResponseBody 
public ErrorResource handleCustomException(CustomGenericException ex) { 

     ErrorResource errorResource=new ErrorResource("Example 1"); 
    errorResource.error=ex.getErrCode(); 

    return errorResource; 

} 

@ExceptionHandler(Exception.class) 
public ResponseEntity<ErrorResource> handleAllException(Exception ex) { 

    ErrorResource errorResource=new ErrorResource("Example 2"); 
    errorResource.error=ex.getMessage(); 

    return new ResponseEntity<ErrorResource>(errorResource,HttpStatus.NOT_FOUND); 

} 

} 
class ErrorResource { 
public String error; 

public ErrorResource(String a){error=a;} 
} 

Я использую плагин для 7 кот Maven для запуска и отладки приложений, поэтому, когда я отладки я могу видеть, что @ExceptionHandler стреляет и осуществления возврата заявление. Но вместо того, чтобы получать JSON, что я получаю это HTTP 500 ошибка:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is com.mkyong.web.exception.CustomGenericException 
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:979) 
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858) 
javax.servlet.http.HttpServlet.service(HttpServlet.java:621) 
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) 
javax.servlet.http.HttpServlet.service(HttpServlet.java:728) 
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) 

Если я возвращаю представление или ModelView работает, но всякий раз, когда я пытаюсь вернуть ResponseBody или ResponseEntity, я до сих пор получив ту же ошибку.

Наконец, если вместо того, чтобы использовать кота, я использую SpringBoot, чтобы запустить приложение, я не получаю сообщение об ошибке, и я ответ, как я должен получить:

{"error":"E888"} 

Почему не работает с Кот?

Спасибо.

+0

Поскольку поведение полностью находится внутри сервлета, а не проблема Tomcat на всех – Raedwald

ответ

0

Причина в том, как Spring обрабатывает исключение. В простом приложении Spring без загрузки @ExceptionHandler используется exceptionResolver, и он работает для пользователя браузера, или, другими словами, он воспринимается для страницы рендеринга при появлении исключения. Поток вашего запроса не проходит через contenNegotiationResolver, и по этой причине вы продолжаете получать исключение. Весной загрузилась история жизненного цикла запроса, предназначенная для управления исключениями для пользователя браузера, а не для браузера-пользователя, как приложение, и по этой причине он работает, я могу предложить ссылку на официальную документацию для более подробной информации.

Обновить для ответа на комментарий.

В весеннем ботинке вы управляете исключительным по-разному способом уважения простого весеннего приложения mvc для многих деталей. Я предлагаю разместить документацию по ссылке spring boot doc. Если вы хотите использовать простой весенний веб-приложение, я могу предложить использовать аспект. Вы можете использовать обычное использование @ExceptionHandler и вернуть реализацию ModelView в ответ на запрос простой страницы в @Controller Класс без @ResponseBody и создать аспект с тем, который управляет исключением для метода, аннотированного с помощью @ResponseBody, и который возвращает ResponseEntity. Этот аспект может выглядеть так, как показано ниже, обратите внимание, что в этом примере я разработал выражение poincut для перехвата методов, возвращающих ResponseEntity в com.springapp.Пакет MVC:

Формат:

@Aspect 
@Component 
public class GlobalExceptionRestAOPController { 


    private ObjectMapper objectMapper = new ObjectMapper(); 

    @Around("execution(org.springframework.http.ResponseEntity com.springapp.mvc..*(..))") 
    public Object manageException(ProceedingJoinPoint pjp) throws Throwable{ 
     Object result; 
     try{ 
      result = pjp.proceed(); 
     } catch (Exception e){ 
      // log it. 
         result = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).contentType(MediaType.APPLICATION_JSON).body(objectMapper.writeValueAsString(new ExceptionReport(e.toString()))); 

     } 

     return result; 
    } 
} 

class ExceptionReport{ 
    private final String error; 

    public ExceptionReport(String error) { 
     this.error = error; 
    } 

    public String getError() { 
     return error; 
    } 
} 

не забыл вставки в конфигурации

XML стиль:

<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xmlns:aop="http://www.springframework.org/schema/aop" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> 

    <aop:aspectj-autoproxy/> 

    <context:component-scan base-package="com.springapp.mvc"/> 

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
     <property name="prefix" value="/WEB-INF/pages/"/> 
     <property name="suffix" value=".jsp"/> 
    </bean> 

... 
</beans>  

Java стиль:

@Configuration 
@EnableAspectJAutoProxy 
... 
class AspectConfiguration{ 
... 
} 

контроллера :

@Controller 
public class HelloController { 


    @RequestMapping(value = "/jsonHelloEx", method = RequestMethod.GET, produces = "application/json") 
    public ResponseEntity printWelcomeWithException() { 
     String nullableString = null; 
     nullableString.equals(""); 
     return ResponseEntity.ok("Hello"); 
    } 
} 

Я надеюсь, что это может помочь вам

+0

Итак, если я хочу обработать эти исключения, мне нужно реализовать Spring Boot в моем приложении и запустить его оттуда? Это единственный вариант? – rcentellesc

+0

Я обновляю свой answare на примере. Я уверен, что он может помочь вам найти решение вашей проблемы. –

+0

Спасибо за помощь. Фактически, я читал некоторую документацию, и я перенес свое приложение на весеннюю загрузку. Спасибо тебе за все. Я дал вам ответ. – rcentellesc

0

@ExceptionHandler метод не имеет @ResponseBody возвращаемый тип может только возвращать ModelView или String, которое переводится на вид

The return type can be a String, which is interpreted as a view name or a ModelAndView object.

см. здесь для получения дополнительной информации: Spring @ExceptionHandler does not work with @ResponseBody

+1

Это изменилось в задних версиях Весны. См. [Link] (http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/ExceptionHandler.html) – rcentellesc

Смежные вопросы