@ControllerAdvice Global Error Handling Example in Spring Boot

In this post, we will see @ControllerAdvice Global Error Handling Example in Spring Boot. Let’s see some points.

@ControllerAdvice

  • This annotation introduced in Spring 3.2 and available in org.springframework.web.bind.annotation package.
  • We are going to use @ControllerAdvice and @Exceptionhandler annotations in this example, @ControllerAdvice is used with class level for global error/exception handling in the Spring MVC application and @Exceptionhandler is used with methods(not with class).
  • We have a class called GlobalErrorHandling.java where we are going to use @ControllerAdvice and @Exceptionhandler annotations. We can configure multiple exceptions in this class so that in our application if that exception will occur, this class will get invoked and we will have a proper error message.

Step 1 – open eclipse and create maven project, Don’t forget to check ‘Create a simple project (skip)click on next.

Step 2 –  Fill all details as below and click on finish.

@ControllerAdvice Global Error Handling Example in Spring Boot

Step 3 – Modify pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>exceptionHandlerexample</groupId>
	<artifactId>exceptionHandlerexample</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>exceptionHandlerexample</name>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.2.RELEASE</version>
	</parent>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>

		</dependency>

	</dependencies>

	<build>
		<finalName>${project.artifactId}</finalName>
		<plugins>

			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<fork>true</fork>
					<executable>C:\Program Files\Java\jdk1.8.0_131\bin\javac.exe</executable>
				</configuration>
			</plugin>


		</plugins>
	</build>
</project>

Directory structure –

Book.java

package com.errorhandling;

public class Book {
	String bookId;
	String bookName;
	String bookPrice;



	public String getBookId() {
		return bookId;
	}

	public void setBookId(String bookId) {
		this.bookId = bookId;
	}

	public String getBookName() {
		return bookName;
	}

	public void setBookName(String bookName) {
		this.bookName = bookName;
	}

	public String getBookPrice() {
		return bookPrice;
	}

	public void setBookPrice(String bookPrice) {
		this.bookPrice = bookPrice;
	}

}

Story.java

package com.errorhandling;


public class Story {

	private String storyId;
	private String storyName;
	public String getStoryId() {
		return storyId;
	}
	public void setStoryId(String storyId) {
		this.storyId = storyId;
	}
	public String getStoryName() {
		return storyName;
	}
	public void setStoryName(String storyName) {
		this.storyName = storyName;
	}

	
	
}

BookController.java

package com.errorhandling;

import javax.validation.valueextraction.ExtractedValue;

import org.springframework.boot.ApplicationArguments;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@Controller
@RequestMapping(value = "/book")
public class BookController {

	@RequestMapping(value = "/test", method = RequestMethod.POST)
	@ResponseBody
	public Book getBook(@RequestBody Book book) {

		if (book.getBookId() == null) {
			throw new RecordNotFoundException("Record not found");
		}
		return book;
	}

}

StoryController.java

package com.errorhandling;

import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping(value = "/story")
public class StroyController {
	@RequestMapping(value = "/test", method = RequestMethod.POST)
	@ResponseBody
	public Story getBook(@RequestBody Story story) {

		if (story.getStoryId() == null) {
			throw new RecordNotFoundException("Record not found");
		}
		return story;
	}

}

GlobalErrorHandler.java

package com.errorhandling;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice
public class GlobalErrorHandler {
	@ExceptionHandler(RecordNotFoundException.class)
	@ResponseBody
	public ResponseError handleCustomException(RecordNotFoundException ex) {
		ResponseError responseError = new ResponseError();
		responseError.setErrorMessage(ex.getMessage());
		responseError.setStatusCode(HttpStatus.NOT_FOUND.value());
		return responseError;

	}
}

RecordNotFoundException.java

package com.errorhandling;

public class RecordNotFoundException extends RuntimeException {
	String message;

	public RecordNotFoundException() {
		super();
	}

	public RecordNotFoundException(String message) {
		super(message);
		this.message = message;
	}
}

ResponseError.java

package com.errorhandling;

public class ResponseError {
	private String errorMessage;
	private int statusCode;

	public String getErrorMessage() {
		return errorMessage;
	}

	public void setErrorMessage(String errorMessage) {
		this.errorMessage = errorMessage;
	}

	public int getStatusCode() {
		return statusCode;
	}

	public void setStatusCode(int statusCode) {
		this.statusCode = statusCode;
	}



}

SpringMain.java

package com.errorhandling;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class SpringMain {
	public static void main(final String[] args) {
		final ConfigurableApplicationContext configurableApplicationContext = SpringApplication
				.run(SpringMain.class, args);
		 
		 
	}
}

application.properties

server.port = 9093

We are done. Let’s run and deploy the application.

@ControllerAdvice Global Error Handling

Request data to test BookController’s API – http://localhost:9093/book/test. We are intentionally providing bookId as null so that it will throw an exception and we will have error response.

{
"bookName":"Premchand's best stories",
"bookId":null,
"bookPrice":"10"
}
@ControllerAdvice Global Error Handling

Request data to test StoryController’s API – http://localhost:9093/story/test

{
"storyName":"Push ki Rat",
"storyId":null
}
@ControllerAdvice Global Error Handling

In this example, we have seen how to handle exception/error globally. Suppose we are using our custom exception multiple places i.e we are throwing exception if reord is not there. In this case we will have error message “Record not found”. The same way we can define some other exception. We can also define NullPointerExcpetion or any other predefined exception as well as user-defined exception.

Using @ExceptionHandler and @ControllerAdvice with Filter.

That’s all about @ControllerAdvice Global Error Handling Example in Spring Boot.

You may like –