不做大哥好多年 不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核

逍遥子

不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核
  • Java基础

  • 面向对象

  • Java进阶

  • Web基础

  • Spring框架

    • 01.Spring之Bean
    • 02.Spring之AOP
    • 03.SpringMVC入门
    • 04.SpringMVC案例
    • 05.SpringBoot入门
    • 06.Maven分模块开发
    • 07.MyBatisPlus
    • 08.SpringBoot案例
      • 01.初始化SpringBoot项目
        • 1、项目初始化
        • 0、项目结构
        • 1、创建表
        • 2、导入坐标
        • 3、配置文件
        • 4、启动入口
        • 2、设置MyBatisPlus
        • ① 添加MyBatis配置
        • ② 制作表实体类
        • ③ 定义数据接口
        • 3、定义接口服务
        • ① service
        • ② controller
        • 4、common
        • ① R.java
        • ② BaseContext.java
        • ③ JacksonObjectMapper.java
        • ④ MyMetaObjecthandler.java
        • 5、filter过滤器
      • 02.测试接口
        • 新增员工
        • 获取员工list
        • 获取员工详情
        • 更新员工信息
    • 09.SpringCloud案例
    • 10.Dubbo
  • 微服务

  • Java
  • Spring框架
xiaonaiqiang
2024-06-03
目录

08.SpringBoot案例

reggie_take_out (opens new window)

# 01.初始化SpringBoot项目

# 1、项目初始化

# 0、项目结构

# 1、创建表

  • 启动服务
# 启动MySQL
docker run --name mysql-server -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql
mysql -h 127.0.0.1 -P 3306 -u root -p123456
# 启动Redis
docker run -d --name redis -p 6379:6379 redis:latest redis-server --appendonly yes --requirepass "123456"
docker exec -ti 59c75afbdfed redis-cli -h localhost -p 6379 -a '123456'
1
2
3
4
5
6
  • 创建表
mysql -h 127.0.0.1 -uroot -p123456
create database reggie2 charset utf8;
use reggie2;

