pull/2/head
三歪 3 years ago
commit bf7c500d82

@ -0,0 +1,44 @@
## 01、项目介绍
austin项目**核心功能**:发送消息
![](https://tva1.sinaimg.cn/large/008i3skNgy1gvztdk1w2wj30ky0p8759.jpg)
**项目出现意义**:只要公司内有发送消息的需求,都应该要有类似`austin`的项目,对各类消息进行统一发送处理。这有利于对功能的收拢,以及提高业务需求开发的效率
![](https://tva1.sinaimg.cn/large/008i3skNgy1gvzz1vifljj31vc0u07dr.jpg)
## 02、项目流程图
austin项目**核心流程**`austin-api`接收到发送消息请求,直接将请求进`MQ`。`austin-handler`消费`MQ`消息后由各类消息的Handler进行发送处理
![](https://tva1.sinaimg.cn/large/008i3skNgy1gvzwltzsdfj31ku0u0q5r.jpg)
**Question 1** 为什么发个消息需要MQ
**Answer 1**发送消息实际上是调用各个服务提供的API假设某消息的服务超时`austin-api`如果是直接调用服务,那存在**超时**风险拖垮整个接口性能。MQ在这是为了做异步和解耦并且在一定程度上抗住业务流量。
**Question 2**`austin-stream`和`austin-datahourse`的作用?
**Answer 2**`austin-handler`在发送消息的过程中会做些**通用业务处理**以及**发送消息**这个过程会产生大量的日志数据。日志数据会被收集至MQ由`austin-stream`流式处理模块进行消费并最后将数据写入至`austin-datahourse`
**Question 3**`austin-admin`和`austin-cron`的作用?
**Answer 3**`autsin-admin`是`austin`项目的**管理后台**,负责管理消息以及查看消息下发的情况。业务方可根据通过`austin-admin`管理后台直接**定时**发送消息,而`austin-cron`就是承载着定时任务的工作了。
## 03、项目技术架构图
2021-11~2021-12实现功能
![](https://tva1.sinaimg.cn/large/008i3skNgy1gvzx4f1iwoj31le0rs0uy.jpg)
实现功能所需引入的技术栈:
![](https://tva1.sinaimg.cn/large/008i3skNgy1gvzxrppbb0j30ym0iaq8v.jpg)
未完待续

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>austin</artifactId>
<groupId>com.java3y.austin</groupId>
<version>0.0.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>austin-common</artifactId>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>

@ -0,0 +1,26 @@
package com.java3y.austin.pojo;
import lombok.Builder;
import lombok.Data;
import java.util.Set;
/**
* @author 3y
* @date 2021/11/4
*
*/
@Data
@Builder
public class SmsParam {
/**
*
*/
private Set<String> phones;
/**
*
*/
private String content;
}

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>austin</artifactId>
<groupId>com.java3y.austin</groupId>
<version>0.0.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>austin-handler</artifactId>
<dependencies>
<dependency>
<groupId>com.java3y.austin</groupId>
<artifactId>austin-common</artifactId>
<version>0.0.2</version>
</dependency>
<dependency>
<groupId>com.java3y.austin</groupId>
<artifactId>austin-support</artifactId>
<version>0.0.2</version>
</dependency>
</dependencies>
</project>

@ -0,0 +1,97 @@
package com.java3y.austin.script;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharPool;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.java3y.austin.pojo.SmsParam;
import com.java3y.austin.utils.OkHttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author 3y
* @date 2021/11/4
* <p>
* https://cloud.tencent.com/document/api/382/55981
*/
@Slf4j
@Service
public class TencentSmsScript {
@Autowired
private OkHttpUtils okHttpUtils;
private static final String URL = "https://sms.tencentcloudapi.com/";
private static final String ACTION = "SendSms";
private static final String VERSION = "2021-01-11";
private static final String SMS_SDK_APP_ID = "1400592125";
private static final String TEMPLATE_ID = "1182097";
private static final String SIGN_NAME = "Java3y公众号";
private static final List<String> REGION = Arrays.asList("ap-beijing", "ap-guangzhou", "ap-nanjing");
/**
*
*/
private static final String AUTHORIZATION_SIGN = "TC3-HMAC-SHA256";
private static final String CREDENTIAL = "Credential=AKIDEXAMPLE";
private static final String service = "sms";
private static final String TC3_REQUEST = "tc3_request";
private static final String SIGNED_HEADERS = "SignedHeaders=content-type;host";
public String send(SmsParam smsParam) {
Map<String, String> header = getHeader();
Map<String, Object> params = getParams(smsParam);
String paramsJSON = JSON.toJSONString(params);
String result = okHttpUtils.doPostJsonWithHeaders(URL, paramsJSON, header);
return result;
}
private Map<String, Object> getParams(SmsParam smsParam) {
HashMap<String, Object> params = new HashMap<>();
int phoneSize = smsParam.getPhones().size() - 1;
int paramSize = Arrays.asList(smsParam.getContent()).size() - 1;
// params.put("PhoneNumberSet", CollUtil.join(smsParam.getPhones(), StrUtil.COMMA));
params.put("PhoneNumberSet."+phoneSize, JSON.toJSONString(smsParam.getPhones()));
params.put("SmsSdkAppId", SMS_SDK_APP_ID);
params.put("TemplateId", TEMPLATE_ID);
params.put("SignName", SIGN_NAME);
params.put("TemplateParamSet."+paramSize, JSON.toJSONString(Arrays.asList(smsParam.getContent())));
params.put("SessionContext", IdUtil.simpleUUID());
return params;
}
private Map<String, String> getHeader() {
HashMap<String, String> headers = new HashMap<>();
headers.put("X-TC-Action", ACTION);
headers.put("X-TC-Version", VERSION);
headers.put("X-TC-Region", REGION.get(RandomUtil.randomInt(REGION.size())));
headers.put("X-TC-Timestamp", String.valueOf(DateUtil.currentSeconds()));
return headers;
}
}

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>austin</artifactId>
<groupId>com.java3y.austin</groupId>
<version>0.0.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>austin-service-api-impl</artifactId>
</project>

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>austin</artifactId>
<groupId>com.java3y.austin</groupId>
<version>0.0.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>austin-service-api</artifactId>
</project>

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>austin</artifactId>
<groupId>com.java3y.austin</groupId>
<version>0.0.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>austin-support</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>

@ -0,0 +1,87 @@
package com.java3y.austin.config;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.net.ssl.*;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;
/**
* @author 3y
* @date 2021/11/4
*/
@Configuration
public class OkHttpConfiguration {
@Value("${ok.http.connect-timeout}")
private Integer connectTimeout;
@Value("${ok.http.read-timeout}")
private Integer readTimeout;
@Value("${ok.http.write-timeout}")
private Integer writeTimeout;
@Value("${ok.http.max-idle-connections}")
private Integer maxIdleConnections;
@Value("${ok.http.keep-alive-duration}")
private Long keepAliveDuration;
@Bean
public OkHttpClient okHttpClient() {
return new OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory(), x509TrustManager())
.retryOnConnectionFailure(false)
.connectionPool(pool())
.connectTimeout(connectTimeout, TimeUnit.SECONDS)
.readTimeout(readTimeout, TimeUnit.SECONDS)
.writeTimeout(writeTimeout,TimeUnit.SECONDS)
.hostnameVerifier((hostname, session) -> true)
.build();
}
@Bean
public X509TrustManager x509TrustManager() {
return new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
}
@Bean
public SSLSocketFactory sslSocketFactory() {
try {
// 信任任何链接
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{x509TrustManager()}, new SecureRandom());
return sslContext.getSocketFactory();
} catch (NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
return null;
}
@Bean
public ConnectionPool pool() {
return new ConnectionPool(maxIdleConnections, keepAliveDuration, TimeUnit.SECONDS);
}
}

@ -0,0 +1,195 @@
package com.java3y.austin.utils;
import cn.hutool.core.map.MapUtil;
import com.google.common.base.Throwables;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
import java.util.Map;
/**
* @author 3y
* @date 2021/11/4
*/
@Slf4j
@Component
public class OkHttpUtils {
private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
private static final MediaType XML = MediaType.parse("application/xml; charset=utf-8");
@Autowired
private OkHttpClient okHttpClient;
/**
* get
*
* @param url url
* @return string
*/
public String doGet(String url) {
return doGet(url, null, null);
}
/**
* get
*
* @param url url
* @param params map
* @return string
*/
public String doGet(String url, Map<String, String> params) {
return doGet(url, params, null);
}
/**
* get
*
* @param url url
* @param headers {k1, v1 k2, v2, ...}
* @return string
*/
public String doGetWithHeaders(String url, Map<String,String> headers) {
return doGet(url, null, headers);
}
/**
* get
*
* @param url url
* @param params map
* @param headers {k1, v1 k2, v2, ...}
* @return string
*/
public String doGet(String url, Map<String, String> params, Map<String,String> headers) {
StringBuilder sb = new StringBuilder(url);
if (params != null && params.keySet().size() > 0) {
boolean firstFlag = true;
for (String key : params.keySet()) {
if (firstFlag) {
sb.append("?").append(key).append("=").append(params.get(key));
firstFlag = false;
} else {
sb.append("&").append(key).append("=").append(params.get(key));
}
}
}
Request.Builder builder = getBuilderWithHeaders(headers);
Request request = builder.url(sb.toString()).build();
log.info("do get request and url[{}]", sb.toString());
return execute(request);
}
/**
* post
*
* @param url url
* @param params map
* @param headers {k1, v1 k2, v2, ...}
* @return string
*/
public String doPost(String url, Map<String, String> params, Map<String,String> headers) {
FormBody.Builder formBuilder = new FormBody.Builder();
if (params != null && params.keySet().size() > 0) {
for (String key : params.keySet()) {
formBuilder.add(key, params.get(key));
}
}
Request.Builder builder = getBuilderWithHeaders(headers);
Request request = builder.url(url).post(formBuilder.build()).build();
log.info("do post request and url[{}]", url);
return execute(request);
}
/**
* request Builder
*
* @param headers {k1, v1 k2, v2, ...}
* @return
*/
private Request.Builder getBuilderWithHeaders(Map<String,String> headers) {
Request.Builder builder = new Request.Builder();
if (!MapUtil.isEmpty(headers)) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
builder.addHeader(entry.getKey(), entry.getValue());
}
}
return builder;
}
/**
* post , json
*
* @param url url
* @param json , json
* @return string
*/
public String doPostJson(String url, String json) {
log.info("do post request and url[{}]", url);
return executePost(url, json, JSON, null);
}
/**
* post , json
*
* @param url url
* @param json , json
* @param headers {k1, v1 k2, v2, ...}
* @return string
*/
public String doPostJsonWithHeaders(String url, String json, Map<String, String> headers) {
log.info("do post request and url[{}]", url);
return executePost(url, json, JSON, headers);
}
/**
* post , xml
*
* @param url url
* @param xml , xml
* @return string
*/
public String doPostXml(String url, String xml) {
log.info("do post request and url[{}]", url);
return executePost(url, xml, XML, null);
}
private String executePost(String url, String data, MediaType contentType, Map<String,String> headers) {
RequestBody requestBody = RequestBody.create(data.getBytes(StandardCharsets.UTF_8), contentType);
Request.Builder builder = getBuilderWithHeaders(headers);
Request request = builder.url(url).post(requestBody).build();
return execute(request);
}
private String execute(Request request) {
Response response = null;
try {
response = okHttpClient.newCall(request).execute();
if (response.isSuccessful()) {
return response.body().string();
}
} catch (Exception e) {
log.error(Throwables.getStackTraceAsString(e));
} finally {
if (response != null) {
response.close();
}
}
return "";
}
}

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>austin</artifactId>
<groupId>com.java3y.austin</groupId>
<version>0.0.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>austin-web</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.java3y.austin</groupId>
<artifactId>austin-handler</artifactId>
<version>0.0.2</version>
</dependency>
</dependencies>
</project>

@ -0,0 +1,39 @@
package com.java3y.austin;
import cn.hutool.setting.SettingUtil;
import com.java3y.austin.pojo.SmsParam;
import com.java3y.austin.script.TencentSmsScript;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.HashSet;
@SpringBootApplication
@RestController
public class AustinApplication {
@Autowired
private TencentSmsScript tencentSmsScript;
public static void main(String[] args) {
SpringApplication.run(AustinApplication.class, args);
}
@GetMapping("/hello")
public String hello() {
SmsParam smsParam = SmsParam.builder()
.phones(new HashSet<>(Arrays.asList("13719193845")))
.content("3333")
.build();
return tencentSmsScript.send(smsParam);
}
}

@ -0,0 +1,6 @@
# ok http配置信息
ok.http.connect-timeout=30
ok.http.read-timeout=30
ok.http.write-timeout=30
ok.http.max-idle-connections=200
ok.http.keep-alive-duration=300

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="10 seconds">
<contextName>austin</contextName>
<!-- 设置日志输出路径 可以使“${}”来使用变量。TODO 这里后面是需要读配置的 -->
<property name="log.path" value="logs"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期%thread表示线程名%-5level级别从左显示5个字符宽度%msg日志消息%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 时间滚动输出 level为 INFO 日志 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/austin-info.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志归档路径以及格式 -->
<fileNamePattern>${log.path}/logs/austin-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>1000MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 ERROR 日志 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/austin-error.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/austin-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>1000MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录ERROR级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<root level="info">
<!-- TODO console打印后面可以只针对dev环境的 -->
<appender-ref ref="CONSOLE"/>
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="ERROR_FILE"/>
</root>
</configuration>

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<modules>
<module>austin-web</module>
<module>austin-service-api</module>
<module>austin-service-api-impl</module>
<module>austin-common</module>
<module>austin-support</module>
<module>austin-handler</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
<relativePath/>
</parent>
<groupId>com.java3y.austin</groupId>
<artifactId>austin</artifactId>
<version>0.0.2</version>
<name>austin</name>
<description>austin-message</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<!--mysql驱动包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</version>
</dependency>
<!--hutool工具包-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.15</version>
</dependency>
<!--guava工具包-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
<!--common工具包-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
<!--http库-->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.2</version>
</dependency>
<!--fastjson包-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Loading…
Cancel
Save