[华为云在线课程][SpringMVC入门][五][文件上传与校验][学习笔记]

举报
John2021 发表于 2022/07/20 06:49:13 2022/07/20
【摘要】 1.文件上传SpringMVC中对文件上传做了封装,因此我们可以更方便实现文件上传功能。从Spring3.1开始,对于文件上传,提供了两个处理器:CommonsMultipartResolver和StandardServletMultipartResolver。 1.1.CommonsMultipartResolver这个处理器兼容性较好,可以兼容Servlet3.0以前的版本,但依赖co...

1.文件上传

SpringMVC中对文件上传做了封装,因此我们可以更方便实现文件上传功能。从Spring3.1开始,对于文件上传,提供了两个处理器:CommonsMultipartResolver和StandardServletMultipartResolver。

1.1.CommonsMultipartResolver

这个处理器兼容性较好,可以兼容Servlet3.0以前的版本,但依赖commons-fileupload这个第三方工具,所以如果要使用的话,一定记得添加commons-fileupload依赖。

  1. 在pom.xml中添加commons-fileupload依赖:
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>
  1. 在SpringMVC配置文件中配置MultipartResolver:
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver"/>

注意这个Bena一定要有id,并且id必须是multipartResolver。

  1. 创建jsp页面
<%--
  Created by IntelliJ IDEA.
  User: John
  Date: 2022/7/19/0019
  Time: 9:36
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>FileUpload</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="file">
    <input type="submit" value="上传">
</form>
</body>
</html>

注意文件上传是用POST请求,enctype一定是multipart/form-data。

  1. 开发文件上传接口
package org.example.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

@Controller
public class FileUploadController {
    @RequestMapping("/fileupload")
    public String fileupload() {
        return "fileUpload";
    }

    //声明日期格式,注意最后一个/千万不要漏掉
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("/yyyy/MM/dd/");

    @RequestMapping("/upload")
    @ResponseBody
    public String upload(MultipartFile file, HttpServletRequest request) {
        //对当前日期进行格式化
        String format = simpleDateFormat.format(new Date());
        //设置保存路径
        String realPath = request.getServletContext().getRealPath("/img") + format;
        //如果不存在则生成
        File folder = new File(realPath);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        //获取当前文件名作为旧名字
        String oldName = file.getOriginalFilename();
        //使用UUID并截取旧名字后缀进行拼接形成新名字
        String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."));
        try {
            file.transferTo(new File(folder, newName));
            String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/img" + format + newName;
            return url;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "failed";
    }
}

在这个方法中,一共做了四件事:

