├── .gitignore
├── README.md
├── basicskill
├── basicskill-java
│ ├── dependency-reduced-pom.xml
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── cn
│ │ │ └── yourbatman
│ │ │ └── basicskill
│ │ │ └── java
│ │ │ └── rain
│ │ │ ├── CodeRainJPanel.java
│ │ │ └── CodeRainMain.java
│ │ └── resources
│ │ └── duanwujie.txt
└── pom.xml
├── cors
├── cors-java
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── cn
│ │ │ └── yourbatman
│ │ │ └── cors
│ │ │ └── java
│ │ │ ├── filter
│ │ │ └── CORSFilter.java
│ │ │ ├── servlet
│ │ │ ├── CookieServlet.java
│ │ │ ├── CorsCookieServlet.java
│ │ │ ├── CorsServlet.java
│ │ │ ├── JSONPServlet.java
│ │ │ └── MultipleOriginsCorsServlet.java
│ │ │ └── spring
│ │ │ └── CorsConfigurationDemo.java
│ │ └── resources
│ │ ├── logback.xml
│ │ └── static
│ │ ├── cookie.html
│ │ ├── cors.html
│ │ ├── corscookie.html
│ │ ├── jsonp.html
│ │ └── multiple_origins_cors.html
├── cors-spring-framework
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── cn
│ │ │ └── yourbatman
│ │ │ └── cors
│ │ │ ├── configuration
│ │ │ ├── MyWebAppInitializer.java
│ │ │ ├── RootConfiguration.java
│ │ │ └── WebMvcConfiguration.java
│ │ │ └── springframework
│ │ │ ├── Application.java
│ │ │ ├── controller
│ │ │ ├── IndexController.java
│ │ │ └── UrlPathHelperController.java
│ │ │ └── filter
│ │ │ └── CORSFilterV2.java
│ │ └── resources
│ │ ├── logback.xml
│ │ └── static
│ │ └── index.html
├── cors-springboot
│ └── pom.xml
└── pom.xml
├── foundation
├── foundation-java
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── cn
│ │ └── yourbatman
│ │ └── foundation
│ │ └── java
│ │ ├── WebUtils.java
│ │ ├── filter
│ │ └── FakeFilter.java
│ │ └── servlet
│ │ ├── Demo1Servlet.java
│ │ ├── Fake1Servlet.java
│ │ ├── FakeServlet.java
│ │ └── UrlPatternDemoServlet.java
├── foundation-spring-framework
│ └── pom.xml
├── foundation-springboot
│ └── pom.xml
└── pom.xml
├── javaee
├── javaee-el
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── cn
│ │ └── yourbatman
│ │ └── javaee
│ │ └── el
│ │ └── Demo.java
├── javaee-jaxrs
│ └── pom.xml
├── javaee-jsonb
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── cn
│ │ └── yourbatman
│ │ └── javaee
│ │ └── jsonb
│ │ ├── Demo.java
│ │ └── Person.java
├── javaee-servlet
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── cn
│ │ │ └── yourbatman
│ │ │ └── javaee
│ │ │ └── servlet
│ │ │ └── HelloServlet.java
│ │ └── webapp
│ │ ├── WEB-INF
│ │ └── web.xml
│ │ └── hello.jsp
├── javaee-websocket
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── cn
│ │ │ └── yourbatman
│ │ │ └── javaee
│ │ │ └── websocket
│ │ │ ├── App.java
│ │ │ ├── WsClient.java
│ │ │ └── WsServer.java
│ │ └── resources
│ │ └── logback.xml
└── pom.xml
├── pom.xml
└── spring5
├── pom.xml
└── spring5-java
├── pom.xml
└── src
└── main
└── java
└── cn
└── yourbatman
└── spring5
└── java
├── antpathmatcher
└── Demo1.java
└── pathpattern
├── CompareDemo.java
├── Demo1.java
├── Demo2.java
└── WebMvcConfiguration.java
/.gitignore:
--------------------------------------------------------------------------------
1 | # Contact me if any problem occurred. mailto:yourbatman@aliyun.com | https://yourbatman.cn
2 | HELP.md
3 | target/
4 | !.mvn/wrapper/maven-wrapper.jar
5 | !**/src/main/**
6 | !**/src/test/**
7 |
8 | ### eclipse/STS ###
9 | .apt_generated
10 | .classpath
11 | .factorypath
12 | .project
13 | .settings
14 | .springBeans
15 | .sts4-cache
16 |
17 | ### IntelliJ IDEA ###
18 | .idea
19 | *.iws
20 | *.iml
21 | *.ipr
22 |
23 | ### NetBeans ###
24 | /nbproject/private/
25 | /nbbuild/
26 | /dist/
27 | /nbdist/
28 | /.nb-gradle/
29 | build/
30 |
31 | ### VS Code ###
32 | .vscode/
33 |
34 | ### temp ignore ###
35 | *.orig
36 | *.log
37 | *.cache
38 | *.diff
39 | *.patch
40 | *.tmp
41 |
42 | ### for project ###
43 | directoryList.md
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### :man_technologist: [方向盘(YourBatman、方哥)](https://yourbatman.cn) | 做爱做之事❣交配交之人
2 | 我是[**方向盘(YourBatman、方哥)**](https://mp.weixin.qq.com/s/PGIFtpI7aZaxY7es0F6C6Q):一个前25年还不会写Hallo World、早已毕业的[**大龄程序员**](https://yourbatman.cn/about)。网瘾失足、清考、延期毕业、房产中介、保险销售、送外卖...是我不可抹灭的黑标签
3 |
4 | ---
5 |
6 |
7 |
8 |

9 |
10 |
11 |
12 |
18 |
19 |
20 | 本仓库是你需要的专栏【**大本营**】,汇聚了方向盘(YourBatman、方哥)原创的几十个小而美的技术专栏,万丈高楼平地起,打实基础方可走得更快、更远。
21 |
22 | ## 专栏目录
23 | | 序号 | 专栏名称 | 专栏地址 |
24 | | :--: | --------------------------------------------- | --------------------------------------------- |
25 | | 01 | 【方向盘】-程序人生 | 待归档... |
26 | | 02 | 【方向盘】-日期时间 | 待归档... |
27 | | 03 | 【方向盘】-资讯/新特性 | 待归档... |
28 | | 04 | 【方向盘】-Spring static | 待归档... |
29 | | 05 | 【方向盘】-Bean Validation | 待归档... |
30 | | 06 | 【方向盘】-Servlet | 待归档... |
31 | | 07 | 【方向盘】-Spring技术栈 | 待归档... |
32 | | 08 | 【方向盘】-JDK | 待归档... |
33 | | 09 | 【方向盘】-Cors跨域 | 待归档... |
34 | | 10 | 【方向盘】-Spring配置类 | 待归档... |
35 | | 11 | 【方向盘】-Spring类型转换 | 待归档... |
36 | | 12 | 【方向盘】-Jackson | 待归档... |
37 | | 13 | 【方向盘】-IntelliJ IDEA | 待归档... |
38 | | 14 | 【方向盘】-Java EE | [专栏地址](https://github.com/yourbatman/FXP-java-ee) |
39 | | 15 | 待归档... | 待归档... | 待归档... |
40 |
41 | > Tips:关注公众号【Java方向盘】,后台回复"专栏列表",可【提前阅读】上面专栏内容
42 |
43 | ## 阅读说明书
44 | 本着追本溯源,拒绝浅尝辄止的学习目的。自上而下的应用,自底向上的学习,做到学有所成,**既知所用又懂原理方可通透**。
45 |
46 | (几乎)所有专栏会按照三步曲进行展开:
47 | 1. 基础:万丈高楼平地起。深入了解其设计理念、架构思想、组件功能、API设计
48 | 2. 进阶:协同进阶以拔高。高级功能、和其它组件/框架协同使用
49 | 3. 应用:智能整合供应用。如何智能化、简单化供给开发者使用,是一个产品的外观
50 |
51 | 三步曲体现在工程目录上如下结构所示:
52 | ```
53 | |-- project
54 | |-- cors // 专栏名
55 | | |-- cors-java
56 | | |-- cors-spring-framework
57 | | |-- cors-spring-boot
58 | |-- xxx // 专栏名
59 | | |-- xxx-java
60 | | |-- xxx-spring-framework
61 | | |-- xxx-spring-boot
62 | ```
63 | 1. xxx-java工程:最纯粹工程。去除一切非相关依赖,直接接触**底层API**。深入理解其设计思想。
64 | - 一般来讲该工程仅依赖JDK以及该专题设计的【底层基础Jar包】
65 | - 启动/运行方式:main方法(servlet web工程除外,需要war包方式部署到外置Tomcat启动)
66 | 2. xxx-spring-framework工程:通过扩展点和Spring框架整合。只有进阶了解了Spring Framework的协同使用,才会有对原理更深一层的理解
67 | - 一般来讲该工程会依赖【Spring容器】,在上工程基础上引入Spring Framework相关依赖
68 | - 启动/运行方式:main方法(spring web工程除外,需要war包方式部署到外置Tomcat启动)
69 | 3. xxx-spirng-boot工程;一切的最终目的都是使用。而开发者必定面向更加智能化的Spring Boot开发应用
70 | - 一般来讲这是最后一步。Spring Boot是高度封装、智能化的基础框架,一切专题/组件最后都需和它整合方可使用
71 | - 启动/运行方式:main方法
72 |
73 | ---
74 |
75 | ### 联系我
76 | > - 🎓2013.07 清考、毕业答辩3次未通过、延期毕业
77 | > - 🏷2013.08-2014.07 宁夏中介公司卖二手房1年,毕业后第1份工作
78 | > - ️️🏷2014.07-2015.05 荆州/武汉,泰康人寿卖保险3月、饿了么送外卖2月,还有炸鸡排、直销等第2345份工作
79 | > - 🏷2015.08 开始从事Java开发,闯过外包,呆过大厂!多年架构经验,任基础架构/中间件团队负责人
80 | > - 🏷2021.08 [因“双减政策”失业!历经9面,终获美团外卖L8的offer](https://mp.weixin.qq.com/s/tMiDQXPt2Gw3hRikAGibAg)
81 | > -
82 | > - 🙅🏻♀️Java架构师、Spring开源贡献者、CSDN博客之星年度Top 10、领域建模专家、写作大赛1/2届评委
83 | > - 📚将出版书籍《Spring奇淫巧技》,致力于国内zui好、zui具深度、zui实用的专栏,为市场贡献微薄之力
84 | > -
85 | > - 现在写纯粹技术专栏(公号后台回复**专栏列表**),不哗众取宠。如果你也有共鸣,可加我好友(fsx1056342982)一起进步
86 |
87 | - Contact me:[方向盘(YourBatman、方哥)](https://yourbatman.cn)
88 | - 公众号:[Java方向盘](https://cdn.jsdelivr.net/gh/yourbatman/cdn/blog/image/yourbatman/wechat-public-8cm.jpg)
89 | - 我的站点:[https://yourbatman.cn](https://yourbatman.cn)
90 | - 我的网盘:[https://wangpan.yourbatman.cn](https://wangpan.yourbatman.cn)
91 | - 注册送1G超小容量,助你做减法(为什么要做减法?读这里:[做加法容易做减法难,程序员的我深有同感](https://yourbatman.cn/x2y/89616c6e.html))
92 |
93 | 
94 |
95 | ### 实用工具
96 | - 【女娲Knife-Initializr工程】访问地址:[http://152.136.106.14:8761](http://152.136.106.14:8761)
97 | - 【程序员专用网盘】公益上线啦,注册送1G超小容量,帮你实践做**减法**:[https://wangpan.yourbatman.cn](https://mp.weixin.qq.com/s/e_ffqJd7edyCM8celr-Uww)
98 | - 【Java开发软件包(Mac)】:[https://wangpan.yourbatman.cn/s/rEH0](https://wangpan.yourbatman.cn/s/rEH0) 提取码:javakit
99 |
100 | ### 期待与你相遇
101 | 喜欢交朋友,喜欢讨论技术,更喜欢向你学习。
期待在程序的世界里我们能相遇!
102 |
103 | ---
104 | *由于作者水平有限,可能存在描述不准确或错别字内容,👏🏻欢迎随时反馈给我。我是方向盘(YourBatman、方哥),一个纯粹技术工!*
--------------------------------------------------------------------------------
/basicskill/basicskill-java/dependency-reduced-pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | basicskill
5 | cn.yourbatman
6 | 1.0-SNAPSHOT
7 |
8 | 4.0.0
9 | basicskill-java
10 |
11 | codeRainApp
12 |
13 |
14 | maven-shade-plugin
15 | 2.4.1
16 |
17 |
18 | package
19 |
20 | shade
21 |
22 |
23 |
24 |
25 |
26 |
27 | cn.yourbatman.basicskill.java.rain.CodeRainMain
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | org.springframework
37 | spring-test
38 | 5.3.20
39 | test
40 |
41 |
42 |
43 | 8
44 | 8
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/basicskill/basicskill-java/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | basicskill
7 | cn.yourbatman
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | basicskill-java
13 |
14 |
15 | 8
16 | 8
17 |
18 |
19 |
20 |
21 | commons-io
22 | commons-io
23 |
24 |
25 | org.apache.commons
26 | commons-lang3
27 |
28 |
29 |
30 |
31 | codeRainApp
32 |
33 |
34 | org.apache.maven.plugins
35 | maven-shade-plugin
36 | 2.4.1
37 |
38 |
39 |
40 | cn.yourbatman.basicskill.java.rain.CodeRainMain
41 |
42 |
43 |
44 |
45 |
46 | package
47 |
48 | shade
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/basicskill/basicskill-java/src/main/java/cn/yourbatman/basicskill/java/rain/CodeRainJPanel.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.basicskill.java.rain;
2 |
3 | import java.awt.Color;
4 | import java.awt.Font;
5 | import java.awt.Graphics;
6 | import java.awt.Graphics2D;
7 | import java.awt.event.KeyAdapter;
8 | import java.awt.event.KeyEvent;
9 | import java.util.List;
10 | import java.util.concurrent.ThreadLocalRandom;
11 | import javax.swing.JPanel;
12 |
13 | /**
14 | * 代码雨面板
15 | * Panel是Java图形用户界面(GUI)工具包swing中的【面板】容器类
16 | *
17 | * @author YourBatman. Send email to me
18 | * @site https://yourbatman.cn
19 | * @date 2022/6/3 11:12
20 | * @since 0.0.1
21 | */
22 | public class CodeRainJPanel extends JPanel {
23 |
24 |
25 | private static final int FONT_SIZE = 33; // 字体大小
26 | private static final int SPACE = 40; // 字间距
27 | private static final int SLEEP_TIME = 130; // 休眠时间(ms),可以尽量慢点
28 |
29 | private String[][] charsetArray; // 字符集合(可从文件、外部配置读取),二位数组
30 | private int[] pos; // 列的起始位置
31 | private Color[] colors = new Color[10]; //列的渐变颜色
32 |
33 | private List surceLines; // 数据源:按行读取
34 |
35 | public CodeRainJPanel(List surceLines) {
36 | this.surceLines = surceLines;
37 | }
38 |
39 | /**
40 | * 按行随机输出
41 | */
42 | private void randomFromSourceLines(String[] charset) {
43 | int lineCount = this.surceLines.size();
44 |
45 | int length = 0;
46 | int destPos = 0;
47 | while (true) {
48 | int index = ThreadLocalRandom.current().nextInt(lineCount);
49 | String line = surceLines.get(index); // 从所有行中随机取一行
50 | String[] lineArray = line.split(""); // 将这一行打散成一个个的字
51 |
52 | boolean breakFlag;
53 | if (lineArray.length + destPos >= charset.length) {
54 | length = charset.length - destPos;
55 | breakFlag = true;
56 | } else {
57 | length = lineArray.length;
58 | breakFlag = false;
59 | }
60 |
61 | System.arraycopy(lineArray, 0, charset, destPos, length); // 放进charset里
62 | destPos += length;
63 | if (breakFlag) {
64 | break;
65 | }
66 | }
67 | }
68 |
69 | public void init() {
70 | int width = getWidth(); // 屏幕宽度
71 | int height = getHeight(); // 屏幕高度
72 |
73 | charsetArray = new String[width / SPACE][height / SPACE];
74 | for (int i = 0; i < charsetArray.length; i++) {
75 | randomFromSourceLines(charsetArray[i]);
76 | }
77 |
78 | //随机化列起始位置
79 | pos = new int[charsetArray.length];
80 | for (int i = 0; i < pos.length; i++) {
81 | pos[i] = ThreadLocalRandom.current().nextInt(1000);
82 | }
83 |
84 | // 生成渐变色:生成从黑色到绿色的渐变颜色
85 | for (int i = 0; i < colors.length - 1; i++) {
86 | colors[i] = new Color(0, 180 / colors.length * (i + 1), 0);
87 | // colors[i] = new Color(0, 255 / colors.length * (i + 1), 0);
88 | }
89 |
90 | // 背景颜色
91 | setBackground(Color.BLACK);
92 | }
93 |
94 | public void start() {
95 | init();
96 | new Thread(() -> {
97 | while (true) {
98 | try {
99 | repaint(); // 重绘,调用paint()方法
100 | Thread.sleep(SLEEP_TIME); // 停一会,继续重回,达到一闪一闪的效果
101 | } catch (InterruptedException e) {
102 | Thread.currentThread().interrupt();
103 | }
104 | }
105 | }).start();
106 |
107 | // 按键盘的任意箭退出
108 | addKeyListener(new KeyAdapter() {
109 | @Override
110 | public void keyPressed(KeyEvent e) {
111 | System.exit(0);
112 | }
113 | });
114 | // addMouseListener(new MouseAdapter() {
115 | // @Override
116 | // public void mousePressed(MouseEvent e) {
117 | // System.exit(0);
118 | // }
119 | // });
120 | }
121 |
122 |
123 | @Override
124 | public void paint(Graphics g) {
125 | //必须设置,否则setBackground(Color.BLACK); 设置背景色无效
126 | super.paint(g);
127 |
128 | Graphics2D g2 = (Graphics2D) g;// 转换为Graphics2D类型
129 | g2.setFont(new Font("华文行楷", Font.BOLD, FONT_SIZE));
130 |
131 | for (int i = 0; i < charsetArray.length; i++) {
132 | for (int j = 0; j < colors.length; j++) {
133 | int index = (pos[i] + j) % charsetArray[i].length;
134 |
135 | // int R = ThreadLocalRandom.current().nextInt(100);// 随机产生颜色的R值
136 | // int G = ThreadLocalRandom.current().nextInt(180);// 随机产生颜色的G值
137 | // int B = ThreadLocalRandom.current().nextInt(100);// 随机产生颜色的B值
138 | // g2.setColor(new Color(R, G, B));
139 |
140 | g2.setColor(colors[j]); // 纯黑色,黑客帝国的感觉,不够喜庆
141 | g2.drawString(charsetArray[i][index], i * SPACE, (index + 1) * SPACE);
142 |
143 | }
144 | pos[i] = (pos[i] + 1) % charsetArray[i].length;
145 | // if(pos[i]==0){
146 | // random(charset[i]);
147 | // }
148 | }
149 | }
150 |
151 | }
152 |
--------------------------------------------------------------------------------
/basicskill/basicskill-java/src/main/java/cn/yourbatman/basicskill/java/rain/CodeRainMain.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.basicskill.java.rain;
2 |
3 | import static java.lang.String.format;
4 | import static java.nio.charset.StandardCharsets.UTF_8;
5 |
6 | import java.awt.Dimension;
7 | import java.awt.Toolkit;
8 | import java.io.IOException;
9 | import java.util.List;
10 | import javax.swing.JFrame;
11 | import org.apache.commons.io.IOUtils;
12 | import org.springframework.core.io.ClassPathResource;
13 |
14 | /**
15 | * 程序入口
16 | *
17 | * @author YourBatman. Send email to me
18 | * @site https://yourbatman.cn
19 | * @date 2022/6/3 16:50
20 | * @since 0.0.1
21 | */
22 | public class CodeRainMain {
23 |
24 | public static void main(String[] args) throws IOException {
25 | // 读取端午节祝福语文案
26 | List lines = IOUtils.readLines(new ClassPathResource("duanwujie.txt").getInputStream(), UTF_8);
27 |
28 | // ========== 读取到文案后,开始展示 =========
29 | Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
30 | int width = (int) (screensize.getWidth() * 0.85); // 笔记本一般是1440
31 | int height = (int) (screensize.getHeight() * 0.85); // 笔记本一般是900
32 | System.out.println(format("屏幕大小为:width:%s height:%s", width, height));
33 |
34 | JFrame frame = new JFrame("YourBatman祝:端午安康");
35 | CodeRainJPanel panel = new CodeRainJPanel(lines); // 自定义的代码雨面板对象
36 |
37 | frame.add(panel); // 将面板添加到JFrame中
38 | frame.setSize(width, height); // 设置窗口大小
39 | frame.setResizable(false);
40 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
41 | frame.setLocationRelativeTo(null); // 窗体居中显示
42 | frame.setVisible(true); // 尽快调用paint
43 |
44 | panel.start();
45 | panel.requestFocus();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/basicskill/basicskill-java/src/main/resources/duanwujie.txt:
--------------------------------------------------------------------------------
1 | 你开发了祝福的程序,
2 | 你安装了虚拟的系统,
3 | 你设置了幸福的密码,
4 | 你下载了流畅的软件,
5 | 端午节到了,
6 | 愿你有个快乐的心情。
7 | 你从智慧中开发财富,
8 | 你从勤奋中耕耘成就,
9 | 你从耐心中创造艺术,
10 | 你从工作中寻找生活,
11 | 端午节到了,
12 | 愿你编出精彩的人生。
13 | 你用命令开启了精彩,
14 | 你用效率创造了价值,
15 | 你用冷静判断了是非,
16 | 你用可观展示了结果,
17 | 端午节到了,
18 | 愿你码出高效的代码。
--------------------------------------------------------------------------------
/basicskill/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | tech-column-learning
7 | cn.yourbatman
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 | pom
12 |
13 | basicskill-java
14 |
15 | basicskill
16 |
17 |
18 | 8
19 | 8
20 |
21 |
22 |
--------------------------------------------------------------------------------
/cors/cors-java/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | cors
7 | cn.yourbatman
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 | cors-java
12 | war
13 |
14 |
15 |
16 | jakarta.servlet
17 | jakarta.servlet-api
18 | provided
19 |
20 |
21 | org.springframework
22 | spring-webmvc
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/cors/cors-java/src/main/java/cn/yourbatman/cors/java/filter/CORSFilter.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.cors.java.filter;
2 |
3 | import javax.servlet.Filter;
4 | import javax.servlet.FilterChain;
5 | import javax.servlet.ServletException;
6 | import javax.servlet.ServletRequest;
7 | import javax.servlet.ServletResponse;
8 | import javax.servlet.http.HttpServletRequest;
9 | import javax.servlet.http.HttpServletResponse;
10 | import java.io.IOException;
11 |
12 | /**
13 | * 在此处添加备注信息
14 | *
15 | * @author YourBatman. Send email to me
16 | * @site https://yourbatman.cn
17 | * @date 2021/6/14 09:50
18 | * @since 0.0.1
19 | */
20 | public class CORSFilter implements Filter {
21 |
22 |
23 | @Override
24 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
25 | HttpServletResponse resp = (HttpServletResponse) response;
26 | resp.addHeader("Access-Control-Allow-Credentials", "true");
27 | resp.addHeader("Access-Control-Allow-Origin", "*");
28 | resp.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
29 | resp.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN");
30 | if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) {
31 | resp.getWriter().println("ok");
32 | return;
33 | }
34 | chain.doFilter(request, resp);
35 | }
36 | }
--------------------------------------------------------------------------------
/cors/cors-java/src/main/java/cn/yourbatman/cors/java/servlet/CookieServlet.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.cors.java.servlet;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 |
5 | import javax.servlet.ServletException;
6 | import javax.servlet.annotation.WebServlet;
7 | import javax.servlet.http.Cookie;
8 | import javax.servlet.http.HttpServlet;
9 | import javax.servlet.http.HttpServletRequest;
10 | import javax.servlet.http.HttpServletResponse;
11 | import java.io.IOException;
12 | import java.util.ArrayList;
13 | import java.util.Arrays;
14 | import java.util.List;
15 |
16 | import static java.util.stream.Collectors.toList;
17 |
18 | /**
19 | * 在此处添加备注信息
20 | *
21 | * @author YourBatman. Send email to me
22 | * @site https://yourbatman.cn
23 | * @date 2021/6/9 10:36
24 | * @since 0.0.1
25 | */
26 | @Slf4j
27 | @WebServlet(urlPatterns = "/cookie")
28 | public class CookieServlet extends HttpServlet {
29 |
30 | @Override
31 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
32 | String requestURI = req.getRequestURI();
33 | String method = req.getMethod();
34 | String originHeader = req.getHeader("Origin");
35 | log.info("收到请求:{},方法:{}, Origin头:{}", requestURI, method, originHeader);
36 |
37 | // 读取Cookie
38 | List myCookies = new ArrayList<>();
39 | if (req.getCookies() != null) {
40 | myCookies = Arrays.stream(req.getCookies()).filter(c -> c.getName().equals("name") || c.getName().equals("age")).collect(toList());
41 | }
42 |
43 | if (myCookies.isEmpty()) { // 种植Cookie
44 | Cookie cookie = new Cookie("name", "YourBatman");
45 | // cookie.setDomain("baidu.com");
46 | cookie.setMaxAge(3600);
47 | resp.addCookie(cookie);
48 | cookie = new Cookie("age", "18");
49 | cookie.setMaxAge(3600);
50 | resp.addCookie(cookie);
51 | } else {
52 | myCookies.stream().forEach(c -> {
53 | log.info("name:{} value:{} domain:{} path:{} maxAge:{} secure:{}", c.getName(), c.getValue(), c.getDomain(), c.getPath(), c.getMaxAge(), c.getVersion(), c.getSecure());
54 | });
55 | }
56 |
57 | resp.getWriter().write("hello cookie...");
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/cors/cors-java/src/main/java/cn/yourbatman/cors/java/servlet/CorsCookieServlet.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.cors.java.servlet;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 |
5 | import javax.servlet.ServletException;
6 | import javax.servlet.annotation.WebServlet;
7 | import javax.servlet.http.Cookie;
8 | import javax.servlet.http.HttpServlet;
9 | import javax.servlet.http.HttpServletRequest;
10 | import javax.servlet.http.HttpServletResponse;
11 | import java.io.IOException;
12 | import java.util.ArrayList;
13 | import java.util.Arrays;
14 | import java.util.List;
15 |
16 | import static java.util.stream.Collectors.toList;
17 |
18 | /**
19 | * 在此处添加备注信息
20 | *
21 | * @author YourBatman. Send email to me
22 | * @site https://yourbatman.cn
23 | * @date 2021/6/9 10:36
24 | * @since 0.0.1
25 | */
26 | @Slf4j
27 | @WebServlet(urlPatterns = "/corscookie")
28 | public class CorsCookieServlet extends HttpServlet {
29 |
30 | @Override
31 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
32 | String requestURI = req.getRequestURI();
33 | String method = req.getMethod();
34 | String originHeader = req.getHeader("Origin");
35 | log.info("收到请求:{},方法:{}, Origin头:{}", requestURI, method, originHeader);
36 |
37 | // 读取Cookie
38 | List myCookies = new ArrayList<>();
39 | if (req.getCookies() != null) {
40 | myCookies = Arrays.stream(req.getCookies()).filter(c -> c.getName().equals("name") || c.getName().equals("age")).collect(toList());
41 | }
42 |
43 | if (myCookies.isEmpty()) { // 种植Cookie
44 | Cookie cookie = new Cookie("name", "YourBatman");
45 | // cookie.setDomain("baidu.com");
46 | cookie.setMaxAge(3600);
47 | resp.addCookie(cookie);
48 | cookie = new Cookie("age", "18");
49 | cookie.setMaxAge(3600);
50 | resp.addCookie(cookie);
51 | } else {
52 | myCookies.stream().forEach(c -> {
53 | log.info("name:{} value:{} domain:{} path:{} maxAge:{} secure:{}", c.getName(), c.getValue(), c.getDomain(), c.getPath(), c.getMaxAge(), c.getVersion(), c.getSecure());
54 | });
55 | }
56 |
57 | setCrosHeader(resp);
58 | resp.getWriter().write("hello cookie...");
59 | }
60 |
61 | private void setCrosHeader(HttpServletResponse resp) {
62 | resp.setHeader("Access-Control-Allow-Origin", "http://localhost:63342");
63 | resp.setHeader("Access-Control-Allow-Credentials", "true");
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/cors/cors-java/src/main/java/cn/yourbatman/cors/java/servlet/CorsServlet.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.cors.java.servlet;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 |
5 | import javax.servlet.ServletException;
6 | import javax.servlet.annotation.WebServlet;
7 | import javax.servlet.http.HttpServlet;
8 | import javax.servlet.http.HttpServletRequest;
9 | import javax.servlet.http.HttpServletResponse;
10 | import java.io.IOException;
11 |
12 | /**
13 | * 在此处添加备注信息
14 | *
15 | * @author YourBatman. Send email to me
16 | * @site https://yourbatman.cn
17 | * @date 2021/6/9 10:36
18 | * @since 0.0.1
19 | */
20 | @Slf4j
21 | @WebServlet(urlPatterns = "/cors")
22 | public class CorsServlet extends HttpServlet {
23 |
24 | @Override
25 | protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
26 | super.doOptions(req, resp);
27 | // setCrosHeader(resp);
28 | }
29 |
30 | @Override
31 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
32 | String requestURI = req.getRequestURI();
33 | String method = req.getMethod();
34 | String originHeader = req.getHeader("Origin");
35 | log.info("收到请求:{},方法:{}, Origin头:{}", requestURI, method, originHeader);
36 |
37 | resp.getWriter().write("hello cors...");
38 | setCrosHeader(resp);
39 | }
40 |
41 | private void setCrosHeader(HttpServletResponse resp) {
42 | resp.setHeader("Access-Control-Allow-Origin", "http://localhost:63342");
43 | resp.setHeader("Access-Control-Expose-Headers", "token,secret");
44 | resp.setHeader("Access-Control-Allow-Headers", "token,secret"); // 一般来讲,让此头的值是上面那个的【子集】(或相同)
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/cors/cors-java/src/main/java/cn/yourbatman/cors/java/servlet/JSONPServlet.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.cors.java.servlet;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 |
5 | import javax.servlet.ServletException;
6 | import javax.servlet.annotation.WebServlet;
7 | import javax.servlet.http.HttpServlet;
8 | import javax.servlet.http.HttpServletRequest;
9 | import javax.servlet.http.HttpServletResponse;
10 | import java.io.IOException;
11 |
12 | /**
13 | * 在此处添加备注信息
14 | *
15 | * @author YourBatman. Send email to me
16 | * @site https://yourbatman.cn
17 | * @date 2021/6/9 10:36
18 | * @since 0.0.1
19 | */
20 | @Slf4j
21 | @WebServlet(urlPatterns = "/jsonp")
22 | public class JSONPServlet extends HttpServlet {
23 |
24 | @Override
25 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
26 | String callback = req.getParameter("callback");
27 | resp.getWriter().write(callback + "('hello jsonp...')");
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/cors/cors-java/src/main/java/cn/yourbatman/cors/java/servlet/MultipleOriginsCorsServlet.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.cors.java.servlet;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 |
5 | import javax.servlet.ServletException;
6 | import javax.servlet.annotation.WebServlet;
7 | import javax.servlet.http.HttpServlet;
8 | import javax.servlet.http.HttpServletRequest;
9 | import javax.servlet.http.HttpServletResponse;
10 | import java.io.IOException;
11 | import java.util.ArrayList;
12 | import java.util.List;
13 |
14 | /**
15 | * 多Origin响应
16 | *
17 | * @author YourBatman. Send email to me
18 | * @site https://yourbatman.cn
19 | * @date 2021/6/9 10:36
20 | * @since 0.0.1
21 | */
22 | @Slf4j
23 | @WebServlet(urlPatterns = "/multiple_origins_cors")
24 | public class MultipleOriginsCorsServlet extends HttpServlet {
25 |
26 | private List ALLOW_ORIGINS = new ArrayList<>();
27 |
28 | @Override
29 | public void init() throws ServletException {
30 | ALLOW_ORIGINS.add("http://localhost:9090");
31 | ALLOW_ORIGINS.add("http://foo.baidu.com:9090");
32 | ALLOW_ORIGINS.add("http://bar.baidu.com:9090");
33 | ALLOW_ORIGINS.add("http://static.yourbatman.cn:9090");
34 | }
35 |
36 | @Override
37 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
38 | String requestURI = req.getRequestURI();
39 | String method = req.getMethod();
40 | String originHeader = req.getHeader("Origin");
41 | log.info("收到请求:{},方法:{}, Origin头:{}", requestURI, method, originHeader);
42 |
43 | resp.getWriter().write("hello multiple origins cors...");
44 | setCrosHeader(originHeader, resp);
45 | }
46 |
47 | /**
48 | * 写跨域响应头
49 | */
50 | // private void setCrosHeader(HttpServletResponse resp) {
51 | // resp.setHeader("Access-Control-Allow-Origin", "http://localhost:9090");
52 | // }
53 | // private void setCrosHeader(HttpServletResponse resp) {
54 | // resp.setHeader("Access-Control-Allow-Origin", "http://foo.baidu.com:9090,http://bar.baidu.com:9090");
55 | // }
56 | // private void setCrosHeader(HttpServletResponse resp) {
57 | // resp.addHeader("Access-Control-Allow-Origin", "http://foo.baidu.com:9090");
58 | // resp.addHeader("Access-Control-Allow-Origin", "http://bar.baidu.com:9090");
59 | // }
60 | // private void setCrosHeader(HttpServletResponse resp) {
61 | // resp.addHeader("Access-Control-Allow-Origin", "http://*.baidu.com:9090");
62 | // }
63 | private void setCrosHeader(String reqOrigin, HttpServletResponse resp) {
64 | if (reqOrigin == null) {
65 | return;
66 | }
67 | // 匹配算法:equals
68 | if (ALLOW_ORIGINS.contains(reqOrigin)) {
69 | resp.addHeader("Access-Control-Allow-Origin", reqOrigin);
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/cors/cors-java/src/main/java/cn/yourbatman/cors/java/spring/CorsConfigurationDemo.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.cors.java.spring;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.http.HttpMethod;
5 | import org.springframework.web.cors.CorsConfiguration;
6 |
7 | import java.util.Arrays;
8 | import java.util.Collections;
9 |
10 | /**
11 | * 在此处添加备注信息
12 | *
13 | * @author YourBatman. Send email to me
14 | * @site https://yourbatman.cn
15 | * @date 2021/6/26 08:00
16 | * @since 0.0.1
17 | * @see CorsConfiguration
18 | */
19 | public class CorsConfigurationDemo {
20 |
21 | @Test
22 | public void test() {
23 | CorsConfiguration corsConfiguration = new CorsConfiguration();
24 |
25 | corsConfiguration.addAllowedOrigin("*");
26 | corsConfiguration.setAllowCredentials(true);
27 |
28 | // 验证:请求Request的此Origin是否合法
29 | String checkedOrigin = corsConfiguration.checkOrigin("https://yourbatman.cn");
30 | System.out.println("Access-Control-Allow-Origin的值为:" + checkedOrigin);
31 | }
32 |
33 |
34 | /**
35 | * allowedOriginPatterns使用示例
36 | */
37 | @Test
38 | public void test1() {
39 | CorsConfiguration corsConfiguration = new CorsConfiguration();
40 |
41 | // 正常的模式匹配(字面量匹配就不演示了)
42 | corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("https://*.yourbatman.cn:[8080,8081]"));
43 | System.out.println("Access-Control-Allow-Origin的值为:" + corsConfiguration.checkOrigin("https://blog.yourbatman.cn:8081"));
44 |
45 | // 使用*进行通配,同时allowCredentials设置为true
46 | corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("*"));
47 | corsConfiguration.setAllowCredentials(true);
48 | System.out.println("Access-Control-Allow-Origin的值为:" + corsConfiguration.checkOrigin("https://blog.yourbatman.cn:8081"));
49 | }
50 |
51 | @Test
52 | public void test2() {
53 | CorsConfiguration corsConfiguration = new CorsConfiguration();
54 |
55 | corsConfiguration.setAllowedOrigins(Collections.singletonList("*"));
56 | System.out.println("Access-Control-Allow-Origin的值为:" + corsConfiguration.checkOrigin("https://blog.yourbatman.cn:8081"));
57 | }
58 |
59 | @Test
60 | public void test3() {
61 | CorsConfiguration corsConfiguration = new CorsConfiguration();
62 |
63 | // 默认case:放行GET和HEAD
64 | System.out.println("allowedMethods的值为:" + corsConfiguration.getAllowedMethods());
65 | System.out.println(corsConfiguration.checkHttpMethod(HttpMethod.GET));
66 | System.out.println(corsConfiguration.checkHttpMethod(HttpMethod.POST));
67 | }
68 |
69 | @Test
70 | public void test4() {
71 | CorsConfiguration corsConfiguration = new CorsConfiguration();
72 |
73 | // 手动明确指定只支持get(即使调用的是add方法),那就只支持GET喽
74 | corsConfiguration.setAllowedMethods(Collections.singletonList("GET"));
75 | System.out.println("allowedMethods的值为:" + corsConfiguration.getAllowedMethods());
76 | System.out.println(corsConfiguration.checkHttpMethod(HttpMethod.GET));
77 | System.out.println(corsConfiguration.checkHttpMethod(HttpMethod.HEAD));
78 |
79 |
80 | corsConfiguration.addAllowedMethod("HEAD");
81 | System.out.println("allowedMethods的值为:" + corsConfiguration.getAllowedMethods());
82 | System.out.println(corsConfiguration.checkHttpMethod(HttpMethod.GET));
83 | System.out.println(corsConfiguration.checkHttpMethod(HttpMethod.HEAD));
84 | System.out.println(corsConfiguration.checkHttpMethod(HttpMethod.POST));
85 |
86 | // 当添加一个*号时
87 | corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
88 | System.out.println("allowedMethods的值为:" + corsConfiguration.getAllowedMethods());
89 | System.out.println(corsConfiguration.checkHttpMethod(HttpMethod.GET));
90 | System.out.println(corsConfiguration.checkHttpMethod(HttpMethod.HEAD));
91 | System.out.println(corsConfiguration.checkHttpMethod(HttpMethod.POST));
92 | System.out.println(corsConfiguration.checkHttpMethod(HttpMethod.PUT));
93 | System.out.println(corsConfiguration.checkHttpMethod(HttpMethod.DELETE));
94 | }
95 |
96 | @Test
97 | public void test5() {
98 | CorsConfiguration corsConfiguration = new CorsConfiguration().applyPermitDefaultValues();
99 |
100 | corsConfiguration.setAllowedHeaders(Arrays.asList("Authorization", "YourBatman"));
101 | System.out.println(corsConfiguration.checkHeaders(Arrays.asList("Authorization", "YourBatman")));
102 | System.out.println(corsConfiguration.checkHeaders(Arrays.asList("yourbatman", "Name")));
103 |
104 | // 添加一个通配符*
105 | corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
106 | System.out.println(corsConfiguration.checkHeaders(Arrays.asList("Name", "Age")));
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/cors/cors-java/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/cors/cors-java/src/main/resources/static/cookie.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Cookie交互机制(同域)
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
20 |
21 |
--------------------------------------------------------------------------------
/cors/cors-java/src/main/resources/static/cors.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CORS跨域请求
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
27 |
28 |
--------------------------------------------------------------------------------
/cors/cors-java/src/main/resources/static/corscookie.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Cookie交互机制(跨域)
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/cors/cors-java/src/main/resources/static/jsonp.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | JSONP跨域请求
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
28 |
29 |
--------------------------------------------------------------------------------
/cors/cors-java/src/main/resources/static/multiple_origins_cors.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 多Origin响应CORS跨域请求
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
21 |
22 |
--------------------------------------------------------------------------------
/cors/cors-spring-framework/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | cors
7 | cn.yourbatman
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 | cors-spring-framework
12 | war
13 |
14 |
15 |
16 | org.springframework
17 | spring-webmvc
18 |
19 |
20 | jakarta.servlet
21 | jakarta.servlet-api
22 | provided
23 |
24 |
25 |
--------------------------------------------------------------------------------
/cors/cors-spring-framework/src/main/java/cn/yourbatman/cors/configuration/MyWebAppInitializer.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.cors.configuration;
2 |
3 | import cn.yourbatman.cors.springframework.filter.CORSFilterV2;
4 | import org.springframework.web.cors.CorsConfiguration;
5 | import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
6 |
7 | import javax.servlet.DispatcherType;
8 | import javax.servlet.FilterRegistration;
9 | import javax.servlet.ServletContext;
10 | import javax.servlet.ServletException;
11 | import java.util.EnumSet;
12 |
13 | /**
14 | * 自己实现 基于注解驱动的ServletInitializer来初始化DispatcherServlet
15 | *
16 | * @author YourBatman. Send email to me
17 | * @site https://yourbatman.cn
18 | * @date 2021/5/19 15:52
19 | * @since 0.0.1
20 | */
21 | public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
22 |
23 | /**
24 | * 根容器的配置类;(Spring的配置文件) 父容器;
25 | */
26 | @Override
27 | protected Class>[] getRootConfigClasses() {
28 | return new Class>[]{RootConfiguration.class};
29 | }
30 |
31 | /**
32 | * web容器的配置类(SpringMVC配置文件) 子容器;
33 | */
34 | @Override
35 | protected Class>[] getServletConfigClasses() {
36 | return new Class>[]{WebMvcConfiguration.class};
37 | }
38 |
39 | //获取DispatcherServlet的映射信息
40 | // 注意: /:拦截所有请求(包括静态资源(xx.js,xx.png)),但是不包括*.jsp;
41 | // /*:拦截所有请求;连*.jsp页面都拦截;jsp页面是tomcat的jsp引擎解析的;
42 | @Override
43 | protected String[] getServletMappings() {
44 | // return new String[]{"/"};
45 | return new String[]{"/api/*"};
46 | }
47 |
48 | @Override
49 | public void onStartup(ServletContext servletContext) throws ServletException {
50 | super.onStartup(servletContext);
51 |
52 | // 注册过滤器
53 | CorsConfiguration corsConfiguration = new CorsConfiguration().applyPermitDefaultValues();
54 | FilterRegistration.Dynamic dynamic = servletContext.addFilter("corsFilter", new CORSFilterV2(corsConfiguration));
55 | dynamic.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/cors/cors-spring-framework/src/main/java/cn/yourbatman/cors/configuration/RootConfiguration.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.cors.configuration;
2 |
3 | import cn.yourbatman.cors.springframework.Application;
4 | import org.springframework.context.annotation.ComponentScan;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.context.annotation.FilterType;
7 | import org.springframework.stereotype.Controller;
8 | import org.springframework.web.bind.annotation.ControllerAdvice;
9 |
10 | /**
11 | * 在此处添加备注信息
12 | *
13 | * @author YourBatman. Send email to me
14 | * @site https://yourbatman.cn
15 | * @date 2021/5/19 15:41
16 | * @since 0.0.1
17 | */
18 | // 备注:此处@ControllerAdvice、RestControllerAdvice 这个注解不要忘了,属于Controller层处理全局异常的,应该交给web去扫描
19 | @ComponentScan(basePackageClasses = {Application.class}, excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class, ControllerAdvice.class})
20 | })
21 | @Configuration(proxyBeanMethods = false)
22 | public class RootConfiguration {
23 |
24 | }
--------------------------------------------------------------------------------
/cors/cors-spring-framework/src/main/java/cn/yourbatman/cors/configuration/WebMvcConfiguration.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.cors.configuration;
2 |
3 | import cn.yourbatman.cors.springframework.Application;
4 | import org.springframework.context.annotation.ComponentScan;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.context.annotation.FilterType;
7 | import org.springframework.stereotype.Controller;
8 | import org.springframework.web.bind.annotation.ControllerAdvice;
9 | import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
10 | import org.springframework.web.servlet.config.annotation.EnableWebMvc;
11 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
12 | import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
13 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
14 |
15 | /**
16 | * 在此处添加备注信息
17 | *
18 | * @author YourBatman. Send email to me
19 | * @site https://yourbatman.cn
20 | * @date 2021/5/19 15:43
21 | * @since 0.0.1
22 | */
23 | @EnableWebMvc
24 | @ComponentScan(basePackageClasses = {Application.class}, useDefaultFilters = false, includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class, ControllerAdvice.class})})
25 | @Configuration(proxyBeanMethods = false)
26 | public class WebMvcConfiguration implements WebMvcConfigurer {
27 |
28 | //视图解析器
29 | @Override
30 | public void configureViewResolvers(ViewResolverRegistry registry) {
31 | //默认所有的页面都从 /WEB-INF/ xxx .jsp
32 | //registry.jsp();
33 | registry.jsp("/WEB-INF/views/", ".jsp");
34 | }
35 |
36 | // 开启静态资源的请求转发到默认servlet上,不配置页面报错404,(默认servlet不是DispatcherServlet!理解的)
37 | @Override
38 | public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
39 | configurer.enable();
40 | }
41 |
42 | //自定义添加拦截器=========这个比较常用
43 | @Override
44 | public void addInterceptors(InterceptorRegistry registry) {
45 | //registry.addInterceptor(new MyFirstInterceptor()).addPathPatterns("/**");
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/cors/cors-spring-framework/src/main/java/cn/yourbatman/cors/springframework/Application.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.cors.springframework;
2 |
3 | public class Application {
4 | }
5 |
--------------------------------------------------------------------------------
/cors/cors-spring-framework/src/main/java/cn/yourbatman/cors/springframework/controller/IndexController.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.cors.springframework.controller;
2 |
3 | import org.springframework.web.bind.annotation.GetMapping;
4 | import org.springframework.web.bind.annotation.RestController;
5 |
6 | /**
7 | * 在此处添加备注信息
8 | *
9 | * @author YourBatman. Send email to me
10 | * @site https://yourbatman.cn
11 | * @date 2021/6/18 15:21
12 | * @since 0.0.1
13 | */
14 | @RestController
15 | class IndexController {
16 |
17 | @GetMapping("/index")
18 | Object index() {
19 | return "Hello Spring";
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/cors/cors-spring-framework/src/main/java/cn/yourbatman/cors/springframework/controller/UrlPathHelperController.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.cors.springframework.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.web.bind.annotation.GetMapping;
5 | import org.springframework.web.bind.annotation.RequestParam;
6 | import org.springframework.web.bind.annotation.RestController;
7 | import org.springframework.web.util.UrlPathHelper;
8 |
9 | import javax.servlet.http.HttpServletRequest;
10 |
11 | /**
12 | * 在此处添加备注信息
13 | *
14 | * @author YourBatman. Send email to me
15 | * @site https://yourbatman.cn
16 | * @date 2021/6/27 10:20
17 | * @since 0.0.1
18 | */
19 | @RestController
20 | public class UrlPathHelperController {
21 |
22 | @Autowired
23 | private HttpServletRequest request;
24 | private UrlPathHelper urlPathHelper = new UrlPathHelper();
25 |
26 | @GetMapping("/demo1")
27 | Object demo1(@RequestParam String name) {
28 | requestPrint();
29 | urlPathHelperPrint();
30 |
31 | return "hello " + name;
32 | }
33 |
34 |
35 |
36 | private void requestPrint(){
37 | String contextPath = request.getContextPath();
38 | String servletPath = request.getServletPath();
39 | StringBuffer requestURL = request.getRequestURL();
40 | String requestURI = request.getRequestURI();
41 |
42 | System.out.println("request contextPath:" + contextPath);
43 | System.out.println("request servletPath:" + servletPath);
44 | System.out.println("request requestURL:" + requestURL);
45 | System.out.println("request requestURI:" + requestURI);
46 | }
47 |
48 | private void urlPathHelperPrint(){
49 | String contextPath = urlPathHelper.getContextPath(request);
50 | String servletPath = urlPathHelper.getServletPath(request);
51 | String requestUri = urlPathHelper.getRequestUri(request);
52 |
53 |
54 | System.out.println("urlPathHelper contextPath:" + contextPath);
55 | System.out.println("urlPathHelper servletPath:" + servletPath);
56 | System.out.println("urlPathHelper requestURL:" + requestUri);
57 | }
58 |
59 |
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/cors/cors-spring-framework/src/main/java/cn/yourbatman/cors/springframework/filter/CORSFilterV2.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.cors.springframework.filter;
2 |
3 | import org.springframework.http.HttpHeaders;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.cors.CorsConfiguration;
6 | import org.springframework.web.cors.CorsUtils;
7 |
8 | import javax.servlet.Filter;
9 | import javax.servlet.FilterChain;
10 | import javax.servlet.ServletException;
11 | import javax.servlet.ServletRequest;
12 | import javax.servlet.ServletResponse;
13 | import javax.servlet.http.HttpServletRequest;
14 | import javax.servlet.http.HttpServletResponse;
15 | import java.io.IOException;
16 |
17 | /**
18 | * 基于{@link CorsConfiguration} 实现
19 | *
20 | * @author YourBatman. Send email to me
21 | * @site https://yourbatman.cn
22 | * @date 2021/6/14 09:50
23 | * @since 0.0.1
24 | * @see CorsConfiguration
25 | */
26 | public class CORSFilterV2 implements Filter {
27 |
28 | private CorsConfiguration corsConfiguration;
29 |
30 | public CORSFilterV2(CorsConfiguration corsConfiguration) {
31 | this.corsConfiguration = corsConfiguration;
32 | }
33 |
34 | @Override
35 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
36 | HttpServletRequest req = (HttpServletRequest) request;
37 | HttpServletResponse resp = (HttpServletResponse) response;
38 |
39 | boolean isValid = process(corsConfiguration, req, resp);
40 | // Cors跨域不通过,拦截掉
41 | if (!isValid) {
42 | return;
43 | }
44 | // 如果是预检请求,即使通过了也不让继续往下走了(注:此方法必须放在process()后面,因为响应头得设置好)
45 | if (CorsUtils.isPreFlightRequest(req)) {
46 | return;
47 | }
48 |
49 | chain.doFilter(request, response);
50 | }
51 |
52 | /**
53 | * 判断该请求是否匹配Cors跨域规则,并且设置好响应头
54 | */
55 | private boolean process(CorsConfiguration corsConfiguration, HttpServletRequest request, HttpServletResponse response) throws IOException {
56 | // 若此请求不是跨域请求,那请回
57 | if (!CorsUtils.isCorsRequest(request)) {
58 | return true;
59 | }
60 | boolean isRreFlightRequest = CorsUtils.isPreFlightRequest(request);
61 |
62 | // 若此请求你自己已经设置过Access-Control-Allow-Origin,那我也不再处理了
63 | if (response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN) != null) {
64 | return true;
65 | }
66 |
67 | // 若没配置Cors策略,那也什么都不能做
68 | if (corsConfiguration == null) {
69 | if (isRreFlightRequest) { //预检请求进来了,但是你又没有配置跨域方案,那肯定拒绝啦
70 | rejectRequest(response);
71 | return false;
72 | }
73 | return true; // 正常请求进来,没配置跨域方案,那就当此过滤器是空气就好
74 | }
75 |
76 |
77 | // =======配置了跨域方案的校验======
78 | String requestOrigin = request.getHeader(HttpHeaders.ORIGIN);
79 | String checkOrigin = corsConfiguration.checkOrigin(requestOrigin);
80 | if (checkOrigin == null) {
81 | rejectRequest(response);
82 | return false;
83 | }
84 |
85 | // ...检查Methods、检查Headers等等
86 |
87 | // ============开始设置响应头=============
88 | response.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, checkOrigin);
89 | // if (isRreFlightRequest) {
90 | // response.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, allowMethods);
91 | // }
92 | // if (corsConfiguration.getAllowCredentials() == true) {
93 | // response.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
94 | // }
95 | // if (isRreFlightRequest && corsConfiguration.getMaxAge() != null) {
96 | // response.addHeader(HttpHeaders.ACCESS_CONTROL_MAX_AGE, corsConfiguration.getMaxAge());
97 | // }
98 | return true;
99 | }
100 |
101 |
102 | protected void rejectRequest(HttpServletResponse response) throws IOException {
103 | response.setStatus(HttpStatus.FORBIDDEN.value());
104 | response.getWriter().write("Invalid CORS request");
105 | response.flushBuffer();
106 | }
107 |
108 |
109 | }
--------------------------------------------------------------------------------
/cors/cors-spring-framework/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/cors/cors-spring-framework/src/main/resources/static/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CORS跨域请求
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/cors/cors-springboot/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | cors
7 | cn.yourbatman
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | cors-springboot
13 |
14 |
15 | 8
16 | 8
17 |
18 |
19 |
--------------------------------------------------------------------------------
/cors/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | tech-column-learning
7 | cn.yourbatman
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 | pom
12 | cn.yourbatman
13 | cors
14 |
15 |
16 | cors-java
17 | cors-spring-framework
18 | cors-springboot
19 |
20 |
21 |
--------------------------------------------------------------------------------
/foundation/foundation-java/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | foundation
7 | cn.yourbatman
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 | war
12 | foundation-java
13 |
14 |
15 | 8
16 | 8
17 |
18 |
19 |
20 |
21 | jakarta.servlet
22 | jakarta.servlet-api
23 | provided
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/foundation/foundation-java/src/main/java/cn/yourbatman/foundation/java/WebUtils.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.foundation.java;
2 |
3 | import javax.servlet.http.HttpServletRequest;
4 |
5 | /**
6 | * Web工具方法
7 | *
8 | * @author YourBatman. Send email to me
9 | * @site https://yourbatman.cn
10 | * @date 2021/6/27 11:03
11 | * @since 0.0.1
12 | */
13 | public abstract class WebUtils {
14 |
15 | /**
16 | * 打印{@link HttpServletRequest}的路径信息
17 | */
18 | public static void printRequestPath(HttpServletRequest request) {
19 | String contextPath = request.getContextPath();
20 | String servletPath = request.getServletPath();
21 | String pathInfo = request.getPathInfo();
22 | String requestURI = request.getRequestURI();
23 |
24 | System.out.println("request contextPath:" + contextPath);
25 | System.out.println("request servletPath:" + servletPath);
26 | System.out.println("request pathInfo:" + pathInfo);
27 | System.out.println("request requestURI:" + requestURI);
28 |
29 | System.out.println("request requestURL(用得很少):" + request.getRequestURL());
30 | System.out.println("---------------------------");
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/foundation/foundation-java/src/main/java/cn/yourbatman/foundation/java/filter/FakeFilter.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.foundation.java.filter;
2 |
3 | import javax.servlet.FilterChain;
4 | import javax.servlet.ServletException;
5 | import javax.servlet.annotation.WebFilter;
6 | import javax.servlet.http.HttpFilter;
7 | import javax.servlet.http.HttpServletRequest;
8 | import javax.servlet.http.HttpServletResponse;
9 | import java.io.IOException;
10 |
11 | /**
12 | * 在此处添加备注信息
13 | *
14 | * @author YourBatman. Send email to me
15 | * @site https://yourbatman.cn
16 | * @date 2021/6/27 17:38
17 | * @since 0.0.1
18 | */
19 | // @WebFilter(urlPatterns = {"/"}) // Filter使用/无效果,拦截所有只能使用/*
20 | // @WebFilter(urlPatterns = {"/*"})
21 | public class FakeFilter extends HttpFilter {
22 |
23 | @Override
24 | protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
25 | System.out.println("FakeFilter收到请求:" + req.getRequestURI());
26 | super.doFilter(req, res, chain);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/foundation/foundation-java/src/main/java/cn/yourbatman/foundation/java/servlet/Demo1Servlet.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.foundation.java.servlet;
2 |
3 | import javax.servlet.ServletException;
4 | import javax.servlet.http.HttpServlet;
5 | import javax.servlet.http.HttpServletRequest;
6 | import javax.servlet.http.HttpServletResponse;
7 | import java.io.IOException;
8 |
9 | import static cn.yourbatman.foundation.java.WebUtils.printRequestPath;
10 |
11 | /**
12 | * 在此处添加备注信息
13 | *
14 | * @author YourBatman. Send email to me
15 | * @site https://yourbatman.cn
16 | * @date 2021/6/27 12:25
17 | * @since 0.0.1
18 | */
19 | // @WebServlet(urlPatterns = {"/api/demo1", "/api/demo2"}) // 精确匹配
20 | // @WebServlet(urlPatterns = {"/api/*", "/*"}) // 路径匹配
21 | // @WebServlet(urlPatterns = {"*.jsp", "*.*"}) // 后缀匹配
22 | // @WebServlet(urlPatterns = "/") // 缺省匹配
23 | public class Demo1Servlet extends HttpServlet {
24 |
25 | @Override
26 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
27 | printRequestPath(req);
28 | resp.getWriter().write("hello " + req.getParameter("name"));
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/foundation/foundation-java/src/main/java/cn/yourbatman/foundation/java/servlet/Fake1Servlet.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.foundation.java.servlet;
2 |
3 | import javax.servlet.ServletException;
4 | import javax.servlet.annotation.WebServlet;
5 | import javax.servlet.http.HttpServlet;
6 | import javax.servlet.http.HttpServletRequest;
7 | import javax.servlet.http.HttpServletResponse;
8 | import java.io.IOException;
9 |
10 | /**
11 | * 举例证明错误言论
12 | *
13 | * @author YourBatman. Send email to me
14 | * @site https://yourbatman.cn
15 | * @date 2021/6/27 17:30
16 | * @since 0.0.1
17 | */
18 | // @WebServlet(urlPatterns = {"/*"})
19 | public class Fake1Servlet extends HttpServlet {
20 |
21 | @Override
22 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
23 | System.out.println("Fake1Servlet收到请求:" + req.getRequestURI());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/foundation/foundation-java/src/main/java/cn/yourbatman/foundation/java/servlet/FakeServlet.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.foundation.java.servlet;
2 |
3 | import javax.servlet.ServletException;
4 | import javax.servlet.http.HttpServlet;
5 | import javax.servlet.http.HttpServletRequest;
6 | import javax.servlet.http.HttpServletResponse;
7 | import java.io.IOException;
8 |
9 | /**
10 | * 举例证明错误言论
11 | *
12 | * @author YourBatman. Send email to me
13 | * @site https://yourbatman.cn
14 | * @date 2021/6/27 17:30
15 | * @since 0.0.1
16 | */
17 | // @WebServlet(urlPatterns = {"/*"})
18 | // @WebServlet(urlPatterns = {"/"})
19 | public class FakeServlet extends HttpServlet {
20 |
21 | @Override
22 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
23 | System.out.println("FakeServlet收到请求:" + req.getRequestURI());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/foundation/foundation-java/src/main/java/cn/yourbatman/foundation/java/servlet/UrlPatternDemoServlet.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.foundation.java.servlet;
2 |
3 | import javax.servlet.ServletException;
4 | import javax.servlet.annotation.WebServlet;
5 | import javax.servlet.http.HttpServlet;
6 | import javax.servlet.http.HttpServletRequest;
7 | import javax.servlet.http.HttpServletResponse;
8 | import java.io.IOException;
9 |
10 | /**
11 | * 在此处添加备注信息
12 | *
13 | * @author YourBatman. Send email to me
14 | * @site https://yourbatman.cn
15 | * @date 2021/6/27 12:25
16 | * @since 0.0.1
17 | */
18 | // @WebServlet(urlPatterns = {"/api/demo1", "/api/demo2"}) // 精确匹配
19 | // @WebServlet(urlPatterns = {"*.jsp", "*.*"}) // 后缀匹配
20 | // @WebServlet(urlPatterns = {"/api/*", "/*"}) // 路径匹配
21 | @WebServlet(urlPatterns = "/") // 缺省匹配
22 | // @WebServlet(urlPatterns = "/api/*.jsp") // 启动报错
23 | public class UrlPatternDemoServlet extends HttpServlet {
24 | @Override
25 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
26 | System.out.printf("收到请求:%s ServletPath:%s PathInfo:%s\n", req.getRequestURI(), req.getServletPath(), req.getPathInfo());
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/foundation/foundation-spring-framework/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | foundation
7 | cn.yourbatman
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | foundation-spring-framework
13 |
14 |
15 | 8
16 | 8
17 |
18 |
19 |
--------------------------------------------------------------------------------
/foundation/foundation-springboot/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | foundation
7 | cn.yourbatman
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | foundation-springboot
13 |
14 |
15 | 8
16 | 8
17 |
18 |
19 |
--------------------------------------------------------------------------------
/foundation/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | tech-column-learning
7 | cn.yourbatman
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 | foundation
12 | pom
13 |
14 | foundation-java
15 | foundation-spring-framework
16 | foundation-springboot
17 |
18 |
19 |
20 | 8
21 | 8
22 |
23 |
24 |
--------------------------------------------------------------------------------
/javaee/javaee-el/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | javaee
7 | cn.yourbatman
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | javaee-el
13 |
14 |
15 | 8
16 | 8
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 | org.apache.tomcat.embed
42 | tomcat-embed-el
43 |
44 |
45 |
46 | javax.servlet.jsp.jstl
47 | jstl-api
48 | 1.2
49 |
50 |
51 |
--------------------------------------------------------------------------------
/javaee/javaee-el/src/main/java/cn/yourbatman/javaee/el/Demo.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.javaee.el;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import javax.el.ELManager;
6 | import javax.el.ExpressionFactory;
7 | import javax.el.MethodExpression;
8 | import javax.el.StandardELContext;
9 | import javax.el.ValueExpression;
10 |
11 | /**
12 | * 在此处添加备注信息
13 | *
14 | * @author YourBatman. Send email to me
15 | * @site https://yourbatman.cn
16 | * @date 2021/7/4 10:52
17 | * @since 0.0.1
18 | */
19 | public class Demo {
20 |
21 | @Test
22 | public void test1() {
23 | ExpressionFactory factory = ELManager.getExpressionFactory();
24 | StandardELContext elContext = new StandardELContext(factory);
25 |
26 | // 将instance转为对应类型
27 | ValueExpression valueExpression = factory.createValueExpression("18", Integer.class);
28 | System.out.println(valueExpression.getValue(elContext));
29 |
30 | // 计算表达式的值
31 | valueExpression = factory.createValueExpression(elContext, "${1+1}", Integer.class);
32 | System.out.println(valueExpression.getValue(elContext));
33 |
34 | // 方法调用
35 | // MethodExpression methodExpression = factory.createMethodExpression(elContext, "${Math.addExact()}", Integer.class, new Class[]{Integer.class, Integer.class});
36 | // System.out.println(methodExpression.invoke(elContext, new Object[]{1, 2}));
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/javaee/javaee-jaxrs/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | javaee
7 | cn.yourbatman
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 | war
12 |
13 | javaee-jaxrs
14 |
15 |
16 | 8
17 | 8
18 |
19 |
20 |
--------------------------------------------------------------------------------
/javaee/javaee-jsonb/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | javaee
7 | cn.yourbatman
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 | javaee-jsonb
12 |
13 |
14 | 8
15 | 8
16 |
17 |
18 |
19 |
20 | javax.json.bind
21 | javax.json.bind-api
22 | 1.0
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/javaee/javaee-jsonb/src/main/java/cn/yourbatman/javaee/jsonb/Demo.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.javaee.jsonb;
2 |
3 | import javax.json.bind.Jsonb;
4 | import javax.json.bind.JsonbBuilder;
5 |
6 | /**
7 | * 在此处添加备注信息
8 | *
9 | * @author YourBatman. Send email to me
10 | * @site https://yourbatman.cn
11 | * @date 2021/7/4 18:51
12 | * @since 0.0.1
13 | */
14 | public class Demo {
15 |
16 | public static void main(String[] args) {
17 | Person p = new Person();
18 | p.setName("YourBatman");
19 | p.setAge(18);
20 |
21 | Jsonb jsonb = JsonbBuilder.create();
22 | String json = jsonb.toJson(p);
23 | System.out.println("序列化结果:" + json);
24 |
25 | // 反序列化
26 | System.out.println(jsonb.fromJson(json, Person.class));
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/javaee/javaee-jsonb/src/main/java/cn/yourbatman/javaee/jsonb/Person.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.javaee.jsonb;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | * 在此处添加备注信息
7 | *
8 | * @author YourBatman. Send email to me
9 | * @site https://yourbatman.cn
10 | * @date 2021/7/4 19:05
11 | * @since 0.0.1
12 | */
13 | @Data
14 | public class Person {
15 |
16 | private String name;
17 | private Integer age;
18 |
19 | }
--------------------------------------------------------------------------------
/javaee/javaee-servlet/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | javaee
7 | cn.yourbatman
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 | war
12 | javaee-servlet
13 |
14 |
15 | 8
16 | 8
17 |
18 |
19 |
20 |
21 | jakarta.servlet
22 | jakarta.servlet-api
23 | provided
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/javaee/javaee-servlet/src/main/java/cn/yourbatman/javaee/servlet/HelloServlet.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.javaee.servlet;
2 |
3 | import javax.servlet.ServletException;
4 | import javax.servlet.annotation.WebServlet;
5 | import javax.servlet.http.HttpServlet;
6 | import javax.servlet.http.HttpServletRequest;
7 | import javax.servlet.http.HttpServletResponse;
8 | import java.io.IOException;
9 |
10 | /**
11 | * 在此处添加备注信息
12 | *
13 | * @author YourBatman. Send email to me
14 | * @site https://yourbatman.cn
15 | * @date 2021/7/3 15:24
16 | * @since 0.0.1
17 | */
18 | @WebServlet(urlPatterns = {"/hello"})
19 | public class HelloServlet extends HttpServlet {
20 |
21 | @Override
22 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
23 | resp.getWriter().write("hello servlet...");
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/javaee/javaee-servlet/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
--------------------------------------------------------------------------------
/javaee/javaee-servlet/src/main/webapp/hello.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="java.util.Date" pageEncoding="utf-8" %>
2 |
3 | JSP示例页面
4 |
5 | <%--可用书写Java代码--%>
6 | 今天的日期是:<%= new Date() %>
7 |
8 |
9 |
--------------------------------------------------------------------------------
/javaee/javaee-websocket/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | javaee
7 | cn.yourbatman
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 | war
12 | javaee-websocket
13 |
14 |
15 | 8
16 | 8
17 |
18 |
19 |
20 |
21 | javax.websocket
22 | javax.websocket-api
23 | provided
24 |
25 |
26 | org.eclipse.jetty.websocket
27 | javax-websocket-client-impl
28 | 9.4.42.v20210604
29 |
30 |
31 |
--------------------------------------------------------------------------------
/javaee/javaee-websocket/src/main/java/cn/yourbatman/javaee/websocket/App.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.javaee.websocket;
2 |
3 | import javax.websocket.ContainerProvider;
4 | import javax.websocket.DeploymentException;
5 | import javax.websocket.Session;
6 | import javax.websocket.WebSocketContainer;
7 | import java.io.IOException;
8 | import java.net.URI;
9 | import java.util.concurrent.TimeUnit;
10 |
11 | /**
12 | * 用Main方法启动WebSocket的客户端,去连接服务端
13 | *
14 | * @author YourBatman. Send email to me
15 | * @site https://yourbatman.cn
16 | * @date 2021/7/4 16:35
17 | * @since 0.0.1
18 | */
19 | public class App {
20 |
21 | private static URI uri = URI.create("ws://localhost:8080/websocket/chat");
22 | private static Session session;
23 |
24 | public static void main(String[] args) throws DeploymentException, IOException, InterruptedException {
25 | WebSocketContainer container = ContainerProvider.getWebSocketContainer();
26 |
27 | // 顺序执行5次会话,端口后再建立新会话
28 | for (int i = 0; i < 3; i++) {
29 | session = container.connectToServer(WsClient.class, uri);
30 | session.close();
31 | TimeUnit.SECONDS.sleep(2);
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/javaee/javaee-websocket/src/main/java/cn/yourbatman/javaee/websocket/WsClient.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.javaee.websocket;
2 |
3 | import javax.websocket.ClientEndpoint;
4 | import javax.websocket.OnClose;
5 | import javax.websocket.OnMessage;
6 | import javax.websocket.OnOpen;
7 | import javax.websocket.Session;
8 | import java.io.IOException;
9 |
10 | /**
11 | * 在此处添加备注信息
12 | *
13 | * @author YourBatman. Send email to me
14 | * @site https://yourbatman.cn
15 | * @date 2021/7/4 16:29
16 | * @since 0.0.1
17 | */
18 | @ClientEndpoint
19 | public class WsClient {
20 |
21 | // 会话(与服务端建立的会话)
22 | private Session session;
23 |
24 | /**
25 | * 建连成功的回调
26 | */
27 | @OnOpen
28 | public void onOpen(Session session) throws IOException {
29 | this.session = session;
30 | System.out.println("Client连接到服务端成功,会话ID:" + session.getId());
31 | sendMessage("这是一条来自Client端,会话["+session.getId()+"]的消息");
32 | }
33 |
34 | @OnMessage
35 | public void onMessage(String message) {
36 | System.out.println("Client端收到消息: " + message);
37 | }
38 |
39 | @OnClose
40 | public void onClose() {
41 | System.out.println("Client会话" + session.getId() + "已断开");
42 | }
43 |
44 | /**
45 | * 发送消息
46 | */
47 | public void sendMessage(String message) throws IOException {
48 | this.session.getBasicRemote().sendText(message);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/javaee/javaee-websocket/src/main/java/cn/yourbatman/javaee/websocket/WsServer.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.javaee.websocket;
2 |
3 | import javax.websocket.OnClose;
4 | import javax.websocket.OnError;
5 | import javax.websocket.OnMessage;
6 | import javax.websocket.OnOpen;
7 | import javax.websocket.Session;
8 | import javax.websocket.server.ServerEndpoint;
9 | import java.io.IOException;
10 | import java.util.Set;
11 | import java.util.concurrent.CopyOnWriteArraySet;
12 |
13 | /**
14 | * 在此处添加备注信息
15 | *
16 | * @author YourBatman. Send email to me
17 | * @site https://yourbatman.cn
18 | * @date 2021/7/4 16:17
19 | * @since 0.0.1
20 | */
21 | @ServerEndpoint("/websocket/chat")
22 | public class WsServer {
23 |
24 |
25 | // 当前连接上来的连接们(每一个连接都是一个WsServerDemo实例,包含一个Session会话)
26 | private static Set webSocketSet = new CopyOnWriteArraySet<>();
27 | // 会话
28 | private Session session;
29 |
30 | /**
31 | * 建连成功的回调
32 | */
33 | @OnOpen
34 | public void onOpen(Session session) {
35 | this.session = session;
36 | webSocketSet.add(this); // 保存当前连接
37 | System.out.println("Server有新连接加入!当前在线人数为" + webSocketSet.size());
38 | }
39 |
40 | /**
41 | * 连接关闭调用的方法
42 | */
43 | @OnClose
44 | public void onClose() {
45 | webSocketSet.remove(this);
46 | System.out.println("Server有一连接关闭!当前在线人数为" + webSocketSet.size());
47 | }
48 |
49 | /**
50 | * 收到客户端消息后调用的方法
51 | */
52 | @OnMessage
53 | public void onMessage(String message) throws IOException {
54 | System.out.println("Server来自客户端的消息:" + message);
55 | sendMessage("会话[" + session.getId() + "]的消息已经收到,内容为:" + message);
56 | // // =======群发消息=========
57 | // for (WsServerDemo item : webSocketSet) {
58 | // try {
59 | // item.sendMessage(message);
60 | // } catch (IOException e) {
61 | // continue;
62 | // }
63 | // }
64 | }
65 |
66 | /**
67 | * 发生错误时调用
68 | */
69 | @OnError
70 | public void onError(Throwable error) {
71 | System.out.println("Server发生错误:" + error.getMessage());
72 | }
73 |
74 | /**
75 | * 发送消息
76 | */
77 | public void sendMessage(String message) throws IOException {
78 | this.session.getBasicRemote().sendText(message);
79 | }
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/javaee/javaee-websocket/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/javaee/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | tech-column-learning
7 | cn.yourbatman
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 | pom
12 |
13 | javaee-jaxrs
14 | javaee-servlet
15 | javaee-el
16 | javaee-websocket
17 | javaee-jsonb
18 |
19 | javaee
20 |
21 |
22 | 8
23 | 8
24 |
25 |
26 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | cn.yourbatman
8 | tech-column-learning
9 | 1.0-SNAPSHOT
10 |
11 | cors
12 | spring5
13 | foundation
14 | javaee
15 | basicskill
16 |
17 | pom
18 |
19 |
20 | 8
21 | 8
22 | 2.7.0
23 |
24 |
25 |
26 | BAT的乌托邦
27 | https://yourbatman.cn
28 |
29 |
30 |
31 | YourBatman
32 | yourbatman@aliyun.com
33 | https://yourbatman.cn
34 | +8
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-dependencies
44 | ${spring-boot-dependencies}
45 | pom
46 | import
47 |
48 |
49 | commons-io
50 | commons-io
51 | 2.11.0
52 |
53 |
54 | org.apache.commons
55 | commons-lang3
56 | 3.12.0
57 |
58 |
59 |
60 |
61 |
62 |
63 | ch.qos.logback
64 | logback-classic
65 |
66 |
67 | org.springframework
68 | spring-core
69 |
70 |
71 | org.springframework
72 | spring-test
73 | test
74 |
75 |
76 | org.junit.jupiter
77 | junit-jupiter-api
78 |
79 |
80 | org.projectlombok
81 | lombok
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | org.apache.maven.plugins
90 | maven-war-plugin
91 | 3.3.1
92 |
93 | false
94 |
95 |
96 |
97 | org.apache.maven.plugins
98 | maven-compiler-plugin
99 | 3.8.1
100 |
101 |
102 |
108 |
109 |
110 | src/main/java
111 |
112 | **/*.properties
113 | **/*.xml
114 | **/*.tld
115 |
116 | false
117 |
118 |
119 |
120 |
121 |
--------------------------------------------------------------------------------
/spring5/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | tech-column-learning
7 | cn.yourbatman
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 | spring5
12 | pom
13 | 这是针对Spring 5提供的一些特殊新功能的工程
14 |
15 | spring5-java
16 |
17 |
18 |
19 | 8
20 | 8
21 |
22 |
23 |
24 |
25 | org.springframework
26 | spring-core
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/spring5/spring5-java/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | spring5
7 | cn.yourbatman
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | spring5-java
13 |
14 |
15 | 8
16 | 8
17 |
18 |
19 |
20 |
21 | org.springframework
22 | spring-webmvc
23 |
24 |
25 |
--------------------------------------------------------------------------------
/spring5/spring5-java/src/main/java/cn/yourbatman/spring5/java/antpathmatcher/Demo1.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.spring5.java.antpathmatcher;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.util.AntPathMatcher;
5 | import org.springframework.util.PathMatcher;
6 |
7 | import java.util.Arrays;
8 | import java.util.Collections;
9 | import java.util.Comparator;
10 | import java.util.List;
11 | import java.util.Map;
12 |
13 | /**
14 | * 在此处添加备注信息
15 | *
16 | * @author YourBatman. Send email to me
17 | * @site https://yourbatman.cn
18 | * @date 2021/6/18 18:01
19 | * @since 0.0.1
20 | * @see AntPathMatcher
21 | */
22 | // @ComponentScan(basePackages = "cn.yourbatman.**.controller")
23 | public class Demo1 {
24 |
25 | private static final PathMatcher MATCHER = new AntPathMatcher();
26 |
27 | @Test
28 | public void test1() {
29 | System.out.println("=======?:匹配任意单字符=======");
30 | String pattern = "/api/your?atman";
31 |
32 | match(1, MATCHER, pattern, "/api/youratman");
33 | match(2, MATCHER, pattern, "/api/yourBatman");
34 | match(3, MATCHER, pattern, "/api/yourBatman/address");
35 | match(4, MATCHER, pattern, "/api/yourBBBatman");
36 | }
37 |
38 | @Test
39 | public void test2() {
40 | System.out.println("=======*:匹配任意数量的字符=======");
41 | String pattern = "/api/*/yourbatman";
42 |
43 | match(1, MATCHER, pattern, "/api//yourbatman");
44 | match(2, MATCHER, pattern, "/api/ /yourbatman");
45 | match(3, MATCHER, pattern, "/api/yourbatman");
46 | match(4, MATCHER, pattern, "/api/v1v2v3/yourbatman");
47 | }
48 |
49 | @Test
50 | public void test3() {
51 | System.out.println("=======**:匹配任意层级的路径/目录=======");
52 | String pattern = "/api/yourbatman/**";
53 |
54 |
55 | match(1, MATCHER, pattern, "/api/yourbatman");
56 | match(2, MATCHER, pattern, "/api/yourbatman/");
57 | match(3, MATCHER, pattern, "/api/yourbatman/address");
58 | match(4, MATCHER, pattern, "/api/yourbatman/a/b/c");
59 | }
60 |
61 | @Test
62 | public void test4() {
63 | System.out.println("=======**:匹配任意层级的路径/目录=======");
64 | String pattern = "/api/**/yourbatman";
65 |
66 | match(1, MATCHER, pattern, "/api/yourbatman");
67 | match(2, MATCHER, pattern, "/api//yourbatman");
68 | match(3, MATCHER, pattern, "/api/a/b/c/yourbatman");
69 | }
70 |
71 | @Test
72 | public void test5() {
73 | System.out.println("======={pathVariable:可选的正则表达式}=======");
74 | String pattern = "/api/yourbatman/{age}";
75 |
76 | match(1, MATCHER, pattern, "/api/yourbatman/10");
77 | match(2, MATCHER, pattern, "/api/yourbatman/Ten");
78 |
79 | // 打印提取到的内容
80 | extractUriTemplateVariables(MATCHER, pattern, "/api/yourbatman/10");
81 | extractUriTemplateVariables(MATCHER, pattern, "/api/yourbatman/Ten");
82 | }
83 |
84 | @Test
85 | public void test6() {
86 | System.out.println("======={pathVariable:可选的正则表达式}=======");
87 | String pattern = "/api/yourbatman/{age:[0-9]*}";
88 |
89 | match(1, MATCHER, pattern, "/api/yourbatman/10");
90 | match(2, MATCHER, pattern, "/api/yourbatman/Ten");
91 |
92 | // 打印提取到的内容
93 | extractUriTemplateVariables(MATCHER, pattern, "/api/yourbatman/10");
94 | extractUriTemplateVariables(MATCHER, pattern, "/api/yourbatman/Ten");
95 | }
96 |
97 | @Test
98 | public void test7() {
99 | System.out.println("=======isPattern方法=======");
100 |
101 | System.out.println(MATCHER.isPattern("/api/yourbatman"));
102 | System.out.println(MATCHER.isPattern("/api/your?atman"));
103 | System.out.println(MATCHER.isPattern("/api/*/yourBatman"));
104 | System.out.println(MATCHER.isPattern("/api/yourBatman/**"));
105 | }
106 |
107 | @Test
108 | public void test8() {
109 | System.out.println("=======matchStart方法=======");
110 | String pattern = "/api/?";
111 |
112 | System.out.println("match方法结果:" + MATCHER.match(pattern, "/api/y"));
113 | System.out.println("match方法结果:" + MATCHER.match(pattern, "/api//"));
114 | System.out.println("match方法结果:" + MATCHER.match(pattern, "/api////"));
115 | System.out.println("matchStart方法结果:" + MATCHER.matchStart(pattern, "/api//"));
116 | System.out.println("matchStart方法结果:" + MATCHER.matchStart(pattern, "/api////"));
117 | System.out.println("matchStart方法结果:" + MATCHER.matchStart(pattern, "/api///a/"));
118 | }
119 |
120 | @Test
121 | public void test9() {
122 | System.out.println("=======extractPathWithinPattern方法=======");
123 | String pattern = "/api/*.html";
124 |
125 | System.out.println("是否匹配成功:" + MATCHER.match(pattern, "/api/yourbatman/address")
126 | + ",提取结果:" + MATCHER.extractPathWithinPattern(pattern, "/api/yourbatman/address"));
127 | System.out.println("是否匹配成功:" + MATCHER.match(pattern, "/api/index.html")
128 | + ",提取结果:" + MATCHER.extractPathWithinPattern(pattern, "/api/index.html"));
129 | }
130 |
131 | @Test
132 | public void test10() {
133 | System.out.println("=======extractPathWithinPattern方法=======");
134 | String pattern = "/api/**/yourbatman/*.html/temp";
135 |
136 | System.out.println("是否匹配成功:" + MATCHER.match(pattern, "/api/yourbatman/address")
137 | + ",提取结果:" + MATCHER.extractPathWithinPattern(pattern, "/api/yourbatman/address"));
138 | System.out.println("是否匹配成功:" + MATCHER.match(pattern, "/api/yourbatman/index.html/temp")
139 | + ",提取结果:" + MATCHER.extractPathWithinPattern(pattern, "/api/yourbatman/index.html/temp"));
140 | }
141 |
142 | @Test
143 | public void test11() {
144 | System.out.println("=======getPatternComparator方法=======");
145 |
146 | List patterns = Arrays.asList(
147 | "/api/**/index.html",
148 | "/api/yourbatman/*.html",
149 | "/api/**/*.html",
150 | "/api/yourbatman/index.html"
151 | );
152 | System.out.println("排序前:" + patterns);
153 |
154 | Comparator patternComparator = MATCHER.getPatternComparator("/api/yourbatman/index.html");
155 | Collections.sort(patterns, patternComparator);
156 | System.out.println("排序后:" + patterns);
157 | }
158 |
159 | private static void match(int index, PathMatcher matcher, String pattern, String reqPath) {
160 | boolean match = matcher.match(pattern, reqPath);
161 | System.out.println(index + "\tmatch结果:" + pattern + "\t" + (match ? "【成功】" : "【失败】") + "\t" + reqPath);
162 | }
163 |
164 | private static void extractUriTemplateVariables(PathMatcher matcher, String pattern, String reqPath) {
165 | Map variablesMap = matcher.extractUriTemplateVariables(pattern, reqPath);
166 | System.out.println("extractUriTemplateVariables结果:" + variablesMap + "\t" + pattern + "\t" + reqPath);
167 | }
168 |
169 |
170 | }
171 |
--------------------------------------------------------------------------------
/spring5/spring5-java/src/main/java/cn/yourbatman/spring5/java/pathpattern/CompareDemo.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.spring5.java.pathpattern;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.http.server.PathContainer;
5 | import org.springframework.util.AntPathMatcher;
6 | import org.springframework.util.PathMatcher;
7 | import org.springframework.web.util.pattern.PathPattern;
8 | import org.springframework.web.util.pattern.PathPatternParser;
9 |
10 | import java.time.Duration;
11 | import java.time.Instant;
12 |
13 | /**
14 | * 在此处添加备注信息
15 | *
16 | * @author YourBatman. Send email to me
17 | * @site https://yourbatman.cn
18 | * @date 2021/6/20 17:25
19 | * @since 0.0.1
20 | */
21 | public class CompareDemo {
22 |
23 |
24 | private static final String pattern = "/api/your?atman/{age}/**";
25 |
26 | @Test
27 | public void test1() {
28 | Instant start = Instant.now();
29 | for (int i = 0; i < 10000000; i++) {
30 | String reqPath = "/api/yourBatman/" + i + "/" + i;
31 | // antPathMatcher(reqPath);
32 | pathPattern(reqPath);
33 | }
34 | System.out.println("耗时(ms):" + Duration.between(start, Instant.now()).toMillis());
35 | }
36 |
37 |
38 | private static final PathMatcher MATCHER = new AntPathMatcher();
39 |
40 | public static void antPathMatcher(String reqPath) {
41 | MATCHER.match(pattern, reqPath);
42 | }
43 |
44 | private static final PathPattern PATTERN = PathPatternParser.defaultInstance.parse(pattern);
45 |
46 | public static void pathPattern(String reqPath) {
47 | PATTERN.matches(PathContainer.parsePath(reqPath));
48 | }
49 |
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/spring5/spring5-java/src/main/java/cn/yourbatman/spring5/java/pathpattern/Demo1.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.spring5.java.pathpattern;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.http.server.PathContainer;
5 | import org.springframework.web.util.pattern.PathPattern;
6 | import org.springframework.web.util.pattern.PathPatternParser;
7 |
8 | /**
9 | * 在此处添加备注信息
10 | *
11 | * @author YourBatman. Send email to me
12 | * @site https://yourbatman.cn
13 | * @date 2021/6/20 09:47
14 | * @since 0.0.1
15 | */
16 | public class Demo1 {
17 |
18 | /**
19 | * 将pattern字符串的每一段都解析为element,用链状形式连接起来
20 | */
21 | @Test
22 | public void test1() {
23 | PathPatternParser parser = new PathPatternParser();
24 | PathPattern pathPattern = parser.parse("/api/v1/**");
25 | System.out.println(pathPattern);
26 | }
27 |
28 | @Test
29 | public void test2() {
30 | PathContainer pathContainer = PathContainer.parsePath("/api/v1/address", PathContainer.Options.HTTP_PATH);
31 | System.out.println(pathContainer);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/spring5/spring5-java/src/main/java/cn/yourbatman/spring5/java/pathpattern/Demo2.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.spring5.java.pathpattern;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.http.server.PathContainer;
5 | import org.springframework.util.AntPathMatcher;
6 | import org.springframework.web.util.pattern.PathPattern;
7 | import org.springframework.web.util.pattern.PathPatternParser;
8 |
9 | import java.util.SortedSet;
10 | import java.util.TreeSet;
11 |
12 | /**
13 | * {@link PathPattern} 是Spring 5推出的用于取代{@link AntPathMatcher}的路径匹配神器。前者性能更强
14 | *
15 | * @author YourBatman. Send email to me
16 | * @site https://yourbatman.cn
17 | * @date 2021/6/18 17:01
18 | * @since 0.0.1
19 | * @see PathPattern
20 | * @see PathPatternParser
21 | */
22 | public class Demo2 {
23 |
24 | @Test
25 | public void test1() {
26 | System.out.println("======={*pathVariable}语法======");
27 | PathPattern pattern = PathPatternParser.defaultInstance.parse("/api/yourbatman/{*pathVariable}");
28 |
29 |
30 | // 提取匹配到的的变量值
31 | System.out.println("是否匹配:" + pattern.matches(PathContainer.parsePath("/api/yourbatman/a/b/c")));
32 | PathPattern.PathMatchInfo pathMatchInfo = pattern.matchAndExtract(PathContainer.parsePath("/api/yourbatman/a/b/c"));
33 | System.out.println("匹配到的值情况:" + pathMatchInfo.getUriVariables());
34 | }
35 |
36 | @Test
37 | public void test2() {
38 | System.out.println("======={*pathVariable}和/**优先级======");
39 | PathPattern pattern1 = PathPatternParser.defaultInstance.parse("/api/yourbatman/{*pathVariable}");
40 | PathPattern pattern2 = PathPatternParser.defaultInstance.parse("/api/yourbatman/**");
41 |
42 | SortedSet sortedSet = new TreeSet<>();
43 | sortedSet.add(pattern1);
44 | sortedSet.add(pattern2);
45 |
46 | System.out.println(sortedSet);
47 | }
48 |
49 |
50 | @Test
51 | public void test3() {
52 | System.out.println("=======/**放在中间语法======");
53 | PathPattern pattern = PathPatternParser.defaultInstance.parse("/api/**/yourbatman");
54 |
55 | pattern.matches(PathContainer.parsePath("/api/a/b/c/yourbatman"));
56 | }
57 |
58 | @Test
59 | public void test4() {
60 | System.out.println("======={*pathVariable}放中间代替/**放中间======");
61 | PathPattern pattern = PathPatternParser.defaultInstance.parse("/api/{*pathVariable}/yourbatman");
62 |
63 | System.out.println(pattern.matches(PathContainer.parsePath("/api/a/b/c/yourbatman")));
64 | }
65 |
66 |
67 |
68 |
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/spring5/spring5-java/src/main/java/cn/yourbatman/spring5/java/pathpattern/WebMvcConfiguration.java:
--------------------------------------------------------------------------------
1 | package cn.yourbatman.spring5.java.pathpattern;
2 |
3 | import org.springframework.context.annotation.Configuration;
4 | import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
5 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
6 | import org.springframework.web.util.pattern.PathPatternParser;
7 |
8 | /**
9 | * 在此处添加备注信息
10 | *
11 | * @author YourBatman. Send email to me
12 | * @site https://yourbatman.cn
13 | * @date 2021/6/20 18:33
14 | * @since 0.0.1
15 | */
16 | @Configuration(proxyBeanMethods = false)
17 | public class WebMvcConfiguration implements WebMvcConfigurer {
18 |
19 | @Override
20 | public void configurePathMatch(PathMatchConfigurer configurer) {
21 | configurer.setPatternParser(PathPatternParser.defaultInstance);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------