• 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>

    这里写图片描述


  • 相关阅读:
    CF1202F You Are Given Some Letters...
    CF1178E Archaeology
    PTA (Advanced Level) 1005 Spell It Right
    PTA (Advanced Level) 1004 Counting Leaves
    Qt5——从零开始的Hello World教程(Qt Creator)
    PTA (Advanced Level) 1003 Emergency
    PTA (Advanced Level) 1002 A+B for Polynomials
    HDU 1272 小希的迷宫
    FZU 2150 Fire Game
    HihoCoder
  • 原文地址:https://www.cnblogs.com/zhong-fucheng/p/7554354.html
Copyright © 2020-2023  润新知