  • 解决文件保存路径问题,将其保存在项目运行目录下的img目录下,然后利用日期继续分类。
  • 处理文件名问题,使用UUID作为新的文件名字,替换旧的文件名,防止文件名冲突。
  • 保存文件。
  • 生成文件访问路径。

注意:SpringMVC默认是自动拦截静态资源的,意味着上传的图片无法访问。所以,还需要我们在SpringMVC的配置文件中再添加如下配置:

<mvc:resources mapping="/**" location="/"/>

完成之后就可以运行项目了。

当然,默认的配置不一定满足我们的需求,还可以自己手动配置文件上传大小等:

<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
    <!--默认编码-->
    <property name="defaultEncoding" value="UTF-8"/>
    <!--上传的总文件大小-->
    <property name="maxUploadSize" value="1048576"/>
    <!--上传的单文件大小-->
    <property name="maxUploadSizePerFile" value="1048576"/>
    <!--内存中的最大数据量,超过这个数据量,数据开始写入磁盘-->
    <property name="maxInMemorySize" value="4096"/>
    <!--临时目录,超过maxInMemorySize配置的大小后,数据开始写入临时目录,等全部上传完毕后,再将数据合并到正式的文件上传目录-->
    <property name="uploadTempDir" value="file:///D:\\tmp"/>
</bean>

1.2.StandardServletMultipartResolver

这个处理器兼容性差一点,适用于Servlet3.0之后的版本,不依赖第三方工具,使用它可以直接做文件上传。
首先在SpringMVC配置文件中配置Bean:

<bean class="org.springframework.web.multipart.support.StandardServletMultipartResolver" id="multipartResolver"/>

这里Bean的名字依然叫multipartResolver。完成配置后需要注意的是,这个Bean无法直接配置上传文件大小等限制。要在Web.xml中进行配置(即使不需要限制文件上传大小,也需要在Web.xml中配置multipart-config):

<!--springmvc-->
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    <multipart-config>
        <!--文件保存的临时目录,这个目录系统不会主动创建-->
        <location>D:\\temp</location>
        <!--上传的单个文件大小-->
        <max-file-size>1048576</max-file-size>
        <!--上传的总文件大小-->
        <max-request-size>1048566</max-request-size>
        <!--内存中保存的文件最大大小-->
        <file-size-threshold>4096</file-size-threshold>
    </multipart-config>
</servlet>

配置完成后就可以进行文件上传了,其他部分跟上例是一样的。

1.3.多文件上传

多文件上传分为两种,一种是key相同的文件,另一种是key不同的文件。

1.3.1.key相同的文件

key相同的前端页面:

<%--
  Created by IntelliJ IDEA.
  User: John
  Date: 2022/7/19/0019
  Time: 11:59
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>key相同文件上传</title>
</head>
<body>
<form action="/upload2" method="post" enctype="multipart/form-data">
    <input type="file" name="files" multiple>
    <input type="submit" value="上传">
</form>
</body>
</html>

主要是input节点多了个multiple属性。后端用一个数组来接收文件即可:

package org.example.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

@Controller
public class FileUploadController2 {
    @RequestMapping("/fileupload2")
    public String fileupload() {
        return "fileUpload2";
    }

    //声明日期格式,注意最后一个/千万不要漏掉
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("/yyyy/MM/dd/");

