Signup/Sign In

Spring REST Exception Handling

In this article, we are going to add exception handling in the Spring REST application. In our previous topic, we learned to create a REST application with an example. Now, we will see error/exception handling to avoid abnormal termination of the application.

It is important to cop the application with bad input or not found resource error. Sometimes when a user requests a resource that does not exist then he faces a 404 - not found.

We created a project that contains several files, you can get most of the file code from the previous topic, here we have provided code for exception handling only.

Project Structure

// CustomerErrorResponse.java

This class is made to design error messages for the user. It contains message attributes like status, message, and timeStamp to provide meaningful information to the user.

package com.studytonight.springdemo.rest;

public class CustomerErrorResponse {
	
	private int status;
	private String message;
	private long timeStamp;
	public CustomerErrorResponse(int status, String message, long timeStamp) {
		super();
		this.status = status;
		this.message = message;
		this.timeStamp = timeStamp;
	}
	public int getStatus() {
		return status;
	}
	public void setStatus(int status) {
		this.status = status;
	}
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
	public long getTimeStamp() {
		return timeStamp;
	}
	public void setTimeStamp(long timeStamp) {
		this.timeStamp = timeStamp;
	}
}

// CustomerNotFoundException.java

Here, we are creating a custom exception class to generate an exception object. It extends RuntimeException class that makes its object an exception.

package com.studytonight.springdemo.rest;

public class CustomerNotFoundException extends RuntimeException{

	public CustomerNotFoundException() {
		super();
	}
	public CustomerNotFoundException(String message, Throwable cause, boolean enableSuppression,
			boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
	}
	public CustomerNotFoundException(String message, Throwable cause) {
		super(message, cause);

	}
	public CustomerNotFoundException(String message) {
		super(message);

	}
	public CustomerNotFoundException(Throwable cause) {
		super(cause);
	}
}

// CustomerRestController.java

This controller class throws a custom exception if the customer id is not found. See, we used custom exception CustomerNotFoundException to handle the application flow.

package com.studytonight.springdemo.rest;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.studytonight.springdemo.entity.Customer;
import com.studytonight.springdemo.service.CustomerService;

@RestController
public class CustomerRestController {

	@Autowired
	private CustomerService customerService;
	
	@GetMapping("/customers")
	public List<Customer> getCustomers(){
		return customerService.getCustomers();
	}
	
	@GetMapping("/customers/{customerId}")
	public Customer getCustomer(@PathVariable int customerId){
		Customer customer = customerService.getCustomer(customerId);
		if(customer == null) {
			throw new CustomerNotFoundException("Customer Id not Found : "+customerId);
		}
		return customerService.getCustomer(customerId);
	}
	
	@PostMapping("/customers")
	public Customer addCustomer(@RequestBody Customer customer){
		customer.setId(0);
		customerService.saveCustomer(customer);
		return customer;
	}
	
	@PutMapping("/customers")
	public Customer updateCustomer(@RequestBody Customer customer){
		customerService.saveCustomer(customer);
		return customer;
	}
	
	@DeleteMapping("/customers/{customerId}")
	public String deleteCustomer(@PathVariable int customerId){
		customerService.deleteCustomer(customerId);
		return "Deleted Customer Id: "+customerId;
	}
}

// CustomerRestExceptionalHandler.java

It is a custom exception handler class that uses Spring ExceptionHandler to handle exceptions. Here, we are handling, NOT_FOUND, and BAD_REQUEST exceptions by using this class.

package com.studytonight.springdemo.rest;

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

@ControllerAdvice
public class CustomerRestExceptionalHandler {
	@ExceptionHandler
	public ResponseEntity<CustomerErrorResponse> handleException(CustomerNotFoundException e){
		CustomerErrorResponse error = new CustomerErrorResponse(HttpStatus.NOT_FOUND.value(), e.getMessage(), System.currentTimeMillis());
		return new ResponseEntity<CustomerErrorResponse>(error, HttpStatus.NOT_FOUND);
	}	
	@ExceptionHandler
	public ResponseEntity<CustomerErrorResponse> handleException(Exception e){
		CustomerErrorResponse error = new CustomerErrorResponse(HttpStatus.BAD_REQUEST.value(), e.getMessage(), System.currentTimeMillis());
		return new ResponseEntity<CustomerErrorResponse>(error, HttpStatus.BAD_REQUEST);
	}	
}

Run the Application

After successfully completing the project and adding the dependencies run the application using the server and you will get the output as below.

To test the application, we used a Postman application. It is a good application to check web requests. You can install it from the official site and then use it.

Access All the Customers

Access a Single Customer by ID

We can access individual customers by their id, but if the record does not found then we get a message.

Bad Input

It may be, if a user enters a non-numeric id then we application handle the exception and provides an appropriate message to the user.



About the author:
I am a Java developer by profession and Java content creator by passion. I have over 5 years of experience in Java development and content writing. I like writing about Java, related frameworks, Spring, Springboot, etc.