Use of ControllerAdvice annotations

Keywords: Spring xml Java SQL

In order to facilitate the unified management of exceptions, spring mvc provides controlleradvise annotation to deal with exceptions in a unified way. After getting the exception information, you can sit and handle it. For example, it provides a unified web interface to view the exception information, or it sends SMS or email to inform the relevant personnel after the exception information, which can help developers quickly find and locate problems, and reduce the previous online day through viewing Log file troubleshooting is a time-consuming process. Let me introduce the specific steps.

To configure

spring version:

<org.springframework-version>4.1.9.RELEASE</org.springframework-version>  

spring-servlet.xml, note that the annotation must be turned on, that is, XML must have

<?xml version="1.0" encoding="UTF-8"?>  
<beans:beans xmlns="http://www.springframework.org/schema/mvc"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"  
    xmlns:context="http://www.springframework.org/schema/context"  
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd  
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">  

    <!-- DispatcherServlet Context: defines this servlet's request-processing   
        infrastructure -->  

    <!-- Enables the Spring MVC @Controller programming model -->  
    <annotation-driven />  

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving   
        up static resources in the ${webappRoot}/resources directory -->  
    <resources mapping="/resources/**" location="/resources/" />  

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources   
        in the /WEB-INF/views directory -->  
    <beans:bean  
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
        <beans:property name="prefix" value="/WEB-INF/views/" />  
        <beans:property name="suffix" value=".jsp" />  
    </beans:bean>  
    <context:component-scan base-package="org.as.asjee" use-default-filters="false">  
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>  
    </context:component-scan>  

</beans:beans> 

Exception unified processing class

package org.as.asjee.core.exception;

import java.sql.SQLException;

import javax.servlet.http.HttpServletRequest;

import org.as.asjee.core.log.AsJEELogger;
import org.as.asjee.core.log.AsJEELoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

/**
 * Catch exception and handle it uniformly
 * @description TODO
 * @author chen.gs
 * @create date 2016 April 28th 2013
 * @modified by 
 * @modify date
 * @version v1.0
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    private final static AsJEELogger LOG = AsJEELoggerFactory.getLogger(GlobalExceptionHandler.class);

    private final static String EXPTION_MSG_KEY = "message";

    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public void handleBizExp(HttpServletRequest request, Exception ex){
        LOG.info("Business exception handler  " + ex.getMessage() );
        request.getSession(true).setAttribute(EXPTION_MSG_KEY, ex.getMessage());
    }

    @ExceptionHandler(SQLException.class)
    public ModelAndView handSql(Exception ex){
        LOG.info("SQL Exception " + ex.getMessage());
        ModelAndView mv = new ModelAndView();
        mv.addObject("message", ex.getMessage());
        mv.setViewName("sql_error");
        return mv;
    }

}

Custom exception class BussinessException.java

package org.as.asjee.core.exception;

/**
 * Business exception
 * @description TODO
 * @author chen.gs
 * @create date 2016 April 28th 2013
 * @modified by 
 * @modify date
 * @version v1.0
 */
public class BusinessException extends Exception{

    private static final long serialVersionUID = 1L;

    //Business type
    private String bizType;
    //Business code
    private int bizCode;
    //error message
    private String message;

    public BusinessException(String bizType, int bizCode, String message){
        super(message);
        this.bizType = bizType;
        this.bizCode = bizCode;
        this.message = message;
    }

    public BusinessException(String message){
        super(message);
        this.bizType = "";
        this.bizCode = -1;
        this.message = message;
    }

    public BusinessException(String bizType, String message){
        super(message);
        this.bizType = bizType;
        this.bizCode = -1;
        this.message = message;
    }

    public BusinessException(int bizCode, String message){
        super(message);
        this.bizType = "";
        this.bizCode = bizCode;
        this.message = message;
    }

    public String getBizType() {
        return bizType;
    }

    public void setBizType(String bizType) {
        this.bizType = bizType;
    }

    public int getBizCode() {
        return bizCode;
    }

    public void setBizCode(int bizCode) {
        this.bizCode = bizCode;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}

controller

package org.as.asjee.core.security.web;

import java.sql.SQLException;

import javax.annotation.Resource;

import org.as.asjee.core.exception.BusinessException;
import org.as.asjee.core.security.model.User;
import org.as.asjee.core.security.service.UserService;
import org.as.asjee.core.service.ServiceFacade;
import org.as.asjee.core.web.AbstractController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/security/user")
public class UserController  extends AbstractController<User>{

    @Resource
    private UserService userService;
    @Resource
    private ServiceFacade serviceFacade;

    @RequestMapping("login")
    public String login() { 
        return "login";
    }

    @RequestMapping("login2")
    public String login2() throws Exception {
        throw new SQLException("Wrong bird.........");
    }   

    @RequestMapping("login3")
    public String login3() throws Exception { 
        throw new BusinessException("Business execution exception");
    }

    //The exception thrown by this method is not handled by the GlobalExceptionHandler
    //It is processed in the catch block
    @RequestMapping("login4")
    public String login4() { 
        try {
            throw new BusinessException("Business execution exception");
        } catch (BusinessException e) {
            e.printStackTrace();
        }
        return "login";
    }

}

Brief description

When the exception thrown in the Controller is not handled by the catch, the processing method defined in the GlobalExceptionHandler can work. Write the annotation @ ExceptionHandler and its exception class in the method. This method can not only work on Controller, but also on DAO layer and service layer. It can be handled by GlobalExceptionHandler. This writing method is recommended to reduce code intrusion.
Unified exception handling is only one of the uses of annotation ControllerAdvice. If you are interested in learning more, please refer to the spring official website.

Posted by Zaid on Fri, 20 Mar 2020 12:20:20 -0700