Sunday, December 20, 2015

Spring MVC Exception Handling

In my previous post "spring-form-validation-using-spring" I have describe how to use Spring Validation API to validate forms in Spring. In this post I will describe how to use Spring exception handling mechanism and show exception error messages to the end user. For this example I will use same project that I had used in previous post. 

Prerequisites 
  1. You should have install java in your PC and set path variable correctly (JAVA_HOME, JRE_HOME)
  2. You should have install Eclipse Java EE LUNA 4.4 IDE or any IDE you preferred (In this post I'm Using Eclipse )
  3. You should have the project which completed on my previous post "spring-form-validation-using-spring"

In any application it's required to handle the possible exceptions properly and give appropriate error messages to the end users. In generally exceptions and not shown to the end users because it might confused the end user about the system and next major fact would be it exposes system details to the third party. So it increases the security vulnerability as well.
   
Step 1 Lets handle exceptions in URL mapping controller on our project
First of all lets throw exception programetically. To throw a exception lets update our newUser method inside the UserController as bellow.

@RequestMapping("/addUser")
public String newUser(Model model)
{
model.addAttribute("user", new User());
List<String> prefContctMethods=new ArrayList<String>();
prefContctMethods.add("E-mail");
prefContctMethods.add("Call");
model.addAttribute("prefContct", prefContctMethods);
List<String> sexType=new ArrayList<String>();
sexType.add("Male");
sexType.add("Female");
model.addAttribute("sexType", sexType);
if(true)
throw new UnauthorizedAccessException();
return "newUser";
}

Then if you try to access New User link(http://localhost:8080/SpringFirstWeb/addUser) you will see similar result to below image.


To handle this kind of exceptions Spring provide @ExceptionHandler annotation which use to return the JSP file which should redirect when exception occurs. This annotation can be used to specify which Exceptions should be handled on particular method. To specify that we have to mention exception class names inside two parenthesis.

For a example
  @ExceptionHandler({RuntimeException.class,IOException.class})
public String exceptionHandler()
{
return "exceptionError";
}

with above method our updated UserController class will be similar to below.

package spring.first.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.sun.servicetag.UnauthorizedAccessException;

import spring.first.data.UserService;
import spring.first.data.validator.UserValidator;
import spring.first.model.User;

@Controller
public class UserController {
@Autowired
UserService userService;

@RequestMapping("/userHandling")
public String home()
{
return "userMain";
}
@RequestMapping("/addUser")
public String newUser(Model model)
{
model.addAttribute("user", new User());
List<String> prefContctMethods=new ArrayList<String>();
prefContctMethods.add("E-mail");
prefContctMethods.add("Call");
model.addAttribute("prefContct", prefContctMethods);
List<String> sexType=new ArrayList<String>();
sexType.add("Male");
sexType.add("Female");
model.addAttribute("sexType", sexType);
if(true)
throw new UnauthorizedAccessException();
return "newUser";
}
@ExceptionHandler({RuntimeException.class,IOException.class})
public String exceptionHandler()
{
return "exceptionError";
}
@RequestMapping(value="saveUser", method=RequestMethod.POST )
public String saveUser(@Valid @ModelAttribute User user,Errors errors, Model model)
{
System.out.println(user);
if(errors.hasErrors())
{
List<String> prefContctMethods=new ArrayList<String>();
prefContctMethods.add("E-mail");
prefContctMethods.add("Call");
model.addAttribute("prefContct", prefContctMethods);
List<String> sexType=new ArrayList<String>();
sexType.add("Male");
sexType.add("Female");
model.addAttribute("sexType", sexType);
return "newUser";
}
userService.saveUser(user);
model.addAttribute("users", userService.getMockedUsers());
return "allUsers";
}
@RequestMapping("/allUsers")
public String allUsers( Model model)
{
model.addAttribute("users", userService.getMockedUsers());
return "allUsers";
}
@InitBinder
public void initBinder(WebDataBinder binder)
{
binder.addValidators(new UserValidator());
}
}


Here we have to add new exceptionError.jsp file in to the JSP folder. I will add following content in to this JSP.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
Error Occurred please contact system administrator for further assistance.
</body>
</html>

Lets restart the server and again we try to access New User URL. (http://localhost:8080/SpringFirstWeb/addUser) You can be expect similar interface to below.



We have completed project with Spring MVC Exception handling and  I will add some advanced features of Spring framework in upcoming posts.

No comments:

Post a Comment