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>
Exception Handler Define a class that extends the RuntimeException class. You can define the @ExceptionHandler method to handle the exceptions as shown. This method should be used for writing the Controller Advice class file. Now, use the code given below to throw the exception from the API.
Using @ResponseEntity Instead of a HttpStatus 500 exception, we can throw a HttpStatus 404 exception stating the resource not found. In order to do this, we need to use ResponseEntity from the controller method. This ResponseEntity class takes two arguments, one is the returning object itself and other the status code.
ResponseEntityExceptionHandler is a convenient base class for controller advice classes. It provides exception handlers for internal Spring exceptions. If we don't extend it, then all the exceptions will be redirected to DefaultHandlerExceptionResolver which returns a ModelAndView object.
One controller advice class per application. It is a good idea to have all exception handlers in a single class instead of annotating multiple ones with @ControllerAdvice . Write a handleException method.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With