Reputation: 193
I am new to spring. I am developing a REST api with spring webmvc. 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
I have tried to use ResponseEntityExceptionHandler in my project . but whenever my controller throws exception it never reaches to this ResponseEntityExceptionHandler.
Following are my code snippet
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
<?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-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>
Upvotes: 13
Views: 36290
Reputation: 981
If you have copied the GlobalExceptionHandler from some tutorial, mind that the functions written in "ResponseEntityExceptionHandler
" are different in different spring versions and different functions are called for the same error across different spring version.
Example in version 2.2.0.RELEASE, spring calls method "handleMethodArgumentTypeMismatch
" but in version 2.6.6 (if you send a string in request body for a long declared field), spring's class "ResponseEntityExceptionHandler
" doesn't even have the "handleMethodArgumentTypeMismatch
" method declared, instead it calls the "handleHttpMessageNotReadable
" method.
To go about this, simply generate the @Override
methods that come compiled with the class.
Upvotes: 0
Reputation: 91
To improve on @Javasick's answer which worked for me.
How to setThrowExceptionIfNoHandlerFound to 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;
}
Upvotes: 0
Reputation: 1
Provide an @ExceptionHandler
method for handling internal Spring MVC exceptions. This method returns a ResponseEntity
for writing to the response with a message converter, in contrast to DefaultHandlerExceptionResolver
which returns a ModelAndView
.
Upvotes: 0
Reputation: 19944
Some workarounds,
ResponseEntityExceptionHandler
from another class of your project OR from any other class of your dependencies.ResponseEntityExceptionHandler::handleException
method.NoHandlerFoundException
you should configure the DispatcherServlet to throw and exception if it doesn't find any handlers, link here.Upvotes: 0
Reputation: 186
The issue is that your @ExceptionHandler declares ResourceNotFoundException whereas as a parameter to the handleResourceNotFound you expect RuntimeException. The parameter exception and the value of ExceptionHandler should match.
So it should be:
@ExceptionHandler(value={ResourceNotFoundException.class})
protected ResponseEntity<Object> handleResourceNotFound(ResourceNotFoundException ex, WebRequest request){
}
Upvotes: 1
Reputation: 61
You just need some configuration
In the application.properties or 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 :
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "xx.xxx.xxxx")
@PropertySource("classpath:application.yml")
public class WebAppConfig {
}
Upvotes: 0
Reputation: 12938
There are some reported situations where both ResponseEntityExceptionHandler
and @ControllerAdvice
didn't work.
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.
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.
Upvotes: 0
Reputation: 59056
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? Did you declare it as a bean in any other way?
Also, you don't need to extend ResponseEntityExceptionHandler
if you don't need all the exception mappings it provides.
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.
Upvotes: 18
Reputation: 2983
I got the same issue in Spring WebMVC 4.2.5. The reason was throwExceptionIfNoHandlerFound
parameter of DispatcherServlet
. By default it's value is false
, so all errors generates HttpServletResponse.SC_NOT_FOUND
servlet response and no exceptions throwes.
After I set it to true, my @ExceptionHandlers
started to work
Upvotes: 3