    @RequestMapping("/upload2")
    @ResponseBody
    public void upload2(MultipartFile[] files, HttpServletRequest request) {
        //对当前日期进行格式化
        String format = simpleDateFormat.format(new Date());
        //设置保存路径
        String realPath = request.getServletContext().getRealPath("/img") + format;
        //如果不存在则生成
        File folder = new File(realPath);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        try {
            for (MultipartFile file : files) {
                //获取当前文件名作为旧名字
                String oldName = file.getOriginalFilename();
                //使用UUID并截取旧名字后缀进行拼接形成新名字
                String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."));
                file.transferTo(new File(folder, newName));
                String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/img" + format + newName;
                System.out.println(url);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1.3.2.key不同的文件

key不同的文件前端定义如下:

<%--
  Created by IntelliJ IDEA.
  User: John
  Date: 2022/7/19/0019
  Time: 13:16
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>fileUpload3</title>
</head>
<body>
<form action="/upload3" method="post" enctype="multipart/form-data">
    <input type="file" name="file1">
    <input type="file" name="file2">
    <input type="submit" value="上传">
</form>
</body>
</html>

这种情况下,在后端用不同的变量来接收:

package org.example.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

@Controller
public class FileUploadController3 {
    @RequestMapping("/fileupload3")
    public String fileupload() {
        return "fileUpload3";
    }

    //声明日期格式,注意最后一个/千万不要漏掉
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("/yyyy/MM/dd/");

    @RequestMapping("/upload3")
    @ResponseBody
    public void upload2(MultipartFile file1, MultipartFile file2, HttpServletRequest request) {
        //对当前日期进行格式化
        String format = simpleDateFormat.format(new Date());
        //设置保存路径
        String realPath = request.getServletContext().getRealPath("/img") + format;
        //如果不存在则生成
        File folder = new File(realPath);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        try {
            //获取当前文件名作为旧名字
            String oldName = file1.getOriginalFilename();
            //使用UUID并截取旧名字后缀进行拼接形成新名字
            String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."));
            file1.transferTo(new File(folder, newName));
            String url1 = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/img" + format + newName;
            System.out.println(url1);
            
            
            //获取当前文件名作为旧名字
            String oldName2 = file2.getOriginalFilename();
            //使用UUID并截取旧名字后缀进行拼接形成新名字
            String newName2 = UUID.randomUUID().toString() + oldName2.substring(oldName2.lastIndexOf("."));
            file2.transferTo(new File(folder, newName2));
            String url2 = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/img" + format + newName2;
            System.out.println(url2);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.异常处理

项目中,可能会抛出多个异常,不可以直接将异常的堆栈信息展示给用户,有两个原因:

  1. 用户体验不好。
  2. 非常不安全。

所以我们要进行自定义异常处理,SpringMVC中,针对全局异常也提供了相应的解决方案,主要是通过@ControllerAdvice和@ExceptionHandler两个注解来处理的。
以一个文件上传大小超出限制为例,自定义异常只需要提供一个异常处理类即可:

package org.example.exception;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

//一个增强版的Controller
@ControllerAdvice
public class MyException {
    @ExceptionHandler(Exception.class)
    public ModelAndView fileuploadException(Exception e) {
        ModelAndView error = new ModelAndView("error");
        error.addObject("error", e.getMessage());
        return error;
    }
}
  • @ControllerAdvice表示这是一个增强版的Controller,用于全局数据处理。
  • @ExceptionHandler表示这是一个异常处理方法,这个注解的参数,表示需要拦截的异常,参数为Exception表示拦截所有异常,这里也可以具体到某一个异常,如果具体到某一个异常,那么发生了其他异常则不会被拦截到。
  • 异常方法的定义,和Controller中方法的定义一样,可以返回ModelAndView,也可以返回String或者void。

结果展示

以下代码专门拦截处理文件上传异常,和其他异常没有关系,其他异常不会进入到这个自定义异常处理的方法来。

package org.example.exception;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.ModelAndView;

@ControllerAdvice
public class MyUploadException {
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public ModelAndView fileuploadException(MaxUploadSizeExceededException e) {
        ModelAndView error = new ModelAndView("error");
        error.addObject("error", e.getMessage());
        return error;
    }
}

3.数据校验

B/S系统中对http请求数据的校验多数在客户端进行,这也是出于简单及用户体验上考虑,但是在一些安全性要求高的系统中服务端校验是不可缺少的,实际上,几乎所有的系统,凡是涉及到数据校验,都需要在服务端进行二次校验。为什么要在服务端进行二次校验呢?这就需要我们理解客户端校验和服务端校验各自的目的。

  1. 客户端校验,我们主要是为了提高用户体验,例如用户输入一个邮箱地址,要校验这个邮箱地址是否合法,这样没必要发送到服务端校验,直接在前端用JavaScript继续校验即可。但前端校验无法替代后端校验,前端校验可以有效提高用户体验,但无法确保数据完整性,因为在B/S架构中,用户可以方便拿到请求地址,然后直接发送请求来传递非法参数。
  2. 服务端校验,虽然用户体验不好,但可以有效保证数据安全与完整性。
  3. 实际项目中,两个一起用比较好。

Spring支持JSR-303验证框架,JSR-303是Java EE 6中的一项子规范,叫做Bean Validation,官方参考实现是Hibernate Validator(与Hibernate ORM没有关系哈😅),JSR-303用于对Java Bean中的字段的值进行验证。

3.1.普通校验

普通校验是最基本的用法。
首先需要引入所需要的依赖:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.1.0.Final</version>
</dependency>

然后在SpringMVC的配置文件中配置校验的Bean:

<bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" id="validatorFactoryBean">
    <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
</bean>
<mvc:annotation-driven validator="validatorFactoryBean"/>

配置时提供一个LocalValidatorFactoryBean的实例,然后Bean的校验使用HibernateValidator。
提供一个添加学生的页面:

<%--
  Created by IntelliJ IDEA.
  User: John
  Date: 2022/7/19/0019
  Time: 15:33
  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="/addstudent" method="post">
    <table>
        <tr>
            <td>学生编号:</td>
            <td><input type="text" name="id"></td>
        </tr>
        <tr>
            <td>学生姓名:</td>
            <td><input type="text" name="email"></td>
        </tr>
        <tr>
            <td>学生年龄:</td>
            <td><input type="text" name="age"></td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" value="提交">
            </td>
        </tr>
    </table>
</form>
</body>
</html>

在这里需要提交的数据中,假设学生编号不能为空,学生姓名长度不能超过10且不能为空,邮箱地址要合法,年龄不能超过200。在定义实体类的时候就可以将限制条件加入。

package org.example.model;


import javax.validation.constraints.Email;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class Student1 {
    @NotNull
    private Integer id;
    @NotNull
    @Size(min = 2,max = 10)
    private String name;
    @Email
    private String email;
    @Max(200)
    private Integer age;

    public Student1() {
    }

    public Student1(@NotNull Integer id, @NotNull @Size(min = 2, max = 10) String name, @Email String email, @Max(200) Integer age) {
        this.id = id;
        this.name = name;
        this.email = email;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student1{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                '}';
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}
  • @NotNull:表示这个字段不能为空。
  • @Size:表示字符串长度限制。
  • @Email:表示字段值必须是一个邮箱地址。
  • @Max:表示字段最大值。

然后在Controller中定义接口:

package org.example.controller;

import org.example.model.Student1;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
public class Student1Controller {
    @RequestMapping("/addstu1")
    public String addstudent() {
        return "addStudent1";
    }

    @RequestMapping("/addstudent")
    @ResponseBody
    public void addStudent(@Validated Student1 student1, BindingResult result) {
        if (result != null) {
            //校验未通过,获取所有的异常信息并展示出来
            List<ObjectError> allErrors = result.getAllErrors();
            for (ObjectError allError : allErrors) {
                System.out.println(allError.getObjectName() + ":" + allError.getDefaultMessage());
            }
        }
    }
}
  • @Validated:表示Student1中定义的校验规则将会生效。
  • BindingResult:表示出错信息,如果这个变量不为空,表示有错误,否则校验通过。

接下来启动项目。输入数据,查看校验规则是否生效。

如果想自定义错误提示信息的话,首先先修改IDEA的编码配置,File->Settings->Editor->File Encodings,修改为UTF-8。

然后在resources目录下新建一个MyMessage.properties配置文件

student.id.notnull=id 不能为空
student.name.notnull=name 不能为空
student.name.length=name 最小长度为2,最大长度为10
student.email.error=email 地址非法
student.age.error=年龄不能超过200岁

接下来SpringMVC配置文件中进行加载

<bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" id="validatorFactoryBean">
    <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
    <property name="validationMessageSource" ref="bundleMessageSource"/>
</bean>
<bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource" id="bundleMessageSource">
    <property name="basenames">
        <list>
            <value>classpath:MyMessage</value>
        </list>
    </property>
    <property name="defaultEncoding" value="UTF-8"/>
    <property name="cacheSeconds" value="300"/>
</bean>
<mvc:annotation-driven validator="validatorFactoryBean"/>

最后在实体类的注解加上校验出错的提示信息

package org.example.model;


import javax.validation.constraints.Email;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class Student1 {
    @NotNull(message = "{student.id.notnull}")
    private Integer id;
    @NotNull(message = "{student.name.notnull}")
    @Size(min = 2,max = 10,message = "{student.name.length}")
    private String name;
    @Email(message = "{student.email.error")
    private String email;
    @Max(value = 200,message = "{student.age.error}")
    private Integer age;

    public Student1() {
    }

    public Student1(@NotNull Integer id, @NotNull @Size(min = 2, max = 10) String name, @Email String email, @Max(200) Integer age) {
        this.id = id;
        this.name = name;
        this.email = email;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student1{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                '}';
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

配置完成后,启动项目查看效果。

注意:导包时不要导错,如果导入了groupId为org.hibernate.validator的包的话,使用注解时显示包为jakarta.validation.constraints.NotNull;这样运行时就会报出javax.servlet.ServletException: Servlet[springmvc]的Servlet.init()引发异常的错误,通过观察错误信息我们会发现提示nested exception is java.lang.NoClassDefFoundError: javax/validation/ValidatorFactory。说明正确的包应该是javax.validation.constraints.NotNull;

3.2.分组校验

由于校验规则都是定义在实体类上的,但在不同的数据提交环境下,校验规则可能不一样。比如,用户id是自增长的,添加的时候不用传递用户id,但修改时必须传递用户id,这种情况下就需要使用分组校验。
首先定义校验组,其实就是空接口:

public interface ValidationGroup1 {
}
public interface ValidationGroup2 {
}

然后在实体类中,指定每一个校验规则所属的组:

package org.example.model;


import org.example.controller.ValidationGroup1;
import org.example.controller.ValidationGroup2;

import javax.validation.constraints.Email;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class Student1 {
    @NotNull(message = "{student.id.notnull}", groups = ValidationGroup1.class)
    private Integer id;
    @NotNull(message = "{student.name.notnull}", groups = {ValidationGroup1.class, ValidationGroup2.class})
    @Size(min = 2, max = 10, message = "{student.name.length}", groups = {ValidationGroup1.class, ValidationGroup2.class})
    private String name;
    @Email(message = "{student.email.error", groups = {ValidationGroup1.class, ValidationGroup2.class})
    private String email;
    @Max(value = 200, message = "{student.age.error}", groups = {ValidationGroup1.class, ValidationGroup2.class})
    private Integer age;

    public Student1() {
    }

    public Student1(@NotNull Integer id, @NotNull @Size(min = 2, max = 10) String name, @Email String email, @Max(200) Integer age) {
        this.id = id;
        this.name = name;
        this.email = email;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student1{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                '}';
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

在group中指定每一个校验规则所属的组,一个规则可以属于一个组,也可以属于多个组。
在接收参数的地方,指定校验组:

package org.example.controller;

import org.example.model.Student1;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
public class Student1Controller {
    @RequestMapping("/addstu1")
    public String addstudent() {
        return "addStudent1";
    }

    @RequestMapping("/addstudent")
    @ResponseBody
    public void addStudent(@Validated(ValidationGroup2.class) Student1 student1, BindingResult result) {
        if (result != null) {
            //校验未通过,获取所有的异常信息并展示出来
            List<ObjectError> allErrors = result.getAllErrors();
            for (ObjectError allError : allErrors) {
                System.out.println(allError.getObjectName() + ":" + allError.getDefaultMessage());
            }
        }
    }
}

配置完成后,数据ValidationGroup2这个组的校验规则才会生效。

3.3.校验注解

校验注解 含义
@Null 元素必须为null
@NotNull 元素必须不为null
@AssertTrue 元素必须为true
@AssertFalse 元素必须为false
@Min(value) 元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=,min=) 元素的大小必须在指定的范围内
@Digits(integer,fraction) 元素必须是一个数字,其值必须在可接受的范围内
@Past 元素必须是一个过去的日期
@Future 元素必须是一个将来的日期
@Pattern(regex=,flag=) 元素必须符合指定的正则表达式
@NotBlank(message=) 验证字符串非null,且长度必须大于0
@Email 元素必须是电子邮箱地址
@Length(min=,max=) 注解的字符串大小必须在指定的范围内
@NotEmpty 注解的字符串必须非空
@Range(min=,max=,message=) 元素必须在合适的范围内
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。