How to Show Spring MVC Exception Messages in Same View

27-01-2015

In Spring MVC, sometimes we want to show user-friendly exception messages in the same page to the user after an error occured. To do this, we should handle exceptions in the same controller as shown below:
@RequestMapping(value = "home/addAdmin", method = RequestMethod.GET)
public String viewLogin(Model model) {
    model.addAttribute("admin", new Admin());
    model.addAttribute("roles", adminRoleService.getAll());
    return "/admin/home/addAdmin";
}
 
@RequestMapping(value = "home/addAdmin/submit", method = RequestMethod.POST)
public String addAdmin(@ModelAttribute("admin") @Valid Admin admin, 
BindingResult result, Model model) {
    if (result.hasErrors()) {
        model.addAttribute("roles", adminRoleService.getAll());
        return "/admin/home/addAdmin";
    } else {
        try {
            adminService.add(admin);
        } catch (RuntimeException e) {
            throw new CustomGenericException("500", e.getMessage());
        }
        String message = "New admin created successfully";
        model.addAttribute("admin", admin);
        model.addAttribute("message", message);
        return "/admin/home/addAdmin";
    }
}
 
@ExceptionHandler(value = {CustomGenericException.class})
public ModelAndView handleAllException(CustomGenericException ex, 
HttpServletRequest req) {
    ModelAndView model = new ModelAndView();
    model.addObject("exception", ex);
    model.addObject("url", req.getRequestURL());
    model.addObject("errMsg", "We are sorry. "+
    "Your request cannot be done, please try again later! ");
    model.addObject("admin", new Admin());
    model.addObject("roles", adminRoleService.getAll());
    model.setViewName("/admin/home/addAdmin");
    return model;
}


At line 18, we throw CustomGenericException class and catch this exception at line 27. Also note that at line 36, we set view name same as line 1. Through this configuration, exception message will be shown in the same jsp page.

Note: At line 31, we add Exception object to the model, as a result addAdmin.jsp page will show detailed exception messages as hidden. Because of some security concerns, you can omit this line.


CustomGenericExceptionClass
public class CustomGenericException extends RuntimeException {
 
    private static final long serialVersionUID = 1L;
 
    private String errCode;
    private String errMsg;
 
    public CustomGenericException() {
    }
 
    public String getErrCode() {
        return errCode;
    }
 
    public void setErrCode(String errCode) {
        this.errCode = errCode;
    }
 
    public String getErrMsg() {
        return errMsg;
    }
 
    public void setErrMsg(String errMsg) {
        this.errMsg = errMsg;
    }
 
    public CustomGenericException(String errCode, String errMsg) {
        this.errCode = errCode;
        this.errMsg = errMsg;
    }
 
}


JSP Page (addAdmin.jsp)
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Admin Add Page</title>
    <link href="<c:url value="/resources/css/pure-min.css" />" rel="stylesheet">
    <link href="<c:url value="/resources/css/main.css" />" rel="stylesheet">
</head>
<body>
<div class="b-add-admin">
    <form:form method="post" class="pure-form pure-form-aligned"
               modelAttribute="admin" action="/admin/home/addAdmin/submit">
 
        <fieldset>
            <legend>Admin Add Page</legend>
            <div class="pure-control-group">
               <label for="txtUserName">Username: </label>
                <form:input id="txtUserName" path="username" placeHolder="Username"/>
            </div>
            <div class="pure-control-group">
                <label for="txtPassword">Password: </label>
                <form:password id="txtPassword" path="password" placeHolder="Password"/>
 
           </div>
            <div class="pure-control-group">
                <label for="txtUserName">Name: </label>
                <form:input id="txtUserName" path="name" placeHolder="Name"/>
 
            </div>
            <div class="pure-control-group">
                <label for="txtSurname">Surname: </label>
                <form:input id="txtSurname" path="surname" placeHolder="Surname"/>
 
            </div>
            <div class="pure-control-group">
                <label for="txtEmail">Email: </label>
                <form:input id="txtEmail" path="email" placeHolder="Email"/>
 
            </div>
            <div class="pure-controls">
 
                <button type="submit" class="buttonSubmit">Save</button>
            </div>
 
        </fieldset>
        <form:errors path="*" cssClass="error message" cssStyle="width: 900px"/>
        <c:if test="${not empty errMsg}">
            <h4 class="error message" style="width: 900px">${errMsg}</h4>
        </c:if>
    </form:form>
    <!--
    Failed URL: ${url}
    Exception:  ${exception.message}
        <c:forEach items="${exception.stackTrace}" var="ste">
         ${ste}
    </c:forEach>
    -->
</div>
</body>
</html>

© 2019 All rights reserved. Codesenior.COM