03-SpringBoot进阶

news2024/9/22 19:40:56

知识回顾

知识目标

1、SpringBoot单元测试【掌握】
2、SpringBoot 整合 MybatisPlus【重点】
3、SpringBoot添加分页插件【掌握】
4、SpringBoot定义拦截器【掌握】
5、SpringBoot使用类型转换器【掌握】
6、文件上传【掌握】
7、SpringBoot异常处理【掌握】
8、SpringBoot定时任务【掌握】
9、SpringBoot热部署【掌握】
10、服务端表单数据校验【掌握】

贯穿案例

切片一、SpringBoot整合单元测试

1、如何使用SpringBoot整合单元测试

在pom.xml中添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>

添加测试类

提示:测试类必须和启动类在同一个包或子包下

package demo.test;

import com.baomidou.mybatisplus.core.metadata.IPage;
import demo.Demo;
import demo.entity.PageInfo;
import demo.entity.User;
import demo.mappers.UserMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {Demo.class}) //启动类
public class JTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void test1(){
        System.out.println("我是一个测试方法");
    }
}

2、课堂编程

需求

使用单元测试向控制台输出1-100之间整数相加的和

关键思路

- 在启动类的子包下创建单元测试类JTest
- 在类上添加单元测试的注解
- 创建单元测试方法输出0-100整数相加的和

3、切片小结

在项目中使用单元测试的关键要点是什么
1、在pom.xml中添加单元测试的依赖
2、在启动类的子包中添加单元测试类,并使用@RunWith注解标注单元测试类,@SpringBootTest注解标注启动类
3、创建测试方法,并使用@Test注解标注
4、注意:单元测试类的类名不可以叫Test

切片二、SpringBoot整合MyBatis

1、如何使用SpringBoot整合MyBatisPlus

1.1、两个必要组件

MyBatis-Spring-Boot-Starter

mybatis-spring-boot-starter是 MyBatis 帮助我们快速集成 SpringBoot 提供的一个组件包,使用这个组件可以做到以下几点:

  • 自动检测现有的DataSource
  • 将创建并注册SqlSessionFactory的实例,该实例使用SqlSessionFactoryBean将该DataSource作为输入进行传递,将创建并注册从SqlSessionFactory中获取的SqlSessionTemplate的实例。
  • 自动扫描您的mappers,将它们链接到SqlSessionTemplate并将其注册到Spring上下文,以便将它们注入到您的bean中

使用了该Starter之后,只需要定义一个DataSource即可(application.properties或application.yml中可配置),它会自动创建使用该DataSource的SqlSessionFactoryBean以及SqlSessionTemplate。会自动扫描你的Mappers,连接到SqlSessionTemplate,并注册到Spring上下文中。

spring-boot-starter-jdbc

从 Spring Boot 2.0 开始,spring-boot-starter-jdbc内部提供了默认的 HikariCP 数据库连接池,(也是传说中最快的数据库连接池)。spring-boot-starter-jdbc主要提供了三个功能,第一个就是对数据源的装配,第二个就是提供一个JdbcTemplate简化使用,第三个就是事务。

1.2、SpringBoot整合连接池

pom.xml中添加依赖

   <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.7.RELEASE</version>
    </parent>

    <dependencies>
        <!--springmvc启动器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.22</version>
            <scope>runtime</scope>
        </dependency>
        <!--spring默认数据库连接池-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!--springboot整合mybaits plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>

        <!--mybatis plus自动代码生成-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.0</version>
            <scope>compile</scope>
        </dependency>

        <!--mybatis-plus默认模板-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.2</version>
        </dependency>

        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

创建SpringBoot配置文件

创建springboot的配置文件application.properties

  • 配置HikariCP
#连接数据库的四大参数
spring:
  datasource:
    url: jdbc:mysql://10.211.55.2:3306/t_mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
    username: root
    password: Aa123123.
    #以下四个参数可省略,Springboot自动推断
    driverClassName: com.mysql.cj.jdbc.Driver
    hikari.idle-timeout: 60000
    hikari.maximum-pool-size: 30
    hikari.minimum-idle: 10

扩展:配置druid

