[英]ResponseEntityExceptionHandler is not getting called when exception occurs
I am new to spring.我是 spring 的新手。 I am developing a REST api with spring webmvc.
我正在使用 spring webmvc 开发 REST api。 For Error Handling I got this link http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-ann-rest-spring-mvc-exceptions
对于错误处理,我得到了这个链接http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-ann-rest-spring-mvc-exceptions
I have tried to use ResponseEntityExceptionHandler in my project.我曾尝试在我的项目中使用 ResponseEntityExceptionHandler。 but whenever my controller throws exception it never reaches to this ResponseEntityExceptionHandler.
但每当我的 controller 抛出异常时,它永远不会到达这个 ResponseEntityExceptionHandler。
Following are my code snippet以下是我的代码片段
Controller Controller
@Controller
@RequestMapping("/hello")
public class HelloController {
private static final Logger logger = Logger.getLogger(HelloController.class);
@RequestMapping(value="/{name}", method=RequestMethod.GET)
public @ResponseBody String greet(@PathVariable(value = "name")String name ) throws InvalidInputException, ResourceNotFoundException{
logger.info("start greet() "+name );
System.out.println("start greet() "+name);
String message = null;
if("".equalsIgnoreCase(name))
{
throw new InvalidInputException("Invalid Input");
}
List<String> names = new ArrayList<String>();
names.add("Harshal");
names.add("Smitesh");
if(names.contains(name)){
message = "Hello "+ name;
}else{
throw new ResourceNotFoundException("Requested Resource not found");
}
System.out.println("end greet");
logger.info("end greet()");
return message;
}
}
Exceptions例外
package com.practice.errorhandlerdemo.exception;
public class InvalidInputException extends RuntimeException{
private static final long serialVersionUID = 5489516240608806490L;
public InvalidInputException() {
super("Invalid Input");
}
public InvalidInputException(String message) {
super(message);
}
}
package com.practice.errorhandlerdemo.exception;
public class ResourceNotFoundException extends RuntimeException {
private static final long serialVersionUID = -4041009155673754859L;
public ResourceNotFoundException() {
super("requested resource not found");
}
public ResourceNotFoundException(String message) {
super(message);
}
}
exceptionhandler异常处理程序
@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
private static final Logger logger = Logger.getLogger(RestResponseEntityExceptionHandler.class);
@ExceptionHandler(value={ResourceNotFoundException.class})
@ResponseStatus(value=HttpStatus.NOT_FOUND)
protected ResponseEntity<Object> handleResourceNotFound(RuntimeException ex, WebRequest request){
logger.info("start handleResourceNotFound()");
String bodyOfResponse = "Requested resource does not found";
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
return handleExceptionInternal(ex, bodyOfResponse, httpHeaders, HttpStatus.NOT_FOUND, request);
}
@ExceptionHandler(value={InvalidInputException.class})
@ResponseStatus(value=HttpStatus.BAD_REQUEST)
protected ResponseEntity<Object> handleInvalidInput(RuntimeException ex, WebRequest request){
logger.info("start handleInvalidInput()");
String bodyOfResponse = "Invalid Input";
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
return handleExceptionInternal(ex, bodyOfResponse, httpHeaders, HttpStatus.BAD_REQUEST, request);
}
}
dispatcher servlet调度程序 servlet
<?xml version="1.0" encoding="UTF-8"?>
<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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="com.practice.errorhandlerdemo.controller"/>
<context:annotation-config/>
</beans>
web.xml web.xml
<web-app>
<display-name>ErrorHandlerDemo</display-name>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/my-servlet.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
First, check that your @ControllerAdvice
annotated class is taken into account by your configuration: is it located in a package that's scanned by Spring?首先,检查您的配置是否考虑了您的
@ControllerAdvice
注释类:它是否位于 Spring 扫描的包中? Did you declare it as a bean in any other way?您是否以其他方式将其声明为 bean?
Also, you don't need to extend ResponseEntityExceptionHandler
if you don't need all the exception mappings it provides.此外,如果您不需要它提供的所有异常映射,则不需要扩展
ResponseEntityExceptionHandler
。
A simpler way to write your exception handling:编写异常处理的更简单方法:
@ControllerAdvice
public class RestResponseEntityExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
protected ResponseEntity<String> handleResourceNotFound(ResourceNotFoundException ex){
return ResponseEntity
.status(HttpStatus.NOT_FOUND)
.body("Requested resource does not found");
}
@ExceptionHandler(InvalidInputException.class)
protected ResponseEntity<String> handleInvalidInput(InvalidInputException ex){
return ResponseEntity
.badRequest()
.body("Invalid Input");
}
}
Note that the ResponseEntity
builder API has been in introduced in Spring 4.1, but you can use the regular constructor on 4.0.x.请注意,
ResponseEntity
builder API 已在 Spring 4.1 中引入,但您可以在 4.0.x 上使用常规构造函数。
I got the same issue in Spring WebMVC 4.2.5.我在 Spring WebMVC 4.2.5 中遇到了同样的问题。 The reason was
throwExceptionIfNoHandlerFound
parameter of DispatcherServlet
.原因是
DispatcherServlet
的throwExceptionIfNoHandlerFound
参数。 By default it's value is false
, so all errors generates HttpServletResponse.SC_NOT_FOUND
servlet response and no exceptions throwes.默认情况下,它的值为
false
,因此所有错误都会生成HttpServletResponse.SC_NOT_FOUND
servlet 响应,并且不会抛出异常。
After I set it to true, my @ExceptionHandlers
started to work将其设置为 true 后,我的
@ExceptionHandlers
开始工作
The issue is that your @ExceptionHandler declares ResourceNotFoundException whereas as a parameter to the handleResourceNotFound you expect RuntimeException.问题是您的@ExceptionHandler 声明了ResourceNotFoundException,而作为handleResourceNotFound 的参数,您期望RuntimeException。 The parameter exception and the value of ExceptionHandler should match.
参数 exception 和 ExceptionHandler 的值应该匹配。
So it should be:所以应该是:
@ExceptionHandler(value={ResourceNotFoundException.class})
protected ResponseEntity<Object> handleResourceNotFound(ResourceNotFoundException ex, WebRequest request){
}
Some workarounds,一些解决方法,
ResponseEntityExceptionHandler
from another class of your project OR from any other class of your dependencies.ResponseEntityExceptionHandler
。ResponseEntityExceptionHandler::handleException
method.ResponseEntityExceptionHandler::handleException
方法中放置一个断点。NoHandlerFoundException
you should configure the DispatcherServlet to throw and exception if it doesn't find any handlers, link here .NoHandlerFoundException
,您应该将 DispatcherServlet 配置为在找不到任何处理程序时抛出异常,请在此处链接。There are some reported situations where both ResponseEntityExceptionHandler
and @ControllerAdvice
didn't work.有一些报告的情况是
ResponseEntityExceptionHandler
和@ControllerAdvice
都不起作用。
Both of them are supposed to compile the methods annotated with @ExceptionHandler
under the class into a common place where all the controllers can refer from.他们都应该将类下带有
@ExceptionHandler
注解的方法编译到所有控制器都可以引用的公共位置。
If it doesn't work for you.如果它不适合你。 You can add you
@ExceptionHandler
methods into a common AbstractController
class which is extended by all other controllers.您可以将
@ExceptionHandler
方法添加到由所有其他控制器扩展的通用AbstractController
类中。
You just need some configuration你只需要一些配置
In the application.properties or application.yml :在 application.properties 或 application.yml 中:
server.error.whitelabel.enabled=false
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false
on springboot load your configuration file :在 springboot 上加载您的配置文件:
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "xx.xxx.xxxx")
@PropertySource("classpath:application.yml")
public class WebAppConfig {
}
Provide an @ExceptionHandler
method for handling internal Spring MVC exceptions.提供一个
@ExceptionHandler
方法来处理内部 Spring MVC 异常。 This method returns a ResponseEntity
for writing to the response with a message converter, in contrast to DefaultHandlerExceptionResolver
which returns a ModelAndView
.此方法返回一个
ResponseEntity
用于使用消息转换器写入响应,而DefaultHandlerExceptionResolver
返回一个ModelAndView
。
To improve on @Javasick's answer which worked for me.改进@Javasick 对我有用的答案。
How to setThrowExceptionIfNoHandlerFound to true.如何将ThrowExceptionIfNoHandlerFound 设置为true。
public class AppSetting extends AbstractAnnotationConfigDispatcherServletInitializer {
@NonNull
@Override
protected DispatcherServlet createDispatcherServlet(@NonNull WebApplicationContext servletAppContext) {
final DispatcherServlet servlet = (DispatcherServlet) super.createDispatcherServlet(servletAppContext);
servlet.setThrowExceptionIfNoHandlerFound(true);
return servlet;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.