zoukankan      html  css  js  c++  java
  • SpringMVC第六篇【校验、统一处理异常】

    Validation

    在我们的Struts2中,我们是继承ActionSupport来实现校验的…它有两种方式来实现校验的功能

    • 手写代码
    • XML配置
      • 这两种方式也是可以特定处理方法或者整个Action的

    而SpringMVC使用JSR-303(javaEE6规范的一部分)校验规范,springmvc使用的是Hibernate Validator(和Hibernate的ORM无关)

    快速入门

    导入jar包

    这里写图片描述

    配置校验器

    
    
    
        <!-- 校验器 -->
        <bean id="validator"
            class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
            <!-- 校验器 -->
            <property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
            <!-- 指定校验使用的资源文件,如果不指定则默认使用classpath下的ValidationMessages.properties -->
            <property name="validationMessageSource" ref="messageSource" />
        </bean>
    
    

    错误信息的校验文件配置

    
        <!-- 校验错误信息配置文件 -->
        <bean id="messageSource"
            class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
            <!-- 资源文件名 -->
            <property name="basenames">
                <list>
                    <value>classpath:CustomValidationMessages</value>
                </list>
            </property>
            <!-- 资源文件编码格式 -->
            <property name="fileEncodings" value="utf-8" />
            <!-- 对资源文件内容缓存时间,单位秒 -->
            <property name="cacheSeconds" value="120" />
        </bean>

    添加到自定义参数绑定的WebBindingInitializer中

    
        <!-- 自定义webBinder -->
        <bean id="customBinder"
            class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
            <!-- 配置validator -->
            <property name="validator" ref="validator" />
        </bean>

    最终添加到适配器中

    
        <!-- 注解适配器 -->
        <bean
            class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
            <!-- 在webBindingInitializer中注入自定义属性编辑器、自定义转换器 -->
            <property name="webBindingInitializer" ref="customBinder"></property>
        </bean>

    创建CustomValidationMessages配置文件

    这里写图片描述

    定义规则

    package entity;
    
    import javax.validation.constraints.NotNull;
    import javax.validation.constraints.Size;
    import java.util.Date;
    
    public class Items {
        private Integer id;
    
        //商品名称的长度请限制在1到30个字符
        @Size(min=1,max=30,message="{items.name.length.error}")
        private String name;
    
        private Float price;
    
        private String pic;
    
        //请输入商品生产日期
        @NotNull(message="{items.createtime.is.notnull}")
        private Date createtime;
    
        private String detail;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name == null ? null : name.trim();
        }
    
        public Float getPrice() {
            return price;
        }
    
        public void setPrice(Float price) {
            this.price = price;
        }
    
        public String getPic() {
            return pic;
        }
    
        public void setPic(String pic) {
            this.pic = pic == null ? null : pic.trim();
        }
    
        public Date getCreatetime() {
            return createtime;
        }
    
        public void setCreatetime(Date createtime) {
            this.createtime = createtime;
        }
    
        public String getDetail() {
            return detail;
        }
    
        public void setDetail(String detail) {
            this.detail = detail == null ? null : detail.trim();
        }
    }
    

    测试:

    
    
    
    <%--
      Created by IntelliJ IDEA.
      User: ozc
      Date: 2017/8/11
      Time: 9:56
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>测试文件上传</title>
    </head>
    <body>
    
    
    <form action="${pageContext.request.contextPath}/validation.action" method="post" >
        名称:<input type="text" name="name">
        日期:<input type="text" name="createtime">
        <input type="submit" value="submit">
    </form>
    
    </body>
    </html>
    
    
    

    Controller需要在校验的参数上添加@Validation注解…拿到BindingResult对象…

    
        @RequestMapping("/validation")
        public void validation(@Validated Items items, BindingResult bindingResult) {
    
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            for (ObjectError allError : allErrors) {
                System.out.println(allError.getDefaultMessage());
            }
    
        }

    由于我在测试的时候,已经把日期转换器关掉了,因此提示了字符串不能转换成日期,但是名称的校验已经是出来了…

    这里写图片描述


    分组校验

    分组校验其实就是为了我们的校验更加灵活,有的时候,我们并不需要把我们当前配置的属性都进行校验,而需要的是当前的方法仅仅校验某些的属性。那么此时,我们就可以用到分组校验了…

    步骤:

    • 定义分组的接口【主要是标识】
    • 定于校验规则属于哪一各组
    • 在Controller方法中定义使用校验分组

    这里写图片描述

    这里写图片描述

    这里写图片描述


    统一异常处理

    在我们之前SSH,使用Struts2的时候也配置过统一处理异常…

    当时候是这么干的:

    • 在service层中自定义异常
    • 在action层也自定义异常
    • 对于Dao层的异常我们先不管【因为我们管不着,dao层的异常太致命了】
    • service层抛出异常,Action把service层的异常接住,通过service抛出的异常来判断是否让请求通过
    • 如果不通过,那么接着抛出Action异常
    • 在Struts的配置文件中定义全局视图,页面显示错误信息

    详情可看:http://blog.csdn.net/hon_3y/article/details/72772559

    那么我们这次的统一处理异常的方案是什么呢????

    我们知道Java中的异常可以分为两类

    • 编译时期异常
    • 运行期异常

    对于运行期异常我们是无法掌控的,只能通过代码质量、在系统测试时详细测试等排除运行时异常

    而对于编译时期的异常,我们可以在代码手动处理异常可以try/catch捕获,可以向上抛出。

    我们可以换个思路,自定义一个模块化的异常信息,比如:商品类别的异常

    
    public class CustomException extends Exception {
    
        //异常信息
        private String message;
    
        public CustomException(String message){
            super(message);
            this.message = message;
    
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
    
    
    }

    我们在查看Spring源码的时候发现:前端控制器DispatcherServlet在进行HandlerMapping、调用HandlerAdapter执行Handler过程中,如果遇到异常,在系统中自定义统一的异常处理器,写系统自己的异常处理代码。。

    这里写图片描述

    这里写图片描述

    我们也可以学着点,定义一个统一的处理器类来处理异常…

    定义统一异常处理器类

    
    public class CustomExceptionResolver implements HandlerExceptionResolver  {
    
        //前端控制器DispatcherServlet在进行HandlerMapping、调用HandlerAdapter执行Handler过程中,如果遇到异常就会执行此方法
        //handler最终要执行的Handler,它的真实身份是HandlerMethod
        //Exception ex就是接收到异常信息
        @Override
        public ModelAndView resolveException(HttpServletRequest request,
                HttpServletResponse response, Object handler, Exception ex) {
            //输出异常
            ex.printStackTrace();
    
            //统一异常处理代码
            //针对系统自定义的CustomException异常,就可以直接从异常类中获取异常信息,将异常处理在错误页面展示
            //异常信息
            String message = null;
            CustomException customException = null;
            //如果ex是系统 自定义的异常,直接取出异常信息
            if(ex instanceof CustomException){
                customException = (CustomException)ex;
            }else{
                //针对非CustomException异常,对这类重新构造成一个CustomException,异常信息为“未知错误”
                customException = new CustomException("未知错误");
            }
    
            //错误 信息
            message = customException.getMessage();
    
            request.setAttribute("message", message);
    
    
            try {
                //转向到错误 页面
                request.getRequestDispatcher("/WEB-INF/jsp/error.jsp").forward(request, response);
            } catch (ServletException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
            return new ModelAndView();
        }
    
    }
    

    配置统一异常处理器

    
        <!-- 定义统一异常处理器 -->
        <bean class="cn.itcast.ssm.exception.CustomExceptionResolver"></bean>

    这里写图片描述


  • 相关阅读:
    只需5分钟就能Get到的神器:Python虚拟环境安装&使用
    Linux——28年桌面进化史
    Linux使用Pidstat命令查看进程状态信息
    提高思维能力的书籍推荐你看这本《决策必读12篇》
    管理和自我管理:领导者自我管理的重要性
    带团队看什么书 ?这本书教你提升团队凝聚力
    基于RNN和CTC的语音识别模型,探索语境偏移解决之道
    详解Spring中Bean的作用域与生命周期
    物联网通信技术,那些你不知道的事
    一招教你数据仓库如何高效批量导入与更新数据
  • 原文地址:https://www.cnblogs.com/zhong-fucheng/p/7554354.html
Copyright © 2011-2022 走看看