但行好事  莫问前程

SpringMvc4.x基本配置(三):@ControllerAdvice注解

一. 点睛

通过@ControllerAdvice。我们可以将对于控制器的全局配置放置在同一个位置,注解了@ControllerAdvice的类的方法可以使用@ExceptionHandler@InitBinder@ModelAttribute注解到方法上,这对所有注解了@RequestMapping的控制器内的方法有效。

@ExceptionHandler:用于全局处理控制器里面的异常。
@InitBinder:用来设置WebDataBinderWebDataBinder用来自动绑定前台请求参数到Model中。
@ModelAttribute@ModelAttribute本来的作用是绑定键值对到Model里,此处是让全局的@RequestMapping都能获得在此处设置的键值对。

下面将使用@ExceptionHandler处理全局异常,将异常信息更加人性化的输出给用户。

二. 示例

1. 定制@ControllerAdvice

package org.light4j.springMvc4.advice;

import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
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.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;

@ControllerAdvice //①
public class ExceptionHandlerAdvice { 

    @ExceptionHandler(value = Exception.class)//②
    public ModelAndView exception(Exception exception, WebRequest request) {
        ModelAndView modelAndView = new ModelAndView("error");// error页面
        modelAndView.addObject("errorMessage", exception.getMessage());
        return modelAndView;
    }

    @ModelAttribute //③
    public void addAttributes(Model model) {
        model.addAttribute("msg", "额外信息"); //④
    }

    @InitBinder //④
    public void initBinder(WebDataBinder webDataBinder) {
        webDataBinder.setDisallowedFields("id"); //⑤
    }
}

代码解释:

@ControllerAdvice声明一个控制器建言,@ControllerAdvice组合了@Component注解,所以自动注册为Spring的Bean
@ExceptionHandler在此处定义全局处理,通过@ExceptionHandlervalue属性可过滤拦截的条件,在此处可以看出拦截的是所有的Exception
③ 此处使用@ModelAttribute注解将键值对添加到全局,所有注解了@RequestMapping的方法可获得此键值对。
④ 通过@InitBinder注解定制WebDataBinder

下面演示忽略request参数的id,更多关于WebDataBinder的配置,请参考WebDataBinderAPI文档。

2. 演示控制器

package org.light4j.springMvc4.web;

import org.light4j.springMvc4.domain.DemoObj;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class AdviceController {
    @RequestMapping("/advice")
    public String getSomething(@ModelAttribute("msg") String msg,DemoObj obj){//①

        throw new IllegalArgumentException("非常抱歉,参数有误/"+"来自@ModelAttribute:"+ msg);
    }
}

3. 异常展示页面

src/main/resources/views下,新建error.jsp,内容如下:


<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page isELIgnored="false" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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=UTF-8">
<title>@ControllerAdvice Demo</title>
</head>
<body>
    ${errorMessage}
</body>
</html>

4. 运行

访问http://localhost/springMvc4.x-advice/advice?id=1&name=xxx。调试查看DemoObjid被过滤掉了,
如下图所示:
error
且获得了@ModelAttributemsg信息,
如下图所示:
erroe
页面效果如下图所示:

注意点:我在测试的时候,error.jsp里面el表达式的值取不出来,拿不到后台传过来的值。后来找到的原因是:web.xml的头内容版本是2.3的话默认jsp不开启el解析,需要开启解析,在error.jsp头部增加如下配置:

<%@ page isELIgnored="false" %>

增加上面的配置之后问题就解决了。

三. 源代码示例:

github地址:点击查看
码云地址:点击查看

打赏
欢迎关注人生设计师的微信公众账号
公众号ID:longjiazuoA

未经允许不得转载:人生设计师 » SpringMvc4.x基本配置(三):@ControllerAdvice注解

分享到:更多 ()

人生设计师-接受不同的声音

联系我关于我