SpringMVC第六篇【校驗、統一處理異常】

Validation

在咱們的Struts2中,咱們是繼承ActionSupport來實現校驗的…它有兩種方式來實現校驗的功能html

  • 手寫代碼
  • XML配置
    • 這兩種方式也是能夠特定處理方法或者整個Action的

而SpringMVC使用JSR-303(javaEE6規範的一部分)校驗規範,springmvc使用的是Hibernate Validator(和Hibernate的ORM無關)前端

快速入門

導入jar包java

這裏寫圖片描述

配置校驗器web

 <!-- 校驗器 --> <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> 

錯誤信息的校驗文件配置spring

<!-- 校驗錯誤信息配置文件 -->
    <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>

最終添加到適配器中markdown

<!-- 註解適配器 -->
    <bean  class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <!-- 在webBindingInitializer中注入自定義屬性編輯器、自定義轉換器 -->
        <property name="webBindingInitializer" ref="customBinder"></property>
    </bean>

建立CustomValidationMessages配置文件mvc

這裏寫圖片描述

定義規則app

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();
    }
}

測試:jsp

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

這裏寫圖片描述

相關文章
相關標籤/搜索