CREATE TABLE `employee` (
  `id` bigint(20) NOT NULL COMMENT '主键',
  `name` varchar(32) COLLATE utf8_bin NOT NULL COMMENT '姓名',
  `username` varchar(32) COLLATE utf8_bin NOT NULL COMMENT '用户名',
  `password` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '密码',
  `phone` varchar(11) COLLATE utf8_bin NOT NULL COMMENT '手机号',
  `sex` varchar(2) COLLATE utf8_bin NOT NULL COMMENT '性别',
  `id_number` varchar(18) COLLATE utf8_bin NOT NULL COMMENT '身份证号',
  `status` int(11) NOT NULL DEFAULT '1' COMMENT '状态 0:禁用,1:正常',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `update_time` datetime NOT NULL COMMENT '更新时间',
  `create_user` bigint(20) NOT NULL COMMENT '创建人',
  `update_user` bigint(20) NOT NULL COMMENT '修改人',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='员工信息';


INSERT INTO `employee` VALUES ('1', '管理员', 'admin', 'e10adc3949ba59abbe56e057f20f883e', '13812312312', '1', '110101199001010047', '1', '2021-05-06 17:20:07', '2021-05-10 02:24:09', '1', '1');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 2、导入坐标

        <!--1、阿里云相关包-->
        <!--为其他阿里云服务的Java SDK提供了基础支持,如认证、网络通信等-->
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>4.5.16</version>
        </dependency>
        <!--阿里云的短信服务-->
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
            <version>2.1.0</version>
        </dependency>

        <!--2、spring-boot相关包-->
        <!--Spring Boot的核心启动器,包含了自动配置支持、日志库和Spring核心等-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!--Spring Boot用于测试的启动器,包含了JUnit、Spring Test、AssertJ等测试库-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--Spring Boot用于创建Web应用的启动器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <scope>compile</scope>
        </dependency>
        <!--操作Redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!--Spring Boot的缓存抽象层的启动器,支持多种缓存解决方案,如EhCache、Redis等-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

        <!--3、数据库相关包-->
        <!--MyBatis Plus的Spring Boot启动器-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>
        <!--用于连接MySQL数据库-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <!--通过<scope>限定,它只在运行时被包含 -->
            <scope>runtime</scope>
        </dependency>
        <!--数据库连接池实现,集监控、日志、缓慢查询、防御SQL注入等功能于一身-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.23</version>
        </dependency>

        <!--4、基础库-->
        <!--Java库,用于通过注解自动化生成代码,如getters, setters, toString等方法,以简化代码编写-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>
        <!--将Java对象与JSON数据格式之间进行快速转换-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.76</version>
        </dependency>
        <!--提供了一些Java基础类库的扩展,如字符串操作、数字操作、日期时间等-->
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

# 3、配置文件

server:
  port: 8080
spring:
  application:
    #应用的名称,可选
    name: reggie_take_out
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/reggie2?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
      username: root
      password: 123456
  redis:
    host: 127.0.0.1
    port: 6379
    password: 123456
    database: 0
  cache:
    redis:
      time-to-live: 1800000 #设置缓存数据的过期时间
mybatis-plus:
  configuration:
    #在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法映射
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      id-type: ASSIGN_ID
reggie:
  path: /Users/tom.xiao/img
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 4、启动入口

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Slf4j  //   //自动为类生成一个 Logger 对象 log,简化日志记录的代码
@SpringBootApplication  //这是 Spring Boot 的核心注解,标志着这是一个 Spring Boot 项目的启动类
@ServletComponentScan  //开启组件扫描(自动可以扫描到filter中的过滤器)
@EnableTransactionManagement //开启事务管理功能
@EnableCaching //开启Spring Cache注解方式是缓存功能
public class ReggieApplication {
    public static void main(String[] args) {
        SpringApplication.run(ReggieApplication.class, args);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 2、设置MyBatisPlus

# ① 添加MyBatis配置

  • src/main/java/com/example/config/MybatisPlusConfig.java
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 配置MP的分页插件
 * 这样配置后,当应用启动时,Spring 将会创建并注册一个名为 mybatisPlusInterceptor 的 Bean
 * 这个拦截器会拦截 MyBatis 的 SQL 执行,实现分页功能
 */
@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  • src/main/java/com/example/config/WebMvcConfig.java
import com.example.common.JacksonObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.util.List;

@Slf4j
@Configuration  // 注解这是一个配置类
public class WebMvcConfig extends WebMvcConfigurationSupport {

    /**
     * 设置静态资源映射
     * @param registry
     */
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        log.info("开始进行静态资源映射...");
        registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
        registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/");
    }

    /**
     * 扩展mvc框架的消息转换器: 将 HTTP 请求和响应中的数据与 Java 对象进行转换
     * @param converters
     */
    @Override
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        log.info("扩展消息转换器...");
        //创建消息转换器对象
        MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
        //设置对象转换器,底层使用Jackson将Java对象转为json
        messageConverter.setObjectMapper(new JacksonObjectMapper());
        //将上面的消息转换器对象追加到mvc框架的转换器集合中
        converters.add(0,messageConverter);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

# ② 制作表实体类

  • src/main/java/com/example/entity/Employee.java
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * 员工实体
 */
@Data
public class Employee implements Serializable {

	private static final long serialVersionUID = 1L;


	@TableId(type = IdType.AUTO)
	private Long id;

	private String username;

	private String name;

	private String password;

	private String phone;

	private String sex;

	private String idNumber;//身份证号码

	private Integer status;

	@TableField(fill = FieldFill.INSERT) //插入时填充字段
	private LocalDateTime createTime;

	@TableField(fill = FieldFill.INSERT_UPDATE) //插入和更新时填充字段
	private LocalDateTime updateTime;

	@TableField(fill = FieldFill.INSERT) //插入时填充字段
	private Long createUser;

	@TableField(fill = FieldFill.INSERT_UPDATE) //插入和更新时填充字段
	private Long updateUser;

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

# ③ 定义数据接口

  • src/main/java/com/example/mapper/EmployeeMapper.java
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.entity.Employee;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface EmployeeMapper extends BaseMapper<Employee>{
}
1
2
3
4
5
6
7

# 3、定义接口服务

# ① service

  • src/main/java/com/example/service/EmployeeService.java 接口
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.entity.Employee;

public interface EmployeeService extends IService<Employee> {
}
1
2
3
4
5
  • src/main/java/com/example/service/impl/EmployeeServiceImpl.java 类
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.entity.Employee;
import com.example.mapper.EmployeeMapper;
import com.example.service.EmployeeService;
import org.springframework.stereotype.Service;

@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper,Employee> implements EmployeeService{
}
1
2
3
4
5
6
7
8
9

# ② controller

  • src/main/java/com/example/controller/EmployeeController.java
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.common.BaseContext;
import com.example.common.R;
import com.example.entity.Employee;
import com.example.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {

	@Autowired
	private EmployeeService employeeService;

	/**
	 * 员工退出: http://127.0.0.1:8080/employee/logout
	 * @param request
	 * @return
	 */
	@PostMapping("/logout")
	public R<String> logout(HttpServletRequest request){
		//清理Session中保存的当前登录员工的id
		request.getSession().removeAttribute("employee");
		return R.success("退出成功");
	}


	/**
	 * 新增员工
	 * @param employee
	 * @return
	 */
	@PostMapping
	public R<String> save(HttpServletRequest request,@RequestBody Employee employee){
		BaseContext.setCurrentId(1L);  //模拟当前用户登录 ID=1
		log.info("新增员工,员工信息:{}",employee.toString());

		//设置初始密码123456,需要进行md5加密处理
		employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));

		//employee.setCreateTime(LocalDateTime.now());
		//employee.setUpdateTime(LocalDateTime.now());

		//获得当前登录用户的id
		//Long empId = (Long) request.getSession().getAttribute("employee");

		//employee.setCreateUser(empId);
		//employee.setUpdateUser(empId);

		employeeService.save(employee);

		return R.success("新增员工成功");
	}

	/**
	 * 员工信息分页查询
	 * @param page
	 * @param pageSize
	 * @param name
	 * @return
	 */
	@GetMapping("/page")
	public R<Page> page(int page,int pageSize,String name){
		log.info("page = {},pageSize = {},name = {}" ,page,pageSize,name);

		//构造分页构造器
		Page pageInfo = new Page(page,pageSize);

		//构造条件构造器
		LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper();
		//添加过滤条件
		//如果name不为空,就添加一个LIKE查询条件,查询Employee的名字中包含name的记录,如果name为空,则不添加这个条件
		queryWrapper.like(StringUtils.isNotEmpty(name),Employee::getName,name);
		//添加排序条件
		queryWrapper.orderByDesc(Employee::getUpdateTime);

		//执行查询
		employeeService.page(pageInfo,queryWrapper);

		return R.success(pageInfo);
	}

	/**
	 * 根据id修改员工信息
	 * @param employee
	 * @return
	 */
	@PutMapping
	public R<String> update(HttpServletRequest request,@RequestBody Employee employee){
		BaseContext.setCurrentId(1L);  //模拟当前用户登录 ID=1
		log.info(employee.toString());

		long id = Thread.currentThread().getId();
		log.info("线程id为:{}",id);
		//Long empId = (Long)request.getSession().getAttribute("employee");
		//employee.setUpdateTime(LocalDateTime.now());
		//employee.setUpdateUser(empId);
		employeeService.updateById(employee);

		return R.success("员工信息修改成功");
	}

	/**
	 * 根据id查询员工信息
	 * @param id
	 * @return
	 */
	@GetMapping("/{id}")
	public R<Employee> getById(@PathVariable Long id){
		log.info("根据id查询员工信息...");
		Employee employee = employeeService.getById(id);
		if(employee != null){
			return R.success(employee);
		}
		return R.error("没有查询到对应员工信息");
	}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

# 4、common

# ① R.java

  • src/main/java/com/example/common/R.java
import lombok.Data;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * 通用返回结果,服务端响应的数据最终都会封装成此对象
 * @param <T>
 */
@Data
public class R<T> implements Serializable{

	private Integer code; //编码:1成功,0和其它数字为失败

	private String msg; //错误信息

	private T data; //数据

	private Map map = new HashMap(); //动态数据

	public static <T> R<T> success(T object) {
		R<T> r = new R<T>();
		r.data = object;
		r.code = 1;
		return r;
	}

	public static <T> R<T> error(String msg) {
		R r = new R();
		r.msg = msg;
		r.code = 0;
		return r;
	}

	public R<T> add(String key, Object value) {
		this.map.put(key, value);
		return this;
	}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

# ② BaseContext.java

  • src/main/java/com/example/common/BaseContext.java
/**
 * 基于ThreadLocal封装工具类,用户保存和获取当前登录用户id
 * 以便在处理请求的过程中随时获取当前用户的信息
 */
public class BaseContext {
    //ThreadLocal 提供了线程局部变量,即每个线程都有自己的独立变量副本,线程之间的变量是互不干扰的
    private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();

    /**
     * 设置值
     * @param id
     */
    public static void setCurrentId(Long id){
        threadLocal.set(id);
    }

    /**
     * 获取值
     * @return
     */
    public static Long getCurrentId(){
        return threadLocal.get();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# ③ JacksonObjectMapper.java

  • src/main/java/com/example/common/JacksonObjectMapper.java
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;

import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;

/**
 * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
 * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
 * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
 */
public class JacksonObjectMapper extends ObjectMapper {

    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";  //指定默认的日期和时间格式
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

    public JacksonObjectMapper() {
        super();
        //收到未知属性时不报异常
        this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);

        //反序列化时,属性不存在的兼容处理(可以不设置,configure已经实现了不报错的兼容)
        this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);


        SimpleModule simpleModule = new SimpleModule()
                //LocalDateTime:使用 DEFAULT_DATE_TIME_FORMAT 格式化
                .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))

                //BigInteger 和 Long:使用 ToStringSerializer 将数值类型转为字符串,防止数值过大时出现精度丢失
                .addSerializer(BigInteger.class, ToStringSerializer.instance)
                .addSerializer(Long.class, ToStringSerializer.instance)

                //LocalDateTime、LocalDate 和 LocalTime:分别使用自定义的格式进行序列化
                .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));

        //注册功能模块 例如,可以添加自定义序列化器和反序列化器
        //注册自定义的 SimpleModule,使得 ObjectMapper 能够使用这些自定义的序列化器和反序列化器
        this.registerModule(simpleModule);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

# ④ MyMetaObjecthandler.java

  • src/main/java/com/example/common/MyMetaObjecthandler.java
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * 自定义元数据对象处理器: 用于在插入和更新操作时自动填充一些公共字段
 */
@Component  //声明为一个 Spring Bean, Spring 会自动检测并管理它的生命周期
@Slf4j
public class MyMetaObjecthandler implements MetaObjectHandler {
    /**
     * 插入操作,自动填充
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("公共字段自动填充[insert]...");
        log.info(metaObject.toString());

        metaObject.setValue("createTime", LocalDateTime.now());
        metaObject.setValue("updateTime",LocalDateTime.now());
        metaObject.setValue("createUser",BaseContext.getCurrentId());
        metaObject.setValue("updateUser",BaseContext.getCurrentId());
    }

    /**
     * 更新操作,自动填充
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("公共字段自动填充[update]...");
        log.info(metaObject.toString());

        long id = Thread.currentThread().getId();
        log.info("线程id为:{}",id);

        metaObject.setValue("updateTime",LocalDateTime.now());
        metaObject.setValue("updateUser",BaseContext.getCurrentId());
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

# 5、filter过滤器

  • src/main/java/com/example/filter/LoginCheckFilter.java
import com.alibaba.fastjson.JSON;
import com.example.common.BaseContext;
import com.example.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 检查用户是否已经完成登录
 * 当应用启动时,Web 容器会自动扫描并初始化使用了 @WebFilter 注解的过滤器类
 * 因此,当应用启动时,该过滤器会被自动初始化,并在每个请求被处理之前进行拦截和处理
 */
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter{
    //路径匹配器,支持通配符
    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //将 servletRequest 对象转型为 HttpServletRequest
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //1、获取本次请求的URI
        String requestURI = request.getRequestURI();// /backend/index.html

        log.info("拦截到请求:{}",requestURI);

        //定义不需要处理的请求路径
        String[] urls = new String[]{
                "/employee/*",
        };

        //2、判断本次请求是否需要处理
        boolean check = check(urls, requestURI);

        //3、如果不需要处理,则直接放行
        if(check){
            log.info("本次请求{}不需要处理",requestURI);
            filterChain.doFilter(request,response);
            return;
        }

        //4-1、判断登录状态,如果已登录,则直接放行
        if(request.getSession().getAttribute("employee") != null){
            System.out.println(request.getSession());
            log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("employee"));

            Long empId = (Long) request.getSession().getAttribute("employee");
            BaseContext.setCurrentId(empId);

            filterChain.doFilter(request,response);
            return;
        }

        //4-2、判断登录状态,如果已登录,则直接放行
        if(request.getSession().getAttribute("user") != null){
            log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("user"));

            Long userId = (Long) request.getSession().getAttribute("user");
            BaseContext.setCurrentId(userId);

            filterChain.doFilter(request,response);
            return;
        }

        log.info("用户未登录");
        //5、如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据
        response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
        return;

    }

    /**
     * 路径匹配,检查本次请求是否需要放行
     * @param urls
     * @param requestURI
     * @return
     */
    public boolean check(String[] urls,String requestURI){
        for (String url : urls) {
            boolean match = PATH_MATCHER.match(url, requestURI);
            if(match){
                return true;
            }
        }
        return false;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

# 02.测试接口

# 新增员工

  • http://127.0.0.1:8080/employee
  • GET
  • Body
{
    "name": "张三",
    "username": "zhangsan",
    "password": "123456",
    "phone": "18538762348",
    "sex": 1,
    "idNumber": "110101199001010047"
}
1
2
3
4
5
6
7
8

# 获取员工list

  • http://127.0.0.1:8080/employee/page?page=1&pageSize=10
  • GET
{
    "code": 1,
    "msg": null,
    "data": {
        "records": [
            {
                "id": 1,
                "username": "admin",
                "name": "管理员",
                "password": "e10adc3949ba59abbe56e057f20f883e",
                "phone": "13812312312",
                "sex": "1",
                "idNumber": "110101199001010047",
                "status": 1,
                "createTime": "2021-05-06T17:20:07",
                "updateTime": "2021-05-10T02:24:09",
                "createUser": 1,
                "updateUser": 1
            }
        ],
        "total": 0,
        "size": 10,
        "current": 1,
        "orders": [],
        "optimizeCountSql": true,
        "hitCount": false,
        "countId": null,
        "maxLimit": null,
        "searchCount": true,
        "pages": 0
    },
    "map": {}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 获取员工详情

  • http://127.0.0.1:8080/employee/1
  • GET
  • 返回
{
    "code": 1,
    "msg": null,
    "data": {
        "id": 1,
        "username": "admin",
        "name": "管理员",
        "password": "e10adc3949ba59abbe56e057f20f883e",
        "phone": "13812312312",
        "sex": "1",
        "idNumber": "110101199001010047",
        "status": 1,
        "createTime": "2021-05-06T17:20:07",
        "updateTime": "2021-05-10T02:24:09",
        "createUser": 1,
        "updateUser": 1
    },
    "map": {}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 更新员工信息

  • http://127.0.0.1:8080/employee
  • PUT
  • body
{
    "id": 1796446729558585345,
    "name": "张三2",
    "username": "zhangsan",
    "password": "123456",
    "phone": "18538762348",
    "sex": 1,
    "idNumber": "110101199001010047"
}
1
2
3
4
5
6
7
8
9
上次更新: 2024/6/17 19:12:09
07.MyBatisPlus
09.SpringCloud案例

← 07.MyBatisPlus 09.SpringCloud案例→

最近更新
01
04.数组双指针排序_子数组
03-25
02
08.动态规划
03-25
03
06.回溯算法
03-25
更多文章>
Theme by Vdoing | Copyright © 2019-2025 逍遥子 技术博客 京ICP备2021005373号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式