diff --git a/api-demos/geely-comon-file-client/pom.xml b/api-demos/geely-comon-file-client/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..cfe20f19476b635272ec42a48fa116ea90e8a3ea
--- /dev/null
+++ b/api-demos/geely-comon-file-client/pom.xml
@@ -0,0 +1,33 @@
+
+
+
+ api-demos
+ com.gsean.demos
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ geely-comon-file-client
+
+
+ 8
+ 8
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ com.geely.commonfile
+ common-file-export-client
+ 1.0-SNAPSHOT
+
+
+
+
\ No newline at end of file
diff --git a/api-demos/geely-comon-file-client/src/main/java/com/gsean/client/ExcelApp.java b/api-demos/geely-comon-file-client/src/main/java/com/gsean/client/ExcelApp.java
new file mode 100644
index 0000000000000000000000000000000000000000..42cfab7530d509fd20c9f3ec08dc11897e0131ac
--- /dev/null
+++ b/api-demos/geely-comon-file-client/src/main/java/com/gsean/client/ExcelApp.java
@@ -0,0 +1,24 @@
+package com.gsean.client;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+
+/**
+ * @authoer Jincheng.Guo11
+ * @description
+ * @date:created in 2021/12/10 9:49
+ * @modificed by
+ **/
+@SpringBootApplication
+@ComponentScan(basePackages = {"com.geely.commonfile"})
+public class ExcelApp {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ExcelApp.class,args);
+ }
+
+
+
+
+}
diff --git a/api-demos/geely-comon-file-client/src/test/java/com/gsean/client/ExcelAppTest.java b/api-demos/geely-comon-file-client/src/test/java/com/gsean/client/ExcelAppTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..aa7ab3c90b1e91956854c92a73033f1bd0eb3a1b
--- /dev/null
+++ b/api-demos/geely-comon-file-client/src/test/java/com/gsean/client/ExcelAppTest.java
@@ -0,0 +1,36 @@
+package com.gsean.client;
+
+import static org.junit.Assert.*;
+
+import com.geely.commonfile.excel.client.ExcelExportTaskClient;
+import com.geely.commonfile.excel.client.dto.ExcelRequestDTO;
+import javax.annotation.Resource;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @authoer Jincheng.Guo11
+ * @description
+ * @date:created in 2021/12/10 9:51
+ * @modificed by
+ **/
+@SpringBootTest
+@RunWith(SpringRunner.class)
+public class ExcelAppTest {
+ @Resource
+ private ExcelExportTaskClient excelExportTaskClient;
+
+
+ @Test
+ public void testA(){
+ String url="http://127.0.0.1:8080/hello";
+ ExcelRequestDTO excelRequestDTO = new ExcelRequestDTO(String.class,url);
+ String resUrl = excelExportTaskClient.exportSync(excelRequestDTO);
+ System.out.println(resUrl);
+ System.out.println("hello");
+ }
+}
\ No newline at end of file
diff --git a/api-demos/pom.xml b/api-demos/pom.xml
index b402fd37d44c0e5447b721201a62436586fc571d..ec023007ee7807a9da54707c845e9faa0d9c6e2b 100644
--- a/api-demos/pom.xml
+++ b/api-demos/pom.xml
@@ -18,6 +18,7 @@
easyopen-demo
responsebody-demo
soap-demo
+ geely-comon-file-client
diff --git a/java8-demos/java-thread-demo/Sumary.md b/java8-demos/java-thread-demo/Sumary.md
new file mode 100644
index 0000000000000000000000000000000000000000..a7873ea37a72b4d8d0bd426bb5274c16753d0b3b
--- /dev/null
+++ b/java8-demos/java-thread-demo/Sumary.md
@@ -0,0 +1,4 @@
+## 说明
+item03: 创建线程的方式
+item02: 线程通知等待机制
+item05: 线程安全问题
\ No newline at end of file
diff --git a/java8-demos/java-thread-demo/src/main/java/com/gsean/thread/item03/MyThread.java b/java8-demos/java-thread-demo/src/main/java/com/gsean/thread/item03/MyThread.java
new file mode 100644
index 0000000000000000000000000000000000000000..4ef72dd0ec50cc50404b81e710e279a07c38c7ea
--- /dev/null
+++ b/java8-demos/java-thread-demo/src/main/java/com/gsean/thread/item03/MyThread.java
@@ -0,0 +1,19 @@
+package com.gsean.thread.item03;
+
+/**
+ * @authoer Jincheng.Guo11
+ * @description
+ * @date:created in 2021/12/10 14:35
+ * @modificed by
+ **/
+public class MyThread extends Thread{
+ public MyThread(String name) {
+ super(name);
+ }
+
+ @Override
+ public void run() {
+ System.out.println(getName()+"开始工作了");
+ }
+
+}
diff --git a/java8-demos/java-thread-demo/src/test/java/com/gsean/thread/item01/JoinThreadTest.java b/java8-demos/java-thread-demo/src/test/java/com/gsean/thread/item01/JoinThreadTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..efc88ff4c3efb87e1ac519a2c7e2261ea726249b
--- /dev/null
+++ b/java8-demos/java-thread-demo/src/test/java/com/gsean/thread/item01/JoinThreadTest.java
@@ -0,0 +1,48 @@
+package com.gsean.thread.item01;
+
+import org.junit.Test;
+
+/**
+ * @authoer Jincheng.Guo11
+ * @description
+ * @date:created in 2021/12/10 15:35
+ * @modificed by
+ **/
+public class JoinThreadTest {
+ /**
+ * join 相当于汇总,汇总线程需要等待所有分支线程结束后才能继续执行
+ *
+ * @author: Jincheng.Guo11
+ * @date: 2021/12/10 15:39
+ * @return: void
+ * @throws: java.lang.Exception
+ * @modificed by:
+ */
+ @Test
+ public void testA(){
+ Runnable runnable=() -> {
+ System.out.println(Thread.currentThread().getName() + "开始工作2s");
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ };
+ Thread t1 = new Thread(runnable, "t1");
+ Thread t2 = new Thread(runnable, "t2");
+ t1.start();
+ t2.start();
+
+ // 汇总线程
+ try {
+ System.out.println("开始汇总线程");
+ t1.join();//第一次调用的时候主线程就开始阻塞了,他需要等待t1执行完成才能继续
+ t2.join();// 这里相当于主线程被顺序阻塞两次
+ System.out.println(Thread.currentThread().getName()+"end");
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+}
diff --git a/java8-demos/java-thread-demo/src/test/java/com/gsean/thread/item02/WaiteThreadTest.java b/java8-demos/java-thread-demo/src/test/java/com/gsean/thread/item02/WaiteThreadTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..668889b68f5ba9424f84a155bd4b3a2ad2871db5
--- /dev/null
+++ b/java8-demos/java-thread-demo/src/test/java/com/gsean/thread/item02/WaiteThreadTest.java
@@ -0,0 +1,130 @@
+package com.gsean.thread.item02;
+
+import org.junit.Test;
+
+/**
+ * @authoer Jincheng.Guo11
+ * @description
+ * @date:created in 2021/12/10 15:06
+ * @modificed by
+ **/
+public class WaiteThreadTest {
+
+ private static volatile Object resourceObj=new Object();
+
+ /**
+ * 线程wait等待,notifyAll唤醒所有线程
+ *
+ * @author: Jincheng.Guo11
+ * @date: 2021/12/10 15:23
+ * @return: void
+ * @throws: java.lang.Exception
+ * @modificed by:
+ */
+ @Test
+ public void testA(){
+ // 获取共享资源锁执行操作
+ Runnable runnable = () -> {
+ synchronized (resourceObj) {
+ String threadName = Thread.currentThread().getName();
+ System.out.println(threadName + "正在执行操作");
+ System.out.println(threadName+"挂起");
+ try {
+ resourceObj.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ // 线程挂起后让出cpu并进入等待状态
+ // 被唤醒后如果共享对象仍然锁定则需要竞争才能执行下面操作
+ System.out.println(threadName+"醒了,继续干活");
+ }
+ };
+
+ Thread t1 = new Thread(runnable, "t1");
+ Thread t2 = new Thread(runnable, "t2");
+ Thread t3 = new Thread(() -> {
+ System.out.println("2s后开始唤醒所有等待线程");
+ try {
+ // 唤醒线程需要先获取到对象锁才能调用该对象的notify方法,否则报 IllegalMonitorStateException
+ synchronized (resourceObj) {
+ Thread.sleep(2000);
+ resourceObj.notifyAll();
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ },"t3");
+ t1.start();
+ t2.start();
+ t3.start();
+
+ //加入main线程
+ try {
+ t1.join();
+ t2.join();
+ t3.join();
+ System.out.println(Thread.currentThread().getName()+"结束");
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ /**
+ * 单独唤醒(随机)
+ *
+ * @author: Jincheng.Guo11
+ * @date: 2021/12/10 15:27
+ * @return: void
+ * @throws: java.lang.Exception
+ * @modificed by:
+ */
+ @Test
+ public void testB(){
+ // 获取共享资源锁执行操作
+ Runnable runnable = () -> {
+ synchronized (resourceObj) {
+ String threadName = Thread.currentThread().getName();
+ System.out.println(threadName + "正在执行操作");
+ System.out.println(threadName+"挂起");
+ try {
+ resourceObj.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ // 线程挂起后让出cpu并进入等待状态
+ System.out.println(threadName+"醒了,继续干活");
+ }
+ };
+
+ Thread t1 = new Thread(runnable, "t1");
+ Thread t2 = new Thread(runnable, "t2");
+ Thread t3 = new Thread(() -> {
+ // 唤醒线程需要先获取到对象锁才能调用该对象的notify方法,否则报 IllegalMonitorStateException
+ synchronized (resourceObj) {
+ // notify是随机唤醒一个等待线程
+ resourceObj.notify();
+ }
+ },"t3");
+ t1.start();
+ t2.start();
+ try {
+ System.out.println("2s后开始唤醒所有等待线程");
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ t3.start();
+
+ //加入main线程
+ try {
+ t1.join();
+ t2.join();
+ t3.join();
+ System.out.println(Thread.currentThread().getName()+"结束");
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/java8-demos/java-thread-demo/src/test/java/com/gsean/thread/item03/CreateThreadTest.java b/java8-demos/java-thread-demo/src/test/java/com/gsean/thread/item03/CreateThreadTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..d97daa772f4a4dc8f66eb2cd6e60e1808811e798
--- /dev/null
+++ b/java8-demos/java-thread-demo/src/test/java/com/gsean/thread/item03/CreateThreadTest.java
@@ -0,0 +1,78 @@
+package com.gsean.thread.item03;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+import org.junit.Test;
+
+/**
+ * @authoer Jincheng.Guo11
+ * @description
+ * @date:created in 2021/12/10 14:33
+ * @modificed by
+ **/
+public class CreateThreadTest {
+
+ /**
+ * 通过继承Thread创建线程
+ */
+ @Test
+ public void testA(){
+ MyThread t1 = new MyThread("t1");
+ t1.start();
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 通过实现Runnable创建线程
+ *
+ * @author: Jincheng.Guo11
+ * @date: 2021/12/10 14:39
+ * @return: void
+ * @throws: java.lang.Exception
+ * @modificed by:
+ */
+ @Test
+ public void testB(){
+ new Thread(() -> {
+ System.out.println("t2开始工作了");
+ },"t2").start();
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ }
+ /**
+ * 通过实现FutureTask创建线程
+ * 线程执行结果有返回值
+ * @author: Jincheng.Guo11
+ * @date: 2021/12/10 14:49
+ * @return: void
+ * @throws: java.lang.Exception
+ * @modificed by:
+ */
+ @Test
+ public void testC(){
+ //创建异步任务
+ FutureTask futureTask = new FutureTask<>(() -> {
+ System.out.println("t3开始工作了");
+ Thread.sleep(2000);
+ return "t3的结果";
+ });
+ new Thread(futureTask,"t3").start();
+ try {
+ // 获取结果是线程阻塞的
+ String result = futureTask.get(1, TimeUnit.SECONDS);
+ System.out.println(result);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/java8-demos/java-thread-demo/src/test/java/com/gsean/thread/item04/SleepThreadTest.java b/java8-demos/java-thread-demo/src/test/java/com/gsean/thread/item04/SleepThreadTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..9ae3fc7a221328870677dd4a341fefadd4a20b8b
--- /dev/null
+++ b/java8-demos/java-thread-demo/src/test/java/com/gsean/thread/item04/SleepThreadTest.java
@@ -0,0 +1,98 @@
+package com.gsean.thread.item04;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import org.junit.Test;
+
+/**
+ * @authoer Jincheng.Guo11
+ * @description
+ * @date:created in 2021/12/10 15:49
+ * @modificed by
+ **/
+public class SleepThreadTest {
+
+ private static volatile Object resourceA=new Object();
+
+
+ private static final Lock lock=new ReentrantLock();
+ /**
+ * sleep
+ * 线程获取到对象锁后如果sleep不会释放锁,但是会让出cpu
+ *
+ * @author: Jincheng.Guo11
+ * @date: 2021/12/10 15:53
+ * @return: void
+ * @throws: java.lang.Exception
+ * @modificed by:
+ */
+ @Test
+ public void testA(){
+ Runnable runnable = () -> {
+ String threadName = Thread.currentThread().getName();
+ synchronized (resourceA) {
+ System.out.println(threadName + "获取到对象锁,开始睡觉");
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ System.out.println(threadName + "睡醒了,继续工作");
+ }
+ };
+ Thread t1 = new Thread(runnable, "t1");
+ Thread t2 = new Thread(runnable, "t2");
+ t1.start();
+ t2.start();
+
+ try {
+ t1.join();
+ t2.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+
+ /**
+ * sleep
+ *
+ * @author: Jincheng.Guo11
+ * @date: 2021/12/10 15:56
+ * @return: void
+ * @throws: java.lang.Exception
+ * @modificed by:
+ */
+ @Test
+ public void testB(){
+ Runnable runnable = () -> {
+ String threadName = Thread.currentThread().getName();
+ // 获取独占锁
+ lock.lock();
+ System.out.println(threadName + "获取到对象锁,开始睡觉");
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }finally {
+ lock.unlock();
+ }
+ System.out.println(threadName + "睡醒了,继续工作");
+ };
+ Thread t1 = new Thread(runnable, "t1");
+ Thread t2 = new Thread(runnable, "t2");
+ t1.start();
+ t2.start();
+
+ try {
+ t1.join();
+ t2.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+
+}
diff --git a/java8-demos/java-thread-demo/src/test/java/com/gsean/thread/item05/DeadLockThreadTest.java b/java8-demos/java-thread-demo/src/test/java/com/gsean/thread/item05/DeadLockThreadTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..2888332735be75aa33e53fce7beeac052880ec8c
--- /dev/null
+++ b/java8-demos/java-thread-demo/src/test/java/com/gsean/thread/item05/DeadLockThreadTest.java
@@ -0,0 +1,72 @@
+package com.gsean.thread.item05;
+
+import org.junit.Test;
+
+/**
+ * @authoer Jincheng.Guo11
+ * @description
+ * @date:created in 2021/12/10 16:14
+ * @modificed by
+ **/
+public class DeadLockThreadTest {
+
+
+ private static volatile Object resourceA=new Object();
+ private static volatile Object resourceB=new Object();
+
+
+ /**
+ * 死锁:互相持有对方想要请求的锁
+ *
+ * @author: Jincheng.Guo11
+ * @date: 2021/12/10 16:18
+ * @return: void
+ * @throws: java.lang.Exception
+ * @modificed by:
+ */
+ @Test
+ public void testA(){
+
+ Thread t1 = new Thread(() -> {
+ String threadName = Thread.currentThread().getName();
+ synchronized (resourceA) {
+ System.out.println(threadName + "获取到resouceA");
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ synchronized (resourceB) {
+ System.out.println(threadName + "获取到resouceB");
+ }
+ }
+ }, "t1");
+
+ Thread t2 = new Thread(() -> {
+ String threadName = Thread.currentThread().getName();
+ synchronized (resourceB) {
+ System.out.println(threadName + "获取到resouceB");
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ synchronized (resourceA) {
+ System.out.println(threadName + "获取到resouceA");
+ }
+ }
+ }, "t1");
+
+ t1.start();
+ t2.start();
+
+ try {
+ t1.join();
+ t2.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+}
diff --git a/java8-demos/java-thread-demo/src/test/java/com/gsean/thread/item06/SecureThreadTest.java b/java8-demos/java-thread-demo/src/test/java/com/gsean/thread/item06/SecureThreadTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0aa59795c44ef7ae5e4659100f6dcc5544882b70
--- /dev/null
+++ b/java8-demos/java-thread-demo/src/test/java/com/gsean/thread/item06/SecureThreadTest.java
@@ -0,0 +1,148 @@
+package com.gsean.thread.item06;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.IntStream;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.notification.RunListener.ThreadSafe;
+
+/**
+ * @authoer Jincheng.Guo11
+ * @description
+ * @date:created in 2021/12/10 17:16
+ * @modificed by
+ **/
+public class SecureThreadTest {
+ private static volatile int x;
+
+ // 原子类中的值定义了volatile,所以是内存可见
+ private static AtomicInteger y=new AtomicInteger(0);
+
+
+ // 自增操作
+ private synchronized void increment(){
+ x++;
+ }
+
+
+ /**
+ * volatile 保证了共享变量内存可见,但是i++不是原子操作,仍然存在数据安全问题
+ *
+ * @author: Jincheng.Guo11
+ * @date: 2021/12/10 17:51
+ * @return: void
+ * @throws: java.lang.Exception
+ * @modificed by:
+ */
+ @Test
+ public void testA(){
+ Runnable runnable=()->{
+ IntStream.range(0,20).forEach(item->{
+ x++;
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ });
+ };
+ Thread t1 = new Thread(runnable, "t1");
+ Thread t2 = new Thread(runnable, "t2");
+ Thread t3 = new Thread(runnable, "t3");
+
+ t1.start();
+ t2.start();
+ t3.start();
+ try {
+ t1.join();
+ t2.join();
+ t3.join();
+ System.out.println("目前x的值="+x);
+ Assert.assertTrue(x!=60);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 通过synchronized控制共享数据操作的原子性,但是会造成线程上线文切换带来的开销
+ *
+ * @author: Jincheng.Guo11
+ * @date: 2021/12/10 17:58
+ * @return: void
+ * @throws: java.lang.Exception
+ * @modificed by:
+ */
+ @Test
+ public void testB(){
+ Runnable runnable=()->{
+ IntStream.range(0,20).forEach(item->{
+ increment();
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ });
+ };
+ Thread t1 = new Thread(runnable, "t1");
+ Thread t2 = new Thread(runnable, "t2");
+ Thread t3 = new Thread(runnable, "t3");
+
+ t1.start();
+ t2.start();
+ t3.start();
+ try {
+ t1.join();
+ t2.join();
+ t3.join();
+ System.out.println("目前x的值="+x);
+ Assert.assertTrue(x==60);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ /**
+ * 原子类通过CAS实现原子操作,所以线程安全
+ *
+ * @author: Jincheng.Guo11
+ * @date: 2021/12/10 18:08
+ * @return: void
+ * @throws: java.lang.Exception
+ * @modificed by:
+ */
+ @Test
+ public void testC(){
+ Runnable runnable=()->{
+ IntStream.range(0,20).forEach(item->{
+ y.getAndAdd(1);
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ });
+ };
+ Thread t1 = new Thread(runnable, "t1");
+ Thread t2 = new Thread(runnable, "t2");
+ Thread t3 = new Thread(runnable, "t3");
+
+ t1.start();
+ t2.start();
+ t3.start();
+ try {
+ t1.join();
+ t2.join();
+ t3.join();
+ System.out.println("目前y的值="+y.get());
+ Assert.assertTrue(y.get()==60);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+
+}
diff --git a/java8-demos/java8-stream-demo/src/test/java/com/gsean/java8/StreamTest.java b/java8-demos/java8-stream-demo/src/test/java/com/gsean/java8/StreamTest.java
index 10232372833aefbfbba48aecc8160d210c8f056c..1eb607469b0a805f70dcc831d1529f665c679cec 100644
--- a/java8-demos/java8-stream-demo/src/test/java/com/gsean/java8/StreamTest.java
+++ b/java8-demos/java8-stream-demo/src/test/java/com/gsean/java8/StreamTest.java
@@ -1,6 +1,7 @@
package com.gsean.java8;
import com.google.common.collect.ImmutableMap;
+import java.util.function.Function;
import org.junit.Test;
import java.util.Arrays;
@@ -63,4 +64,17 @@ public class StreamTest {
System.out.println("并行流计算耗时"+(end2-start2));
}
+
+
+
+ @Test
+ public void testB(){
+ String s = int2String(String::valueOf, 1, 2);
+ System.out.println(s);
+ }
+
+ private String int2String(Function mapFun,int a,int b){
+ int c=a+b;
+ return mapFun.apply(c);
+ }
}
diff --git a/starter-demos/oss-spring-boot-starter/pom.xml b/starter-demos/oss-spring-boot-starter/pom.xml
index afbc4b0d9ec21e05caed58d56d1aa9db29778933..858816b614cf83b3e5d44c164a07cf1e8f033ab7 100644
--- a/starter-demos/oss-spring-boot-starter/pom.xml
+++ b/starter-demos/oss-spring-boot-starter/pom.xml
@@ -44,6 +44,11 @@
hutool-core
5.7.16
+
+ commons-io
+ commons-io
+ 2.6
+
\ No newline at end of file
diff --git a/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/config/AliyunOSSConfig.java b/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/config/AliyunOSSConfig.java
index 399115da8a31939e5af61e010af4c7211d1f021c..d4796610c866b0b0668ccb8379077a00b1aadcf7 100644
--- a/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/config/AliyunOSSConfig.java
+++ b/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/config/AliyunOSSConfig.java
@@ -16,7 +16,7 @@ import org.springframework.context.annotation.Configuration;
* @modificed by
**/
@Configuration(proxyBeanMethods = false)
-@ConditionalOnProperty(prefix = CommonConstant.GLOBAL_PREFIX,name = CommonConstant.OSS_TYPE,havingValue = CommonConstant.ALIYUN)
+@ConditionalOnProperty(prefix = CommonConstant.GLOBAL_PREFIX,name = CommonConstant.OSS_TYPE,havingValue = "aliyun")
public class AliyunOSSConfig {
diff --git a/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/config/TencentOSSConfig.java b/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/config/TencentOSSConfig.java
index 99850436706a182e905f0c3f5a4d62d6eb9a5f37..b047f6db646d74d64f7afa7e80c4fc23ea3a251d 100644
--- a/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/config/TencentOSSConfig.java
+++ b/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/config/TencentOSSConfig.java
@@ -16,7 +16,7 @@ import org.springframework.context.annotation.Configuration;
* @modificed by
**/
@Configuration(proxyBeanMethods = false)
-@ConditionalOnProperty(prefix = CommonConstant.GLOBAL_PREFIX,name = CommonConstant.OSS_TYPE,havingValue = CommonConstant.TENCENT)
+@ConditionalOnProperty(prefix = CommonConstant.GLOBAL_PREFIX,name = CommonConstant.OSS_TYPE,havingValue = "tencent")
public class TencentOSSConfig {
@Bean
@ConditionalOnMissingBean({OssService.class})
diff --git a/java8-demos/java-thread-demo/src/main/java/com/gsean/thread/item02/CreateDemo01.java b/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/constant/OSSType.java
similarity index 34%
rename from java8-demos/java-thread-demo/src/main/java/com/gsean/thread/item02/CreateDemo01.java
rename to starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/constant/OSSType.java
index b6ed21969deaf5e6665c6cbd4a3c750a86ed75db..af113c59264415d40b0ad8f75de744f76dea9c38 100644
--- a/java8-demos/java-thread-demo/src/main/java/com/gsean/thread/item02/CreateDemo01.java
+++ b/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/constant/OSSType.java
@@ -1,12 +1,14 @@
-package com.gsean.thread.item02;
+package com.gsean.oss.constant;
+
+import lombok.Getter;
/**
* @authoer Jincheng.Guo11
* @description
- * @date:created in 2021/11/29 12:50
+ * @date:created in 2021/12/9 13:30
* @modificed by
**/
-public class CreateDemo01 {
-
-
+@Getter
+public enum OSSType {
+ TENCENT,ALIYUN
}
diff --git a/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/props/OSSCoreProperty.java b/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/props/OSSCoreProperty.java
index f9bc1dce85cc6aac38236f4757f4c8aa8dd8d095..79c03bde5d5a1a70b0469566abf716d10184e1e8 100644
--- a/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/props/OSSCoreProperty.java
+++ b/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/props/OSSCoreProperty.java
@@ -1,6 +1,7 @@
package com.gsean.oss.props;
import com.gsean.oss.constant.CommonConstant;
+import com.gsean.oss.constant.OSSType;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -15,7 +16,9 @@ public class OSSCoreProperty {
// 是否可用
private boolean enabled = true;
// oss类型,默认腾讯云
- private String type= CommonConstant.TENCENT;
+
+// private String type;
+ private OSSType type;
private String bucketName;
diff --git a/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/service/impl/AliyunOssServiceImpl.java b/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/service/impl/AliyunOssServiceImpl.java
index d969dbd2f1abedec6f12c77936b83d43d1ad5322..91d9c77d06cba2786d93aa8f52fd34711ecac9ae 100644
--- a/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/service/impl/AliyunOssServiceImpl.java
+++ b/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/service/impl/AliyunOssServiceImpl.java
@@ -2,14 +2,22 @@ package com.gsean.oss.service.impl;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
+import com.aliyun.oss.model.PutObjectRequest;
+import com.gsean.oss.constant.CommonConstant;
import com.gsean.oss.props.OSSCoreProperty;
import com.gsean.oss.service.OssService;
+import com.gsean.oss.utils.CommonUtil;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
+import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.region.Region;
import java.io.File;
+import java.nio.charset.Charset;
+import java.util.Arrays;
import javax.annotation.PostConstruct;
+import org.apache.http.client.utils.URLEncodedUtils;
+import org.springframework.util.Assert;
/**
* @authoer Jincheng.Guo11
@@ -38,8 +46,38 @@ public class AliyunOssServiceImpl implements OssService {
@Override
- public String upload(String bucket, String fileName, File file) {
- return null;
+ public String upload(String bucket, String prefix, File file) {
+ Assert.notNull(bucket,"bucket必需");
+ Assert.notNull(prefix,"prefix必需");
+ String name = file.getName();
+ String key = CommonUtil.createFileKey(prefix, name);
+ if (key.startsWith("/")){
+ key = key.replaceFirst("\\/", "");
+ }
+ PutObjectRequest objectRequest = new PutObjectRequest(bucket, key, file);
+ oss.putObject(objectRequest);
+ return genericUrl(bucket, key);
+ }
+
+ private String genericUrl(String bucket, String fullFilePath) {
+ if (fullFilePath.startsWith("/")){
+ fullFilePath = fullFilePath.replaceFirst("\\/", "");
+ }
+ String host = getMainUrl(bucket);
+ String url = String.format("%s%s", host,
+ URLEncodedUtils.formatSegments(Arrays.asList(fullFilePath.split("\\/")), Charset.forName("UTF-8")));
+ return url;
+ }
+
+
+ private String getMainUrl() {
+ return getMainUrl(ossCoreProperty.getBucketName());
+ }
+
+ private String getMainUrl(String bucket) {
+ String endPointSplit = ossCoreProperty.getAliyun().getEndPoint().replaceFirst("https?://", "");
+ String url = String.format("https://%s.%s", bucket, endPointSplit);
+ return url;
}
@Override
diff --git a/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/service/impl/TencentOssServiceImpl.java b/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/service/impl/TencentOssServiceImpl.java
index 79250b6754e6278e096260adb70c10805d21f276..cbf576b1b61cc3e9b61c3e7f6c47ae8be4221b8b 100644
--- a/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/service/impl/TencentOssServiceImpl.java
+++ b/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/service/impl/TencentOssServiceImpl.java
@@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
import com.gsean.oss.constant.CommonConstant;
import com.gsean.oss.props.OSSCoreProperty;
import com.gsean.oss.service.OssService;
+import com.gsean.oss.utils.CommonUtil;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
@@ -19,8 +20,10 @@ import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.region.Region;
import java.io.File;
import java.util.Date;
+import java.util.Objects;
import javax.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.util.Assert;
/**
* @authoer Jincheng.Guo11
@@ -49,8 +52,11 @@ public class TencentOssServiceImpl implements OssService {
@Override
public String upload(String bucket, String prefix, File file) {
+ Assert.notNull(bucket,"bucket必需");
+ Assert.notNull(prefix,"prefix必需");
String name = file.getName();
- String key= ObjectUtil.isEmpty(prefix)?ossCoreProperty.getPrefix()+"/"+name:prefix+"/"+name;
+// String key= ObjectUtil.isEmpty(prefix)?ossCoreProperty.getPrefix()+"/"+name:prefix+"/"+name;
+ String key = CommonUtil.createFileKey(prefix, name);
PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, key, file);
PutObjectResult putObjectResult = this.cosClient.putObject(putObjectRequest);
return putObjectResult == null ? null : String.format(CommonConstant.COS_URL_FORMAT, bucket, ossCoreProperty.getTencent().getRegion(), key);
diff --git a/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/utils/CommonUtil.java b/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/utils/CommonUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..0d2a2e808cface9e2037a26bdd1c7f674633656d
--- /dev/null
+++ b/starter-demos/oss-spring-boot-starter/src/main/java/com/gsean/oss/utils/CommonUtil.java
@@ -0,0 +1,39 @@
+package com.gsean.oss.utils;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.FilenameUtils;
+
+/**
+ * @authoer Jincheng.Guo11
+ * @description
+ * @date:created in 2021/12/9 17:24
+ * @modificed by
+ **/
+@Slf4j
+public class CommonUtil {
+
+
+
+ /**
+ * 创建文件key
+ *
+ * @param path
+ * @param fileName
+ * @author: Jincheng.Guo11
+ * @date: 2021/12/9 17:25
+ * @return: java.lang.String
+ * @throws: java.lang.Exception
+ * @modificed by:
+ */
+ public static String createFileKey(String path, String fileName) {
+ String fullPath = FilenameUtils.normalize(FilenameUtils.concat(path, fileName), true);
+ log.debug(path + "/" + fileName + "->" + fullPath);
+ return fullPath;
+ }
+
+
+ public static void main(String[] args) {
+ System.out.println(createFileKey("subprefix/","fiel.xml"));
+ }
+
+}
diff --git a/starter-demos/starter-sample/src/main/resources/application.yml b/starter-demos/starter-sample/src/main/resources/application.yml
index 6b07f6abea334f222f00019320bc67a69c60c166..ea9c8b1ff134c8fed233bf1fca06bb4cf9526c85 100644
--- a/starter-demos/starter-sample/src/main/resources/application.yml
+++ b/starter-demos/starter-sample/src/main/resources/application.yml
@@ -13,17 +13,12 @@ gsean.tencent.oss:
# endPoint: http://oss-cn-chengdu.aliyuncs.com
---
-gsean.oss:
-# accessKeyId: AKIDNXR4TbT4PUIp78sKVQ4RXNvDF4exzjDQ
-# secret: xd2A1bvxiCOL1RaT5QTGlzwc2A1bw0nI
- accessKeyId: LTAI4G28ijo7sGUmidu9S5qB
- secret: H5Ba1UaYXO01DBKkEmGyLVDxagPzFL
- enabled: true
-# type: tencent
- type: aliyun
- aliyun:
- endPoint: http://oss-cn-chengdu.aliyuncs.com
-
-# tencent:
-# region: ap-chengdu
-
+gsean:
+ oss:
+ type: aliyun
+ access-key-id: LTAI4G28ijo7sGUmidu9S5qB
+ secret: H5Ba1UaYXO01DBKkEmGyLVDxagPzFL
+ aliyun:
+ endPoint: http://oss-cn-chengdu.aliyuncs.com
+ bucket-name: common-file-test
+ prefix: /test1
diff --git a/starter-demos/starter-sample/src/test/java/com/gsean/starter/sample/StarterSampleAppTest.java b/starter-demos/starter-sample/src/test/java/com/gsean/starter/sample/StarterSampleAppTest.java
index 56ee33065a21f3bddc1c32a7957e2b9905d7befc..6939dc83d10ab22d97052a94257ecf2260cfec72 100644
--- a/starter-demos/starter-sample/src/test/java/com/gsean/starter/sample/StarterSampleAppTest.java
+++ b/starter-demos/starter-sample/src/test/java/com/gsean/starter/sample/StarterSampleAppTest.java
@@ -27,6 +27,7 @@ public class StarterSampleAppTest {
private final static String TENCENT_BUCKET="common-file-tencent-1302654654";
+ private final static String ALIYUN_BUCKET="common-file-test";
@Autowired
@@ -48,13 +49,13 @@ public class StarterSampleAppTest {
@Test
public void test3(){
// System.out.println(ossService.exsistBucket("common-file-tencent-1302654654"));
- System.out.println(ossService.exsistBucket("common-file-test"));
+ System.out.println(ossService.exsistBucket(ALIYUN_BUCKET));
}
@Test
public void testD(){
- String upload = ossService.upload(TENCENT_BUCKET, "",
+ String upload = ossService.upload(ALIYUN_BUCKET, "/test2",
new File("D:\\tmp\\logs\\running.2021-11-24.log"));
System.out.println(upload);
}