如果你更喜欢Druid连接池,也可以使⽤Druid官⽅提供的启动器,那麼就不需要spring-boot-starter-jdbc启动器了。

  • ⽽连接信息的配置与上⾯是类似的,只不过在连接池特有属性上,⽅式略有不同:
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/woniu_db?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.max-wait=60000
#初始化连接数
spring.datasource.initial-size=1 #最⼩空闲连接
spring.datasource.min-idle=1 #最⼤活动连接
spring.datasource.max-active=20
#获取连接时测试是否可⽤
spring.datasource.test-on-borrow=true
#监控⻚⾯启动
spring.datasource.stat-view-servlet.allow=true

1.3、配置MyBatisPlus

-在启动类上通过@MapperScan注解扫描dao

package demo;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("demo.mappers") //扫描DAO
public class Demo {
    public static void main(String[] args) {
        SpringApplication.run(Demo.class, args);
    }
}

1.3、编写业务代码

-实体:User

package demo.entity;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("t_user")
public class User {
    @TableId
    private int id;
    private String userName;
    private String passwd;
}

-DAO:UserMapper

package demo.mappers;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import demo.entity.User;
import org.springframework.stereotype.Repository;

@Repository
public interface UserMapper extends BaseMapper<User> {
        
}

-单元测试:TestMyBatis

package demo.test;

import demo.Demo;
import demo.entity.User;
import demo.mappers.UserMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {Demo.class}) //启动类
public class TestMyBatis {
    @Autowired
    private UserMapper userMapper;
    
    @Test
    public void test1(){
        List<User> users = userMapper.selectList(null);
        for(User user : users){
            System.out.println(user);
        }
    }
}

2、课堂编程

需求

使用MyBatisPlus完成用户管理的增删改查功能

关键思路

- 创建SpringBoot项目
- 在pom中添加MyBatisPlus相关依赖
- 在application.yml中配置数据源
- 在启动类中扫描dao
- 创建User实体映射数据库t_user表
- 创建UserMapper访问数据库
- 创建测试类TestUser,提供4个测试方法,分别是:addUser、deleteUser、updateUser、loginUser

3、切片小结

在SpringBoot中使用MyBatisPlus的关键步骤是什么?
1、创建SpringBoot项目
2、在pom中添加MyBatisPlus相关依赖
3、在application.yml中配置数据源
4、在启动类通过@MapperScan注解扫描DAO
5、添加业务代码:实体层、数据库访问层、单元测试

切片三、SpringBoot整合分页插件

1、如何使用SpringBoot整合分页插件

-在pom.xml中添加相关依赖

		<!-- 分页插件-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.3.1</version>
        </dependency>

-在UserMapper中实现分页查询用户列表

package demo.mappers;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import demo.entity.User;
import org.springframework.stereotype.Repository;

@Repository
public interface UserMapper extends BaseMapper<User> {

    /**
     * 查询所有并分页
     * @param pageNo
     * @param pageSize
     * @return
     */
    default  IPage<User> listUserPage(Integer pageNo, Integer pageSize){
        //实例化mybatis plus的分页对象
        Page<User> page = new Page<>(pageNo, pageSize);//参数一是当前页,参数二是每页个数
        //获得数据  参数一:分页参数   参数二:查询条件,没有查询条件则为null
        IPage<User> mapIPage=this.selectPage(page,null);
        return mapIPage;
    }
}

-单元测试

package demo.test;

import com.baomidou.mybatisplus.core.metadata.IPage;
import demo.Demo;
import demo.entity.PageInfo;
import demo.entity.User;
import demo.mappers.UserMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {Demo.class}) //启动类
public class TestPage {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void test1(){
        //获得分页数据
        IPage<User> userPage = userMapper.listUserPage(1,3);
        //将数据保存到分页数据对象中
        PageInfo<User> pageInfo = new PageInfo<User>(userPage);
        System.out.println(pageInfo);
    }
}

2、课堂编程

需求

结合BootStrap+VUE实现用户列表的展示,要求带分页器

关键思路

后台开发
- 创建SpringBoot项目,并添加web依赖
- 添加并配置数据源
- 在pom中添加MyBatisPlus依赖
- 在启动类通过@MapperScan注解扫描DAO
- 在pom中添加PageHelper依赖
- 编写业务代码:Controller层、Service层、DAO层、domain层
前台开发
- 创建一个html页面,并导入VUE和BootStrap的相关css、js库
- 使用BootStrap的表格样式和分页导航样式实现页面的绘制
- 使用axios请求后台Controller响应带有分页的用户列表
- 通过vue的双向绑定,将用户列表数据通过v-for指令渲染到html表格

