1. Spring MVC
2. 三层架构
3. MVC
MVC(Model View Controller) 设计创建Web应用程序表现层的模式
- Model 模型 : 数据模型,用于封装数据
View 视图 : 页面视图,用于展示数据
- jsp
- html
Contoller 控制器 :处理用户交互的调度器,用于根据用户需求处理程序逻辑
- Servlet
4. 项目构建 xml
导入坐标
<!-- servlet3.1规范的坐标 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--jsp坐标-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<!--spring web的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<!--springmvc的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.itheima">
<!-- 包含以下注解则加载 -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--放行指定类型静态资源配置方式-->
<!-- <mvc:resources mapping="/img/**" location="/img/"/>-->
<!-- <mvc:resources mapping="/js/**" location="/js/"/>-->
<!-- <mvc:resources mapping="/css/**" location="/css/"/>-->
<!--SpringMVC提供的通用资源放行方式 释放所有静态资源-->
<mvc:default-servlet-handler/>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--乱码处理过滤器,与Servlet中使用的完全相同,差异之处在于处理器的类由Spring提供-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 扫描mvc配置文件 -->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
5. 技术架构图
6. 注解驱动
6.1. 扫描包含Controller注解的类
在springmvc 配置类中
@ComponentScan(value = "com.itheima",includeFilters =
@ComponentScan.Filter(type=FilterType.ANNOTATION,classes = {Controller.class})
)
6.2. 注解配置指定放行的资源
实现WebMvcConfigurer接口 重写addResourceHandlers方法
public class SpringMVCConfiguration implements WebMvcConfigurer{
//注解配置放行指定资源格式
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/img/**").addResourceLocations("/img/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
}
}
6.3. 注解配置放行所有静态资源
实现WebMvcConfigurer接口 重写configureDefaultServletHandling方法
public class SpringMVCConfiguration implements WebMvcConfigurer{
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();;
}
}
6.4. servlet扫描mvc配置文件
继承 AbstractDispatcherServletInitializer 类 重写里面的 createServletApplicationContext createRootApplicationContext 和 getServletMappings 方法
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import java.util.EnumSet;
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//创建Servlet容器时,使用注解的方式加载SPRINGMVC配置类中的信息,并加载成WEB专用的ApplicationContext对象
//该对象放入了ServletContext范围,后期在整个WEB容器中可以随时获取调用
@Override
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
//需要一个MVC配置类
ctx.register(SpringMVCConfiguration.class);
return ctx;
}
//注解配置映射地址方式,服务于SpringMVC的核心控制器DispatcherServlet
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
@Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}
//乱码处理作为过滤器,在servlet容器启动时进行配置,相关内容参看Servlet零配置相关课程
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
CharacterEncodingFilter cef = new CharacterEncodingFilter();
cef.setEncoding("UTF-8");
FilterRegistration.Dynamic registration = servletContext.addFilter("characterEncodingFilter", cef);
registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST,DispatcherType.FORWARD,DispatcherType.INCLUDE),false,"/*");
}
}
7. 请求
7.1. 请求参数
SpringMVC将传递的参数封装到处理器方法的形参中,达到快速访问参数的目的
只需在形参上与请求地址上的参数名字一致 即可获取到请求参数的值
//请求参数 http://localhost/requestParam1?name=hello
@RequestMapping("/requestParam1")
public String requestParam1(String name){
System.out.println(name);
return "index.jsp";
}
7.1.1. 普通类型
参数名与处理器方法形参名保持一致 否则无法获取对应的值
如果想要绑定具体的请求名 则需要使用 @RequestParam
-
- value 请求属性名
- required 不允许为空 默认为true
- defaultValue 为空时默认值
//请求参数形参绑定名 http://localhost/requestParam2?username=hello&age=10
@RequestMapping("/requestParam2")
public String requestParam2(@RequestParam(value = "username",required = true,defaultValue = "zhangsan") String name, int age){
System.out.println(name);
System.out.println(age);
return "index.jsp";
}
7.1.2. POJO类型
如果形参为一个对象 则请求参数会将值 一一对应为对象中属性值
//POJO类型参数 http://localhost/requestParam3?username=zhangsan&age=10
@RequestMapping("/requestParam3")
public String requestParam3(User user){
System.out.println(user.toString());
return "index.jsp";
}
7.1.2.1. POJO类型与普通类型同时存在
将会被同时赋值 如果想进行区分 建议使用@RequestParam进行绑定
//POJO类型参数与普通类型同时存在 http://localhost/requestParam4?name=zhangsan&age=10
@RequestMapping("/requestParam4")
public String requestParam4(User user,String age){
System.out.println(user.toString());
System.out.println(age);
return "index.jsp";
}
7.1.2.2. 复杂POJO类型 嵌套
如果POJO中嵌套POJO则 需要请求地址 需要按照层次结构要书写
//复杂POJO类型 http://localhost/requestParam5?address.city=shanghai
@RequestMapping("/requestParam5")
public String requestParam5(User user){
System.out.println(user.getAddress().getCity());
return "index.jsp";
}
7.1.2.3. 复杂POJO类型 集合
如果POJO中出现集合 保存简单数据 使用多个相同名称的参数为其进行赋值
//复杂POJO类型 集合 http://localhost/requestParam6?nick=zhangsan&nick=lisi&nick=wangwu
@RequestMapping("/requestParam6")
public String requestParam6(User user){
System.out.println(user);
return "index.jsp";
}
7.1.2.4. 复杂POJO类型 集合对象
集合对象 以索引形式的请求地址
//复杂POJO类型 集合对象 http://localhost/requestParam7?addresses[0].province=bj&addresses[1].province=gd
@RequestMapping("/requestParam7")
public String requestParam7(User user){
System.out.println(user.getAddresses());
return "index.jsp";
}
7.1.2.5. 复杂POJO类型 Map集合
Map集合 在请求地址中以 key的形式赋值
//复杂POJO类型 集合对象 http://localhost/requestParam8?addressMap['home'].province=bj&addressMap['job'].province=gd
@RequestMapping("/requestParam8")
public String requestParam8(User user){
System.out.println(user.getAddressMap());
return "index.jsp";
}
7.1.3. 数组类型
请求参数名与数组名一致 并请求参数数量大于1个
//数组类型 http://localhost/requestParam9?nick=abc&nick=def
@RequestMapping("/requestParam9")
public String requestParam9(String[] nick) {
System.out.println(nick[0] + " " + nick[1]);
return "index.jsp";
}
7.1.4. 集合类型
MVC默认将list作为对象处理 赋值前先创建对象 然后将nick作为对象的属性赋值 但list是接口 无法创建对象 和 有此属性值 所以报错
我们通过@RequestParam 将请求参数打包成数组
//集合类型 http://localhost/requestParam10?nick=abc&nick=def
@RequestMapping("/requestParam10")
public String requestParam10(@RequestParam("nick") List<String> nick) {
System.out.println(nick);
return "index.jsp";
}
7.2. 类型转换器
MVC对接受的数据进行自动类型转换 通过Converter接口实现
7.2.1. xml 日期类型格式转换
spring默认的日期格式为 2021/09/11 如果我们传递为2021-09-11则会报错 我们需要自定义日期格式转换
<!-- 自定义转换格式-->
<mvc:annotation-driven conversion-service="conversionService"/>
<!-- 注册bean 让spring管理-->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatters">
<set>
<bean class="org.springframework.format.datetime.DateFormatter">
<property name="pattern" value="yyyy-MM-dd"/>
</bean>
</set>
</property>
</bean>
7.2.2. 注解版 日期类型格式转换
//日期类型 自定义格式转换 http://localhost/requestParam11?date=2021-09-11
@RequestMapping("/requestParam11")
public String requestParam11(@DateTimeFormat(pattern = "yyyy-MM-dd") Date date) {
System.out.println(date);
return "index.jsp";
}
并开启mvc注解驱动
<mvc:annotation-driven />
7.2.3. 自定义类型转换器
实现 Converter 接口 泛型1为原始数据类型 泛型2为返回的数据类型 并实现 convert 方法
<!-- 自定义类型转换器-->
<mvc:annotation-driven conversion-service="conversionService"/>
<!-- 注册bean 让spring管理-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.itheima.converter.MyDateConverter">
</bean>
</set>
</property>
</bean>
处理类
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MyDateConverter implements Converter<String, Date> {
@Override
public Date convert(String s) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
try {
date = simpleDateFormat.parse(s);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
7.3. 请求映射
- @RequestMapping 设置在方法上则是方法体的请求映射 定义在类上则是整个类的访问前缀
- value 请求路径
- method = RequestMethod.GET 请求方式
- params = “name” 请求地址必须传递此属性才能访问
- headers = “content-type=text/*” 请求头条件
- consumes = “text/*” 可以接受的请求正文类型
- produces = “text/*” 可以生成的响应正文类型
8. 响应
8.1. 页面跳转方式
- 转发(默认)
@RequestMapping("/showPageAndData1")
public String showPageAndData1(HttpServletRequest request){
return "forward:success.jsp";
}
- 重定向
@RequestMapping("/showPageAndData7")
public String showPageAndData7(){
return "redirect:index.jsp";
}
- 页面访问快捷设定 设置了快捷访问 后默认访问是设定的路径下制定的后缀文件 默认为转发跳转 无法重定向
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/page/"/>
<property name="suffix" value=".jsp"/>
</bean>
如果方法体没有返回值 也配置了快捷方式 则自动跳转到指定的路径下 访问路径 + 后缀 的文件
8.2. request传递数据
@RequestMapping("/showPageAndData1")
public String showPageAndData1(HttpServletRequest request){
request.setAttribute("name","hello");
return "success.jsp";
}
8.3. Model 类型形参进行数据传递
@RequestMapping("/showPageAndData2")
public String showPageAndData2(Model model){
model.addAttribute("name","hello");
User user =new User();
user.setAge(156);
//可以传递对象
model.addAttribute("user",user);
return "success.jsp";
}
8.4. ModelAndView 类型传递
@RequestMapping("/showPageAndData3")
public ModelAndView showPageAndData3(ModelAndView modelAndView){
modelAndView.addObject("name","hello");
User user =new User();
user.setAge(156);
//添加属性
modelAndView.addObject("user",user);
//跳转页面
modelAndView.setViewName("success.jsp");
return modelAndView;
}
8.4.1. 重定向
@RequestMapping("/showPageAndData5")
public ModelAndView showPageAndData5(ModelAndView modelAndView){
//重定向
modelAndView.setViewName("redirect:index.jsp");
return modelAndView;
}
@RequestMapping("/showPageAndData6")
public ModelAndView showPageAndData6(ModelAndView modelAndView){
//跳转
modelAndView.setViewName("forward:index.jsp");
return modelAndView;
}
8.5. 返回JSON数据
响应方法体 返回的数据默认会直接跳转到 返回值对应的页面文件
我们可以在方法体上 加上 @ResponseBody 注解 来声明为一个响应体
@RequestMapping("showData1")
@ResponseBody
public String showData1() throws JsonProcessingException {
User user = new User();
user.setAge(15);
user.setName("zhangsan");
ObjectMapper om = new ObjectMapper();
return om.writeValueAsString(user);
}
- 返回一个对象或者集合 Jackson 已经帮我们做好了 自定义类型转换了 我们只需要在spring配置中开启注解驱动 即可
<mvc:annotation-driven />
注解版 开启注解驱动 为 @EnableWebMvc
@RequestMapping("showData2")
@ResponseBody
public User showData2() throws JsonProcessingException {
User user = new User();
user.setAge(15);
user.setName("zhangsan");
return user;
}
9. Servlet相关接口
原始的 request response 和 session 提供给我们使用但是不太推荐使用原生的功能
9.1. Head数据获取
- @RequestHeader 获取头中指定的值
@RequestMapping("/headApi")
public String headApi(@RequestHeader("Accept-Language") String head){
System.out.println(head);
return "index.jsp";
}
9.2. Cookie 数据获取
- @CookieValue 获取cookie指定key的值
@RequestMapping("/cookieApi")
public String cookieApi(@CookieValue("_xsrf") String cookie){
System.out.println(cookie);
return "index.jsp";
}
9.3. Session 数据获取和设置
设置 只有在类注解上方标记的变量名称才会被放到session中
获取
@RequestMapping("/sessionApi")
public String sessionApi(@SessionAttribute("name") String session){
System.out.println(session);
return "index.jsp";
}
10. 发送异步请求
通过ajax发送的异步请求 是无法直接被赋值给形参的 需要在形参前面 加上 @RequestBody
@RequestMapping("/ajax1")
public String ajax1(@RequestBody String data) {
System.out.println(data);
return "index.jsp";
}
JSON转POJO 会自动赋值给POJO中属性
@RequestMapping("/ajax2")
public String ajax2(@RequestBody User user) {
System.out.println(user);
return "index.jsp";
}
集合
@RequestMapping("/ajax3")
public String ajax3(@RequestBody List<User> user) {
System.out.println(user);
return "index.jsp";
}
11. 异步请求响应
返回字符串
@RequestMapping("/ajax4")
@ResponseBody
public String ajax4() {
return "hello";
}
返回对象
@RequestMapping("/ajax5")
@ResponseBody
public User ajax5() {
User user = new User();
user.setName("hhh");
user.setAge(13);
return user;
}
返回集合
@RequestMapping("/ajax6")
@ResponseBody
public List ajax6() {
User user = new User();
User user2 = new User();
user.setName("hhh");
user.setAge(13);
user2.setName("qqqq");
user2.setAge(17);
ArrayList<User> arrayList = new ArrayList<>();
arrayList.add(user);
arrayList.add(user2);
return arrayList;
}
12. 跨域访问
当通过A域名下的操作访问 域名B下的资源时 称为跨域访问
我们可以通过设置头信息 开启跨域访问限制
但spring 帮我完成这个操作 我们只需要添加@CrossOrigin 就可以解决 定义在方法体或类上
@RequestMapping("/cross")
@ResponseBody
@CrossOrigin
public void cross() {
}
13. 拦截器
拦截器(Interceptor) 是一种动态拦截方法调用的机制
- 在指定的方法调用前后执行预先设定后的代码
- 阻止原始方法的执行
核心原理:AOP思想
拦截器链:多个拦截器按照一定的顺序 对原始被调用功能进行增强
实现 HandlerInterceptor 接口 重写需要的方法
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("前置运行");
//如果为false 则直接拦截业务处理器不放行
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("后置运行");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("完成运行");
}
}
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/handleRun"/>
<bean class="com.itheima.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
13.1. 拦截器参数
- request 请求对象
- response 响应对象
- handler 被调用的处理器对象,对反射中的method对象进行了包装
- ModelAndView 可以读取或者修改 页面信息和对应数据
- Exception 如果处理器执行中出现异常 如何处理
13.2. 多个拦截器
多个拦截器执行顺序与xml配置有关
但多个拦截器中的前置运行 后置运行 都会同时启用
按照链式 执行顺序
13.3. 责任链模式
14. 异常处理
类注解 @Component 绑定Bean为 并实现 HandlerExceptionResolver 接口 实现方法
此bean会拦截mvc上请求的异常
@Component
public class ExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
System.out.println("发生异常了");
ModelAndView modelAndView =new ModelAndView();
if(e instanceof NullPointerException){
//添加错误信息
modelAndView.addObject("msg","空指针异常");
}else if (e instanceof ArithmeticException){
//添加错误信息
modelAndView.addObject("msg","算术异常");
}else {
//添加错误信息
modelAndView.addObject("msg","未知异常");
}
//转发页面
modelAndView.setViewName("error.jsp");
return modelAndView;
}
}
14.1. 注解版异常处理
- @ExceptionHandler 注解 标记要捕抓的异常
@Component
@ControllerAdvice
public class ExceptionAdivce {
//异常 的类
@ExceptionHandler(NullPointerException.class)
@ResponseBody
public String doNullException(Exception e){
System.out.println("空指针异常");
return "空指针异常";
}
//异常 的类
@ExceptionHandler(ArithmeticException.class)
@ResponseBody
public String doArithmeticException(Exception e){
System.out.println("算术异常");
return "算术异常";
}
//异常 的类
@ExceptionHandler(Exception.class)
@ResponseBody
public String doException(Exception e){
System.out.println("all");
return "all";
}
}
注意事项:
@ExceptionHandler 注解 会比 HandlerExceptionResolver 运行早
HandlerExceptionResolver 无法捕抓到参数异常 而注解可以捕抓到
15. 文件上传下载
坐标
<!--文件上传下载-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
上传文件传递的name 要与 形参的名称一致
16. Restful
16.1. PathVariable
@PathVariable 为Restful 规范的请求路径 赋值给指定形参
并且在@RequestMapping 的 method 指定请求方式
@RequestMapping(value = "/user/{id}",method = RequestMethod.GET)
public String restLocation(@PathVariable Integer id){
System.out.println(id);
return "page.jsp";
}
16.2. RestController
@RestController 结合了 @Controller和@ResponseBody 两个注解的功能
绑定为bean 并且 所有返回内容都不会解析为网页结构
16.3. XXXMapping
如 @GetMapping @PostMapping 请求等等
我们不用在@RequestMapping 中定义指定的请求方式 和 请求路径
只需在方法体加上指定请求方式的注解即
@PostMapping("{id}")
public String postrestLocation(@PathVariable Integer id){
System.out.println(id);
return "page.jsp";
}
17. 表单验证框架
Hibernate框架
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.0.Final</version>
</dependency>
- @Valid 形参注解 开启此形参的验证
- @Valid 属性注解 开启此对象或属性验证 对象校验在对象内部属性定义规则
- @NotBlank(message = “提醒信息”) 属性验证规则 不能为null 并且长度必须大于0和不全为空格 则不能为空
- @NotNull (message = “提醒信息”) 不能为null 可以为空
- @NotEmpty(message = “”) 不能为空和null
- @Max(value = “” , message =” “) 限定最大值
- @Min(value = “” , message = “”) 最小值
- @Range(max = ,min = ,message = ) 最大最小值
@RequestMapping(value = "/addemployee2")
//使用@Valid开启校验,使用@Validated也可以开启校验
//Errors对象用于封装校验结果,如果不满足校验规则,对应的校验结果封装到该对象中,包含校验的属性名和校验不通过返回的消息
public String addEmployee2(@Valid Employee employee, Errors errors, Model m){
//判定Errors对象中是否存在未通过校验的字段
if(errors.hasErrors()){
//获取所有未通过校验规则的信息
List<FieldError> fieldErrors = errors.getFieldErrors();
System.out.println(fieldErrors.size());
for(FieldError error : fieldErrors){
System.out.println(error.getField());
System.out.println(error.getDefaultMessage());
//将校验结果信息添加到Model对象中,用于页面显示,后期实际开发中无需这样设定,返回json数据即可
m.addAttribute(error.getField(),error.getDefaultMessage());
}
//当出现未通过校验的字段时,跳转页面到原始页面,进行数据回显
return "addemployee.jsp";
}
return "success.jsp";
}
@NotBlank(message = "姓名不能为空")
private String name;//员工姓名
//一个属性可以添加多个校验器
@NotNull(message = "请输入您的年龄")
@Max(value = 60,message = "年龄最大值不允许超过60岁")
@Min(value = 18,message = "年龄最小值不允许低于18岁")
private Integer age;//员工年龄
//实体类中的引用类型通过标注@Valid注解,设定开启当前引用类型字段中的属性参与校验
@Valid
private Address address;
17.1. 分组校验
如果不开启分组校验 则会校验当前全部开启校验的属性/对象
在属性/对象校验注解中 加上 groups 属性 并给予一个 用于标识的字节码文件
//设定校验器,设置校验不通过对应的消息,设定所参与的校验组
@NotBlank(message = "姓名不能为空",groups = {GroupA.class})
private String name;//员工姓名
拦截校验器 开启校验注解要改为 @Validated 并加上标识字节码文件
@RequestMapping(value = "/addemployee")
public String addEmployee(@Validated({GroupA.class}) Employee employee, Errors errors, Model m){
if(errors.hasErrors()){
List<FieldError> fieldErrors = errors.getFieldErrors();
System.out.println(fieldErrors.size());
for(FieldError error : fieldErrors){
System.out.println(error.getField());
System.out.println(error.getDefaultMessage());
m.addAttribute(error.getField(),error.getDefaultMessage());
}
return "addemployee.jsp";
}
return "success.jsp";
}
18. SSM
Spring + SpringMVC + MyBatis