发表于: 2019-12-23 23:17:59

1 1136


今天完成的事情:


理了理关于校验的流程和代码


注入依赖


validation-api

提供关于注解的验证,但只有定义没有实现



然后注入依赖hibernate-validator ,此jar包通过了hibernate的校验规则

它的运行还依赖于classmate   jboss-logging


所有依赖

<!--      验证注解,只有定义,没有实现-->
 <dependency>
     <groupId>javax.validation</groupId>
     <artifactId>validation-api</artifactId>
     <version>2.0.1.Final</version>
 </dependency>

<!--通过hibernate校验规则的包-->
 <dependency>
     <groupId>org.hibernate</groupId>
     <artifactId>hibernate-validator</artifactId>
     <version>5.0.1.Final</version>
 </dependency>
 <dependency>
     <groupId>org.jboss.logging</groupId>
     <artifactId>jboss-logging</artifactId>
     <version>3.1.4.GA</version>
 </dependency>
 <dependency>
     <groupId>com.fasterxml</groupId>
     <artifactId>classmate</artifactId>
     <version>1.3.4</version>
 </dependency>




实体添加校验

选择student实体类内的值  添加验证注解   就加了这个5个做测试


//    验证字符串非空,且长度必须大于0
   @NotBlank( message = "student.name.null")
private String name;

   //不为空
   @NotNull( message = "student.qq.null")
private int qq;
   
   //    验证字符串非空,且长度必须大于0
   @NotBlank( message = "student.type.null")
private String type;

   //    验证字符串非空,且长度必须大于0
   @NotBlank( message = "student.time.null")
private String time;

   //最大值不超过30

   @Max(value=30, message = "student.stunum.max")

private int stunum;



controler层内的post方法


先跳转到添加表格的jsp页面 

//get方法跳转表单
@RequestMapping(value = "/add", method = RequestMethod.GET)
public ModelAndView add() {
ModelAndView mv = new ModelAndView();
   mv.setViewName("forpost");
   return mv;
}


forpost.jsp


<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<title>请插入数据</title>
</head>
<body>
<br>请在下方的表单中插入你的数据:</br>
</br>
</br
<form action ="/student/addstudent"  method="POST">
<table>
<tr>
<td>学生ID:<input = "text"  name="id" ></td>
</tr>
<tr>
<td>学生姓名:<input = "text"  name="name" ></td>
</tr>
<tr>
<td>学生QQ:<input = "text"  name="qq" ></td>
</tr>
<tr>
<td>学习类型:<input = "text"  name="type" ></td>
</tr>
<tr>
<td>入学时间:<input = "text"  name="time" ></td>
</tr>
<tr>
<td>学号:<input = "text"  name="stunum" ></td>
</tr>
<tr>
<td>日报:<input = "text"  name="daily" ></td>
</tr>
<tr>
<td>立下愿望:<input = "text"  name="wish" ></td>
</tr>
<tr>
<td>他的师兄:<input = "text"  name="senior" ></td>
</tr>
<tr>
<td>提交按钮:<input type = "submit" value = "提交"></td>
</tr>
</table>
</form>

   </body>

</html>

form表单提交狗,传入controller层的post页面处理


这里使用了@validated函数 对student校验 传入后面的error

然后用hasErrors方法判断错误     主动抛出Exception错误 并传入得到的message

 @RequestMapping(value = "/addstudent",method = RequestMethod.POST)

//   使用@validated注解  对student数据进行校验
//   如果有错误,将student的校验错误,传入到BindingResult
   public ModelAndView addStudent(@Validated Student student,
                                  BindingResult error) throws Exception {

       ModelAndView mav = new ModelAndView();


       if (error.hasErrors()) {

//            error.getFieldError()获取错误信息
//            这段代码的含义是获取错误内容的  默认message的信息(message=xxx

           String message = error.getFieldError().getDefaultMessage();
           throw new Exception(message);

       }
ss.insertStudent(student);
       mav.setViewName("redirect:/student/AllPage");
       return mav;
   }

这段代码写完   如果不主动抛出错误 ,也可以主动去打印错误的字段信息。

但为了结合下面spring的 message Source     这段代码就直接抛出了Exception异常




spring的 message Source  的搭建


先在spring配置文件注册bean

<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">

   <property name="basenames" value="classpath:message" />

   <property name="defaultEncoding" value="UTF-8"/>

   <property name="cacheSeconds" value="60"/>