3、切片小结

在MyBatisPlus中使用分页插件的关键步骤是什么?
1、创建SpringBoot项目,并添加web依赖
2、添加并配置数据源
3、在pom中添加MyBatisPlus依赖
4、在启动类通过@MapperScan注解扫描DAO
5、在pom中添加PageHelper依赖
6、在Mapper的分页查询方法中创建Page对象设置起始页和每页显示的条数
7、在Mapper的分页查询方法中调用selectPage方法实现分页查询

切片四、SpringBoot使用类型转换器

1、为什么要使用类型转换器

前端调用后端接口,后端需要将输入参数解析为Java中的数据类型,但是Spring仅支持对于基本类型的转换,对于Spring转Date,或者Long转Date这些,是需要提供自定义类型转换器来进行转换的。

2、如何在SpringBoot中使用类型转换器

-添加日期类型转换处理类MyDateConverter

package demo.convert;

import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

@Component
public class MyDateConverter implements Converter<String, Date> {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    @Override
    public Date convert(String source) {
        try {
            return sdf.parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}

-在Controller中测试

	@RequestMapping("/tt2")
    public Date test2(Date birth){
        System.out.println(birth);
        return birth;
    }

-在浏览器中进行测试

在这里插入图片描述

3、课堂编程

将以上案例练习一遍

4、切片小结

在SpringBoot中使用类型转换器的关键步骤是什么?
1、创建类型转换器类MyDateConverter
2、实现Convert接口
3、实现convert方法,添加转换的功能

切片五、SpringBoot异常处理

1、为什么使用SpringBoot异常处理

       在项目中,我们不可能能够预知并catch所有的异常,为了避免非期望异常抛给客户端,Spring为我们提供了统一异常处理的机制@RestControllerAdvice,能够让我们在逻辑抛出异常时,能够将异常友好化或者指定返回的数据结构给前台。

1、如何使用SpringBoot实现异常处理

添加全局异常处理类ExceptionHandleAdvice

package demo.exception;

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class ExceptionHandleAdvice {
    @ExceptionHandler(Exception.class)
    public String exceptionHandle(Exception e){
        System.out.println(e); //处理异常,比如保存日志
        return "系统异常!";
    }
}

在controller中模拟500错误

package demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class Test1 {
    
    @RequestMapping("/t1")
    public String t1(){
        System.out.println(1/0); //模拟错误
        return "hello";
    }
}

运行效果:
在这里插入图片描述
在这里插入图片描述

2、课堂编程

按照以上案例再次操练

3、课堂小结

实现全局异常处理的关键步骤是什么?
1、添加全局异常处理类,并使用@RestControllerAdvice注解标注
2、添加处理异常的方法,并使用@ExceptionHandler(Exception.class)注解标注

切片六、SpringBoot实现定时任务

1、如何使用SpringBoot实现定时任务

在pom.xml中添加依赖

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

创建定时任务类

package demo.schedule;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class SaticScheduleTask {
    /**
     *定时任务方法
     * @Scheduled:设置定时任务 cron 属性:cron 表达式。定时任务触发是时间的一个字符串表达形式
     */
    //@Scheduled(cron = "0/2 * * * * ?")
    @Scheduled(fixedRate=2000) //每2秒钟执行一次
    public void scheduledMethod() {
        System.out.println("定时器被触发" + new Date());
    }
}

在启动类中开启定时任务

package demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling //开启定时任务
public class Demo {
    public static void main(String[] args) {
        SpringApplication.run(Demo.class, args);
    }
}

测试效果

在这里插入图片描述

扩展:Cron 表达式

Cron 表达式是一个字符串,分为 6 或 7 个域,每一个域代表一个含义;
Cron 从左到右(用空格隔开): 秒   分   小时   月份中的日期   月份   星期中的日期    年份

Cron 有如下两种语法格式:

  • Seconds Minutes Hours Day Month Week Year
  • Seconds Minutes Hours Day Month Week
序号说明取值表达式
10-59-*/
2分钟0-59-*/
3小时0-23-*/
41-31-*/LWC
51-12-*/
6星期1-7-*?/LC#
7年(可选)1970-2099-*/

Cron 表达式的时间字段除允许设置数值外,还可使用一些特殊的字符,提供列表、范围、通配符等功,如下:

  • 星号(**):可用在所有字段中,表示对应时间域的每一个时刻,例如,*在分钟字段时,表示“每分钟”;
  • 问号(?):该字符只在日期和星期字段中使用,它通常指定为“无意义的值”,相当于占位符;
  • 减号(-):表达一个范围,如在小时字段中使用“10-12”,则表示从 10 到 12 点,即 10,11,12;
  • 逗号(,):表达一个列表值,如在星期字段中使用“MON,WED,FRI”,则表示星期一,星期三和星期五;
  • 斜杠(/):x/y 表达一个等步长序列,x 为起始值,y 为增量步长值。如在分钟字段中使用 0/15,则表示为 0,15,30 和 45 秒,而 5/15 在分钟字段中表示 5,20,35,50,你也可以使用*/y,它等同于 0/y;
  • L:该字符只在日期和星期字段中使用,代表“Last”的意思,但它在两个字段中意思不同。L 在日期字段中,表示这个月份的最后一天,如一月的 31 号,非闰年二月的 28 号;如果 L 用在星期中,则表示星期六,等同于 7。但是,如果 L 出现在星期字段里,而且在前面有一个数值 X,则表示“这个月的最后 X 天”,例如,6L 表示该月的最后星期五;
  • W:该字符只能出现在日期字段里,是对前导日期的修饰,表示离该日期最近的工作日。例如 15W表示离该月 15 号最近的工作日,如果该月 15 号是星期六,则匹配 14 号星期五;如果 15 日是星期日,则匹配 16 号星期一;如果 15 号是星期二,那结果就是 15 号星期二。但必须注意关联的匹配日期不能够跨月,如你指定 1W,如果 1 号是星期六,结果匹配的是 3 号星期一,而非上个月最后的那天。W 字符串只能指定单一日期,而不能指定日期范围;
  • LW 组合:在日期字段可以组合使用 LW,它的意思是当月的最后一个工作日;
  • 井号(#):该字符只能在星期字段中使用,表示当月某个工作日。如 6#3 表示当月的第三个星期五(6表示星期五,#3 表示当前的第三个),而 4#5 表示当月的第五个星期三,假设当月没有第五个星期三,忽略不触发;
  • C:该字符只在日期和星期字段中使用,代表“Calendar”的意思。它的意思是计划所关联的日期,如果日期没有被关联,则相当于日历中所有日期。例如 5C 在日期字段中就相当于日历 5 日以后的第一天。1C 在星期字段中相当于星期日后的第一天。

案例说明:

@Scheduled(cron = "0 0 1 1 1 ?")//每年一月的一号的 1:00:00 执行一次
@Scheduled(cron = "0 0 1 1 1,6 ?") //一月和六月的一号的 1:00:00 执行一次
@Scheduled(cron = "0 0 1 1 1,4,7,10 ?") //每个季度的第一个月的一号的 1:00:00 执行一次
@Scheduled(cron = "0 0 1 1 * ?")//每月一号 1:00:00 执行一次
@Scheduled(cron="0 0 1 * * *") //每天凌晨 1 点执行一次

2、课堂编程

将以上案例再次操练

3、课堂小结

使用定时任务的关键步骤有哪些?
1、在pom.xml中添加依赖
2、在启动类中使用@EnableScheduling注解开启定时任务
3、创建定时任务类,通过@Scheduled注解规定任务执行的周期

切片七、SpringBoot实现热部署

1、什么是热部署

	作为一个Java程序员,在日常的工作中,经常需要修改代码,然后重启服务,在验证代码是否生效。如果是小项目还好,重启速度比较快,等待时间比较短。但是随着项目逐渐变大,并且被拆分成多个服务时,改动一些代码,可能需要重启多个服务才能生效。这样下来就耗费了大量的时间在等待服务重启。
这样肯定是不行的,极大的影响了我的开发效率,那么是否有方式能够实现,修改完代码之后,能够不重启项目呢?
    那肯定是有的,要不然这篇文章咋来的 。
	热部署(Hot Swap)
	从Java1.4起,JVM引入了HotSwap,能够在Debug的时候更新类的字节码。所以使用热部署,可以实现修改代码后,无须重启服务就可以加载修改的代码,但是它只能用来更新方法体。作为神器的IDEA自然是支持这一技术的。

2、如何使用SpringBoot热部署

         DevTools是Spring为开发者提供了一个名为spring-boot-devtools的模块,来使Spring Boot应用支持热部署,提高开发者的开发效率,无需手动重启Spring Boot应用。使用起来非常简单,只需要将下面的依赖引入项目里面就可以了。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
</dependency>

触发重启

	DevTools严格意义上其实不算热部署,而是快速重启。为什么这样说呢?DevTools的实现原理是:使用两个类加载器,一个是base classloader来加载不会被更改的类(例如,来自第三方的Jar),还有一个是restart classloader用来加载当前正在开发的类。所以当应用程序重新启动时,restart classloader将被丢弃,并创建一个新的类加载器。也就意味着应用程序重新启动通常比“冷启动”快得多,因为base classloader已经填充好了并且是可用的。
简而言之就是:通过监控类路径资源,当类路径上的文件发生更改时,自动重新启动应用程序,由于只需要重新读取被修改的类所,所以要比冷启动快。

配置自动重启
只需要进行下面两步的配置就可以实现了。

第1步:开启Build project automatically。

在这里插入图片描述

第2步:调出 Registry 窗口,勾选 compiler.automake.allow.when.app.running 选项

使用快捷键:Ctrl + Alt + Shift + / 调出 Registry 窗口,勾选 compiler.automake.allow.when.app.running 选项。
在这里插入图片描述
在这里插入图片描述

注意1:有的idea版本在项目中点击CTRL + ALT + SHIFT + / 无反应,那么就可以点击CTRL+SHIFT+A搜索Registry点击进去找到上面的那个key在后面勾上对勾即可
在这里插入图片描述

如果点击进去后,发现没有compiler.automake.allow.when.app.running,那么就需要我们去这个地方进行勾选:
在这里插入图片描述

第3步:在application.yml中设置开启或关闭热部署

spring:
  devtools:
    livereload:
      #ture=开启热部署;false=关闭热部署
      enabled: true

2、课堂编程

按照如上案例再次操练

3、切片小结

实现热部署的关键步骤有哪些?
1、在pom.xml中添加依赖
2、在idea中开启热部署(2步)

切片八、服务端表单数据校验

1、为什么要使用表单校验

        早期的网站,用户输入一个邮箱地址,需要将邮箱地址发送到服务端,服务端进行校验,校验成功后再给前端一个响应。自从有了 JavaScript 后,校验工作可以放在前端去执行。那么为什么还需要服务端校验呢?因为前端传来的数据不可信,前端很容易获取到后端的接口,如果有人直接调用接口,就可能会出现非法数据,因此服务端也要数据校验。
总的来说:

前端校验,提高用户体验
后端校验,保证数据安全可靠

2、如何实现服务端表单数据校验

在pom.xml中添加依赖

		<!-- 表单校验框架-->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.0.18.Final</version>
        </dependency>
        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

在实体层通过注解校验表单参数

package demo;

import lombok.Data;

import javax.validation.constraints.*;

@Data
public class User {
    @NotNull(message = "用户ID不可为null")
    private int id;

    @NotEmpty(message = "用户名不可以是空字符串")
    private String userName;

    @Min(value = 18, message = "年龄最小18岁")
    @Max(value = 80, message = "年龄最大80岁")
    private int age;

    @Pattern(regexp = "[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$", message = "邮箱格式不正确")
    private String email;
}

在controller中通过@Validated注解标注要校验的参数

//import org.springframework.validation.annotation.Validated;

@RequestMapping("/t2")
    public User t2(@Validated User user){
        return user;
    }

扩展:hibernate-validator 常用注解及对应描述

@AssertTrue:用于boolean字段,该字段只能为true
@AssertFalse:用于boolean字段,该字段只能为false
@CreditCardNumber:对信用卡号进行一个大致的验证
@DecimalMax:只能小于或等于该值
@DecimalMin:只能大于或等于该值
@Email:检查是否是一个有效的email地址
@Future:检查该字段的日期是否是属于将来的日期
@Length(min=,max=):检查所属的字段的长度是否在min和max之间,只能用于字符串
@Max:该字段的值只能小于或等于该值
@Min:该字段的值只能大于或等于该值
@NotNull:该字段的值不能为null
@NotBlank:不能为空,检查时会将空格忽略
@NotEmpty:不能为空,这里的空是指空字符串
@Pattern(regex=):被注释的元素必须符合指定的正则表达式
@URL(protocol=,host,port):检查是否是一个有效的URL,如果提供了protocol,host等,则该URL还需满足提供的条件

2、课堂编程

将以上案例再次操练

3、课堂小结

通过springboot使用后台表单校验的关键步骤有哪些?
1、在pom.xml中添加依赖
2、在实体中通过注解标注校验规则
3、在controller中通过@Validated注解标注参数

课堂总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/69258.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Navicat 16 和表空间 | 第 一 部分

优点 你知道 Navicat 16 支持表空间吗&#xff1f;表空间是表&#xff08;以及索引、大型对象和长数据&#xff09;的存储结构&#xff0c;它将数据库中的数据组织成与在文件系统上存储数据的位置相关的逻辑存储组。它的主要功能是联接物理存储层和逻辑存储层。通过将表分配给表…

c盘空间怎么扩大?

电脑系统主要存储在C盘&#xff0c;用户还可能会将一些软件、文件夹存储在C盘&#xff0c;所以电脑C盘必须拥有足够充足的空间&#xff0c;为了大家更好地使用电脑&#xff0c;这里小编带来的就是电脑扩大C盘空间的教程。 1、右击桌面的计算机图标&#xff0c;然后选择管理! 2、…

过滤器的使用

过滤器的使用过滤器介绍过滤器的使用配置过滤器过滤器路径的配置规则前置、后置、环绕过滤器过滤器链过滤器的优先级过滤器介绍 过滤器(Filter)是位于客户端与服务器资源之间的一道过滤技术&#xff0c;可以在客户端请求到达目标资源之前进行预处理业务。 过滤器作用 执行多个…

【Java实战】系统设计需要注意的细节

目录 一、前言 二、设计规约 1.【强制】存储方案和底层数据结构的设计获得评审一致通过&#xff0c;并沉淀成为文档。 2.【强制】在需求分析阶段&#xff0c;如果与系统交互的 User 超过一类并且相关的 UseCase 超过 5 个&#xff0c;使用用例图来表达更加清晰的结构化需求。…

小说电子书阅读系统毕业设计,小说电子书阅读系统设计与实现,毕业设计论文源码开题报告需求分析

项目背景和意义 目的&#xff1a;本课题主要目标是设计并能够实现一个基于web网页的电子书阅读系统&#xff0c;整个网站项目使用了B/S架构&#xff0c;基于java的springboot框架下开发&#xff1b;管理员通过后台录入信息、管理信息&#xff0c;设置网站信息&#xff0c;管理会…

4款游戏开发引擎优缺点分析

随着微信生态中&#xff0c;小程序应用指数级的增长&#xff0c;许多休闲游戏变成为了众多游戏厂商流量变现的新手段。以近期很火的“羊了个羊”为例&#xff0c;它便是我们常常所说的小游戏。 游戏和小游戏的区别 要盘点小游戏开发引擎之前&#xff0c;我们得先来了解下游戏…

vue3+ts 实现文件在线预览

一、背景 企业微信自建项目中要求PC端也能进行文件预览&#xff0c;但是企业微信提供的接口只能在移动端使用&#xff0c;通过查阅资料修改成贴合项目的方法。参考&#xff1a;https://blog.csdn.net/w_t_y_y/article/details/115767747 kkFileView官方文档 二、preview-file…

浅析能源物联网技术在校园能耗监测系统中的应用与研究

摘要:绿色环保已成为时代的主题&#xff0c;与此同时&#xff0c;节能减排也成为我国蓝天保卫战的重要措施。我国大型公共建筑年耗电量约占全国城镇总耗电量的22%&#xff0c;每平方米年耗电量是普通居民住宅的10&#xff5e;20倍&#xff0c;是欧洲、日本等发达国家同类建筑的…

《四》多线程基础——Java线程生命周期及转换

Java并发编程系列文章 《一》多线程基础——Java线程与进程的基本概念 《二》多线程基础——Java线程入门类和接口 《三》多线程基础——Java线程组和线程优先级 《四》多线程基础——Java线程生命周期及转换 《五》多线程基础——Java线程间的通信&#xff08;互斥与协作&…

Git统计代码行数;Java实现统计代码行数,忽略空行、注释行

前言 某天&#xff0c;产品叫我算下某个项目的代码行数&#xff0c;我一愣&#xff0c;这怎么统计&#xff1f;总不可能一个文件一个文件算吧&#xff1f;后面我找了下&#xff0c;git是可以统计提交到仓库的所有的代码的&#xff0c;不过有个问题&#xff0c;就是假如有些文件…

在STM32F103C8T6上使用RT_Thread Nano移植控制台和Finsh

一、移植环境&#xff1a; 开发环境&#xff1a;Keil MDK 5.33 硬件平台&#xff1a;STM32F103C8T6 RT_Thread版本&#xff1a;RT-Thread Nano V3.1.5 二、在RT-Thread Nano V3.1.5添加uart控制台 1.需要在rtconfig.h开启以下两个宏 1&#xff09;#define RT_USING_CONSO…

ITK (1)窗宽窗位的意义与设置

背景与意义 医学图像与传统可视化图像相比&#xff0c;其具有更大的“灰度”范围。如&#xff0c;普通图像&#xff08;灰度图像&#xff09;的灰度范围一般是256级&#xff08;即图像中最亮的点的灰度值定义为0&#xff0c;最亮的定义为255&#xff0c;也就是2^8&#xff0c;…

【图像处理OpenCV(C++版)】——2.1 深入理解OpenCV之Mat类及相关成员函数

前言&#xff1a; &#x1f60a;&#x1f60a;&#x1f60a;欢迎来到本博客&#x1f60a;&#x1f60a;&#x1f60a; &#x1f31f;&#x1f31f;&#x1f31f; 本专栏主要结合OpenCV和C来实现一些基本的图像处理算法并详细解释各参数含义&#xff0c;适用于平时学习、工作快…

【论文阅读31】《OptCuts: Joint Optimization of Surface Cuts and Parameterization》

目录 一些疑惑 0 引言 1 introduction 2 related work 2.1 parameterization with fixed connectivity 2.2 Separate Cut Computation 3 problem statement ​编辑​ 3.1 数学形式1 3.2 数学形式2 3.3 能量函数 3.3.1 接缝线长度&#xff08;归一化&#xff09;&am…

程序员们,你会考虑使用中文编程吗?

众所周知&#xff0c;编程语言有一条无形的“鄙视链”。 Java和C#相互不服&#xff0c;并且看不起写Python的&#xff0c;Python看不起PHP&#xff0c;PHP看不起前端。而中文编程就在这个语言“鄙视链”的底端艰难生存。 有人对中文编程嗤之以鼻&#xff0c;相比于“人生苦短…

免费网课题库系统接口

免费网课题库系统接口 本平台优点&#xff1a;免费查题接口搭建 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a;题库后台http://daili.jueguangzhe.cn/ 题…

[附源码]计算机毕业设计JAVA职业中介信息管理系统

[附源码]计算机毕业设计JAVA职业中介信息管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM my…

Java进阶——IO流(I)

文章目录IO流一、文件1.1、文件流1.2、常用的文件操作1.2.1、创建文件对象相关构造和方法1.2.2、获取文件的相关信息1.2.3、目录的操作和文件删除二、IO流原理及流的分类2.1、Java IO流的原理2.2、流的分类2.3、IO流常用的类2.3.1、InputStream&#xff1a;字节输入流FileInput…

SSH 远程连接协议详解

一、SSH 协议 1、SSH 协议简介 SSH全称是Secure Shell,SSH协议是基于应用层的协议,为远程登录会话和其他网络服务提供安全性的协议。 SSH使用最多的是远程登录和传输文件,实现此功能的传统协议都不安全(ftp、telnet等),因为它们使用明文传输数据,而SSH在传输过程中的…

【云原生.docker】docker部署Redis集群

1、镜像拉取 docker pull redis:5.0.5 2、容器启动 docker run -d --nameredis-6400 --net host --privilegedtrue -v /home/dev/toms/docker_redis/data/redis-6400:/data redis:5.0.5 --cluster-enabled yes --appendonly yes --port 6400 & docker run -d --nameredis-…