├── .gitignore ├── LICENSE ├── README.md ├── docker-compose ├── conf │ └── my.cnf ├── docker-compose.yml └── redis │ ├── conf │ └── redis.conf │ └── data │ └── “” ├── pom.xml ├── springboot-alipay ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── github │ │ └── cuifuan │ │ └── alipay │ │ ├── SpringbootAlipaySandboxSpringboot.java │ │ ├── config │ │ ├── AlipayConfig.java │ │ └── MyConfig.java │ │ └── controller │ │ └── AlipayController.java │ └── resources │ └── application.yml ├── springboot-aop ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── github │ │ │ └── gleans │ │ │ └── springbootaop │ │ │ ├── SpringbootAopApplication.java │ │ │ ├── aop │ │ │ └── TestAspectJ.java │ │ │ └── controller │ │ │ └── TestController.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── github │ └── gleans │ └── springbootaop │ └── SpringbootAopApplicationTests.java ├── springboot-auth ├── LICENSE ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── bran │ │ └── admin │ │ ├── SpringbootAdminApplication.java │ │ ├── common │ │ └── bean │ │ │ └── ResultBean.java │ │ ├── config │ │ ├── MybatisPlusConfig.java │ │ └── WebSecurityConfig.java │ │ ├── controller │ │ └── UserController.java │ │ ├── exception │ │ ├── CheckException.java │ │ ├── GlobalExceptionHandler.java │ │ └── JwtAuthException.java │ │ ├── filter │ │ └── JwtAuthenticationTokenFilter.java │ │ ├── mapper │ │ └── AdminUserMapper.java │ │ ├── model │ │ └── AdminUser.java │ │ ├── service │ │ └── AdminUserService.java │ │ └── utils │ │ ├── DateUtil.java │ │ ├── JwtTokenUtils.java │ │ └── NumUtil.java │ └── resources │ ├── application-dev.yml │ ├── application-prod.yml │ ├── application.yml │ └── mapper │ └── AdminUserMapper.xml ├── springboot-common ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── github │ └── cuifuan │ └── common │ ├── SprigbootCommonApplication.java │ ├── test │ └── TestUtil.java │ └── util │ └── DateUtil.java ├── springboot-email ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── github │ │ │ └── cuifuan │ │ │ └── mail │ │ │ ├── SpringbootEmailApplication.java │ │ │ ├── controller │ │ │ └── MailController.java │ │ │ ├── model │ │ │ ├── MailVO.java │ │ │ ├── Weather.java │ │ │ └── Whours.java │ │ │ └── service │ │ │ ├── EmailService.java │ │ │ └── impl │ │ │ └── EmailServiceImpl.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── github │ └── cuifuan │ └── mail │ └── SpringbootEmailApplicationTests.java ├── springboot-excel ├── README.md ├── images │ └── exportExcel.png ├── pom.xml ├── src │ └── main │ │ ├── java │ │ └── com │ │ │ └── github │ │ │ └── cuifuan │ │ │ └── excel │ │ │ ├── SpringbootExcelApplication.java │ │ │ ├── controller │ │ │ └── ExcelController.java │ │ │ ├── service │ │ │ └── ExcelService.java │ │ │ └── utils │ │ │ └── ExcelUtil.java │ │ └── resources │ │ ├── application.yml │ │ └── employees.xlsx └── test_emp.xlsx ├── springboot-init-db ├── pom.xml └── src │ ├── main │ ├── java │ │ └── store │ │ │ └── zabbix │ │ │ └── initdb │ │ │ ├── SpringbootInitDbApplication.java │ │ │ └── model │ │ │ └── UserInfo.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── store │ └── zabbix │ └── initdb │ └── SpringbootInitDbApplicationTests.java ├── springboot-jpa ├── pom.xml └── src │ └── main │ ├── java │ └── store │ │ └── zabbix │ │ └── jpa │ │ ├── SpringbootJpaApplication.java │ │ ├── controller │ │ └── UserController.java │ │ ├── model │ │ └── SysUser.java │ │ └── repository │ │ └── UserRepository.java │ └── resources │ ├── application.properties │ └── data.sql ├── springboot-kafka ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── springbootkafka │ │ │ ├── Consumer.java │ │ │ ├── Producer.java │ │ │ └── SpringbootKafkaApplication.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── com │ └── example │ └── springbootkafka │ ├── SpringbootKafkaApplicationTests.java │ └── singleton │ ├── DclSingleton.java │ ├── EnumSingleton.java │ ├── LazySingleton.java │ ├── SingletonEager.java │ └── Solution.java ├── springboot-mongodb ├── docker-compose.yml ├── mongo │ └── init-mongo.js ├── pom.xml ├── springboot-mongodb.iml └── src │ └── main │ └── java │ └── com │ └── example │ └── mongodb │ ├── controller │ └── DepartmentController.java │ ├── model │ ├── Department.java │ └── Employee.java │ └── repository │ ├── DepartmentRepository.java │ ├── DeptRepository.java │ └── EmpRepository.java ├── springboot-mybatis-plus ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── github │ │ └── cuifuan │ │ └── mp │ │ ├── SpringBootMybatisApplication.java │ │ ├── controller │ │ ├── TestController.java │ │ └── UserInfoController.java │ │ ├── domain │ │ ├── MybatisTest.java │ │ ├── User.java │ │ └── UserInfo.java │ │ ├── mapper │ │ ├── TestMapper.java │ │ └── UserInfoMapper.java │ │ ├── service │ │ ├── TestService.java │ │ ├── UserInfoService.java │ │ └── impl │ │ │ └── TestServiceImpl.java │ │ ├── singleton │ │ ├── LazyInitializedSingleton.java │ │ ├── StaticBlockSingleton.java │ │ └── ThreadSafeSingleton.java │ │ ├── test │ │ └── UserTest.java │ │ └── util │ │ └── ObjUtil.java │ └── resources │ ├── application.yml │ └── mapper │ ├── TestMapper.xml │ └── UserInfoMapper.xml ├── springboot-redis ├── docker-compose.yml ├── pom.xml ├── redis │ └── conf │ │ └── redis.conf └── src │ └── main │ ├── java │ └── com │ │ └── github │ │ └── cuifuan │ │ └── redis │ │ ├── SpringBootRedisApplication.java │ │ ├── controller │ │ └── UserController.java │ │ ├── dao │ │ └── UserRepository.java │ │ └── model │ │ └── User.java │ └── resources │ └── application.properties ├── springboot-upfile ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── springbootupfile │ │ │ ├── SpringbootUpfileApplication.java │ │ │ ├── controller │ │ │ └── UploadController.java │ │ │ └── service │ │ │ ├── UploadService.java │ │ │ └── impl │ │ │ └── UploadServiceImpl.java │ └── resources │ │ ├── application.properties │ │ └── templates │ │ ├── index.html │ │ └── result.html │ └── test │ └── java │ └── com │ └── example │ └── springbootupfile │ └── SpringbootUpfileApplicationTests.java └── src └── main └── java └── com └── github └── cuifuan └── main └── JacksonToMap.java /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | .DS_Store 35 | springboot-jpa/.mvn 36 | .idea/ 37 | spring-quick-start/.mvn/ 38 | rebel.xml 39 | spring-quick-start/src/main/resources/rebel.xml 40 | */rebel.xml 41 | springboot-email/src/main/resources/rebel.xml 42 | docker-compose/mysql/ 43 | docker-compose/redis/data/dump.rdb 44 | JavaTestCode/target/ 45 | springboot-autocsdn/.mvn/ 46 | out/ 47 | springboot-redis/redis/data/dump.rdb 48 | springboot-redis/.mvn/ 49 | sprigboot-common/.mvn/wrapper 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Spring Boot 学习笔记 2 | 3 | ### 版本介绍 4 | 5 | | 技术 | 版本 | 6 | |--------------|-------| 7 | | Spring Boot | 2.7.0 | 8 | | MySQL | 5.7.2 | 9 | | MyBatis PLUS | 3.5.2 | 10 | 11 | ### 目录导航 12 | 13 | | 目录 | 详情 | 14 | |-------------------|--| 15 | | springboot-excel | [Excel 导入导出](./springboot-excel) | 16 | 17 | ### 博客笔记 18 | 19 | - Spring Boot 基础篇 20 | - [Spring Boot 2022 快速入门指南](https://juejin.cn/post/7102309008064643108) 21 | - [Spring Boot 2.x: 支付宝沙箱支付](https://www.yuque.com/ekko/develop/nx4zap) 22 | - [Spring Boot 2.x: 定时给对象发送天气](https://juejin.im/post/5ee64e63518825432e25dc72) 23 | - [Spring Boot 2.x: 集成JPA快速开发](https://blog.csdn.net/Fine_Cui/article/details/106270118) 24 | - [Spring Boot 2.x: 集成 MongoDB](https://blog.csdn.net/Fine_Cui/article/details/106195498) 25 | - [Spring Boot 2.x: 集成 Redis 缓存](https://blog.csdn.net/Fine_Cui/article/details/103067129) 26 | - [Spring Boot 2.x: 整合 Redis 入门](https://blog.csdn.net/Fine_Cui/article/details/103067109) 27 | - [Spring Boot 2.x: 爬取ip代理池](https://blog.csdn.net/Fine_Cui/article/details/106797872) 28 | - [Spring Boot 2.x: 实现文件上传](https://blog.csdn.net/Fine_Cui/article/details/107600487) 29 | - [Spring Boot 2.x: 操作 Excel 导入导出](https://blog.csdn.net/Fine_Cui/article/details/115373033) 30 | - 所需工具安装 31 | - [跨平台一键启动常用MySQL/Redis/Rabbit等环境](https://blog.csdn.net/Fine_Cui/article/details/106892828) 32 | - [MongoDB快速入门指南与docker-compose快体验](https://www.yuque.com/ekko/database/dkluyg) 33 | - Docker 34 | - [Linux安装Docker(CentOS 8)与docker-compose套装](https://blog.csdn.net/Fine_Cui/article/details/106736626) 35 | - [windows安装Docker与docker-compose套装](https://blog.csdn.net/Fine_Cui/article/details/106596590) 36 | - [MacBook 安装 Docker 与 docker-compose 套装](https://blog.csdn.net/Fine_Cui/article/details/106893152) 37 | - Redis 可视化管理工具 38 | - [redis desktop manager for windows](https://javapro.lanzous.com/iNFkPdmrkjg) 39 | - [redis desktop manager for mac](https://javapro.lanzous.com/i7wvnbe) 40 | - MySQL安装 41 | - [windows 安装解压版 mysql-5.7.28-winx64](https://blog.csdn.net/Fine_Cui/article/details/111012619) 42 | - [Linux 安装 Mysql5.7.20 版本](https://blog.csdn.net/Fine_Cui/article/details/111397398) -------------------------------------------------------------------------------- /docker-compose/conf/my.cnf: -------------------------------------------------------------------------------- 1 | [mysqld] 2 | sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION -------------------------------------------------------------------------------- /docker-compose/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | mysql5.7: 5 | image: mysql:5.7 6 | restart: always 7 | environment: 8 | MYSQL_ROOT_PASSWORD: root # 设置root用户密码 9 | ports: 10 | - 3306:3306 11 | volumes: # 挂载持久化地址(个人理解) 12 | - ./mysql/:/var/lib/mysql/ 13 | - ./conf/:/etc/mysql/ 14 | redis: 15 | image: redis:4.0.2 16 | container_name: my_redis 17 | volumes: 18 | - ./redis/data:/data 19 | - ./redis/conf/:/usr/local/etc/redis/ 20 | command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf" 21 | ports: 22 | - 8089:6379 -------------------------------------------------------------------------------- /docker-compose/redis/data/“”: -------------------------------------------------------------------------------- 1 | 1:C 21 Mar 12:36:59.130 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 2 | 1:C 21 Mar 12:36:59.138 # Redis version=4.0.2, bits=64, commit=00000000, modified=0, pid=1, just started 3 | 1:C 21 Mar 12:36:59.149 # Configuration loaded 4 | _._ 5 | _.-``__ ''-._ 6 | _.-`` `. `_. ''-._ Redis 4.0.2 (00000000/0) 64 bit 7 | .-`` .-```. ```\/ _.,_ ''-._ 8 | ( ' , .-` | `, ) Running in standalone mode 9 | |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 10 | | `-._ `._ / _.-' | PID: 1 11 | `-._ `-._ `-./ _.-' _.-' 12 | |`-._`-._ `-.__.-' _.-'_.-'| 13 | | `-._`-._ _.-'_.-' | http://redis.io 14 | `-._ `-._`-.__.-'_.-' _.-' 15 | |`-._`-._ `-.__.-' _.-'_.-'| 16 | | `-._`-._ _.-'_.-' | 17 | `-._ `-._`-.__.-'_.-' _.-' 18 | `-._ `-.__.-' _.-' 19 | `-._ _.-' 20 | `-.__.-' 21 | 22 | 1:M 21 Mar 12:36:59.165 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. 23 | 1:M 21 Mar 12:36:59.173 # Server initialized 24 | 1:M 21 Mar 12:36:59.179 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled. 25 | 1:M 21 Mar 12:36:59.184 * Ready to accept connections 26 | 1:signal-handler (1584794483) Received SIGTERM scheduling shutdown... 27 | 1:M 21 Mar 12:41:23.702 # User requested shutdown... 28 | 1:M 21 Mar 12:41:23.706 * Removing the pid file. 29 | 1:M 21 Mar 12:41:23.712 # Redis is now ready to exit, bye bye... 30 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | org.springframework.boot 8 | spring-boot-starter-parent 9 | 2.7.0 10 | 11 | 12 | 13 | com.github.cuifuan 14 | springboot-learn 15 | 1.0.0 16 | springboot-learn 17 | Spring Boot 集成项目学习 18 | pom 19 | 20 | 21 | springboot-common 22 | springboot-auth 23 | springboot-redis 24 | springboot-jpa 25 | springboot-aop 26 | springboot-excel 27 | springboot-init-db 28 | springboot-email 29 | 30 | springboot-alipay 31 | 32 | springboot-kafka 33 | springboot-mybatis-plus 34 | 35 | 36 | 37 | 1.8 38 | 39 | 40 | 41 | 42 | org.projectlombok 43 | lombok 44 | provided 45 | 46 | 47 | com.fasterxml.jackson.core 48 | jackson-databind 49 | 2.13.3 50 | 51 | 52 | com.fasterxml.jackson.datatype 53 | jackson-datatype-jsr310 54 | 2.13.3 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /springboot-alipay/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | com.github.cuifuan 8 | springboot-learn 9 | 1.0.0 10 | 11 | 12 | 13 | springboot-alipay 14 | 15 | 16 | 17 | 18 | 19 | org.springframework.boot 20 | spring-boot-starter-web 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-test 26 | test 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-aop 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-logging 37 | 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-jdbc 42 | 43 | 44 | 45 | mysql 46 | mysql-connector-java 47 | runtime 48 | 49 | 50 | 51 | com.alibaba 52 | druid 53 | 1.1.8 54 | 55 | 56 | 57 | org.mybatis.spring.boot 58 | mybatis-spring-boot-starter 59 | 1.3.1 60 | 61 | 62 | 63 | 64 | com.alipay.sdk 65 | alipay-sdk-java 66 | 4.9.5.ALL 67 | 68 | 69 | 70 | org.springframework.boot 71 | spring-boot-test 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | org.springframework.boot 80 | spring-boot-maven-plugin 81 | 82 | 83 | 84 | 85 | 86 | 87 | aliyun 88 | aliyun 89 | https://maven.aliyun.com/repository/public 90 | 91 | true 92 | 93 | 94 | false 95 | 96 | 97 | 98 | 99 | spring-milestones 100 | Spring Milestones 101 | https://maven.aliyun.com/repository/spring 102 | 103 | true 104 | 105 | 106 | false 107 | 108 | 109 | 110 | 111 | 112 | 113 | spring-plugin 114 | spring-plugin 115 | https://maven.aliyun.com/repository/spring-plugin 116 | 117 | true 118 | 119 | 120 | false 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /springboot-alipay/src/main/java/com/github/cuifuan/alipay/SpringbootAlipaySandboxSpringboot.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.alipay; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringbootAlipaySandboxSpringboot { 8 | public static void main(String[] args) { 9 | SpringApplication.run(SpringbootAlipaySandboxSpringboot.class, args); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /springboot-alipay/src/main/java/com/github/cuifuan/alipay/config/AlipayConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.alipay.config; 2 | 3 | import java.io.FileWriter; 4 | import java.io.IOException; 5 | 6 | 7 | public class AlipayConfig { 8 | //↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 9 | 10 | // 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号 11 | public static String APP_ID = "应用ID,您的APPID"; 12 | 13 | /** 14 | * 这里填写刚刚在 https://miniu.alipay.com/keytool/create 15 | * 生成的私钥!!私钥!!私钥!! 16 | */ 17 | public static String MERCHANT_PRIVATE_KEY = "生成的私钥!!私钥!!私钥!!"; 18 | /** 19 | * 支付宝公钥,查看地址:https://openhome.alipay.com/platform/appDaily.htm 20 | * -> RSA2(SHA256)密钥(推荐) -> 设置/查看 -> 支付宝公钥 21 | */ 22 | public static String ALIPAY_PUBLIC_KEY = "支付宝公钥"; 23 | // 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 24 | /** 25 | * 返回的时候此页面不会返回到用户页面,只会执行你写到控制器里的地址 26 | */ 27 | public static String notify_url = "http://utb97j.natappfree.cc/notify_url"; 28 | // 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 29 | /** 30 | * 此页面是同步返回用户页面,也就是用户支付后看到的页面,上面的notify_url是异步返回商家操作,谢谢 31 | * 要是看不懂就找度娘,或者多读几遍,或者去看支付宝第三方接口API,不看API直接拿去就用,遇坑不怪别人 32 | */ 33 | public static String return_url = "http://utb97j.natappfree.cc/return_url"; 34 | // 签名方式 35 | public static String SIGN_TYPE = "RSA2"; 36 | 37 | // 字符编码格式 38 | public static String CHARSET = "utf-8"; 39 | 40 | // 支付宝网关 41 | public static String GATEWAY_URL = "https://openapi.alipaydev.com/gateway.do"; 42 | 43 | // 支付宝网关 44 | public static String log_path = ".\\alipay-logs"; 45 | 46 | 47 | //↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 48 | 49 | /** 50 | * 写日志,方便测试(看网站需求,也可以改成把记录存入数据库) 51 | * 52 | * @param sWord 要写入日志里的文本内容 53 | */ 54 | public static void logResult(String sWord) { 55 | FileWriter writer = null; 56 | try { 57 | writer = new FileWriter(log_path + "alipay_log_" + System.currentTimeMillis() + ".txt"); 58 | writer.write(sWord); 59 | } catch (Exception e) { 60 | e.printStackTrace(); 61 | } finally { 62 | if (writer != null) { 63 | try { 64 | writer.close(); 65 | } catch (IOException e) { 66 | e.printStackTrace(); 67 | } 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /springboot-alipay/src/main/java/com/github/cuifuan/alipay/config/MyConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.alipay.config; 2 | 3 | import javax.sql.DataSource; 4 | 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.web.cors.CorsConfiguration; 9 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 10 | import org.springframework.web.filter.CorsFilter; 11 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 12 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 13 | 14 | import com.alibaba.druid.pool.DruidDataSource; 15 | 16 | @Configuration 17 | public class MyConfig { 18 | 19 | @Bean 20 | @ConfigurationProperties("spring.datasource") 21 | public DataSource ds(){ 22 | return new DruidDataSource(); 23 | } 24 | 25 | private CorsConfiguration buildConfig() { 26 | CorsConfiguration corsConfiguration = new CorsConfiguration(); 27 | corsConfiguration.addAllowedOrigin("*"); // 允许任何域名使用 28 | corsConfiguration.addAllowedHeader("*"); // 允许任何头 29 | corsConfiguration.addAllowedMethod("*"); // 允许任何方法(post、get等) 30 | return corsConfiguration; 31 | } 32 | 33 | @Bean 34 | public CorsFilter corsFilter() { 35 | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 36 | source.registerCorsConfiguration("/**", buildConfig()); // 对接口配置跨域设置 37 | return new CorsFilter(source); 38 | } 39 | 40 | @Bean//将组件注册在容器 41 | public WebMvcConfigurer webMvcConfigurer(){ 42 | WebMvcConfigurer configurer = new WebMvcConfigurer(){ 43 | //配置资源映射路径 44 | @Override 45 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 46 | /** 47 | * 资源映射路径 48 | * addResourceHandler:访问映射路径 49 | * addResourceLocations:资源绝对路径 50 | */ 51 | registry.addResourceHandler("/img/**").addResourceLocations("file:C:/update/"); 52 | } 53 | 54 | 55 | }; 56 | 57 | return configurer; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /springboot-alipay/src/main/java/com/github/cuifuan/alipay/controller/AlipayController.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.alipay.controller; 2 | 3 | import com.alipay.api.AlipayApiException; 4 | import com.alipay.api.AlipayClient; 5 | import com.alipay.api.DefaultAlipayClient; 6 | import com.alipay.api.request.AlipayTradePagePayRequest; 7 | import com.github.cuifuan.alipay.config.AlipayConfig; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | import javax.servlet.http.HttpServletRequest; 13 | import javax.servlet.http.HttpServletResponse; 14 | import java.util.Objects; 15 | 16 | @RestController 17 | public class AlipayController { 18 | 19 | @GetMapping("/order") 20 | public String abc(String shopName) { 21 | 22 | 23 | //获得初始化的AlipayClient 24 | AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.GATEWAY_URL, 25 | AlipayConfig.APP_ID, 26 | AlipayConfig.MERCHANT_PRIVATE_KEY, 27 | "json", 28 | AlipayConfig.CHARSET, 29 | AlipayConfig.ALIPAY_PUBLIC_KEY, 30 | AlipayConfig.SIGN_TYPE); 31 | 32 | //设置请求参数 33 | AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest(); 34 | alipayRequest.setReturnUrl(AlipayConfig.return_url); 35 | alipayRequest.setNotifyUrl(AlipayConfig.notify_url); 36 | //商户订单号,商户网站订单系统中唯一订单号,必填 37 | String out_trade_no = "1621301678234"; 38 | //付款金额,必填 39 | String total_amount = "9998"; 40 | //商品标题/交易标题/订单标题/订单关键字等,必填 41 | String subject = Objects.isNull(shopName) ? "双飞" : shopName; 42 | //商品描述,可空 43 | String body = ""; 44 | 45 | alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\"," 46 | + "\"total_amount\":\""+ total_amount +"\"," 47 | + "\"subject\":\""+ subject +"\"," 48 | + "\"body\":\""+ body +"\"," 49 | + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}"); 50 | //请求 51 | String result = ""; 52 | try { 53 | result = alipayClient.pageExecute(alipayRequest).getBody(); 54 | } catch (AlipayApiException e) { 55 | // TODO Auto-generated catch block 56 | e.printStackTrace(); 57 | } 58 | return result; 59 | } 60 | 61 | /** 62 | * 支付完成回调验证操作 63 | */ 64 | @RequestMapping("notify_url") 65 | public void notifyUrl(HttpServletResponse response, HttpServletRequest request) throws Exception { 66 | System.out.println("----------------------------notify_url------------------------"); 67 | // 商户订单号 68 | String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "GBK"); 69 | // 付款金额 70 | String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "GBK"); 71 | // 支付宝交易号 72 | String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "GBK"); 73 | // 交易说明 74 | String cus = new String(request.getParameter("body").getBytes("ISO-8859-1"), "GBK"); 75 | // 交易状态 76 | String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "GBK"); 77 | if (trade_status.equals("TRADE_SUCCESS")) {//支付成功商家操作 78 | //下面是我写的一个简单的插入操作,根据你的操作自行编写 79 | /*Map map = new HashMap(); 80 | map.put("cuId", Integer.valueOf(cus)); 81 | RepaymentPlan repaymentPlan = new RepaymentPlan(); 82 | Integer id = Integer.valueOf(out_trade_no); 83 | double payablesCheck = Double.valueOf(total_amount); 84 | RepaymentPlan repayCheck = serviceMain.selectByPrimaryKey(id); 85 | double total = repayCheck.getPayables(); 86 | if (Double.valueOf(total_amount) < repayCheck.getPayables()) { 87 | map.put("ubalance", total - Double.valueOf(total_amount)); 88 | serviceMain.updateCusMoney(map); 89 | } 90 | repaymentPlan.setId(id); 91 | repaymentPlan.setActualPayment(total); 92 | repaymentPlan.setRepaymentStatus(1); 93 | int i = serviceMain.updateByPrimaryKeySelective(repaymentPlan); 94 | System.out.println("---------------------还款影响行数----------------------------" + i);*/ 95 | } 96 | } 97 | 98 | /** 99 | * 同步通知的页面的Controller 100 | */ 101 | @RequestMapping("return_url") 102 | public String returnUrl() throws InterruptedException { 103 | System.out.println("----------------------------return_url------------------------"); 104 | return "alipayexit"; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /springboot-alipay/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9998 -------------------------------------------------------------------------------- /springboot-aop/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import java.net.*; 18 | import java.io.*; 19 | import java.nio.channels.*; 20 | import java.util.Properties; 21 | 22 | public class MavenWrapperDownloader { 23 | 24 | private static final String WRAPPER_VERSION = "0.5.6"; 25 | /** 26 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 27 | */ 28 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" 29 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; 30 | 31 | /** 32 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 33 | * use instead of the default one. 34 | */ 35 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 36 | ".mvn/wrapper/maven-wrapper.properties"; 37 | 38 | /** 39 | * Path where the maven-wrapper.jar will be saved to. 40 | */ 41 | private static final String MAVEN_WRAPPER_JAR_PATH = 42 | ".mvn/wrapper/maven-wrapper.jar"; 43 | 44 | /** 45 | * Name of the property which should be used to override the default download url for the wrapper. 46 | */ 47 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 48 | 49 | public static void main(String args[]) { 50 | System.out.println("- Downloader started"); 51 | File baseDirectory = new File(args[0]); 52 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 53 | 54 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 55 | // wrapperUrl parameter. 56 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 57 | String url = DEFAULT_DOWNLOAD_URL; 58 | if (mavenWrapperPropertyFile.exists()) { 59 | FileInputStream mavenWrapperPropertyFileInputStream = null; 60 | try { 61 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 62 | Properties mavenWrapperProperties = new Properties(); 63 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 64 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 65 | } catch (IOException e) { 66 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 67 | } finally { 68 | try { 69 | if (mavenWrapperPropertyFileInputStream != null) { 70 | mavenWrapperPropertyFileInputStream.close(); 71 | } 72 | } catch (IOException e) { 73 | // Ignore ... 74 | } 75 | } 76 | } 77 | System.out.println("- Downloading from: " + url); 78 | 79 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 80 | if (!outputFile.getParentFile().exists()) { 81 | if (!outputFile.getParentFile().mkdirs()) { 82 | System.out.println( 83 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 84 | } 85 | } 86 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 87 | try { 88 | downloadFileFromURL(url, outputFile); 89 | System.out.println("Done"); 90 | System.exit(0); 91 | } catch (Throwable e) { 92 | System.out.println("- Error downloading"); 93 | e.printStackTrace(); 94 | System.exit(1); 95 | } 96 | } 97 | 98 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 99 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { 100 | String username = System.getenv("MVNW_USERNAME"); 101 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); 102 | Authenticator.setDefault(new Authenticator() { 103 | @Override 104 | protected PasswordAuthentication getPasswordAuthentication() { 105 | return new PasswordAuthentication(username, password); 106 | } 107 | }); 108 | } 109 | URL website = new URL(urlString); 110 | ReadableByteChannel rbc; 111 | rbc = Channels.newChannel(website.openStream()); 112 | FileOutputStream fos = new FileOutputStream(destination); 113 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 114 | fos.close(); 115 | rbc.close(); 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /springboot-aop/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuifuan/springboot-learn/2d14ede546b1f309817a0a09b697a3b8cf912fe6/springboot-aop/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /springboot-aop/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /springboot-aop/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.github.cuifuan 7 | springboot-learn 8 | 1.0.0 9 | 10 | 11 | store.zabbix.gleans 12 | springboot-aop 13 | 1.0.0 14 | springboot-aop 15 | Demo project for Spring Boot AOP 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-aop 30 | 2.3.3.RELEASE 31 | 32 | 33 | 34 | org.projectlombok 35 | lombok 36 | true 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-test 41 | test 42 | 43 | 44 | org.junit.vintage 45 | junit-vintage-engine 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | org.springframework.boot 55 | spring-boot-maven-plugin 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /springboot-aop/src/main/java/com/github/gleans/springbootaop/SpringbootAopApplication.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.bran.springbootaop; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.annotation.EnableAspectJAutoProxy; 6 | 7 | @SpringBootApplication 8 | @EnableAspectJAutoProxy(proxyTargetClass = true) 9 | public class SpringbootAopApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(SpringbootAopApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /springboot-aop/src/main/java/com/github/gleans/springbootaop/aop/TestAspectJ.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.bran.springbootaop.aop; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.aspectj.lang.JoinPoint; 5 | import org.aspectj.lang.ProceedingJoinPoint; 6 | import org.aspectj.lang.annotation.*; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | @Slf4j 13 | @Aspect 14 | @Configuration 15 | public class TestAspectJ { 16 | 17 | // 前置通知 18 | @Before("execution(* store.zabbix.gleans.springbootaop.controller..*(..))") 19 | public void before(JoinPoint joinPoint) { 20 | // 通知 21 | log.info("前置通知测试"); 22 | log.info(" 当前节点:{}", joinPoint); 23 | } 24 | 25 | // 后置通知 26 | @After("execution(* store.zabbix.gleans.springbootaop.controller..*(..))") 27 | public void after(JoinPoint joinPoint) { 28 | // 通知 29 | log.info("后置通知测试,当前节点:{}", joinPoint); 30 | } 31 | 32 | // 环绕通知 33 | @Around("execution(* store.zabbix.gleans.springbootaop.controller..*(..))") 34 | public Object handlerControllerMethod(ProceedingJoinPoint joinPoint) { 35 | long startTime = System.currentTimeMillis(); 36 | Object res = null; 37 | try { 38 | res = joinPoint.proceed(); 39 | } catch (Throwable throwable) { 40 | log.error("出错了:{}", throwable.getLocalizedMessage()); 41 | } 42 | 43 | log.info(joinPoint.getSignature() + "=耗时:=" + (System.currentTimeMillis() - startTime)); 44 | 45 | return res; 46 | } 47 | 48 | 49 | //也可以定义切入点 50 | @Pointcut(value = "execution(* store.zabbix.gleans.springbootaop.controller..*(..))") 51 | public void testAfterReturing(){}; 52 | 53 | // 正常返回通知 54 | @AfterReturning(value = "testAfterReturing()", returning = "res") 55 | public Object afterReturning(String res) { 56 | // 通知 57 | log.info("正常返回通知测试,返回值:{}", res); 58 | return "222"; 59 | } 60 | 61 | @AfterThrowing(value = "testAfterReturing()", throwing="ex") 62 | public void AfterThrowing(JoinPoint jp, Throwable ex) { 63 | log.info("=====异常返回通知====:{}", ex.getLocalizedMessage()); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /springboot-aop/src/main/java/com/github/gleans/springbootaop/controller/TestController.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.bran.springbootaop.controller; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | @Slf4j 9 | @RequestMapping("test") 10 | @RestController 11 | public class TestController { 12 | 13 | @GetMapping("/before") 14 | public String before() { 15 | log.info("请求 test/before 接口"); 16 | return "前置通知测试"; 17 | } 18 | 19 | @GetMapping("/after") 20 | public String after() { 21 | log.info("请求 test/after 接口"); 22 | return "后置通知测试"; 23 | } 24 | 25 | @GetMapping("/error") 26 | public String error() { 27 | int a = 1/0; 28 | return "异常通知测试"; 29 | } 30 | } -------------------------------------------------------------------------------- /springboot-aop/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /springboot-aop/src/test/java/com/github/gleans/springbootaop/SpringbootAopApplicationTests.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.bran.springbootaop; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class SpringbootAopApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springboot-auth/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 cuifuan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /springboot-auth/README.md: -------------------------------------------------------------------------------- 1 | ### springboot-admin 2 | 3 | Java 后端快速开发模板 4 | 5 | ### 技术栈 6 | 7 | | 技术 | 版本/说明 | 8 | | ------------ | ---------------------- | 9 | | MySQL DB | 8.0.29 | 10 | | Spring Boot | 2.7.0 | 11 | | Mybatis Plus | 3.5.2 | 12 | | 权限 | Spring Security | 13 | | 登录 | [Json Web Token](https://jwt.io/) | 14 | | API接口文档 | Knife4j + OpenAPI3 | 15 | 16 | ### 功能模块 17 | 18 | - [x] 集成 Spring Security 权限模块 19 | - [项目集成 Spring Security 做登录鉴权(一)](https://juejin.cn/post/7124859232679100423) 20 | - [项目集成 Spring Security 自定义登录(二)](https://juejin.cn/post/7125225162198220813) 21 | - [项目集成 Spring Security 携带 token 访问接口(三)](https://juejin.cn/post/7125651443196887053) 22 | - [安全框架 Spring Security 自定义异常(四)](https://juejin.cn/post/7126191963212087309) 23 | - [x] 登录获取唯一 token 标识 24 | - [x] 标准化 Restful 接口返回 25 | - [x] 全局异常处理 26 | - [ ] 接口文档 27 | - [ ] 日志处理 28 | - [ ] 用户管理 29 | - [ ] 角色管理 30 | - [ ] 菜单管理 31 | -------------------------------------------------------------------------------- /springboot-auth/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | com.github.cuifuan 8 | springboot-learn 9 | 1.0.0 10 | 11 | 12 | springboot-auth 13 | springboot-auth 14 | 权限模块 15 | 16 | 17 | 1.8 18 | 3.5.2 19 | 0.11.5 20 | 2.0.2 21 | 22 | 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-security 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-web 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-actuator 37 | 38 | 39 | 40 | mysql 41 | mysql-connector-java 42 | runtime 43 | 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-configuration-processor 48 | true 49 | 50 | 51 | org.projectlombok 52 | lombok 53 | true 54 | 55 | 56 | 57 | com.baomidou 58 | mybatis-plus-boot-starter 59 | ${mybatis-plus.version} 60 | 61 | 62 | io.jsonwebtoken 63 | jjwt-api 64 | ${jjwt.version} 65 | 66 | 67 | io.jsonwebtoken 68 | jjwt-impl 69 | ${jjwt.version} 70 | runtime 71 | 72 | 73 | io.jsonwebtoken 74 | jjwt-jackson 75 | ${jjwt.version} 76 | runtime 77 | 78 | 79 | 80 | com.alibaba 81 | fastjson 82 | ${fastjson.version} 83 | 84 | 85 | 86 | org.springframework.boot 87 | spring-boot-starter-test 88 | test 89 | 90 | 91 | 92 | cn.hutool 93 | hutool-all 94 | 5.8.8 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | org.springframework.boot 103 | spring-boot-maven-plugin 104 | 105 | 106 | 107 | org.projectlombok 108 | lombok 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /springboot-auth/src/main/java/com/bran/admin/SpringbootAdminApplication.java: -------------------------------------------------------------------------------- 1 | package com.bran.admin; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringbootAdminApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringbootAdminApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springboot-auth/src/main/java/com/bran/admin/common/bean/ResultBean.java: -------------------------------------------------------------------------------- 1 | package com.bran.admin.common.bean; 2 | 3 | 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | //@Schema(name = "统一返回处理") 10 | @Data 11 | @NoArgsConstructor 12 | public class ResultBean implements Serializable { 13 | 14 | private static final long serialVersionUID = 1L; 15 | public static final int SUCCESS = 0; 16 | public static final int FAIL = -1; 17 | 18 | private String msg = "接口返回成功"; 19 | 20 | private int code = SUCCESS; 21 | 22 | private T data; 23 | 24 | public ResultBean(T data) { 25 | super(); 26 | this.data = data; 27 | } 28 | 29 | public static ResultBean ok(T data) { 30 | return new ResultBean<>(data); 31 | } 32 | 33 | public static ResultBean error(String errorMsg) { 34 | ResultBean result = new ResultBean<>(); 35 | result.setCode(ResultBean.FAIL); 36 | result.setMsg(errorMsg); 37 | return result; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /springboot-auth/src/main/java/com/bran/admin/config/MybatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package com.bran.admin.config; 2 | 3 | import com.baomidou.mybatisplus.annotation.DbType; 4 | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; 5 | import org.mybatis.spring.annotation.MapperScan; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | @Configuration 10 | @MapperScan("com.bran.admin.mapper") 11 | public class MybatisPlusConfig { 12 | /** 13 | * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除) 14 | */ 15 | @Bean 16 | public PaginationInnerInterceptor mybatisPlusInterceptor() { 17 | PaginationInnerInterceptor interceptor = new PaginationInnerInterceptor(); 18 | interceptor.setMaxLimit(500L); 19 | interceptor.setDbType(DbType.MYSQL); 20 | return interceptor; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /springboot-auth/src/main/java/com/bran/admin/config/WebSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.bran.admin.config; 2 | 3 | import com.bran.admin.exception.JwtAuthException; 4 | import com.bran.admin.filter.JwtAuthenticationTokenFilter; 5 | import com.bran.admin.service.AdminUserService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.security.authentication.AuthenticationManager; 10 | import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; 11 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 12 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 13 | import org.springframework.security.config.http.SessionCreationPolicy; 14 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 15 | import org.springframework.security.crypto.password.PasswordEncoder; 16 | import org.springframework.security.web.SecurityFilterChain; 17 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 18 | import org.springframework.web.cors.CorsConfiguration; 19 | import org.springframework.web.cors.CorsConfigurationSource; 20 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 21 | 22 | @Configuration 23 | @EnableWebSecurity 24 | public class WebSecurityConfig { 25 | 26 | private static final String[] SKIP_AUTH = new String[]{"/*.html", "/favicon.ico", "/**/*.html", "/**/*.css", "/**/*.js", 27 | "/api/user/login", "/test/**", "/v3/**"}; 28 | 29 | private AdminUserService adminUserService; 30 | 31 | @Autowired 32 | public void setAdminUserService(AdminUserService adminUserService) { 33 | this.adminUserService = adminUserService; 34 | } 35 | 36 | /** 37 | * 获取AuthenticationManager(认证管理器),登录时认证使用 38 | */ 39 | @Bean 40 | public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { 41 | return authenticationConfiguration.getAuthenticationManager(); 42 | } 43 | 44 | @Bean 45 | public PasswordEncoder passwordEncoder() { 46 | return new BCryptPasswordEncoder(); 47 | } 48 | 49 | // jwt 校验过滤器,从 http 头部 Authorization 字段读取 token 并校验 50 | @Bean 51 | public JwtAuthenticationTokenFilter authFilter() { 52 | return new JwtAuthenticationTokenFilter(); 53 | } 54 | 55 | // 权限不足错误信息处理,包含认证错误与鉴权错误处理 56 | private JwtAuthException jwtAuthException; 57 | 58 | @Autowired 59 | public void setJwtAuthException(JwtAuthException jwtAuthException) { 60 | this.jwtAuthException = jwtAuthException; 61 | } 62 | 63 | @Bean 64 | SecurityFilterChain filterChain(HttpSecurity http) throws Exception { 65 | return http 66 | // 基于 token,不需要 csrf 67 | .csrf().disable() 68 | // 基于 token,不需要 session 69 | .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() 70 | // 设置 jwtAuthError 处理认证失败、鉴权失败 71 | .exceptionHandling().authenticationEntryPoint(jwtAuthException).accessDeniedHandler(jwtAuthException).and() 72 | // 下面开始设置权限 73 | .authorizeRequests(authorize -> authorize 74 | // 请求放开 75 | .antMatchers(SKIP_AUTH).permitAll() 76 | // 其他地址的访问均需验证权限 77 | .anyRequest().authenticated() 78 | ) 79 | // 添加 JWT 过滤器,JWT 过滤器在用户名密码认证过滤器之前 80 | .addFilterBefore(authFilter(), UsernamePasswordAuthenticationFilter.class) 81 | // 认证用户时用户信息加载配置,注入springAuthUserService 82 | .userDetailsService(adminUserService) 83 | .build(); 84 | } 85 | 86 | /** 87 | * 配置跨源访问(CORS) 88 | */ 89 | @Bean 90 | CorsConfigurationSource corsConfigurationSource() { 91 | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 92 | source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues()); 93 | return source; 94 | } 95 | } -------------------------------------------------------------------------------- /springboot-auth/src/main/java/com/bran/admin/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.bran.admin.controller; 2 | 3 | import com.bran.admin.common.bean.ResultBean; 4 | import com.bran.admin.model.AdminUser; 5 | import com.bran.admin.service.AdminUserService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.web.bind.annotation.PostMapping; 8 | import org.springframework.web.bind.annotation.RequestBody; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | @RestController 13 | @RequestMapping("/api/user") 14 | public class UserController { 15 | 16 | private AdminUserService adminUserService; 17 | 18 | @Autowired 19 | public void setAdminUserService(AdminUserService adminUserService) { 20 | this.adminUserService = adminUserService; 21 | } 22 | 23 | // @Operation(summary = "后台用户登录") 24 | @PostMapping("login") 25 | public ResultBean adminLogin(@RequestBody AdminUser admin) { 26 | return ResultBean.ok(adminUserService.adminLogin(admin)); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /springboot-auth/src/main/java/com/bran/admin/exception/CheckException.java: -------------------------------------------------------------------------------- 1 | package com.bran.admin.exception; 2 | 3 | public class CheckException extends RuntimeException{ 4 | public CheckException(String msg, Throwable t) { 5 | super(msg, t); 6 | } 7 | 8 | public CheckException(String msg) { 9 | super(msg); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /springboot-auth/src/main/java/com/bran/admin/exception/GlobalExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.bran.admin.exception; 2 | 3 | import com.bran.admin.common.bean.ResultBean; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.http.converter.HttpMessageNotReadableException; 6 | import org.springframework.util.StringUtils; 7 | import org.springframework.web.bind.annotation.ExceptionHandler; 8 | import org.springframework.web.bind.annotation.RestControllerAdvice; 9 | 10 | import javax.servlet.http.HttpServletRequest; 11 | 12 | @Slf4j 13 | @RestControllerAdvice 14 | public class GlobalExceptionHandler { 15 | 16 | /** 17 | * desc:处理自定义异常 18 | **/ 19 | @ExceptionHandler(value = CheckException.class) 20 | public ResultBean exceptionHandler(CheckException e) { 21 | return ResultBean.error(e.getMessage()); 22 | } 23 | 24 | @ExceptionHandler(value = HttpMessageNotReadableException.class) 25 | public ResultBean exceptionHandler(Exception ex) { 26 | log.error("HttpMessageNotReadableException ==> :{}", ex.getLocalizedMessage(), ex); 27 | String errMsg = ex.getLocalizedMessage(); 28 | if (StringUtils.hasText(errMsg) && errMsg.contains("body is missing")) { 29 | return ResultBean.error("参数必传,请检查请求 body 参数!"); 30 | } else { 31 | return ResultBean.error(errMsg); 32 | } 33 | } 34 | 35 | @ExceptionHandler(value = Exception.class) 36 | public ResultBean exceptionHandler(HttpServletRequest req, Exception e) { 37 | log.error("ZxspException==>{}", e.getMessage(), e); 38 | if (StringUtils.hasText(e.getLocalizedMessage())) { 39 | return ResultBean.error(e.getLocalizedMessage()); 40 | } else { 41 | return ResultBean.error(e.getMessage()); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /springboot-auth/src/main/java/com/bran/admin/exception/JwtAuthException.java: -------------------------------------------------------------------------------- 1 | package com.bran.admin.exception; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import com.bran.admin.common.bean.ResultBean; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.http.HttpStatus; 9 | import org.springframework.http.MediaType; 10 | import org.springframework.security.access.AccessDeniedException; 11 | import org.springframework.security.core.AuthenticationException; 12 | import org.springframework.security.web.AuthenticationEntryPoint; 13 | import org.springframework.security.web.access.AccessDeniedHandler; 14 | import org.springframework.stereotype.Component; 15 | 16 | import javax.servlet.ServletException; 17 | import javax.servlet.http.HttpServletRequest; 18 | import javax.servlet.http.HttpServletResponse; 19 | import java.io.IOException; 20 | import java.io.PrintWriter; 21 | import java.io.Serializable; 22 | 23 | @Component 24 | @Slf4j 25 | public class JwtAuthException implements Serializable, AccessDeniedHandler, AuthenticationEntryPoint { 26 | private static final long serialVersionUID = -8970718410437077606L; 27 | 28 | /** 29 | * AccessDeineHandler 用来解决认证过的用户访问无权限资源时的异常 30 | */ 31 | @Override 32 | public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException ex) 33 | throws IOException { 34 | restJson(request, response); 35 | } 36 | 37 | /** 38 | * AuthenticationEntryPoint 用来解决匿名用户访问无权限资源时的异常 39 | */ 40 | @Override 41 | public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { 42 | restJson(request, response); 43 | } 44 | 45 | private static void restJson(HttpServletRequest request, 46 | HttpServletResponse resp) throws IOException { 47 | resp.setContentType(MediaType.APPLICATION_JSON_VALUE); 48 | resp.setCharacterEncoding("UTF-8"); 49 | PrintWriter writer = resp.getWriter(); 50 | ResultBean resultBean = new ResultBean<>(); 51 | resultBean.setCode(HttpStatus.UNAUTHORIZED.value()); 52 | String msg = StrUtil.format("请求访问:{},认证失败,无法访问系统资源", request.getRequestURI()); 53 | resultBean.setMsg(msg); 54 | writer.write(new ObjectMapper().writeValueAsString(resultBean)); 55 | writer.flush(); 56 | writer.close(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /springboot-auth/src/main/java/com/bran/admin/filter/JwtAuthenticationTokenFilter.java: -------------------------------------------------------------------------------- 1 | package com.bran.admin.filter; 2 | 3 | import com.bran.admin.utils.JwtTokenUtils; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 7 | import org.springframework.security.core.context.SecurityContextHolder; 8 | import org.springframework.security.core.userdetails.UserDetails; 9 | import org.springframework.security.core.userdetails.UserDetailsService; 10 | import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; 11 | import org.springframework.stereotype.Component; 12 | import org.springframework.util.StringUtils; 13 | import org.springframework.web.filter.OncePerRequestFilter; 14 | 15 | import javax.servlet.FilterChain; 16 | import javax.servlet.ServletException; 17 | import javax.servlet.http.HttpServletRequest; 18 | import javax.servlet.http.HttpServletResponse; 19 | import java.io.IOException; 20 | 21 | @Slf4j 22 | @Component 23 | public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { 24 | 25 | private UserDetailsService userDetailsService; 26 | private JwtTokenUtils jwtTokenUtils; 27 | 28 | @Autowired 29 | private void setUserDetailsService(UserDetailsService userDetailsService) { 30 | this.userDetailsService = userDetailsService; 31 | } 32 | 33 | @Autowired 34 | public void setJwtTokenUtils(JwtTokenUtils jwtTokenUtils) { 35 | this.jwtTokenUtils = jwtTokenUtils; 36 | } 37 | 38 | private static final String TOKEN_HEADER = "Authorization"; 39 | 40 | private static final String TOKEN_START = "Bearer "; 41 | 42 | @Override 43 | public final void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { 44 | String authHeader = request.getHeader(TOKEN_HEADER); 45 | 46 | // 存在token 47 | if (StringUtils.hasText(authHeader) && authHeader.startsWith(TOKEN_START)) { 48 | String authToken = authHeader.substring(TOKEN_START.length()); 49 | String username = jwtTokenUtils.extractUsername(authToken); 50 | // 存在token 但是用户名未登录 51 | if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { 52 | // 登录 53 | UserDetails userDetails = userDetailsService.loadUserByUsername(username); 54 | // 验证token是否有效,重新设置用户对象 55 | if (jwtTokenUtils.validateToken(authToken, userDetails)) { 56 | UsernamePasswordAuthenticationToken authenticationToken = 57 | new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); 58 | // 重新设置回用户对象 59 | authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); 60 | SecurityContextHolder.getContext().setAuthentication(authenticationToken); 61 | } 62 | } 63 | } 64 | // 放行 65 | chain.doFilter(request, response); 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /springboot-auth/src/main/java/com/bran/admin/mapper/AdminUserMapper.java: -------------------------------------------------------------------------------- 1 | package com.bran.admin.mapper; 2 | 3 | import com.bran.admin.model.AdminUser; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | 6 | /** 7 | * @author bran 8 | * @description 针对表【admin_user】的数据库操作Mapper 9 | * @createDate 2022-05-11 12:04:41 10 | * @Entity com.admin.model.AdminUser 11 | */ 12 | public interface AdminUserMapper extends BaseMapper { 13 | 14 | } 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /springboot-auth/src/main/java/com/bran/admin/model/AdminUser.java: -------------------------------------------------------------------------------- 1 | package com.bran.admin.model; 2 | 3 | import com.baomidou.mybatisplus.annotation.*; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import org.springframework.security.core.GrantedAuthority; 7 | import org.springframework.security.core.userdetails.UserDetails; 8 | 9 | import java.io.Serializable; 10 | import java.util.Collection; 11 | import java.util.Collections; 12 | 13 | @Data 14 | @NoArgsConstructor 15 | @TableName(value = "admin_user") 16 | public class AdminUser implements Serializable, UserDetails { 17 | @TableField(exist = false) 18 | private static final long serialVersionUID = 1L; 19 | /** 20 | * 自增 ID 21 | */ 22 | @TableId(type = IdType.AUTO) 23 | private Long userId; 24 | 25 | /** 26 | * 用户名 27 | */ 28 | private String username; 29 | 30 | /** 31 | * 手机号 32 | */ 33 | private String userPhone; 34 | 35 | /** 36 | * 密码 37 | */ 38 | private String password; 39 | 40 | /** 41 | * 头像 42 | */ 43 | private String avatar; 44 | 45 | /** 46 | * 逻辑删除 0-未删除 1-已删除 47 | */ 48 | @TableLogic 49 | private Integer isDelete; 50 | 51 | @TableField(exist = false) 52 | private String token; 53 | 54 | @Override 55 | public boolean equals(Object that) { 56 | if (this == that) { 57 | return true; 58 | } 59 | if (that == null) { 60 | return false; 61 | } 62 | if (getClass() != that.getClass()) { 63 | return false; 64 | } 65 | AdminUser other = (AdminUser) that; 66 | return (this.getUserId() == null ? other.getUserId() == null : this.getUserId().equals(other.getUserId())) 67 | && (this.getUsername() == null ? other.getUsername() == null : this.getUsername().equals(other.getUsername())) 68 | && (this.getUserPhone() == null ? other.getUserPhone() == null : this.getUserPhone().equals(other.getUserPhone())) 69 | && (this.getPassword() == null ? other.getPassword() == null : this.getPassword().equals(other.getPassword())) 70 | && (this.getAvatar() == null ? other.getAvatar() == null : this.getAvatar().equals(other.getAvatar())) 71 | && (this.getIsDelete() == null ? other.getIsDelete() == null : this.getIsDelete().equals(other.getIsDelete())); 72 | } 73 | 74 | @Override 75 | public int hashCode() { 76 | final int prime = 31; 77 | int result = 1; 78 | result = prime * result + ((getUserId() == null) ? 0 : getUserId().hashCode()); 79 | result = prime * result + ((getUsername() == null) ? 0 : getUsername().hashCode()); 80 | result = prime * result + ((getUserPhone() == null) ? 0 : getUserPhone().hashCode()); 81 | result = prime * result + ((getPassword() == null) ? 0 : getPassword().hashCode()); 82 | result = prime * result + ((getAvatar() == null) ? 0 : getAvatar().hashCode()); 83 | result = prime * result + ((getIsDelete() == null) ? 0 : getIsDelete().hashCode()); 84 | return result; 85 | } 86 | 87 | @Override 88 | public String toString() { 89 | StringBuilder sb = new StringBuilder(); 90 | sb.append(getClass().getSimpleName()); 91 | sb.append(" ["); 92 | sb.append("Hash = ").append(hashCode()); 93 | sb.append(", userId=").append(userId); 94 | sb.append(", username=").append(username); 95 | sb.append(", userPhone=").append(userPhone); 96 | sb.append(", password=").append(password); 97 | sb.append(", avatar=").append(avatar); 98 | sb.append(", isDelete=").append(isDelete); 99 | sb.append(", serialVersionUID=").append(serialVersionUID); 100 | sb.append("]"); 101 | return sb.toString(); 102 | } 103 | 104 | @Override 105 | public Collection extends GrantedAuthority> getAuthorities() { 106 | return Collections.emptyList(); 107 | } 108 | 109 | @Override 110 | public boolean isAccountNonExpired() { 111 | return true; 112 | } 113 | 114 | @Override 115 | public boolean isAccountNonLocked() { 116 | return true; 117 | } 118 | 119 | @Override 120 | public boolean isCredentialsNonExpired() { 121 | return true; 122 | } 123 | 124 | @Override 125 | public boolean isEnabled() { 126 | return true; 127 | } 128 | } -------------------------------------------------------------------------------- /springboot-auth/src/main/java/com/bran/admin/service/AdminUserService.java: -------------------------------------------------------------------------------- 1 | package com.bran.admin.service; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 4 | import com.baomidou.mybatisplus.core.toolkit.Wrappers; 5 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 6 | import com.bran.admin.exception.CheckException; 7 | import com.bran.admin.mapper.AdminUserMapper; 8 | import com.bran.admin.model.AdminUser; 9 | import com.bran.admin.utils.JwtTokenUtils; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.security.authentication.AuthenticationManager; 12 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 13 | import org.springframework.security.core.Authentication; 14 | import org.springframework.security.core.context.SecurityContextHolder; 15 | import org.springframework.security.core.userdetails.UserDetails; 16 | import org.springframework.security.core.userdetails.UserDetailsService; 17 | import org.springframework.stereotype.Service; 18 | 19 | import java.util.Optional; 20 | 21 | /** 22 | * desc: 用户模块逻辑层 23 | * date 2022/5/11 12:06 24 | * 25 | * @author cuifuan 26 | **/ 27 | @Service 28 | public class AdminUserService extends ServiceImpl implements UserDetailsService { 29 | 30 | private AuthenticationManager authenticationManager; 31 | private JwtTokenUtils jwtTokenUtils; 32 | 33 | @Autowired 34 | public void setJwtTokenUtils(JwtTokenUtils jwtTokenUtils) { 35 | this.jwtTokenUtils = jwtTokenUtils; 36 | } 37 | 38 | @Autowired 39 | public void setAuthenticationManager(AuthenticationManager authenticationManager) { 40 | this.authenticationManager = authenticationManager; 41 | } 42 | 43 | /** 44 | * 根据用户名加载用户 45 | */ 46 | @Override 47 | public AdminUser loadUserByUsername(String username) { 48 | 49 | LambdaQueryWrapper userQuery = Wrappers.lambdaQuery() 50 | .eq(AdminUser::getUsername, username); 51 | 52 | return baseMapper.selectOne(userQuery); 53 | } 54 | 55 | public AdminUser adminLogin(AdminUser admin) { 56 | 57 | AdminUser adminUserx = loadUserByUsername(admin.getUsername()); 58 | Optional.ofNullable(adminUserx) 59 | .orElseThrow(() -> new CheckException("用户名密码错误!")); 60 | UsernamePasswordAuthenticationToken upaToken = new UsernamePasswordAuthenticationToken(admin.getUsername(), admin.getPassword()); 61 | 62 | authenticationManager.authenticate(upaToken); 63 | 64 | final UserDetails userDetails = this.loadUserByUsername(admin.getUsername()); 65 | final String token = jwtTokenUtils.generateToken(userDetails.getUsername()); 66 | 67 | Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); 68 | SecurityContextHolder.getContext().setAuthentication(authentication); 69 | 70 | AdminUser adminUser = this.getCurrentAdminUser(); 71 | adminUser.setToken(token); 72 | adminUser.setPassword(null); 73 | 74 | return adminUser; 75 | } 76 | 77 | private AdminUser getCurrentAdminUser() { 78 | return (AdminUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 79 | } 80 | 81 | } 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /springboot-auth/src/main/java/com/bran/admin/utils/DateUtil.java: -------------------------------------------------------------------------------- 1 | package com.bran.admin.utils; 2 | 3 | import java.time.DayOfWeek; 4 | import java.time.LocalDateTime; 5 | import java.time.format.DateTimeFormatter; 6 | import java.time.temporal.TemporalAdjusters; 7 | import java.util.stream.IntStream; 8 | 9 | public class DateUtil { 10 | 11 | private final static String DATE_TIME_FMT = "yyyy-MM-dd HH:mm:ss"; 12 | 13 | 14 | /** 15 | * desc: 获取起止日期 16 | * date 2022/9/14 12:57 17 | * 18 | * @param isFirst true 表示开始时间,false表示结束时间] 19 | * @author cuifuan 20 | **/ 21 | public static LocalDateTime getStartOrEndOfDay(LocalDateTime today, Boolean isFirst) { 22 | LocalDateTime resDate = LocalDateTime.now(); 23 | 24 | if (today == null) { 25 | today = resDate; 26 | } 27 | 28 | if (isFirst) { 29 | resDate = today.withHour(0).withMinute(0).withSecond(0).withNano(0); 30 | } else { 31 | resDate = today.withHour(23).withMinute(59).withSecond(59).withNano(999999999); 32 | } 33 | 34 | return resDate; 35 | } 36 | 37 | /** 38 | * desc: 获取指定日期的当月开始与结束时间 39 | * date 2022/9/14 12:57 40 | * 41 | * @param isFirst true 表示开始时间,false表示结束时间] 42 | * @author cuifuan 43 | **/ 44 | public static LocalDateTime getStartOrEndDayOfMonth(LocalDateTime today, Boolean isFirst) { 45 | LocalDateTime resDate = LocalDateTime.now(); 46 | 47 | if (today == null) { 48 | today = resDate; 49 | } 50 | 51 | if (isFirst) { 52 | resDate = today.with(TemporalAdjusters.firstDayOfMonth()); 53 | } else { 54 | resDate = today.with(TemporalAdjusters.lastDayOfMonth()); 55 | } 56 | 57 | resDate = DateUtil.getStartOrEndOfDay(resDate, isFirst); 58 | 59 | return resDate; 60 | } 61 | 62 | 63 | /** 64 | * desc: 获取指定日期的当年开始与结束时间 65 | * date 2022/9/14 12:57 66 | * 67 | * @param isFirst true 表示开始时间,false表示结束时间] 68 | * @author cuifuan 69 | **/ 70 | public static LocalDateTime getStartOrEndDayOfYear(LocalDateTime today, Boolean isFirst) { 71 | LocalDateTime resDate = LocalDateTime.now(); 72 | 73 | if (today == null) { 74 | today = resDate; 75 | } 76 | 77 | if (isFirst) { 78 | resDate = today.with(TemporalAdjusters.firstDayOfYear()); 79 | } else { 80 | resDate = today.with(TemporalAdjusters.lastDayOfYear()); 81 | } 82 | 83 | resDate = DateUtil.getStartOrEndOfDay(resDate, isFirst); 84 | 85 | return resDate; 86 | } 87 | 88 | /** 89 | * desc: 获取指定日期的当周开始与结束时间 90 | * date 2022/9/14 12:57 91 | * 92 | * @param isFirst true 表示开始时间,false表示结束时间] 93 | * @author cuifuan 94 | **/ 95 | public static LocalDateTime getStartOrEndDayOfWeek(LocalDateTime today, Boolean isFirst) { 96 | LocalDateTime resDate = LocalDateTime.now(); 97 | 98 | if (today == null) { 99 | today = resDate; 100 | } 101 | 102 | if (isFirst) { 103 | resDate = today.with(DayOfWeek.MONDAY); 104 | } else { 105 | resDate = today.with(DayOfWeek.SUNDAY); 106 | } 107 | 108 | resDate = DateUtil.getStartOrEndOfDay(resDate, isFirst); 109 | 110 | return resDate; 111 | } 112 | 113 | /** 114 | * 格式化时间格式为字符串 115 | */ 116 | public static String dateFormat(LocalDateTime localDateTime) { 117 | DateTimeFormatter dtf = DateTimeFormatter.ofPattern(DATE_TIME_FMT); 118 | if (null == localDateTime) { 119 | return null; 120 | } else { 121 | return localDateTime.format(dtf); 122 | } 123 | } 124 | 125 | /** 126 | * 时间字符串 转 LocalDateTime 127 | */ 128 | public static LocalDateTime dateTimeFormat(String dateTimeStr) { 129 | DateTimeFormatter fmt = DateTimeFormatter.ofPattern(DateUtil.DATE_TIME_FMT); 130 | return LocalDateTime.parse(dateTimeStr, fmt); 131 | } 132 | 133 | public static void main(String[] args) { 134 | // System.out.printf("获取当周的开始时间:%s\n", dateFormat(getStartOrEndDayOfWeek(null, true))); 135 | // System.out.printf("获取当周的结束时间:%s\n", dateFormat(getStartOrEndDayOfWeek(null, false))); 136 | IntStream.range(0, 7) 137 | .forEach(i -> System.out.println(i)); 138 | } 139 | 140 | 141 | } 142 | -------------------------------------------------------------------------------- /springboot-auth/src/main/java/com/bran/admin/utils/JwtTokenUtils.java: -------------------------------------------------------------------------------- 1 | package com.bran.admin.utils; 2 | 3 | import io.jsonwebtoken.Claims; 4 | import io.jsonwebtoken.Jwts; 5 | import io.jsonwebtoken.SignatureAlgorithm; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.security.core.userdetails.UserDetails; 8 | import org.springframework.stereotype.Component; 9 | 10 | import javax.crypto.spec.SecretKeySpec; 11 | import javax.xml.bind.DatatypeConverter; 12 | import java.security.Key; 13 | import java.util.Date; 14 | import java.util.function.Function; 15 | 16 | @Slf4j 17 | @Component 18 | public class JwtTokenUtils { 19 | 20 | private static final String JWT_SECRET = "springboot-admin13921springboot-admin13921springboot-admin13921"; 21 | // 过期时间-毫秒计时 默认 7 天 22 | private static final Long JWT_EXPIRATION = 7L * 24 * 60 * 1000; 23 | 24 | private static final SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS256; 25 | 26 | 27 | /** 28 | * 根据用户信息生成token 29 | */ 30 | public String generateToken(String username) { 31 | 32 | Claims claims = Jwts.claims().setSubject(username); 33 | 34 | return Jwts.builder() 35 | .setClaims(claims) 36 | .setExpiration(generateExpirationDate()) 37 | .signWith(getSignKey()) 38 | .compact(); 39 | } 40 | 41 | /** 42 | * 从token中获取用户名 43 | */ 44 | public String extractUsername(String token) { 45 | return extractClaim(token, Claims::getSubject); 46 | } 47 | 48 | public T extractClaim(String token, Function claimsResolver) { 49 | final Claims claims = extractAllClaims(token); 50 | return claimsResolver.apply(claims); 51 | } 52 | 53 | /** 54 | * 判断token是否有效 55 | * 两方面:token是否过期 56 | * token用户名是否和userDetails中用户名一致 57 | */ 58 | public boolean validateToken(String token, UserDetails userDetails) { 59 | final String username = this.extractUsername(token); 60 | if (null == userDetails) { 61 | return false; 62 | } 63 | return username.equals(userDetails.getUsername()) && !isTokenExpired(token); 64 | } 65 | 66 | /** 67 | * 判断token是否失效 68 | */ 69 | public boolean isTokenExpired(String token) { 70 | Date expiredDate = this.getExpiredDateFromToken(token); 71 | return expiredDate.before(new Date()); 72 | } 73 | 74 | /** 75 | * 从token中获取失效时间 76 | */ 77 | public Date getExpiredDateFromToken(String token) { 78 | Claims claims = extractAllClaims(token); 79 | return claims.getExpiration(); 80 | } 81 | 82 | /** 83 | * 从token中获取负载 84 | */ 85 | private Claims extractAllClaims(String token) { 86 | return Jwts.parserBuilder() 87 | .setSigningKey(getSignKey()) 88 | .build() 89 | .parseClaimsJws(token) 90 | .getBody(); 91 | } 92 | 93 | /** 94 | * 生成token失效时间 95 | */ 96 | private Date generateExpirationDate() { 97 | return new Date(System.currentTimeMillis() + JWT_EXPIRATION); 98 | } 99 | 100 | private static Key getSignKey() { 101 | // 使用我们的 JWT_SECRET 密钥签署我们的 JWT 102 | byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(JWT_SECRET); 103 | return new SecretKeySpec(apiKeySecretBytes, SIGNATURE_ALGORITHM.getJcaName()); 104 | } 105 | } -------------------------------------------------------------------------------- /springboot-auth/src/main/java/com/bran/admin/utils/NumUtil.java: -------------------------------------------------------------------------------- 1 | package com.bran.admin.utils; 2 | 3 | import java.math.BigDecimal; 4 | import java.math.RoundingMode; 5 | import java.text.DecimalFormat; 6 | import java.util.Objects; 7 | 8 | public class NumUtil { 9 | 10 | /** 11 | * 获取百分比 12 | */ 13 | public static String getPercentage(Double v1, Double v2) { 14 | 15 | if (Objects.isNull(v1) || Objects.isNull(v2)) { 16 | return null; 17 | } 18 | 19 | Double res; 20 | if (v1.compareTo(0.0) == 0) { 21 | res = v1; 22 | } else if (v2.compareTo(0.0) == 0) { 23 | res = 1.0; 24 | } else { 25 | res = BigDecimal.valueOf(v1).divide(BigDecimal.valueOf(v2), RoundingMode.HALF_UP).doubleValue(); 26 | } 27 | 28 | DecimalFormat df1 = new DecimalFormat("0.00%"); //##.00% 百分比格式,后面不足2位的用0补 29 | return df1.format(res); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /springboot-auth/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | driver-class-name: com.mysql.cj.jdbc.Driver 4 | url: jdbc:mysql://127.0.0.1:3306/springboot-admin?serverTimezone=Asia/Shanghai&characterEncoding=utf8&sslMode=DISABLED 5 | username: root 6 | password: root -------------------------------------------------------------------------------- /springboot-auth/src/main/resources/application-prod.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuifuan/springboot-learn/2d14ede546b1f309817a0a09b697a3b8cf912fe6/springboot-auth/src/main/resources/application-prod.yml -------------------------------------------------------------------------------- /springboot-auth/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | # 项目配置 端口与路径 2 | server: 3 | port: 10010 4 | servlet: 5 | context-path: /admin 6 | # 数据源配置 7 | spring: 8 | profiles: 9 | active: dev 10 | main: 11 | allow-circular-references: true -------------------------------------------------------------------------------- /springboot-auth/src/main/resources/mapper/AdminUserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | user_id,username,user_phone, 18 | password,avatar,is_delete 19 | 20 | 21 | -------------------------------------------------------------------------------- /springboot-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.github.cuifuan 7 | springboot-learn 8 | 1.0.0 9 | 10 | 11 | springboot-common 12 | springboot-common 13 | 公共模块 14 | 15 | 8 16 | 17 | 18 | 19 | org.springframework.boot 20 | spring-boot-starter 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-test 26 | test 27 | 28 | 29 | 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-maven-plugin 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /springboot-common/src/main/java/com/github/cuifuan/common/SprigbootCommonApplication.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.common; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SprigbootCommonApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SprigbootCommonApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springboot-common/src/main/java/com/github/cuifuan/common/test/TestUtil.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.common.test; 2 | 3 | import com.github.cuifuan.common.util.DateUtil; 4 | 5 | import java.time.LocalDateTime; 6 | import java.time.format.DateTimeFormatter; 7 | 8 | public class TestUtil { 9 | 10 | public static void main(String[] args) { 11 | // 时间字符串 转 LocalDateTime 12 | String time = "2020-01-01 00:00:00"; 13 | System.out.println(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /springboot-common/src/main/java/com/github/cuifuan/common/util/DateUtil.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.common.util; 2 | 3 | import java.time.DayOfWeek; 4 | import java.time.LocalDateTime; 5 | import java.time.format.DateTimeFormatter; 6 | import java.time.temporal.TemporalAdjusters; 7 | import java.util.stream.IntStream; 8 | 9 | public class DateUtil { 10 | 11 | public final static String DATE_TIME_FMT = "yyyy-MM-dd HH:mm:ss"; 12 | 13 | 14 | /** 15 | * desc: 获取起止日期 16 | * date 2022/9/14 12:57 17 | * 18 | * @param isFirst true 表示开始时间,false表示结束时间] 19 | * @author cuifuan 20 | **/ 21 | public static LocalDateTime getStartOrEndOfDay(LocalDateTime today, Boolean isFirst) { 22 | LocalDateTime resDate = LocalDateTime.now(); 23 | 24 | if (today == null) { 25 | today = resDate; 26 | } 27 | 28 | if (isFirst) { 29 | resDate = today.withHour(0).withMinute(0).withSecond(0).withNano(0); 30 | } else { 31 | resDate = today.withHour(23).withMinute(59).withSecond(59).withNano(999999999); 32 | } 33 | 34 | return resDate; 35 | } 36 | 37 | /** 38 | * desc: 获取指定日期的当月开始与结束时间 39 | * date 2022/9/14 12:57 40 | * 41 | * @param isFirst true 表示开始时间,false表示结束时间] 42 | * @author cuifuan 43 | **/ 44 | public static LocalDateTime getStartOrEndDayOfMonth(LocalDateTime today, Boolean isFirst) { 45 | LocalDateTime resDate = LocalDateTime.now(); 46 | 47 | if (today == null) { 48 | today = resDate; 49 | } 50 | 51 | if (isFirst) { 52 | resDate = today.with(TemporalAdjusters.firstDayOfMonth()); 53 | } else { 54 | resDate = today.with(TemporalAdjusters.lastDayOfMonth()); 55 | } 56 | 57 | resDate = DateUtil.getStartOrEndOfDay(resDate, isFirst); 58 | 59 | return resDate; 60 | } 61 | 62 | 63 | /** 64 | * desc: 获取指定日期的当年开始与结束时间 65 | * date 2022/9/14 12:57 66 | * 67 | * @param isFirst true 表示开始时间,false表示结束时间] 68 | * @author cuifuan 69 | **/ 70 | public static LocalDateTime getStartOrEndDayOfYear(LocalDateTime today, Boolean isFirst) { 71 | LocalDateTime resDate = LocalDateTime.now(); 72 | 73 | if (today == null) { 74 | today = resDate; 75 | } 76 | 77 | if (isFirst) { 78 | resDate = today.with(TemporalAdjusters.firstDayOfYear()); 79 | } else { 80 | resDate = today.with(TemporalAdjusters.lastDayOfYear()); 81 | } 82 | 83 | resDate = DateUtil.getStartOrEndOfDay(resDate, isFirst); 84 | 85 | return resDate; 86 | } 87 | 88 | /** 89 | * desc: 获取指定日期的当周开始与结束时间 90 | * date 2022/9/14 12:57 91 | * 92 | * @param isFirst true 表示开始时间,false表示结束时间] 93 | * @author cuifuan 94 | **/ 95 | public static LocalDateTime getStartOrEndDayOfWeek(LocalDateTime today, Boolean isFirst) { 96 | LocalDateTime resDate = LocalDateTime.now(); 97 | 98 | if (today == null) { 99 | today = resDate; 100 | } 101 | 102 | if (isFirst) { 103 | resDate = today.with(DayOfWeek.MONDAY); 104 | } else { 105 | resDate = today.with(DayOfWeek.SUNDAY); 106 | } 107 | 108 | resDate = DateUtil.getStartOrEndOfDay(resDate, isFirst); 109 | 110 | return resDate; 111 | } 112 | 113 | /** 114 | * 格式化时间格式为字符串 115 | */ 116 | public static String dateFormat(LocalDateTime localDateTime) { 117 | DateTimeFormatter dtf = DateTimeFormatter.ofPattern(DATE_TIME_FMT); 118 | if (null == localDateTime) { 119 | return null; 120 | } else { 121 | return localDateTime.format(dtf); 122 | } 123 | } 124 | 125 | public static void main(String[] args) { 126 | // System.out.printf("获取当周的开始时间:%s\n", dateFormat(getStartOrEndDayOfWeek(null, true))); 127 | // System.out.printf("获取当周的结束时间:%s\n", dateFormat(getStartOrEndDayOfWeek(null, false))); 128 | IntStream.range(0, 7) 129 | .forEach(i -> System.out.println(i)); 130 | } 131 | 132 | 133 | } 134 | -------------------------------------------------------------------------------- /springboot-email/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import java.net.*; 18 | import java.io.*; 19 | import java.nio.channels.*; 20 | import java.util.Properties; 21 | 22 | public class MavenWrapperDownloader { 23 | 24 | private static final String WRAPPER_VERSION = "0.5.6"; 25 | /** 26 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 27 | */ 28 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" 29 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; 30 | 31 | /** 32 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 33 | * use instead of the default one. 34 | */ 35 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 36 | ".mvn/wrapper/maven-wrapper.properties"; 37 | 38 | /** 39 | * Path where the maven-wrapper.jar will be saved to. 40 | */ 41 | private static final String MAVEN_WRAPPER_JAR_PATH = 42 | ".mvn/wrapper/maven-wrapper.jar"; 43 | 44 | /** 45 | * Name of the property which should be used to override the default download url for the wrapper. 46 | */ 47 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 48 | 49 | public static void main(String args[]) { 50 | System.out.println("- Downloader started"); 51 | File baseDirectory = new File(args[0]); 52 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 53 | 54 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 55 | // wrapperUrl parameter. 56 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 57 | String url = DEFAULT_DOWNLOAD_URL; 58 | if (mavenWrapperPropertyFile.exists()) { 59 | FileInputStream mavenWrapperPropertyFileInputStream = null; 60 | try { 61 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 62 | Properties mavenWrapperProperties = new Properties(); 63 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 64 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 65 | } catch (IOException e) { 66 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 67 | } finally { 68 | try { 69 | if (mavenWrapperPropertyFileInputStream != null) { 70 | mavenWrapperPropertyFileInputStream.close(); 71 | } 72 | } catch (IOException e) { 73 | // Ignore ... 74 | } 75 | } 76 | } 77 | System.out.println("- Downloading from: " + url); 78 | 79 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 80 | if (!outputFile.getParentFile().exists()) { 81 | if (!outputFile.getParentFile().mkdirs()) { 82 | System.out.println( 83 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 84 | } 85 | } 86 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 87 | try { 88 | downloadFileFromURL(url, outputFile); 89 | System.out.println("Done"); 90 | System.exit(0); 91 | } catch (Throwable e) { 92 | System.out.println("- Error downloading"); 93 | e.printStackTrace(); 94 | System.exit(1); 95 | } 96 | } 97 | 98 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 99 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { 100 | String username = System.getenv("MVNW_USERNAME"); 101 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); 102 | Authenticator.setDefault(new Authenticator() { 103 | @Override 104 | protected PasswordAuthentication getPasswordAuthentication() { 105 | return new PasswordAuthentication(username, password); 106 | } 107 | }); 108 | } 109 | URL website = new URL(urlString); 110 | ReadableByteChannel rbc; 111 | rbc = Channels.newChannel(website.openStream()); 112 | FileOutputStream fos = new FileOutputStream(destination); 113 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 114 | fos.close(); 115 | rbc.close(); 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /springboot-email/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuifuan/springboot-learn/2d14ede546b1f309817a0a09b697a3b8cf912fe6/springboot-email/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /springboot-email/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /springboot-email/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.github.cuifuan 7 | springboot-learn 8 | 1.0.0 9 | 10 | 11 | springboot-email 12 | springboot-email 13 | 邮件发送模块 14 | 15 | 16 | 1.8 17 | 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-mail 23 | 24 | 25 | cn.hutool 26 | hutool-all 27 | 4.6.1 28 | 29 | 30 | com.alibaba 31 | fastjson 32 | 1.2.70 33 | 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-web 38 | 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-test 43 | test 44 | 45 | 46 | 47 | 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-maven-plugin 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /springboot-email/src/main/java/com/github/cuifuan/mail/SpringbootEmailApplication.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mail; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringbootEmailApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringbootEmailApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springboot-email/src/main/java/com/github/cuifuan/mail/controller/MailController.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mail.controller; 2 | 3 | import com.github.cuifuan.mail.model.Weather; 4 | import com.github.cuifuan.mail.service.EmailService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.scheduling.annotation.EnableScheduling; 7 | import org.springframework.scheduling.annotation.Scheduled; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | import java.util.List; 12 | 13 | @RestController 14 | @EnableScheduling 15 | public class MailController { 16 | 17 | private EmailService emailService; 18 | 19 | @Autowired 20 | public void setEmailService(EmailService emailService) { 21 | this.emailService = emailService; 22 | } 23 | 24 | @GetMapping("/send") 25 | @Scheduled(cron = "0 0 23 * * ? ") 26 | public boolean sendEmail() { 27 | return emailService.sendSimpleMessage(); 28 | } 29 | 30 | @GetMapping("get-weather") 31 | public List getWeather() { 32 | return emailService.getWeather(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /springboot-email/src/main/java/com/github/cuifuan/mail/model/MailVO.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mail.model; 2 | 3 | import lombok.Data; 4 | import lombok.NoArgsConstructor; 5 | 6 | @Data 7 | @NoArgsConstructor 8 | public class MailVO { 9 | 10 | private String to; 11 | 12 | private String recipientName; 13 | 14 | private String subject; 15 | 16 | private String text; 17 | 18 | private String senderName; 19 | 20 | private String templateEngine; 21 | } 22 | -------------------------------------------------------------------------------- /springboot-email/src/main/java/com/github/cuifuan/mail/model/Weather.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mail.model; 2 | 3 | import lombok.Data; 4 | import lombok.NoArgsConstructor; 5 | 6 | import java.util.List; 7 | 8 | @Data 9 | @NoArgsConstructor 10 | public class Weather { 11 | private String day; 12 | private String date; 13 | private String week; 14 | //天气情况 15 | private String wea; 16 | private String weaImg; 17 | private String air; 18 | private String humidity; 19 | // 空气质量 优 20 | private String airLevel; 21 | // 空气质量描述:空气很好,可以外出活动,呼吸新鲜空气,拥抱大自然 22 | private String airTips; 23 | private String tem1; 24 | private String tem2; 25 | private String tem; 26 | 27 | private List hours; 28 | } 29 | -------------------------------------------------------------------------------- /springboot-email/src/main/java/com/github/cuifuan/mail/model/Whours.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mail.model; 2 | 3 | import lombok.Data; 4 | import lombok.NoArgsConstructor; 5 | 6 | @Data 7 | @NoArgsConstructor 8 | public class Whours { 9 | // 14日20时 10 | private String day; 11 | //中雨 12 | private String wea; 13 | //28℃ 实时温度 14 | private String tem; 15 | //无持续风向 16 | private String win; 17 | // 风速 3-4级 18 | private String winSpeed; 19 | } 20 | -------------------------------------------------------------------------------- /springboot-email/src/main/java/com/github/cuifuan/mail/service/EmailService.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mail.service; 2 | 3 | import com.github.cuifuan.mail.model.Weather; 4 | 5 | import java.util.List; 6 | 7 | public interface EmailService { 8 | boolean sendSimpleMessage(); 9 | 10 | List getWeather(); 11 | } 12 | -------------------------------------------------------------------------------- /springboot-email/src/main/java/com/github/cuifuan/mail/service/impl/EmailServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mail.service.impl; 2 | 3 | import cn.hutool.http.HttpRequest; 4 | import cn.hutool.http.HttpUtil; 5 | import com.alibaba.fastjson.JSON; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.mail.javamail.JavaMailSender; 8 | import org.springframework.mail.javamail.MimeMessageHelper; 9 | import org.springframework.stereotype.Service; 10 | import com.github.cuifuan.mail.model.Weather; 11 | import com.github.cuifuan.mail.service.EmailService; 12 | 13 | import javax.mail.internet.MimeMessage; 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | import java.util.Optional; 17 | 18 | @Service 19 | public class EmailServiceImpl implements EmailService { 20 | private final static String FROM_MAIL = "你的发送邮箱,和配置文件中相同"; 21 | private final static String TO_MAIL = "接收人邮箱"; 22 | private final static String APPID = "你申请的天气api的appid,自行替换"; 23 | private final static String APPSECRET = "你申请的天气api的APPSECRET,自行替换"; 24 | 25 | public JavaMailSender emailSender; 26 | 27 | @Autowired 28 | public void setEmailSender(JavaMailSender emailSender) { 29 | this.emailSender = emailSender; 30 | } 31 | 32 | @Override 33 | public boolean sendSimpleMessage() { 34 | try { 35 | MimeMessage message = emailSender.createMimeMessage(); 36 | MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(message, true); 37 | mimeMessageHelper.setTo(TO_MAIL); 38 | mimeMessageHelper.setFrom(FROM_MAIL); 39 | mimeMessageHelper.setSubject("今日份天气到了~~"); 40 | mimeMessageHelper.setText(buildHtml(getWeather().get(0)), true); 41 | emailSender.send(message); 42 | } catch (Exception e) { 43 | e.printStackTrace(); 44 | return false; 45 | } 46 | return true; 47 | } 48 | 49 | public List getWeather() { 50 | HttpRequest httpRequest = HttpUtil.createGet("https://www.tianqiapi.com/api?version=v1&" + "appid=" + APPID + "&appsecret=" + APPSECRET + "&cityid=101020100"); 51 | String res = httpRequest.execute().body(); 52 | Object data = JSON.parseObject(res).get("data"); 53 | 54 | return JSON.parseArray(JSON.toJSONString(data), Weather.class); 55 | } 56 | 57 | private String buildHtml(Weather weather) { 58 | StringBuffer html = new StringBuffer(""); 59 | html.append("\n" + 60 | "\n" + 61 | "\n" + 62 | "\n" + 63 | "文档标题\n" + 64 | ""); 65 | if (weather.getWea().contains("雨")) { 66 | html.append("今日有雨,狗子请带伞!"); 67 | } 68 | html.append("今日天气如下时间天气温度"); 69 | Optional.ofNullable(weather.getHours()) 70 | .orElse(new ArrayList<>()) 71 | .forEach(whours -> { 72 | html.append("") 73 | .append(whours.getDay()) 74 | .append("") 75 | .append(whours.getWea()) 76 | .append("") 77 | .append(whours.getTem()) 78 | .append(""); 79 | }); 80 | 81 | html.append("" + 82 | ""); 83 | return html.toString(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /springboot-email/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=9090 2 | server.servlet.context-path=/mail 3 | spring.mail.host=smtp.qq.com 4 | spring.mail.port=465 5 | spring.mail.username=你的邮箱地址 6 | spring.mail.password=刚刚获取的授权码 7 | spring.mail.properties.mail.smtp.auth=true 8 | spring.mail.properties.mail.smtp.ssl.enable=true 9 | spring.mail.properties.mail.smtp.starttls.enable=true -------------------------------------------------------------------------------- /springboot-email/src/test/java/com/github/cuifuan/mail/SpringbootEmailApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mail; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class SpringbootEmailApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springboot-excel/README.md: -------------------------------------------------------------------------------- 1 | ## 导出图例 2 | 3 | 请求地址: [http://127.0.0.1:10001/springboot-excel/api/v1/excel/export](http://127.0.0.1:10001/springboot-excel/api/v1/excel/export) 4 | 5 |  -------------------------------------------------------------------------------- /springboot-excel/images/exportExcel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuifuan/springboot-learn/2d14ede546b1f309817a0a09b697a3b8cf912fe6/springboot-excel/images/exportExcel.png -------------------------------------------------------------------------------- /springboot-excel/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.github.cuifuan 7 | springboot-learn 8 | 1.0.0 9 | 10 | 11 | springboot-excel 12 | springboot-excel 13 | Excel 导入导出的示例 14 | 15 | 16 | 1.8 17 | 18 | 19 | 20 | org.apache.poi 21 | poi 22 | 5.0.0 23 | 24 | 25 | 26 | org.apache.poi 27 | poi-ooxml 28 | 5.0.0 29 | 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-web 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-maven-plugin 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /springboot-excel/src/main/java/com/github/cuifuan/excel/SpringbootExcelApplication.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.excel; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringbootExcelApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringbootExcelApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springboot-excel/src/main/java/com/github/cuifuan/excel/controller/ExcelController.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.excel.controller; 2 | 3 | 4 | import com.github.cuifuan.excel.service.ExcelService; 5 | import com.github.cuifuan.excel.utils.ExcelUtil; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.web.bind.annotation.*; 8 | import org.springframework.web.multipart.MultipartFile; 9 | 10 | import javax.servlet.http.HttpServletResponse; 11 | import java.io.IOException; 12 | import java.util.LinkedHashMap; 13 | import java.util.List; 14 | 15 | @RequestMapping("/api/v1/excel") 16 | @RestController 17 | public class ExcelController { 18 | 19 | private ExcelService excelService; 20 | 21 | @Autowired 22 | public void setExcelService(ExcelService excelService) { 23 | this.excelService = excelService; 24 | } 25 | 26 | /** 27 | * 导出模板 28 | */ 29 | @RequestMapping("export") 30 | public void export(HttpServletResponse response) throws IOException { 31 | LinkedHashMap titleMap = new LinkedHashMap<>(16); 32 | titleMap.put("id", "编号"); 33 | titleMap.put("name", "姓名"); 34 | titleMap.put("sex", "性别"); 35 | titleMap.put("age", "年龄"); 36 | ExcelUtil.exportExcel(response, 37 | titleMap, 38 | null, 39 | "sheet", 40 | "Excel模板"); 41 | } 42 | 43 | /** 44 | * Import an Excel file 45 | */ 46 | @PostMapping("import") 47 | public List> importExcelData(@RequestParam("file") MultipartFile file) throws Exception { 48 | return excelService.readExcel(file); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /springboot-excel/src/main/java/com/github/cuifuan/excel/service/ExcelService.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.excel.service; 2 | 3 | import com.github.cuifuan.excel.utils.ExcelUtil; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.stereotype.Service; 6 | import org.springframework.web.multipart.MultipartFile; 7 | 8 | import java.util.List; 9 | 10 | @Slf4j 11 | @Service 12 | public class ExcelService { 13 | 14 | 15 | /** 16 | * read Excel file 17 | * @param file 导入的 excel 文件 18 | * @return 读取到的数据 19 | * @throws Exception 过程中的报错信息 20 | */ 21 | public List> readExcel(MultipartFile file) throws Exception { 22 | return ExcelUtil.readExcel(file); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /springboot-excel/src/main/java/com/github/cuifuan/excel/utils/ExcelUtil.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.excel.utils; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.apache.poi.hssf.usermodel.HSSFWorkbook; 5 | import org.apache.poi.ss.usermodel.*; 6 | import org.apache.poi.xssf.usermodel.*; 7 | import org.springframework.web.multipart.MultipartFile; 8 | 9 | import javax.servlet.http.HttpServletResponse; 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | import java.math.BigDecimal; 13 | import java.net.URLEncoder; 14 | import java.text.DecimalFormat; 15 | import java.time.format.DateTimeFormatter; 16 | import java.util.ArrayList; 17 | import java.util.Iterator; 18 | import java.util.LinkedHashMap; 19 | import java.util.List; 20 | 21 | import static org.apache.logging.log4j.util.Strings.EMPTY; 22 | 23 | @Slf4j 24 | public class ExcelUtil { 25 | // excel 2003 版本 excel 26 | public static final String MICROSOFT_EXCEL_2003 = "xls"; 27 | // excel 2007 版本 excel 28 | public static final String MICROSOFT_EXCEL_2007 = "xlsx"; 29 | 30 | /** 31 | * 读取excel文件 32 | */ 33 | public static List> readExcel(MultipartFile file) throws Exception { 34 | if (file.isEmpty()) { 35 | throw new RuntimeException("上传失败,上传文件为空!"); 36 | } 37 | String originalFileName = file.getOriginalFilename(); 38 | 39 | log.info("文件名:originalFileName:{}", originalFileName); 40 | 41 | if (originalFileName == null) { 42 | throw new RuntimeException("文件名不能为空!"); 43 | } 44 | String[] postfixArray = originalFileName.split("\\."); 45 | int lastIndex = postfixArray.length - 1; 46 | String postfix = postfixArray[lastIndex]; 47 | 48 | InputStream fileInput = file.getInputStream(); 49 | Workbook workbook; 50 | switch (postfix) { 51 | case ExcelUtil.MICROSOFT_EXCEL_2003: 52 | workbook = new HSSFWorkbook(fileInput); 53 | break; 54 | case ExcelUtil.MICROSOFT_EXCEL_2007: 55 | workbook = new XSSFWorkbook(fileInput); 56 | break; 57 | default: 58 | throw new RuntimeException("文件不符合要求"); 59 | } 60 | 61 | List> dataList = new ArrayList<>(); 62 | 63 | // 获取第一张Sheet页 64 | Sheet sheet = workbook.getSheetAt(0); 65 | // 获取行的一个迭代器方法 66 | Iterator rowIterator = sheet.rowIterator(); 67 | while (rowIterator.hasNext()) { 68 | List rowData = new ArrayList<>(); 69 | Row row = rowIterator.next(); 70 | //获取每行中的每一列 71 | Iterator cellIterator = row.cellIterator(); 72 | //计数.控制跳出循环.循环读取列 73 | int i = -1; 74 | //获取每行的列数 75 | int lastCellNum = row.getLastCellNum(); 76 | boolean isBlankRow = true; 77 | for (Cell cell : row) { 78 | if (cell.getCellType() != CellType.BLANK) { 79 | isBlankRow = false; 80 | break; 81 | } 82 | } 83 | if (!isBlankRow) { 84 | // 处理非空白行 85 | while (cellIterator.hasNext()) { 86 | i++; 87 | //能正常读取空单元格 88 | Cell cell = row.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK); 89 | if (i == lastCellNum) { 90 | break; 91 | } 92 | String value; 93 | if (cell == null || cell.getCellType().equals(CellType.BLANK)) { 94 | value = ""; 95 | } else { 96 | value = getCellValue(cell); 97 | } 98 | rowData.add(value); 99 | } 100 | dataList.add(rowData); 101 | } 102 | } 103 | 104 | return dataList; 105 | } 106 | 107 | /** 108 | * @param titleMap key-value格式的 excel 109 | * @param dataList 数据 list 110 | */ 111 | public static void exportExcel(HttpServletResponse response, 112 | LinkedHashMap titleMap, 113 | List> dataList, 114 | String sheetName, 115 | String fileName) throws IOException { 116 | try (XSSFWorkbook workbook = new XSSFWorkbook()) { 117 | XSSFSheet sheet = workbook.createSheet(sheetName); 118 | List keyList = new ArrayList<>(); 119 | List titleList = new ArrayList<>(); 120 | titleMap.forEach((k, v) -> { 121 | keyList.add(k); 122 | titleList.add(v); 123 | }); 124 | // 设置 key 125 | XSSFRow keyRow = sheet.createRow(0); 126 | keyRow.setZeroHeight(true); 127 | for (int i = 0; i < keyList.size(); i++) { 128 | String title = keyList.get(i); 129 | Cell headerCell = keyRow.createCell(i); 130 | headerCell.setCellValue(title); 131 | } 132 | // 设置标题 133 | XSSFRow header = sheet.createRow(1); 134 | ExcelUtil.setExcelTitle(titleList, workbook, sheet, header); 135 | ExcelUtil.setExcelData(workbook, sheet, dataList, 2); 136 | extracted(response, fileName, workbook); 137 | } 138 | } 139 | 140 | /** 141 | * Excel 表格导出, 格式为 xlsx 142 | * 143 | * @param titleList 标题集合 144 | * @param dataList 内容集合 145 | */ 146 | public static void exportExcel(HttpServletResponse response, 147 | List titleList, 148 | List> dataList, 149 | String sheetName, 150 | String fileName) throws IOException { 151 | try (XSSFWorkbook workbook = new XSSFWorkbook()) { 152 | XSSFSheet sheet = workbook.createSheet(sheetName); 153 | // 设置标题 154 | XSSFRow header = sheet.createRow(0); 155 | ExcelUtil.setExcelTitle(titleList, workbook, sheet, header); 156 | ExcelUtil.setExcelData(workbook, sheet, dataList, 1); 157 | extracted(response, fileName, workbook); 158 | } 159 | } 160 | 161 | private static void extracted(HttpServletResponse response, 162 | String fileName, 163 | XSSFWorkbook workbook) throws IOException { 164 | String fileNameEncode = URLEncoder.encode(fileName, "UTF-8"); 165 | response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); 166 | response.setHeader("content-disposition", "attachment;filename=" + fileNameEncode + ".xlsx"); 167 | response.setCharacterEncoding("utf-8"); 168 | //刷新缓冲 169 | response.flushBuffer(); 170 | //workbook将Excel写入到response的输出流中,供页面下载该Excel文件 171 | workbook.write(response.getOutputStream()); 172 | } 173 | 174 | /** 175 | * 设置标题 176 | */ 177 | public static void setExcelTitle(List titleList, 178 | XSSFWorkbook workbook, 179 | XSSFSheet sheet, 180 | XSSFRow header) { 181 | XSSFCellStyle headerStyle = ExcelUtil.getTitleCellStyle(workbook); 182 | for (int i = 0; i < titleList.size(); i++) { 183 | String title = titleList.get(i); 184 | sheet.setColumnWidth(i, 20 * 256 + 184); 185 | Cell headerCell = header.createCell(i); 186 | headerCell.setCellStyle(headerStyle); 187 | headerCell.setCellValue(title); 188 | } 189 | } 190 | 191 | public static void setExcelData(XSSFWorkbook workbook, 192 | XSSFSheet sheet, 193 | List> dataList, 194 | int startRowIndex) { 195 | if (null != dataList && !dataList.isEmpty()) { 196 | XSSFCellStyle cellStyle = ExcelUtil.getCellStyle(workbook); 197 | for (int i = startRowIndex; i < dataList.size(); i++) { 198 | XSSFRow row = sheet.createRow(i); 199 | List rowList = dataList.get(i); 200 | for (int j = 0; j < rowList.size(); j++) { 201 | XSSFCell cell = row.createCell(j); 202 | cell.setCellValue(rowList.get(j)); 203 | cell.setCellStyle(cellStyle); 204 | } 205 | } 206 | } 207 | } 208 | 209 | /** 210 | * 设置单元格格式 211 | */ 212 | public static XSSFCellStyle getCellStyle(XSSFWorkbook workbook) { 213 | XSSFCellStyle cellStyle = workbook.createCellStyle(); 214 | XSSFFont font = workbook.createFont(); 215 | font.setFontName("黑体"); 216 | font.setFontHeightInPoints((short) 16); 217 | font.setColor(IndexedColors.BLACK.getIndex()); 218 | cellStyle.setFont(font); 219 | cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 220 | cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 221 | cellStyle.setBorderTop(BorderStyle.THIN);//上边框 222 | cellStyle.setBorderRight(BorderStyle.THIN);//右边框 223 | return cellStyle; 224 | } 225 | 226 | /** 227 | * 设置标题的风格 228 | */ 229 | public static XSSFCellStyle getTitleCellStyle(XSSFWorkbook workbook) { 230 | XSSFCellStyle cellStyle = ExcelUtil.getCellStyle(workbook); 231 | XSSFFont font = workbook.createFont(); 232 | font.setFontName("黑体"); 233 | font.setFontHeightInPoints((short) 16); 234 | font.setColor(IndexedColors.WHITE.getIndex()); 235 | cellStyle.setFont(font); 236 | cellStyle.setFillForegroundColor(IndexedColors.INDIGO.getIndex()); 237 | cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); 238 | // 设置水平居中 239 | cellStyle.setAlignment(HorizontalAlignment.CENTER); 240 | // 设置垂直居中 241 | cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); 242 | return cellStyle; 243 | } 244 | 245 | /** 246 | * 单元格不同格式获取值 247 | */ 248 | public static String getCellValue(Cell cell) { 249 | switch (cell.getCellType()) { 250 | case BOOLEAN: 251 | return String.valueOf(cell.getBooleanCellValue()); 252 | case STRING: 253 | return cell.getStringCellValue(); 254 | case NUMERIC: 255 | if (DateUtil.isCellDateFormatted(cell)) { 256 | DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒"); 257 | return timeFormatter.format(cell.getLocalDateTimeCellValue()); 258 | } else { 259 | BigDecimal value = BigDecimal.valueOf(cell.getNumericCellValue()); 260 | BigDecimal noZeros = value.stripTrailingZeros(); 261 | return noZeros.toPlainString(); 262 | } 263 | case FORMULA: 264 | return cell.getCellFormula() + EMPTY; 265 | default: 266 | return EMPTY; 267 | } 268 | } 269 | 270 | } 271 | -------------------------------------------------------------------------------- /springboot-excel/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 20000 3 | servlet: 4 | context-path: /springboot-excel -------------------------------------------------------------------------------- /springboot-excel/src/main/resources/employees.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuifuan/springboot-learn/2d14ede546b1f309817a0a09b697a3b8cf912fe6/springboot-excel/src/main/resources/employees.xlsx -------------------------------------------------------------------------------- /springboot-excel/test_emp.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuifuan/springboot-learn/2d14ede546b1f309817a0a09b697a3b8cf912fe6/springboot-excel/test_emp.xlsx -------------------------------------------------------------------------------- /springboot-init-db/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | com.github.cuifuan 8 | springboot-learn 9 | 1.0.0 10 | 11 | 12 | springboot-init-db 13 | springboot-init-db 14 | springboot-init-db 15 | 16 | 1.8 17 | 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-starter 22 | 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-test 27 | test 28 | 29 | 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-data-jpa 34 | 35 | 36 | 37 | 38 | mysql 39 | mysql-connector-java 40 | 8.0.29 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | org.springframework.boot 49 | spring-boot-maven-plugin 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /springboot-init-db/src/main/java/store/zabbix/initdb/SpringbootInitDbApplication.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.initdb; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringbootInitDbApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringbootInitDbApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springboot-init-db/src/main/java/store/zabbix/initdb/model/UserInfo.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.initdb.model; 2 | 3 | import lombok.Data; 4 | import lombok.NoArgsConstructor; 5 | 6 | import javax.persistence.Entity; 7 | import javax.persistence.GeneratedValue; 8 | import javax.persistence.GenerationType; 9 | import javax.persistence.Id; 10 | import java.time.LocalDateTime; 11 | 12 | @Data 13 | @NoArgsConstructor 14 | @Entity(name = "user_info") 15 | public class UserInfo { 16 | 17 | @Id 18 | @GeneratedValue(strategy = GenerationType.AUTO) 19 | private Long id; 20 | 21 | private String email; 22 | 23 | private String username; 24 | 25 | private String cardNo; 26 | 27 | private String password; 28 | 29 | private LocalDateTime inTime; 30 | 31 | private String remark; 32 | 33 | private Boolean isMember; 34 | 35 | private String address; 36 | 37 | } -------------------------------------------------------------------------------- /springboot-init-db/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | ## MySQL 2 | spring.datasource.url=jdbc:mysql://127.0.0.1:3306/springboot 3 | spring.datasource.username=root 4 | spring.datasource.password=root 5 | ## 配置在日志中打印出执行的 SQL 语句信息 6 | spring.jpa.show-sql=true 7 | # 配置指明在程序启动的时候要删除并且创建实体类对应的表 8 | # create 这个参数很危险,因为他会把对应的表删除掉然后重建。所以千万不要在生成环境中使用。只有在测试环境中,一开始初始化数据库结构的时候才能使用一次。 9 | # ddl-auto:create----每次运行该程序,没有表格会新建表格,表内有数据会清空 10 | # ddl-auto:create-drop----每次程序结束的时候会清空表 11 | # ddl-auto:update----每次运行程序,没有表格会新建表格,表内有数据不会清空,只会更新(推荐) 12 | # ddl-auto:validate----运行程序会校验数据与数据库的字段类型是否相同,不同会报错 13 | spring.jpa.hibernate.ddl-auto=update -------------------------------------------------------------------------------- /springboot-init-db/src/test/java/store/zabbix/initdb/SpringbootInitDbApplicationTests.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.initdb; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class SpringbootInitDbApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springboot-jpa/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.github.cuifuan 7 | springboot-learn 8 | 1.0.0 9 | 10 | 11 | springboot-jpa 12 | springboot-jpa 13 | jpa 项目的 demo 14 | 15 | 16 | 1.8 17 | 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-web 24 | 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-data-jpa 30 | 31 | 32 | 33 | 34 | mysql 35 | mysql-connector-java 36 | 8.0.29 37 | 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-test 42 | test 43 | 44 | 45 | 46 | 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-maven-plugin 51 | 2.7.0 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /springboot-jpa/src/main/java/store/zabbix/jpa/SpringbootJpaApplication.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.jpa; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringbootJpaApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringbootJpaApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springboot-jpa/src/main/java/store/zabbix/jpa/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.jpa.controller; 2 | 3 | import store.zabbix.jpa.model.SysUser; 4 | import store.zabbix.jpa.repository.UserRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.*; 7 | 8 | import java.util.List; 9 | 10 | @RestController 11 | @RequestMapping("user") 12 | public class UserController { 13 | 14 | private UserRepository userRepository; 15 | 16 | @Autowired 17 | public void setUserRepository(UserRepository userRepository) { 18 | this.userRepository = userRepository; 19 | } 20 | 21 | @PostMapping("add") 22 | public SysUser addUser(@RequestBody SysUser sysUser) { 23 | return userRepository.save(sysUser); 24 | } 25 | 26 | @GetMapping("all") 27 | public List getUserList() { 28 | return userRepository.findAll(); 29 | } 30 | 31 | @GetMapping("get/{id}") 32 | public SysUser getUserList(@PathVariable("id") Long id) { 33 | return userRepository.getOne(id); 34 | } 35 | 36 | @PutMapping("update") 37 | public SysUser updateUser(@RequestBody SysUser sysUser) { 38 | return userRepository.saveAndFlush(sysUser); 39 | } 40 | 41 | @DeleteMapping("del/{id}") 42 | public void delUser(@PathVariable("id") Long id) { 43 | userRepository.deleteById(id); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /springboot-jpa/src/main/java/store/zabbix/jpa/model/SysUser.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.jpa.model; 2 | 3 | import lombok.Data; 4 | import lombok.NoArgsConstructor; 5 | 6 | import javax.persistence.Entity; 7 | import javax.persistence.GeneratedValue; 8 | import javax.persistence.GenerationType; 9 | import javax.persistence.Id; 10 | 11 | @Data 12 | @NoArgsConstructor 13 | @Entity(name = "sys_user") 14 | public class SysUser { 15 | 16 | @Id 17 | @GeneratedValue(strategy = GenerationType.AUTO) 18 | private Long id; 19 | 20 | private String email; 21 | 22 | private String username; 23 | 24 | private String password; 25 | 26 | public SysUser(String email, String username, String password) { 27 | this.email = email; 28 | this.username = username; 29 | this.password = password; 30 | } 31 | } -------------------------------------------------------------------------------- /springboot-jpa/src/main/java/store/zabbix/jpa/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.jpa.repository; 2 | 3 | import store.zabbix.jpa.model.SysUser; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | @Repository 8 | public interface UserRepository extends JpaRepository { 9 | 10 | } -------------------------------------------------------------------------------- /springboot-jpa/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.jpa.open-in-view=true 2 | spring.jpa.database-platform=org.hibernate.dialect.H2Dialect 3 | # 配置在日志中打印出执行的 SQL 语句信息 4 | spring.jpa.show-sql=true 5 | # 配置指明在程序启动的时候要删除并且创建实体类对应的表 6 | # create 这个参数很危险,因为他会把对应的表删除掉然后重建。所以千万不要在生成环境中使用。只有在测试环境中,一开始初始化数据库结构的时候才能使用一次。 7 | # ddl-auto:create----每次运行该程序,没有表格会新建表格,表内有数据会清空 8 | # ddl-auto:create-drop----每次程序结束的时候会清空表 9 | # ddl-auto:update----每次运行程序,没有表格会新建表格,表内有数据不会清空,只会更新(推荐) 10 | # ddl-auto:validate----运行程序会校验数据与数据库的字段类型是否相同,不同会报错 11 | spring.jpa.hibernate.ddl-auto=create -------------------------------------------------------------------------------- /springboot-jpa/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS sys_user; 2 | 3 | CREATE TABLE sys_user 4 | ( 5 | id INT AUTO_INCREMENT PRIMARY KEY, 6 | email VARCHAR(250) DEFAULT NULL, 7 | username VARCHAR(250) NOT NULL, 8 | password VARCHAR(250) NOT NULL 9 | ); -------------------------------------------------------------------------------- /springboot-kafka/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuifuan/springboot-learn/2d14ede546b1f309817a0a09b697a3b8cf912fe6/springboot-kafka/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /springboot-kafka/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar 3 | -------------------------------------------------------------------------------- /springboot-kafka/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | com.github.cuifuan 8 | springboot-learn 9 | 1.0.0 10 | 11 | 12 | springboot-kafka 13 | springboot-kafka 14 | 学习 Kafka 15 | 16 | 1.8 17 | 18 | 19 | 20 | 21 | 22 | org.springframework.kafka 23 | spring-kafka 24 | 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter 29 | 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-test 34 | test 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-web 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-maven-plugin 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /springboot-kafka/src/main/java/com/example/springbootkafka/Consumer.java: -------------------------------------------------------------------------------- 1 | package com.example.springbootkafka; 2 | 3 | import org.apache.kafka.clients.consumer.ConsumerRecord; 4 | import org.springframework.kafka.annotation.KafkaListener; 5 | import org.springframework.kafka.support.Acknowledgment; 6 | import org.springframework.stereotype.Component; 7 | 8 | @Component 9 | public class Consumer { 10 | //kafka的监听器,topic为"zhTest",消费者组为"zhTestGroup" 11 | @KafkaListener(topics = "zhTest", groupId = "zhTestGroup") 12 | public void listenZhugeGroup(ConsumerRecord record, Acknowledgment ack) { 13 | String value = record.value(); 14 | System.out.println(value); 15 | System.out.println(record); 16 | //手动提交offset 17 | ack.acknowledge(); 18 | } 19 | 20 | //配置多个消费组 21 | @KafkaListener(topics = "zhTest",groupId = "zhTestGroup2") 22 | public void listenTulingGroup(ConsumerRecord record, Acknowledgment ack) { 23 | String value = record.value(); 24 | System.out.println(value); 25 | System.out.println(record); 26 | ack.acknowledge(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /springboot-kafka/src/main/java/com/example/springbootkafka/Producer.java: -------------------------------------------------------------------------------- 1 | package com.example.springbootkafka; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.kafka.core.KafkaTemplate; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | /** 9 | * kafka生产者【实际上就是一个Controller,用来进行消息生产】 10 | * 11 | * @author 有梦想的肥宅 12 | * @date 2021/10/29 13 | */ 14 | @RestController 15 | public class Producer { 16 | private final static String TOPIC_NAME = "zhTest"; //topic的名称 17 | 18 | @Autowired 19 | private KafkaTemplate kafkaTemplate; 20 | 21 | @RequestMapping("/send") 22 | public void send() { 23 | //发送功能就一行代码~ 24 | kafkaTemplate.send(TOPIC_NAME, "key", "test message send~"); 25 | } 26 | } -------------------------------------------------------------------------------- /springboot-kafka/src/main/java/com/example/springbootkafka/SpringbootKafkaApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.springbootkafka; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringbootKafkaApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringbootKafkaApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springboot-kafka/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9999 3 | 4 | spring: 5 | application: 6 | name: kafka 7 | kafka: 8 | bootstrap-servers: 127.0.0.1:9092 # kafka???? 9 | producer: # ????? 10 | retries: 3 # ????0???????????????????? 11 | batch-size: 16384 #16K 12 | buffer-memory: 33554432 #32M 13 | acks: 1 14 | # ????key?????????? 15 | key-serializer: org.apache.kafka.common.serialization.StringSerializer 16 | value-serializer: org.apache.kafka.common.serialization.StringSerializer 17 | consumer: 18 | group-id: zhTestGroup # ???? 19 | enable-auto-commit: false # ?????? 20 | auto-offset-reset: earliest # ??????????offset??????offset?????????offset???????? 21 | key-deserializer: org.apache.kafka.common.serialization.StringDeserializer 22 | value-deserializer: org.apache.kafka.common.serialization.StringDeserializer 23 | listener: 24 | # ??????????????ListenerConsumer??????? 25 | # RECORD 26 | # ????poll()???????????ListenerConsumer??????? 27 | # BATCH 28 | # ????poll()???????????ListenerConsumer????????????????TIME??? 29 | # TIME 30 | # ????poll()???????????ListenerConsumer?????????record??????COUNT??? 31 | # COUNT 32 | # TIME |?COUNT??????????? 33 | # COUNT_TIME 34 | # ????poll()???????????ListenerConsumer?????, ????Acknowledgment.acknowledge()??? 35 | # MANUAL 36 | # ????Acknowledgment.acknowledge()???????????? 37 | # MANUAL_IMMEDIATE 38 | ack-mode: manual_immediate -------------------------------------------------------------------------------- /springboot-kafka/src/test/java/com/example/springbootkafka/SpringbootKafkaApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.example.springbootkafka; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class SpringbootKafkaApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springboot-kafka/src/test/java/com/example/springbootkafka/singleton/DclSingleton.java: -------------------------------------------------------------------------------- 1 | package com.example.springbootkafka.singleton; 2 | 3 | public class DclSingleton { 4 | private volatile static DclSingleton instance; 5 | 6 | /** 7 | * 增加安全性,防止除自身之外的类访问它 8 | */ 9 | private DclSingleton() { 10 | } 11 | 12 | public static DclSingleton getInstance() { 13 | if (instance == null) { 14 | synchronized (DclSingleton.class) { 15 | if (instance == null) { 16 | instance = new DclSingleton(); 17 | } 18 | } 19 | } 20 | return instance; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return super.toString(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /springboot-kafka/src/test/java/com/example/springbootkafka/singleton/EnumSingleton.java: -------------------------------------------------------------------------------- 1 | package com.example.springbootkafka.singleton; 2 | 3 | /** 4 | * 枚举单例模式 5 | */ 6 | public enum EnumSingleton { 7 | INSTANCE; 8 | 9 | public void method() { 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /springboot-kafka/src/test/java/com/example/springbootkafka/singleton/LazySingleton.java: -------------------------------------------------------------------------------- 1 | package com.example.springbootkafka.singleton; 2 | 3 | public class LazySingleton { 4 | @Override 5 | public String toString() { 6 | return ""; 7 | } 8 | 9 | private static LazySingleton instance; 10 | 11 | private LazySingleton() { 12 | 13 | } 14 | 15 | public static LazySingleton getInstance() { 16 | if (instance != null) { 17 | instance = new LazySingleton(); 18 | } 19 | return instance; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /springboot-kafka/src/test/java/com/example/springbootkafka/singleton/SingletonEager.java: -------------------------------------------------------------------------------- 1 | package com.example.springbootkafka.singleton; 2 | 3 | public class SingletonEager { 4 | 5 | private static volatile SingletonEager singletonEager = new SingletonEager(); 6 | 7 | private SingletonEager() { 8 | System.out.println("饿汉式单例模式"); 9 | } 10 | 11 | public static SingletonEager getInstance() { 12 | return singletonEager; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /springboot-kafka/src/test/java/com/example/springbootkafka/singleton/Solution.java: -------------------------------------------------------------------------------- 1 | package com.example.springbootkafka.singleton; 2 | 3 | import java.util.Arrays; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | import java.util.Objects; 7 | 8 | public class Solution { 9 | public boolean winnerOfGame(String colors) { 10 | if (colors != null && colors.length() > 0) { 11 | String[] split = colors.split("|"); 12 | String temp = "A"; 13 | int times = 0; 14 | int index = 0; 15 | for (String s : split) { 16 | if (Objects.equals(s, temp)) { 17 | times++; 18 | if (times >= 3) { 19 | if (Objects.equals(temp, "A")) { 20 | index++; 21 | } else { 22 | index--; 23 | } 24 | } 25 | } else { 26 | temp = s; 27 | times = 1; 28 | } 29 | } 30 | return index > 0; 31 | } else { 32 | return false; 33 | } 34 | } 35 | 36 | /** 37 | * 两数字之和 38 | */ 39 | public int[] twoSum(int[] nums, int target) { 40 | // 暴力循环 41 | // for (int i = 0; i < nums.length; i++) { 42 | // for (int j = 0; j < nums.length; j++) { 43 | // if (nums[i] + nums[j] == target && i != j) { 44 | // return new int[]{i, j}; 45 | // } 46 | // } 47 | // } 48 | // return null; 49 | Map map = new HashMap<>(); 50 | int[] result = new int[2]; 51 | for (int i = 0; i < nums.length; i++) { 52 | if (map.containsKey(nums[i])) { 53 | result[0] = i; 54 | result[1] = map.get(nums[i]); 55 | } 56 | map.put(target - nums[i], i); 57 | } 58 | return result; 59 | } 60 | 61 | public static void main(String[] args) { 62 | // System.out.println(new Solution().winnerOfGame("AAABABB")); 63 | // System.out.println("AABB".length()); 64 | System.out.println(Arrays.toString(new Solution().twoSum(new int[]{3, 2, 4}, 6))); 65 | } 66 | } -------------------------------------------------------------------------------- /springboot-mongodb/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | mongodb: 4 | image: mongo:4.2.6 # 镜像:版本 5 | container_name: mongo_db 6 | environment: 7 | - MONGO_INITDB_DATABASE=默认的数据库 8 | - MONGO_INITDB_ROOT_USERNAME=你的root管理员名称 9 | - MONGO_INITDB_ROOT_PASSWORD=你的root管理员名称密码 10 | volumes: 11 | - ./mongo/init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro 12 | - ./mongo/mongo-volume:/data/db 13 | ports: 14 | - "27017-27019:27017-27019" 15 | restart: always 16 | -------------------------------------------------------------------------------- /springboot-mongodb/mongo/init-mongo.js: -------------------------------------------------------------------------------- 1 | // db.getSiblingDB() 相当于 use admin; 2 | db.getSiblingDB('admin') 3 | .createUser({ 4 | user: 'user', 5 | pwd: 'user', 6 | roles: ['readWrite'] 7 | }); -------------------------------------------------------------------------------- /springboot-mongodb/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | com.github.cuifuan 8 | springboot-learn 9 | 1.0.0 10 | 11 | 12 | com.example 13 | springboot-mongodb 14 | 1.0.0 15 | 16 | 17 | springboot-mongodb 18 | Demo project for Spring Boot 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 27.1-jre 26 | 27 | 28 | 29 | 30 | 31 | 32 | org.projectlombok 33 | lombok 34 | 1.18.12 35 | provided 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-starter-web 40 | 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-starter-data-mongodb 45 | 2.7.0 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /springboot-mongodb/springboot-mongodb.iml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /springboot-mongodb/src/main/java/com/example/mongodb/controller/DepartmentController.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.mongodb.controller; 2 | 3 | import store.zabbix.mongodb.model.Department; 4 | import store.zabbix.mongodb.model.Employee; 5 | import store.zabbix.mongodb.repository.DepartmentRepository; 6 | import store.zabbix.mongodb.repository.DeptRepository; 7 | import store.zabbix.mongodb.repository.EmpRepository; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | import java.util.Collections; 12 | import java.util.List; 13 | import java.util.Optional; 14 | 15 | @RestController 16 | public class DepartmentController { 17 | @Autowired 18 | DepartmentRepository departmentRepository; 19 | @Autowired 20 | DeptRepository deptRepository; 21 | @Autowired 22 | EmpRepository empRepository; 23 | 24 | @PostMapping("/v1/dept/s") 25 | public Department v1save(@RequestBody Department department) { 26 | List employees = Optional.ofNullable(department.getEmployees()).orElse(Collections.emptyList()); 27 | employees.forEach(employee -> empRepository.save(employee)); 28 | return departmentRepository.save(department); 29 | } 30 | 31 | @GetMapping("/v1/dept/l") 32 | public List v1list() { 33 | return departmentRepository.findAll(); 34 | } 35 | 36 | @PutMapping("/v1/dept/u/{deptId}") 37 | public Department v1update(@RequestBody Department department, @PathVariable String deptId) { 38 | department.setId(deptId); 39 | List employees = Optional.ofNullable(department.getEmployees()).orElse(Collections.emptyList()); 40 | employees.forEach(employee -> empRepository.save(employee)); 41 | return departmentRepository.save(department); 42 | } 43 | 44 | @DeleteMapping("/v1/dept/d/{deptId}") 45 | public String v1delete(@PathVariable String deptId) { 46 | departmentRepository.deleteById(deptId); 47 | return deptId; 48 | } 49 | 50 | @GetMapping("/v1/dept/get/{deptName}") 51 | public List v1getByName(@PathVariable String deptName) { 52 | return departmentRepository.findDepartmentByName(deptName); 53 | } 54 | 55 | @GetMapping("/v1/dept/get/emp/{empName}") 56 | public Department v1getByEmpName(@PathVariable String empName) { 57 | return departmentRepository.findDepartmentByEmployeeName(empName); 58 | } 59 | 60 | @PostMapping("/v2/dept/s") 61 | public Department v2save(Department department) { 62 | List employees = Optional.ofNullable(department.getEmployees()).orElse(Collections.emptyList()); 63 | employees.forEach(employee -> empRepository.save(employee)); 64 | return deptRepository.save(department); 65 | } 66 | 67 | @GetMapping("/v2/dept/l") 68 | public List v2list() { 69 | return deptRepository.findAll(); 70 | } 71 | 72 | @PutMapping("/v2/dept/u") 73 | public Department v2update(Department department) { 74 | List employees = Optional.ofNullable(department.getEmployees()).orElse(Collections.emptyList()); 75 | employees.forEach(employee -> empRepository.save(employee)); 76 | return deptRepository.update(department); 77 | } 78 | 79 | @DeleteMapping("/v2/dept/d/{deptId}") 80 | public void v2delete(@PathVariable String deptId) { 81 | deptRepository.deleteById(deptId); 82 | } 83 | 84 | @GetMapping("/v2/dept/get/{deptName}") 85 | public List v2getByName(@PathVariable String deptName) { 86 | return deptRepository.findDepartmentByName(deptName); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /springboot-mongodb/src/main/java/com/example/mongodb/model/Department.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.mongodb.model; 2 | 3 | import org.springframework.data.annotation.Id; 4 | import org.springframework.data.mongodb.core.index.Indexed; 5 | import org.springframework.data.mongodb.core.mapping.DBRef; 6 | import org.springframework.data.mongodb.core.mapping.Document; 7 | 8 | import java.util.List; 9 | 10 | @Document("Department") 11 | public class Department { 12 | @Id 13 | private String id; 14 | @Indexed(name = "deptName") 15 | private String name; 16 | private String description; 17 | @DBRef 18 | private List employees; 19 | 20 | public String getId() { 21 | return id; 22 | } 23 | 24 | public void setId(String id) { 25 | this.id = id; 26 | } 27 | 28 | public String getName() { 29 | return name; 30 | } 31 | 32 | public void setName(String name) { 33 | this.name = name; 34 | } 35 | 36 | public String getDescription() { 37 | return description; 38 | } 39 | 40 | public void setDescription(String description) { 41 | this.description = description; 42 | } 43 | 44 | public List getEmployees() { 45 | return employees; 46 | } 47 | 48 | public void setEmployees(List employees) { 49 | this.employees = employees; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /springboot-mongodb/src/main/java/com/example/mongodb/model/Employee.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.mongodb.model; 2 | 3 | import org.springframework.data.annotation.Id; 4 | import org.springframework.data.mongodb.core.mapping.Document; 5 | 6 | @Document("Employee") 7 | public class Employee { 8 | 9 | @Id 10 | private String empId; 11 | private String name; 12 | private int age; 13 | private double salary; 14 | 15 | public String getEmpId() { 16 | return empId; 17 | } 18 | 19 | public void setEmpId(String empId) { 20 | this.empId = empId; 21 | } 22 | 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | public void setName(String name) { 28 | this.name = name; 29 | } 30 | 31 | public int getAge() { 32 | return age; 33 | } 34 | 35 | public void setAge(int age) { 36 | this.age = age; 37 | } 38 | 39 | public double getSalary() { 40 | return salary; 41 | } 42 | 43 | public void setSalary(double salary) { 44 | this.salary = salary; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /springboot-mongodb/src/main/java/com/example/mongodb/repository/DepartmentRepository.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.mongodb.repository; 2 | 3 | import store.zabbix.mongodb.model.Department; 4 | import org.springframework.data.mongodb.repository.MongoRepository; 5 | import org.springframework.data.mongodb.repository.Query; 6 | import org.springframework.stereotype.Repository; 7 | 8 | import java.util.List; 9 | 10 | @Repository 11 | public interface DepartmentRepository extends MongoRepository { 12 | @Query(value = "{'Employee.name': ?0}", fields = "{'employees' : 0}") 13 | Department findDepartmentByEmployeeName(String empName); 14 | 15 | List findDepartmentByName(String name); 16 | } 17 | -------------------------------------------------------------------------------- /springboot-mongodb/src/main/java/com/example/mongodb/repository/DeptRepository.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.mongodb.repository; 2 | 3 | import store.zabbix.mongodb.model.Department; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.data.mongodb.core.MongoTemplate; 6 | import org.springframework.data.mongodb.core.query.Criteria; 7 | import org.springframework.data.mongodb.core.query.Query; 8 | import org.springframework.data.mongodb.core.query.Update; 9 | import org.springframework.stereotype.Repository; 10 | 11 | import java.util.List; 12 | 13 | @Repository 14 | public class DeptRepository { 15 | 16 | @Autowired 17 | private MongoTemplate mongoTemplate; 18 | 19 | public List findAll() { 20 | return mongoTemplate.findAll(Department.class); 21 | } 22 | 23 | public List findDepartmentByName(String deptName) { 24 | Query query = new Query(); 25 | query.addCriteria(Criteria.where("name").is(deptName)); 26 | return mongoTemplate.find(query, Department.class); 27 | } 28 | 29 | public Department save(Department department) { 30 | mongoTemplate.save(department); 31 | return department; 32 | } 33 | 34 | public Department update(Department department) { 35 | Query query = new Query(); 36 | query.addCriteria(Criteria.where("id").is(department.getId())); 37 | Update update = new Update(); 38 | update.set("name", department.getName()); 39 | update.set("description", department.getDescription()); 40 | return mongoTemplate.findAndModify(query, update, Department.class); 41 | } 42 | 43 | public void deleteById(String deptId) { 44 | Query query = new Query(); 45 | query.addCriteria(Criteria.where("id").is(deptId)); 46 | mongoTemplate.remove(query, Department.class); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /springboot-mongodb/src/main/java/com/example/mongodb/repository/EmpRepository.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.mongodb.repository; 2 | 3 | import store.zabbix.mongodb.model.Employee; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.data.mongodb.core.MongoTemplate; 6 | import org.springframework.stereotype.Repository; 7 | 8 | @Repository 9 | public class EmpRepository { 10 | 11 | @Autowired 12 | private MongoTemplate mongoTemplate; 13 | 14 | public void save(Employee employee) { 15 | mongoTemplate.save(employee); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /springboot-mybatis-plus/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /springboot-mybatis-plus/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import java.net.*; 17 | import java.io.*; 18 | import java.nio.channels.*; 19 | import java.util.Properties; 20 | 21 | public class MavenWrapperDownloader { 22 | 23 | private static final String WRAPPER_VERSION = "0.5.6"; 24 | /** 25 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 26 | */ 27 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" 28 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; 29 | 30 | /** 31 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 32 | * use instead of the default one. 33 | */ 34 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 35 | ".mvn/wrapper/maven-wrapper.properties"; 36 | 37 | /** 38 | * Path where the maven-wrapper.jar will be saved to. 39 | */ 40 | private static final String MAVEN_WRAPPER_JAR_PATH = 41 | ".mvn/wrapper/maven-wrapper.jar"; 42 | 43 | /** 44 | * Name of the property which should be used to override the default download url for the wrapper. 45 | */ 46 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 47 | 48 | public static void main(String args[]) { 49 | System.out.println("- Downloader started"); 50 | File baseDirectory = new File(args[0]); 51 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 52 | 53 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 54 | // wrapperUrl parameter. 55 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 56 | String url = DEFAULT_DOWNLOAD_URL; 57 | if(mavenWrapperPropertyFile.exists()) { 58 | FileInputStream mavenWrapperPropertyFileInputStream = null; 59 | try { 60 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 61 | Properties mavenWrapperProperties = new Properties(); 62 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 63 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 64 | } catch (IOException e) { 65 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 66 | } finally { 67 | try { 68 | if(mavenWrapperPropertyFileInputStream != null) { 69 | mavenWrapperPropertyFileInputStream.close(); 70 | } 71 | } catch (IOException e) { 72 | // Ignore ... 73 | } 74 | } 75 | } 76 | System.out.println("- Downloading from: " + url); 77 | 78 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 79 | if(!outputFile.getParentFile().exists()) { 80 | if(!outputFile.getParentFile().mkdirs()) { 81 | System.out.println( 82 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 83 | } 84 | } 85 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 86 | try { 87 | downloadFileFromURL(url, outputFile); 88 | System.out.println("Done"); 89 | System.exit(0); 90 | } catch (Throwable e) { 91 | System.out.println("- Error downloading"); 92 | e.printStackTrace(); 93 | System.exit(1); 94 | } 95 | } 96 | 97 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 98 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { 99 | String username = System.getenv("MVNW_USERNAME"); 100 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); 101 | Authenticator.setDefault(new Authenticator() { 102 | @Override 103 | protected PasswordAuthentication getPasswordAuthentication() { 104 | return new PasswordAuthentication(username, password); 105 | } 106 | }); 107 | } 108 | URL website = new URL(urlString); 109 | ReadableByteChannel rbc; 110 | rbc = Channels.newChannel(website.openStream()); 111 | FileOutputStream fos = new FileOutputStream(destination); 112 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 113 | fos.close(); 114 | rbc.close(); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /springboot-mybatis-plus/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuifuan/springboot-learn/2d14ede546b1f309817a0a09b697a3b8cf912fe6/springboot-mybatis-plus/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /springboot-mybatis-plus/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /springboot-mybatis-plus/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | com.github.cuifuan 8 | springboot-learn 9 | 1.0.0 10 | 11 | 12 | springboot-mybatis-plus 13 | springboot-mybatis-plus 14 | 使用Spring Boot 与 MyBatis Plus 快速构建应用 15 | 16 | 17 | 1.8 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter 24 | 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-web 29 | 30 | 31 | 32 | org.projectlombok 33 | lombok 34 | true 35 | 36 | 37 | 38 | com.baomidou 39 | mybatis-plus-boot-starter 40 | 3.5.0 41 | 42 | 43 | 44 | 45 | mysql 46 | mysql-connector-java 47 | 8.0.12 48 | 49 | 50 | 51 | com.github.cuifuan 52 | springboot-common 53 | 1.0.0 54 | 55 | 56 | 57 | 58 | springboot-mybatis-plus 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-maven-plugin 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /springboot-mybatis-plus/src/main/java/com/github/cuifuan/mp/SpringBootMybatisApplication.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mp; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; 5 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; 6 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; 7 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; 8 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; 9 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; 10 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; 11 | import org.mybatis.spring.annotation.MapperScan; 12 | import org.springframework.boot.SpringApplication; 13 | import org.springframework.boot.autoconfigure.SpringBootApplication; 14 | import org.springframework.context.annotation.Bean; 15 | import org.springframework.transaction.annotation.EnableTransactionManagement; 16 | 17 | import java.time.LocalDate; 18 | import java.time.LocalDateTime; 19 | import java.time.LocalTime; 20 | import java.time.format.DateTimeFormatter; 21 | 22 | @EnableTransactionManagement 23 | @SpringBootApplication 24 | @MapperScan("com.github.cuifuan.mp.mapper") 25 | public class SpringBootMybatisApplication { 26 | 27 | public static void main(String[] args) { 28 | SpringApplication.run(SpringBootMybatisApplication.class, args); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /springboot-mybatis-plus/src/main/java/com/github/cuifuan/mp/controller/TestController.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mp.controller; 2 | 3 | import com.github.cuifuan.mp.service.TestService; 4 | import com.github.cuifuan.mp.domain.MybatisTest; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.*; 7 | 8 | @RequestMapping("/test") 9 | @RestController 10 | public class TestController { 11 | 12 | private TestService testService; 13 | 14 | @Autowired 15 | public void setTestService(TestService testService) { 16 | this.testService = testService; 17 | } 18 | 19 | @GetMapping("getById/{id}") 20 | public MybatisTest getClient(@PathVariable("id") final Long id) { 21 | return testService.getMybatisTestById(id); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /springboot-mybatis-plus/src/main/java/com/github/cuifuan/mp/controller/UserInfoController.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mp.controller; 2 | 3 | import com.github.cuifuan.mp.domain.UserInfo; 4 | import com.github.cuifuan.mp.service.UserInfoService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.PathVariable; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | @RestController 12 | @RequestMapping("/users") 13 | public class UserInfoController { 14 | 15 | @Autowired 16 | private UserInfoService userService; 17 | 18 | @GetMapping("/{id}") 19 | public UserInfo getUserById(@PathVariable Long id) { 20 | return userService.getById(id); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /springboot-mybatis-plus/src/main/java/com/github/cuifuan/mp/domain/MybatisTest.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mp.domain; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | @Data 8 | public class MybatisTest implements Serializable { 9 | 10 | private static final long serialVersionUID = 8897018268303812871L; 11 | 12 | private Long id; 13 | 14 | private String firstName; 15 | 16 | private String enName; 17 | } 18 | -------------------------------------------------------------------------------- /springboot-mybatis-plus/src/main/java/com/github/cuifuan/mp/domain/User.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mp.domain; 2 | 3 | import lombok.Data; 4 | import lombok.NoArgsConstructor; 5 | 6 | import java.time.LocalDateTime; 7 | 8 | @Data 9 | @NoArgsConstructor 10 | public class User { 11 | 12 | private String name; 13 | 14 | private Integer age; 15 | 16 | private LocalDateTime brithday; 17 | 18 | private String fullName; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /springboot-mybatis-plus/src/main/java/com/github/cuifuan/mp/domain/UserInfo.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mp.domain; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.baomidou.mybatisplus.annotation.TableId; 6 | import com.baomidou.mybatisplus.annotation.TableName; 7 | import lombok.Data; 8 | 9 | import java.io.Serializable; 10 | import java.time.LocalDateTime; 11 | 12 | /** 13 | * TableName user_info 14 | */ 15 | @TableName(value = "user_info") 16 | @Data 17 | public class UserInfo implements Serializable { 18 | 19 | @TableId(type = IdType.AUTO) 20 | private Long id; 21 | 22 | private String username; 23 | 24 | private String fullName; 25 | 26 | private String address; 27 | 28 | private String cardNo; 29 | 30 | private String email; 31 | 32 | private String sex; 33 | 34 | private LocalDateTime inTime; 35 | 36 | private Boolean isMember; 37 | 38 | private String password; 39 | 40 | /** 41 | * 42 | */ 43 | private String remark; 44 | 45 | @TableField(exist = false) 46 | private static final long serialVersionUID = 1L; 47 | } -------------------------------------------------------------------------------- /springboot-mybatis-plus/src/main/java/com/github/cuifuan/mp/mapper/TestMapper.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mp.mapper; 2 | 3 | import com.github.cuifuan.mp.domain.MybatisTest; 4 | import org.apache.ibatis.annotations.Insert; 5 | import org.apache.ibatis.annotations.Mapper; 6 | import org.apache.ibatis.annotations.Options; 7 | import org.apache.ibatis.annotations.Select; 8 | 9 | import java.util.List; 10 | 11 | @Mapper 12 | public interface TestMapper { 13 | 14 | @Select("SELECT id, first_name as firstName, en_name as enName FROM mybatis_test WHERE id = #{id}") 15 | MybatisTest selectOne(long id); 16 | 17 | @Select("SELECT id, first_name as firstName, en_name as enName FROM mybatis_test") 18 | List findAll(); 19 | 20 | @Insert("INSERT INTO mybatis_test (id, first_name, en_name) VALUES (#{id}, #{firstName}, #{enName})") 21 | // 将对象ID设置为数据库中生成的ID 22 | @Options(useGeneratedKeys = true, keyColumn = "id", keyProperty = "id") 23 | void insertMybatisTest(MybatisTest mybatisTest); 24 | 25 | List findByFirstName(String value); 26 | } 27 | -------------------------------------------------------------------------------- /springboot-mybatis-plus/src/main/java/com/github/cuifuan/mp/mapper/UserInfoMapper.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mp.mapper; 2 | 3 | import com.github.cuifuan.mp.domain.UserInfo; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | 6 | /** 7 | * @author bran 8 | * @description 针对表【user_info】的数据库操作Mapper 9 | * @createDate 2023-08-09 14:03:10 10 | * @Entity com.github.cuifuan.mp.domain.UserInfo 11 | */ 12 | public interface UserInfoMapper extends BaseMapper { 13 | 14 | } 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /springboot-mybatis-plus/src/main/java/com/github/cuifuan/mp/service/TestService.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mp.service; 2 | 3 | import com.github.cuifuan.mp.domain.MybatisTest; 4 | 5 | import java.util.List; 6 | 7 | public interface TestService { 8 | 9 | MybatisTest getMybatisTestById(Long id); 10 | 11 | void createMybatisTest(final MybatisTest mybatisTest); 12 | 13 | List getMybatisTests(); 14 | } 15 | -------------------------------------------------------------------------------- /springboot-mybatis-plus/src/main/java/com/github/cuifuan/mp/service/UserInfoService.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mp.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 4 | import com.github.cuifuan.mp.domain.UserInfo; 5 | import com.github.cuifuan.mp.mapper.UserInfoMapper; 6 | import org.springframework.stereotype.Service; 7 | 8 | /** 9 | * desc: 用户信息的业务逻辑层 10 | * date 2023/8/9 14:07 11 | * @author cuifuan 12 | **/ 13 | @Service 14 | public class UserInfoService extends ServiceImpl { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /springboot-mybatis-plus/src/main/java/com/github/cuifuan/mp/service/impl/TestServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mp.service.impl; 2 | 3 | import com.github.cuifuan.mp.mapper.TestMapper; 4 | import com.github.cuifuan.mp.service.TestService; 5 | import com.github.cuifuan.mp.domain.MybatisTest; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.util.List; 10 | 11 | @Service 12 | public class TestServiceImpl implements TestService { 13 | 14 | 15 | private TestMapper testMapper; 16 | 17 | @Autowired 18 | public void setTestMapper(TestMapper testMapper) { 19 | this.testMapper = testMapper; 20 | } 21 | 22 | @Override 23 | public MybatisTest getMybatisTestById(Long id) { 24 | return testMapper.selectOne(id); 25 | } 26 | 27 | @Override 28 | public List getMybatisTests() { 29 | return testMapper.findAll(); 30 | } 31 | 32 | @Override 33 | public void createMybatisTest(final MybatisTest mybatisTest) { 34 | testMapper.insertMybatisTest(mybatisTest); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /springboot-mybatis-plus/src/main/java/com/github/cuifuan/mp/singleton/LazyInitializedSingleton.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mp.singleton; 2 | 3 | public class LazyInitializedSingleton { 4 | private static LazyInitializedSingleton instance; 5 | 6 | private LazyInitializedSingleton() { 7 | } 8 | 9 | public static LazyInitializedSingleton getInstance() { 10 | if (instance == null) { 11 | instance = new LazyInitializedSingleton(); 12 | } 13 | return instance; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /springboot-mybatis-plus/src/main/java/com/github/cuifuan/mp/singleton/StaticBlockSingleton.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mp.singleton; 2 | 3 | public class StaticBlockSingleton { 4 | 5 | private static StaticBlockSingleton instance; 6 | 7 | private StaticBlockSingleton() { 8 | } 9 | 10 | // 用于异常处理的静态块初始化 11 | static { 12 | try { 13 | instance = new StaticBlockSingleton(); 14 | } catch (Exception e) { 15 | throw new RuntimeException("创建单例时发生异常!"); 16 | } 17 | } 18 | 19 | public static StaticBlockSingleton getInstance() { 20 | return instance; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /springboot-mybatis-plus/src/main/java/com/github/cuifuan/mp/singleton/ThreadSafeSingleton.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mp.singleton; 2 | 3 | public class ThreadSafeSingleton { 4 | 5 | private static ThreadSafeSingleton instance; 6 | 7 | private ThreadSafeSingleton() { 8 | } 9 | 10 | public static synchronized ThreadSafeSingleton getInstance() { 11 | if (instance == null) { 12 | instance = new ThreadSafeSingleton(); 13 | } 14 | return instance; 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /springboot-mybatis-plus/src/main/java/com/github/cuifuan/mp/test/UserTest.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mp.test; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import com.fasterxml.jackson.databind.node.ObjectNode; 6 | import com.github.cuifuan.mp.domain.User; 7 | import com.github.cuifuan.mp.util.ObjUtil; 8 | 9 | import java.time.LocalDateTime; 10 | 11 | public class UserTest { 12 | public static void main(String[] args) throws JsonProcessingException { 13 | User user = new User(); 14 | user.setBrithday(LocalDateTime.now()); 15 | user.setName("张三"); 16 | ObjectMapper objectMapper = ObjUtil.objectMapper(); 17 | String result = objectMapper.writeValueAsString(user); 18 | System.out.println("User ==> " + result); 19 | ObjectNode jsonNode = (ObjectNode) objectMapper.readTree(result); 20 | jsonNode.put("remark", "精英"); 21 | System.out.println("jsonNode ==> " + objectMapper.writeValueAsString(jsonNode)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /springboot-mybatis-plus/src/main/java/com/github/cuifuan/mp/util/ObjUtil.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.mp.util; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; 5 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; 6 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; 7 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; 8 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; 9 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; 10 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; 11 | 12 | import java.time.LocalDate; 13 | import java.time.LocalDateTime; 14 | import java.time.LocalTime; 15 | import java.time.format.DateTimeFormatter; 16 | 17 | public class ObjUtil { 18 | public static ObjectMapper objectMapper() { 19 | ObjectMapper objectMapper = new ObjectMapper(); 20 | 21 | JavaTimeModule javaTimeModule = new JavaTimeModule(); 22 | 23 | javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); 24 | javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); 25 | 26 | javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss"))); 27 | javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); 28 | 29 | javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); 30 | javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss"))); 31 | 32 | objectMapper.registerModule(javaTimeModule); 33 | return objectMapper; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /springboot-mybatis-plus/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | driver-class-name: com.mysql.cj.jdbc.Driver 4 | url: jdbc:mysql://localhost:3306/springboot?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true 5 | username: root 6 | password: root 7 | mybatis-plus: 8 | type-aliases-package: com.github.cuifuan.mp.domain 9 | mapper-locations: classpath:/mapper/*Mapper.xml 10 | configuration: 11 | map-underscore-to-camel-case: true 12 | mapper-default-scope: classpath*:mapper/*.xml -------------------------------------------------------------------------------- /springboot-mybatis-plus/src/main/resources/mapper/TestMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SELECT 7 | id, 8 | first_name as firstName, 9 | en_name as enName 10 | FROM mybatis_test 11 | WHERE first_name = #{value} 12 | 13 | 14 | -------------------------------------------------------------------------------- /springboot-mybatis-plus/src/main/resources/mapper/UserInfoMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | id,username,full_name, 23 | address,card_no,email, 24 | sex,in_time,is_member, 25 | password,remark 26 | 27 | 28 | -------------------------------------------------------------------------------- /springboot-redis/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | redis: 5 | image: redis:4.0.2 6 | container_name: my_redis 7 | volumes: 8 | - ./redis/data:/data 9 | - ./redis/conf/:/usr/local/etc/redis/ 10 | command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf" 11 | ports: 12 | - 6379:6379 -------------------------------------------------------------------------------- /springboot-redis/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.github.cuifuan 7 | springboot-learn 8 | 1.0.0 9 | 10 | 11 | springboot-redis 12 | springboot-redis 13 | Spring Boot Redis Demo 14 | 15 | 16 | 1.8 17 | 8.0.29 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-data-redis 24 | 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-data-jpa 29 | 30 | 31 | mysql 32 | mysql-connector-java 33 | ${mysql.version} 34 | 35 | 36 | 37 | 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-maven-plugin 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /springboot-redis/src/main/java/com/github/cuifuan/redis/SpringBootRedisApplication.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.redis; 2 | 3 | import com.github.cuifuan.redis.dao.UserRepository; 4 | import com.github.cuifuan.redis.model.User; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.CommandLineRunner; 8 | import org.springframework.boot.SpringApplication; 9 | import org.springframework.boot.autoconfigure.SpringBootApplication; 10 | import org.springframework.cache.annotation.EnableCaching; 11 | 12 | @Slf4j 13 | //springboot启动时执行任务CommandLineRunner 14 | @SpringBootApplication 15 | //开启缓存 16 | @EnableCaching 17 | public class SpringBootRedisApplication implements CommandLineRunner { 18 | 19 | private UserRepository userRepository; 20 | 21 | public static void main(String[] args) { 22 | SpringApplication.run(SpringBootRedisApplication.class, args); 23 | } 24 | 25 | @Autowired 26 | public void setUserRepository(UserRepository userRepository) { 27 | this.userRepository = userRepository; 28 | } 29 | 30 | @Override 31 | public void run(String... args) throws Exception { 32 | log.info("开始初始化user ->user count ->{}", userRepository.count()); 33 | User james = new User(1L, "James", 2000); 34 | User potter = new User(2L, "Potter", 4000); 35 | User dumbledore = new User(3L, "Dumbledore", 999999); 36 | 37 | userRepository.save(james); 38 | userRepository.save(potter); 39 | userRepository.save(dumbledore); 40 | log.info("初始化完成 数据-> {}.", userRepository.findAll()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /springboot-redis/src/main/java/com/github/cuifuan/redis/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.redis.controller; 2 | 3 | import com.github.cuifuan.redis.dao.UserRepository; 4 | import com.github.cuifuan.redis.model.User; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.cache.annotation.CachePut; 8 | import org.springframework.cache.annotation.Cacheable; 9 | import org.springframework.data.redis.core.StringRedisTemplate; 10 | import org.springframework.web.bind.annotation.*; 11 | 12 | @Slf4j 13 | @RestController 14 | public class UserController { 15 | 16 | private UserRepository userRepository; 17 | 18 | @Autowired 19 | public void setUserRepository(UserRepository userRepository) { 20 | this.userRepository = userRepository; 21 | } 22 | 23 | @Cacheable(cacheNames = "userAll") 24 | @GetMapping("user/all") 25 | public Object getUserAll() { 26 | return userRepository.findAll(); 27 | } 28 | 29 | @Cacheable(value = "users", key = "#userId", unless = "#result.money < 10000") 30 | @GetMapping("user/con/{userId}") 31 | public Object getUserByCondition(@PathVariable Long userId) { 32 | return userRepository.findById(userId); 33 | } 34 | 35 | @CachePut(value = "users", key = "#user.id") 36 | @PutMapping("/update") 37 | public User updatePersonByID(@RequestBody User user) { 38 | userRepository.save(user); 39 | return user; 40 | } 41 | 42 | // @CacheEvict(value = "users", allEntries=true) 43 | // @DeleteMapping("/{id}") 44 | // public void deleteUserByID(@PathVariable Long id) { 45 | // List userListOld = userRepository.findAll(); 46 | // log.info("删除前:{}", userListOld.toString()); 47 | // userRepository.deleteById(id); 48 | // List userList = userRepository.findAll(); 49 | // log.info("删除后:{}", userList.toString()); 50 | // } 51 | 52 | @Autowired 53 | private StringRedisTemplate stringRedisTemplate; 54 | 55 | 56 | @GetMapping("test/{id}") 57 | public void test(@PathVariable Long id) { 58 | System.out.println(stringRedisTemplate.opsForValue().get("abc")); 59 | } 60 | } -------------------------------------------------------------------------------- /springboot-redis/src/main/java/com/github/cuifuan/redis/dao/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.redis.dao; 2 | 3 | import com.github.cuifuan.redis.model.User; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | * 操作数据库 9 | */ 10 | @Repository 11 | public interface UserRepository extends JpaRepository { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springboot-redis/src/main/java/com/github/cuifuan/redis/model/User.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.redis.model; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import lombok.ToString; 7 | 8 | import javax.persistence.*; 9 | import java.io.Serializable; 10 | 11 | @Data 12 | @Entity 13 | @ToString 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class User implements Serializable { 17 | 18 | private static final long serialVersionUID = 1L; 19 | 20 | @Id 21 | @SequenceGenerator(name = "SEQ_GEN", sequenceName = "SEQ_USER", allocationSize = 1) 22 | @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_GEN") 23 | private Long id; 24 | 25 | private String name; 26 | 27 | private long money; 28 | 29 | } -------------------------------------------------------------------------------- /springboot-redis/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver 2 | spring.datasource.url=jdbc:mysql://127.0.0.1:3306/springboot?serverTimezone=Asia/Shanghai&characterEncoding=utf8&sslMode=DISABLED 3 | spring.datasource.username=root 4 | spring.datasource.password=root 5 | spring.datasource.hikari.max-lifetime=500000 6 | spring.datasource.hikari.maximum-pool-size=10 7 | spring.cache.type=redis 8 | spring.redis.host=127.0.0.1 9 | spring.redis.port=6379 10 | spring.jpa.open-in-view=true 11 | spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect 12 | # 配置在日志中打印出执行的 SQL 语句信息 13 | spring.jpa.show-sql=true 14 | # 配置指明在程序启动的时候要删除并且创建实体类对应的表 15 | # create 这个参数很危险,因为他会把对应的表删除掉然后重建。所以千万不要在生成环境中使用。只有在测试环境中,一开始初始化数据库结构的时候才能使用一次。 16 | # ddl-auto:create----每次运行该程序,没有表格会新建表格,表内有数据会清空 17 | # ddl-auto:create-drop----每次程序结束的时候会清空表 18 | # ddl-auto:update----每次运行程序,没有表格会新建表格,表内有数据不会清空,只会更新(推荐) 19 | # ddl-auto:validate----运行程序会校验数据与数据库的字段类型是否相同,不同会报错 20 | spring.jpa.hibernate.ddl-auto=update -------------------------------------------------------------------------------- /springboot-upfile/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /springboot-upfile/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import java.net.*; 18 | import java.io.*; 19 | import java.nio.channels.*; 20 | import java.util.Properties; 21 | 22 | public class MavenWrapperDownloader { 23 | 24 | private static final String WRAPPER_VERSION = "0.5.6"; 25 | /** 26 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 27 | */ 28 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" 29 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; 30 | 31 | /** 32 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 33 | * use instead of the default one. 34 | */ 35 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 36 | ".mvn/wrapper/maven-wrapper.properties"; 37 | 38 | /** 39 | * Path where the maven-wrapper.jar will be saved to. 40 | */ 41 | private static final String MAVEN_WRAPPER_JAR_PATH = 42 | ".mvn/wrapper/maven-wrapper.jar"; 43 | 44 | /** 45 | * Name of the property which should be used to override the default download url for the wrapper. 46 | */ 47 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 48 | 49 | public static void main(String args[]) { 50 | System.out.println("- Downloader started"); 51 | File baseDirectory = new File(args[0]); 52 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 53 | 54 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 55 | // wrapperUrl parameter. 56 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 57 | String url = DEFAULT_DOWNLOAD_URL; 58 | if (mavenWrapperPropertyFile.exists()) { 59 | FileInputStream mavenWrapperPropertyFileInputStream = null; 60 | try { 61 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 62 | Properties mavenWrapperProperties = new Properties(); 63 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 64 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 65 | } catch (IOException e) { 66 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 67 | } finally { 68 | try { 69 | if (mavenWrapperPropertyFileInputStream != null) { 70 | mavenWrapperPropertyFileInputStream.close(); 71 | } 72 | } catch (IOException e) { 73 | // Ignore ... 74 | } 75 | } 76 | } 77 | System.out.println("- Downloading from: " + url); 78 | 79 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 80 | if (!outputFile.getParentFile().exists()) { 81 | if (!outputFile.getParentFile().mkdirs()) { 82 | System.out.println( 83 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 84 | } 85 | } 86 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 87 | try { 88 | downloadFileFromURL(url, outputFile); 89 | System.out.println("Done"); 90 | System.exit(0); 91 | } catch (Throwable e) { 92 | System.out.println("- Error downloading"); 93 | e.printStackTrace(); 94 | System.exit(1); 95 | } 96 | } 97 | 98 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 99 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { 100 | String username = System.getenv("MVNW_USERNAME"); 101 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); 102 | Authenticator.setDefault(new Authenticator() { 103 | @Override 104 | protected PasswordAuthentication getPasswordAuthentication() { 105 | return new PasswordAuthentication(username, password); 106 | } 107 | }); 108 | } 109 | URL website = new URL(urlString); 110 | ReadableByteChannel rbc; 111 | rbc = Channels.newChannel(website.openStream()); 112 | FileOutputStream fos = new FileOutputStream(destination); 113 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 114 | fos.close(); 115 | rbc.close(); 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /springboot-upfile/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuifuan/springboot-learn/2d14ede546b1f309817a0a09b697a3b8cf912fe6/springboot-upfile/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /springboot-upfile/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /springboot-upfile/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.3.2.RELEASE 9 | 10 | 11 | com.example 12 | springboot-upfile 13 | 0.0.1-SNAPSHOT 14 | springboot-upfile 15 | Demo project for Spring Boot 16 | 17 | 18 | UTF-8 19 | 1.8 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-web 26 | 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-thymeleaf 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-test 37 | test 38 | 39 | 40 | org.junit.vintage 41 | junit-vintage-engine 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-maven-plugin 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /springboot-upfile/src/main/java/com/example/springbootupfile/SpringbootUpfileApplication.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.springbootupfile; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringbootUpfileApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringbootUpfileApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springboot-upfile/src/main/java/com/example/springbootupfile/controller/UploadController.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.springbootupfile.controller; 2 | 3 | import store.zabbix.springbootupfile.service.UploadService; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.PostMapping; 8 | import org.springframework.web.bind.annotation.RequestParam; 9 | import org.springframework.web.multipart.MultipartFile; 10 | import org.springframework.web.servlet.ModelAndView; 11 | 12 | import java.io.IOException; 13 | import java.util.Map; 14 | 15 | @Controller 16 | public class UploadController { 17 | 18 | @Autowired 19 | private UploadService uploadService; 20 | 21 | @PostMapping("upload") 22 | public ModelAndView upload(@RequestParam MultipartFile file) throws IOException { 23 | ModelAndView modelAndView = new ModelAndView(); 24 | Map map = uploadService.uploadFile(file); 25 | modelAndView.setViewName("result"); 26 | modelAndView.addObject("code", map.get("code")); 27 | modelAndView.addObject("msg", map.get("msg")); 28 | return modelAndView; 29 | } 30 | 31 | @GetMapping("index") 32 | public String index() { 33 | 34 | return "index.html"; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /springboot-upfile/src/main/java/com/example/springbootupfile/service/UploadService.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.springbootupfile.service; 2 | 3 | import org.springframework.web.multipart.MultipartFile; 4 | 5 | import java.io.IOException; 6 | import java.util.Map; 7 | 8 | public interface UploadService { 9 | Map uploadFile(MultipartFile file) throws IOException; 10 | } 11 | -------------------------------------------------------------------------------- /springboot-upfile/src/main/java/com/example/springbootupfile/service/impl/UploadServiceImpl.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.springbootupfile.service.impl; 2 | 3 | import store.zabbix.springbootupfile.service.UploadService; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.stereotype.Service; 6 | import org.springframework.web.multipart.MultipartFile; 7 | 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | import java.nio.file.Files; 11 | import java.nio.file.Paths; 12 | import java.nio.file.StandardCopyOption; 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | 16 | @Service 17 | public class UploadServiceImpl implements UploadService { 18 | 19 | @Value("${file.path}") 20 | private String path; 21 | 22 | @Override 23 | public Map uploadFile(MultipartFile file) throws IOException { 24 | Map resultMap = new HashMap<>(4); 25 | 26 | if (file.isEmpty()) { 27 | resultMap.put("code", -1); 28 | resultMap.put("msg", "文件不能为空"); 29 | } 30 | 31 | // 得到上传时的文件名 32 | String fileName = file.getOriginalFilename(); 33 | // 获取文件输入流 34 | InputStream is = file.getInputStream(); 35 | 36 | /* 37 | * 使用 Files.copy 命令将文件从输入流源复制到目标目录 38 | * StandardCopyOption.REPLACE_EXISTING 覆盖已有的目标路径 39 | */ 40 | Files.copy(is, Paths.get(path + fileName), StandardCopyOption.REPLACE_EXISTING); 41 | 42 | resultMap.put("code", 0); 43 | resultMap.put("msg", "success"); 44 | return resultMap; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /springboot-upfile/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | file.path=D:\\baidu\\ 2 | -------------------------------------------------------------------------------- /springboot-upfile/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 上传文件 9 | 10 | 11 | 选择文件 12 | 13 | 上传 14 | 15 | 16 | -------------------------------------------------------------------------------- /springboot-upfile/src/main/resources/templates/result.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 返回页面 6 | 7 | 8 | 返回结果 9 | 10 | 返回代码: 11 | message: 12 | 13 | -------------------------------------------------------------------------------- /springboot-upfile/src/test/java/com/example/springbootupfile/SpringbootUpfileApplicationTests.java: -------------------------------------------------------------------------------- 1 | package store.zabbix.springbootupfile; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class SpringbootUpfileApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/github/cuifuan/main/JacksonToMap.java: -------------------------------------------------------------------------------- 1 | package com.github.cuifuan.main; 2 | 3 | import com.fasterxml.jackson.core.type.TypeReference; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | public class JacksonToMap { 10 | public static void main(String[] args) { 11 | String json = "{\"id\": 1,\"name\": \"张三\",\"age\": 30}"; 12 | 13 | Map map = new HashMap(); 14 | 15 | ObjectMapper mapper = new ObjectMapper(); 16 | try { 17 | // 转换 json 为 Map 18 | map = mapper.readValue(json, new TypeReference>() { 19 | }); 20 | 21 | // 输出 Map 22 | System.out.println(map); 23 | } catch (Exception ex) { 24 | ex.printStackTrace(); 25 | } 26 | 27 | } 28 | 29 | } 30 | --------------------------------------------------------------------------------
返回代码:
message: