发表于: 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 code, Object[] args, String defaultMessage, Locale locale) {}
/**
** 用来从MessageSource获取消息的基本方法,如果在指定的locale中没有找到消息,则使用默认的消息。args中的参数将使用标准
** 类库中的MessageFormat来作消息中替换值
*/
@Overridepublic final String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException {}
/**
** 本质上和上一个方法相同,其区别在:没有指定默认值,如果没找到消息,则会抛出一个 NoSuchMessageException 异常
*/
@Overridepublic final String getMessage(MessageSourceResolvable resolvable, Locale locale) throws 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先提交
评论