</bean>


再新建一个message,properties  解析消息请求


前面实体类内的定义

student.name.null=学生姓名不能为空
student.qq.null=学生qq不能为空
student.type.null=学生修真类型不能为空
student.stunum.max=学号不能超过30 !!!
student.time.null=入学时间不能为空


前面的内容是根据实体类内定义信息来写的



新建一个类,接收抛出的所有异常


再新建一个Advice类  用来接受抛出的错误


package controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

@ControllerAdvice
public class  advice {

@Autowired
   private MessageSource messageSource;

   @ExceptionHandler(Exception.class)
public ModelAndView handleException(Exception e) {

String message = e.getMessage();

       String error = messageSource.getMessage(message,null, null);

       ModelAndView mv = new ModelAndView("fail");
       mv.addObject("error", error);
       return mv;
   }
}


@ControllerAdvice是Spring3.2提供的新注解,它是一个Controller增强器

使用这个 Controller ,可以实现三个方面的功能:


全局异常处理
全局数据绑定
全局数据预处理



我们这里只需要使用  统一异常处理


需要配合@ExceptionHandler使用。

@ExceptionHandler 注解用来指明异常的处理类型

当将异常抛到controller时,可以对异常进行统一处理,规定返回的json格式或是跳转到一个错误页面

package controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;


@ControllerAdvice
public class  advice {

@Autowired
   private MessageSource messageSource;


   @ExceptionHandler(Exception.class)
public ModelAndView handleException(Exception e) {


//获取传入的message参数

String message = e.getMessage();

       String error = messageSource.getMessage(message,null, null);

       ModelAndView mv = new ModelAndView("fail");
       mv.addObject("error", error);
       return mv;
   }
}


@ExceptionHandler(Exception.class)即为处理Exception类型的异常

所以可以处理之前controller类抛出的异常

   



后面就是获取messageSource方法的值    获取message自定义错误结果 (error)

传入到ModelAndView中


ApplicationContext接口扩展了MessageSource接口,它有三个方法   我们用的是第2种

虽然用了,但还是不太理解

@Override

public final String getMessage(String codeObject[] argsString defaultMessageLocale locale) {}

/**

** 用来从MessageSource获取消息的基本方法,如果在指定的locale中没有找到消息,则使用默认的消息。args中的参数将使用标准

** 类库中的MessageFormat来作消息中替换值

*/

@Override

public final String getMessage(String codeObject[] argsLocale localethrows NoSuchMessageException {}

/**

** 本质上和上一个方法相同,其区别在:没有指定默认值,如果没找到消息,则会抛出一个 NoSuchMessageException 异常

*/

@Override

public final String getMessage(MessageSourceResolvable resolvableLocale localethrows NoSuchMessageException {}

/**

** 上面方法中所使用属性都封装到一个 MessageSourceResolvable 实现类中,而本方法可以指定 MessageSourceResolvable 实现

*/




添加失败 fail 的jsp页面

<%@page contentType="text/html; charset=utf-8" pageEncoding="utf-8" isErrorPage="true" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<html>
<head>
<title>失败啦失败啦失败啦</title>
</head>
<body>
<h1>添加失败<h1>
<tr>
提示信息
${error}
</tr>
</body>
</html>




测试一下

学号最高为30  我写的33



输出页面~   成功引入了message自定义的值


但其他的测试没出现上面的fail 页面

比如姓名为空

//    验证字符串非空,且长度必须大于0
   @NotBlank( message = "student.name.null")
private String name;
student.name.null=学生姓名不能为空



居然没有报错   传递成功并跳转到了主页面


可是我数据库里name字段设置为非NULL

怎么还能添加成功   





如果qq号为空


就是最基本的传参报错      


不应该也返回fail页面么     


还是说  基本错误显示   的优先级   比校验高一些




遇到的问题:


<!--    //插入单个   传入类型必须为包装型user定义类-->
<insert id="insertStudent"    parameterType="model.Student">
insert into bj (id,name,qq,type,time,stunum,daily,wish,senior) values (#{id},#{name},#{qq},#{type},#{time},#{stunum},#{daily},#{wish},#{senior})
</insert>


insert提交表单  最后一个senior总是提交不了任何参数


报错是sql语句的问题   可是我怎么检查也没问题


明天计划的事情:


提交任务

做任务2的深度思考


任务代码git先提交

任务代码




返回列表 返回列表
评论

    分享到