大家好,本文是基于 SpringBoot 从0搭建一个企业级开发项目,基于SpringBoot 的项目,并集成MyBatis-Plus、Druid、Logback 等主流技术。希望对大家有所帮助~
随着技术栈的不断更新迭代,我们需要快速的在企业中搭建一个项目,并使用市面上前沿且稳定的技术栈。本期将跟大家一起从0到1搭建一个基于SpringBoot 的项目,并集成MyBatis-Plus、Druid、Logback 等主流技术。后续也会整合 Docker,自定义构建 Docker 项目,实现 Docker Compose 部署。源码附在文末。
创建一个名称为 my-project-dependencies
的项目,该项目负责统一的依赖管理
pom.xml
内容如下:
<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">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.3.9.RELEASEversion>
parent>
<groupId>com.micromaplegroupId>
<artifactId>my-project-dependenciesartifactId>
<version>1.0.0-SNAPSHOTversion>
<packaging>pompackaging>
<name>my-project-dependenciesname>
<properties>
<java.version>1.8java.version>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<spring-boot-alibaba-druid.version>1.2.11spring-boot-alibaba-druid.version>
<spring-boot-mybatis-plus.version>3.5.2spring-boot-mybatis-plus.version>
<mysql.version>8.0.30mysql.version>
<lombok.version>1.18.18lombok.version>
<guava.version>25.1-jreguava.version>
<jackson.version>2.11.4jackson.version>
<apache-httpclient.version>4.5.5apache-httpclient.version>
<collections.version>3.2.1collections.version>
<poi.version>3.10-FINALpoi.version>
<hutool.version>5.3.7hutool.version>
<velocity.version>2.3velocity.version>
<hibernate-validator.version>6.0.15.Finalhibernate-validator.version>
<log4j2.version>2.16.0log4j2.version>
<mybatis-plus-generator.version>3.5.1mybatis-plus-generator.version>
properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>${spring-boot-alibaba-druid.version}version>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>${spring-boot-mybatis-plus.version}version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>${mysql.version}version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>${lombok.version}version>
dependency>
<dependency>
<groupId>com.google.guavagroupId>
<artifactId>guavaartifactId>
<version>${guava.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>${jackson.version}version>
dependency>
<dependency>
<groupId>commons-collectionsgroupId>
<artifactId>commons-collectionsartifactId>
<version>${collections.version}version>
dependency>
<dependency>
<groupId>org.apache.httpcomponentsgroupId>
<artifactId>httpclientartifactId>
<version>${apache-httpclient.version}version>
dependency>
<dependency>
<groupId>org.apache.httpcomponentsgroupId>
<artifactId>fluent-hcartifactId>
<version>${apache-httpclient.version}version>
dependency>
<dependency>
<groupId>org.apache.httpcomponentsgroupId>
<artifactId>httpmimeartifactId>
<version>${apache-httpclient.version}version>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxmlartifactId>
<version>${poi.version}version>
dependency>
<dependency>
<groupId>cn.hutoolgroupId>
<artifactId>hutool-allartifactId>
<version>${hutool.version}version>
dependency>
<dependency>
<groupId>org.apache.velocitygroupId>
<artifactId>velocity-engine-coreartifactId>
<version>${velocity.version}version>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-generatorartifactId>
<version>${mybatis-plus-generator.version}version>
dependency>
dependencies>
dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<configuration>
<showWarnings>trueshowWarnings>
configuration>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-jar-pluginartifactId>
<configuration>
<archive>
<addMavenDescriptor>falseaddMavenDescriptor>
archive>
configuration>
<executions>
<execution>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>trueaddDefaultImplementationEntries>
<addDefaultSpecificationEntries>trueaddDefaultSpecificationEntries>
<addClasspath>trueaddClasspath>
manifest>
archive>
configuration>
execution>
executions>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-resources-pluginartifactId>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-install-pluginartifactId>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-clean-pluginartifactId>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-antrun-pluginartifactId>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-dependency-pluginartifactId>
plugin>
plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-javadoc-pluginartifactId>
<executions>
<execution>
<phase>prepare-packagephase>
<goals>
<goal>jargoal>
goals>
execution>
executions>
plugin>
<plugin>
<groupId>net.alchim31.mavengroupId>
<artifactId>yuicompressor-maven-pluginartifactId>
<version>1.5.1version>
<executions>
<execution>
<phase>prepare-packagephase>
<goals>
<goal>compressgoal>
goals>
execution>
executions>
<configuration>
<encoding>UTF-8encoding>
<jswarn>falsejswarn>
<nosuffix>truenosuffix>
<linebreakpos>30000linebreakpos>
<force>trueforce>
<includes>
<include>**/*.jsinclude>
<include>**/*.cssinclude>
includes>
<excludes>
<exclude>**/*.min.jsexclude>
<exclude>**/*.min.cssexclude>
excludes>
configuration>
plugin>
plugins>
pluginManagement>
<resources>
<resource>
<directory>src/main/javadirectory>
<excludes>
<exclude>**/*.javaexclude>
excludes>
resource>
<resource>
<directory>src/main/resourcesdirectory>
resource>
resources>
build>
project>
创建一个名称为 my-project-common
的项目,该项目负责通用的类库以及工具类
pom.xml
内容如下:
<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">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>com.micromaplegroupId>
<artifactId>my-project-dependenciesartifactId>
<version>1.0.0-SNAPSHOTversion>
<relativePath>../my-project-dependencies/pom.xmlrelativePath>
parent>
<artifactId>my-project-commonartifactId>
<packaging>jarpackaging>
<name>my-project-commonname>
<dependencies>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-lang3artifactId>
dependency>
<dependency>
<groupId>cn.hutoolgroupId>
<artifactId>hutool-allartifactId>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
dependency>
<dependency>
<groupId>com.google.guavagroupId>
<artifactId>guavaartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
<dependency>
<groupId>commons-collectionsgroupId>
<artifactId>commons-collectionsartifactId>
dependency>
<dependency>
<groupId>org.apache.httpcomponentsgroupId>
<artifactId>httpclientartifactId>
dependency>
<dependency>
<groupId>org.apache.httpcomponentsgroupId>
<artifactId>fluent-hcartifactId>
dependency>
<dependency>
<groupId>org.apache.httpcomponentsgroupId>
<artifactId>httpmimeartifactId>
dependency>
dependencies>
project>
创建 src/main/java
目录后,创建包名,包名为:com.micromaple.my.project.common
此工程是放一些通用的类库或者是工具类之类的。
创建常量包constant
。
通用常量返回状态码HttpStatus
package com.micromaple.my.project.common.constant;
/**
* 返回状态码
* Title: HttpStatus
* Description:
*
* @author Micromaple
*/
public class HttpStatus {
/**
* 操作成功
*/
public static final int SUCCESS = 200;
/**
* 对象创建成功
*/
public static final int CREATED = 201;
/**
* 请求已经被接受
*/
public static final int ACCEPTED = 202;
/**
* 操作已经执行成功,但是没有返回数据
*/
public static final int NO_CONTENT = 204;
/**
* 资源已被移除
*/
public static final int MOVED_PERM = 301;
/**
* 重定向
*/
public static final int SEE_OTHER = 303;
/**
* 资源没有被修改
*/
public static final int NOT_MODIFIED = 304;
/**
* 参数列表错误(缺少,格式不匹配)
*/
public static final int BAD_REQUEST = 400;
/**
* 未授权
*/
public static final int UNAUTHORIZED = 401;
/**
* 访问受限,授权过期
*/
public static final int FORBIDDEN = 403;
/**
* 资源,服务未找到
*/
public static final int NOT_FOUND = 404;
/**
* 不允许的http方法
*/
public static final int BAD_METHOD = 405;
/**
* 资源冲突,或者资源被锁
*/
public static final int CONFLICT = 409;
/**
* 不支持的数据,媒体类型
*/
public static final int UNSUPPORTED_TYPE = 415;
/**
* 系统内部错误
*/
public static final int ERROR = 500;
/**
* 接口未实现
*/
public static final int NOT_IMPLEMENTED = 501;
}
创建数据传输包dto
。
通用数据传输返回结果BaseResult
package com.micromaple.my.project.common.dto;
import com.micromaple.my.project.common.constant.HttpStatus;
import java.util.HashMap;
/**
* 返回结果
* Title: BaseResult
* Description:
*
* @author Micromaple
*/
public class BaseResult extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
/**
* 状态码
*/
public static final String CODE_TAG = "code";
/**
* 返回内容
*/
public static final String MSG_TAG = "msg";
/**
* 数据对象
*/
public static final String DATA_TAG = "data";
/**
* 初始化一个新创建的 BaseResult 对象,使其表示一个空消息。
*/
public BaseResult() {
}
/**
* 初始化一个新创建的 BaseResult 对象
*
* @param code 状态码
* @param msg 返回内容
*/
public BaseResult(int code, String msg) {
super.put(CODE_TAG, code);
super.put(MSG_TAG, msg);
}
/**
* 初始化一个新创建的 BaseResult 对象
*
* @param code 状态码
* @param msg 返回内容
* @param data 数据对象
*/
public BaseResult(int code, String msg, Object data) {
super.put(CODE_TAG, code);
super.put(MSG_TAG, msg);
super.put(DATA_TAG, data);
}
/**
* 返回成功消息
*
* @return 成功消息
*/
public static BaseResult success() {
return BaseResult.success("操作成功");
}
/**
* 返回成功数据
*
* @return 成功消息
*/
public static BaseResult success(Object data) {
return BaseResult.success("操作成功", data);
}
/**
* 返回成功消息
*
* @param msg 返回内容
* @return 成功消息
*/
public static BaseResult success(String msg) {
return BaseResult.success(msg, null);
}
/**
* 返回成功消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 成功消息
*/
public static BaseResult success(String msg, Object data) {
return new BaseResult(HttpStatus.SUCCESS, msg, data);
}
/**
* 返回错误消息
*
* @return
*/
public static BaseResult error() {
return BaseResult.error("操作失败");
}
/**
* 返回错误消息
*
* @param msg 返回内容
* @return 警告消息
*/
public static BaseResult error(String msg) {
return BaseResult.error(msg, null);
}
/**
* 返回错误消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 警告消息
*/
public static BaseResult error(String msg, Object data) {
return new BaseResult(HttpStatus.ERROR, msg, data);
}
/**
* 返回错误消息
*
* @param code 状态码
* @param msg 返回内容
* @return 警告消息
*/
public static BaseResult error(int code, String msg) {
return new BaseResult(code, msg, null);
}
}
创建工具类包utils
。
通用Jackson
工具类MapperUtils
package com.micromaple.my.project.common.utils;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Jackson 工具类
* Title: MapperUtils
* Description:
*
* @author Micromaple
*/
public class MapperUtils {
private final static ObjectMapper objectMapper = new ObjectMapper();
public static ObjectMapper getInstance() {
return objectMapper;
}
/**
* 转换为 JSON 字符串
*
* @param obj
* @return
* @throws Exception
*/
public static String obj2json(Object obj) {
try {
return objectMapper.writeValueAsString(obj);
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
/**
* 转换为 JSON 字符串,忽略空值
*
* @param obj
* @return
* @throws Exception
*/
public static String obj2jsonIgnoreNull(Object obj) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
return mapper.writeValueAsString(obj);
}
/**
* 转换为 JavaBean
*
* @param jsonString
* @param clazz
* @return
* @throws Exception
*/
public static <T> T json2pojo(String jsonString, Class<T> clazz){
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
try{
return objectMapper.readValue(jsonString, clazz);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
/**
* 字符串转换为 Map
*
* @param jsonString
* @return
* @throws Exception
*/
public static <T> Map<String, Object> json2map(String jsonString){
if(StringUtils.isBlank(jsonString)) return null;
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
try {
return mapper.readValue(jsonString, Map.class);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 深度转换 JSON 成 Map
*
* @param json
* @return
*/
public static Map<String, Object> json2mapDeeply(String json) throws Exception {
return json2MapRecursion(json, objectMapper);
}
/**
* 把 JSON 解析成 List,如果 List 内部的元素存在 jsonString,继续解析
*
* @param json
* @param mapper 解析工具
* @return
* @throws Exception
*/
private static List<Object> json2ListRecursion(String json, ObjectMapper mapper) throws Exception {
if (json == null) {
return null;
}
List<Object> list = mapper.readValue(json, List.class);
for (Object obj : list) {
if (obj != null && obj instanceof String) {
String str = (String) obj;
if (str.startsWith("[")) {
obj = json2ListRecursion(str, mapper);
} else if (obj.toString().startsWith("{")) {
obj = json2MapRecursion(str, mapper);
}
}
}
return list;
}
/**
* 把 JSON 解析成 Map,如果 Map 内部的 Value 存在 jsonString,继续解析
*
* @param json
* @param mapper
* @return
* @throws Exception
*/
private static Map<String, Object> json2MapRecursion(String json, ObjectMapper mapper) throws Exception {
if (json == null) {
return null;
}
Map<String, Object> map = mapper.readValue(json, Map.class);
for (Map.Entry<String, Object> entry : map.entrySet()) {
Object obj = entry.getValue();
if (obj != null && obj instanceof String) {
String str = ((String) obj);
if (str.startsWith("[")) {
List<?> list = json2ListRecursion(str, mapper);
map.put(entry.getKey(), list);
} else if (str.startsWith("{")) {
Map<String, Object> mapRecursion = json2MapRecursion(str, mapper);
map.put(entry.getKey(), mapRecursion);
}
}
}
return map;
}
/**
* 将 JSON 数组转换为集合
*
* @param jsonArrayStr
* @param clazz
* @return
* @throws Exception
*/
public static <T> List<T> json2list(String jsonArrayStr, Class<T> clazz) throws Exception {
JavaType javaType = getCollectionType(ArrayList.class, clazz);
List<T> list = (List<T>) objectMapper.readValue(jsonArrayStr, javaType);
return list;
}
/**
* 获取泛型的 Collection Type
*
* @param collectionClass 泛型的Collection
* @param elementClasses 元素类
* @return JavaType Java类型
* @since 1.0
*/
public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
}
/**
* 将 Map 转换为 JavaBean
*
* @param map
* @param clazz
* @return
*/
public static <T> T map2pojo(T map, Class<T> clazz) {
return objectMapper.convertValue(map, clazz);
}
/**
* 将 Map 转换为 JSON
*
* @param map
* @return
*/
public static String mapToJson(Map map) {
try {
return objectMapper.writeValueAsString(map);
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
/**
* 将 JSON 对象转换为 JavaBean
*
* @param obj
* @param clazz
* @return
*/
public static <T> T obj2pojo(Object obj, Class<T> clazz) {
return objectMapper.convertValue(obj, clazz);
}
}
HttpClient
工具类
package com.micromaple.my.project.common.utils;
import com.google.common.collect.Maps;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
/**
* HttpClient 工具类
* Title: HttpClientUtils
* Description:
*
* @author Micromaple
*/
public class HttpClientUtils {
public static final String GET = "get";
public static final String POST = "post";
public static final String REQUEST_HEADER_CONNECTION = "keep-alive";
public static final String REQUEST_HEADER_CONTENTTYPE = "application/json;charset=UTF-8";
public static final String REQUEST_HEADER_CONSUMES = "application/json";
//设置连接超时时间,单位毫秒。
public static final int CONNECTTIMEOUT = 18000;
//请求获取数据的超时时间,单位毫秒。 如果访问一个接口,多少时间内无法返回数据,就直接放弃此次调用。
public static final int SOCKETTIMEOUT = 60000;
//设置从connect Manager获取Connection 超时时间,单位毫秒
public static final int CONNECTIONREQUESTTIMEOUT = 18000;
/**
* GET 请求
*
* @param url 请求地址
* @return
*/
public static String doGet(String url) {
return createRequest(url, GET, null, false, null, 0);
}
/**
* GET 请求 - 代理
*
* @param url 请求地址
* @param useProxy 是否需要代理
* @param proxyHost 代理地址
* @param proxyPort 代理端口
* @return
*/
public static String doGet(String url, boolean useProxy, String proxyHost, int proxyPort) {
return createRequest(url, GET, null, useProxy, proxyHost, proxyPort);
}
/**
* GET 请求
*
* @param url 请求地址
* @param cookie cookie
* @return
*/
public static String doGet(String url, String cookie) {
return createRequest(url, GET, cookie, false, null, 0);
}
/**
* POST 请求
*
* @param url 请求地址
* @param params 请求参数(可选)
* @return
*/
public static String doPost(String url, BasicNameValuePair... params) {
return createRequest(url, POST, null, false, null, 0, params);
}
/**
* POST 请求 - 代理
*
* @param url 请求地址
* @param useProxy 是否需要代理
* @param proxyHost 代理地址
* @param proxyPort 代理端口
* @param params 请求参数(可选)
* @return
*/
public static String doPost(String url, boolean useProxy, String proxyHost, int proxyPort, BasicNameValuePair... params) {
return createRequest(url, POST, null, useProxy, proxyHost, proxyPort, params);
}
/**
* POST 请求
*
* @param url 请求地址
* @param cookie cookie
* @param params 请求参数(可选)
* @return
*/
public static String doPost(String url, String cookie, BasicNameValuePair... params) {
return createRequest(url, POST, cookie, false, null, 0, params);
}
/**
* POST 请求 - 文本 方式
*
* @param url 请求地址
* @param jsonBodyParams 请求参数 (JSON 格式)
* @return
*/
public static String doPostForRow(String url, String jsonBodyParams) {
return createRequestForRow(url, jsonBodyParams, false, null, 0);
}
/**
* POST 请求 - 文本 方式 - 代理
*
* @param url 请求地址
* @param jsonBodyParams 请求参数
* @param useProxy 是否需要代理
* @param proxyHost 代理地址
* @param proxyPort 代理端口
* @return
*/
public static String doPostForRow(String url, String jsonBodyParams, boolean useProxy, String proxyHost, int proxyPort) {
return createRequestForRow(url, jsonBodyParams, useProxy, proxyHost, proxyPort);
}
/**
* POST 请求
*
* @param url 请求地址
* @param pMap 请求参数
* @param useProxy 是否需要代理
* @param proxyHost 代理地址
* @param proxyPort 代理端口
* @return
*/
public static Map<String, Object> doPost(String url, Map<String, String> pMap, boolean useProxy, String proxyHost, int proxyPort) {
String str = HttpClientUtils.doPost(url, useProxy, proxyHost, proxyPort, generatNameValuePair(pMap));
Map<String, Object> rtnMap = Maps.newHashMap();
try {
rtnMap = MapperUtils.json2map(str);
} catch (Exception e) {
e.printStackTrace();
}
return rtnMap;
}
/**
* 创建请求
*
* @param url 请求地址
* @param requestMethod 请求方式 GET/POST
* @param cookie cookie
* @param useProxy 是否需要代理
* @param proxyHost 代理地址
* @param proxyPort 代理端口
* @param params 请求参数 仅限于 POST 请求用
* @return
*/
private static String createRequest(String url, String requestMethod, String cookie, boolean useProxy, String proxyHost, int proxyPort, BasicNameValuePair... params) {
//创建 HTTPClient 客户端
// CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpClient httpClient = getHttpClient(useProxy, proxyHost, proxyPort);
String result = null;
try {
//请求结果
result = null;
//请求方式
HttpGet httpGet = null;
HttpPost httpPost = null;
//响应
CloseableHttpResponse httpResponse = null;
// GET 请求
if (GET.equals(requestMethod)) {
httpGet = new HttpGet(url);
httpGet.setHeader("Connection", REQUEST_HEADER_CONNECTION);
httpGet.setHeader("Cookie", cookie);
httpResponse = httpClient.execute(httpGet);
}
// POST 请求
else if (POST.equals(requestMethod)) {
httpPost = new HttpPost(url);
httpPost.setHeader("Connection", REQUEST_HEADER_CONNECTION);
httpPost.setHeader("Cookie", cookie);
//有参数进来
if (params != null && params.length > 0) {
httpPost.setEntity(new UrlEncodedFormEntity(Arrays.asList(params), "UTF-8"));
}
httpResponse = httpClient.execute(httpPost);
}
HttpEntity httpEntity = httpResponse.getEntity();
result = EntityUtils.toString(httpEntity);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (httpClient != null) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
/**
* 创建 ROW POST 请求
*
* @param url 请求地址
* @param jsonBodyParam 请求参数 (JSON 格式)
* @param useProxy 是否需要代理
* @param proxyHost 代理地址
* @param proxyPort 代理端口
* @return
*/
private static String createRequestForRow(String url, String jsonBodyParam, boolean useProxy, String proxyHost, int proxyPort) {
//创建 HTTPClient 客户端
// CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpClient httpClient = getHttpClient(useProxy, proxyHost, proxyPort);
String result = null;
try {
//请求结果
result = null;
//请求方式
HttpPost httpPost = null;
//响应
CloseableHttpResponse httpResponse = null;
httpPost = new HttpPost(url);
httpPost.setHeader("Connection", REQUEST_HEADER_CONNECTION);
httpPost.setHeader("Content-Type", REQUEST_HEADER_CONTENTTYPE);
httpPost.setHeader("consumes", REQUEST_HEADER_CONSUMES);
httpPost.setEntity(new StringEntity(jsonBodyParam, "UTF-8"));
httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
result = EntityUtils.toString(httpEntity);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (httpClient != null) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
/**
* 创建 HttpClient 客户端
*
* @param useProxy 是否代理
* @param proxyHost 代理地址
* @param proxyPort 代理端口
* @return
*/
private static CloseableHttpClient getHttpClient(boolean useProxy, String proxyHost, int proxyPort) {
CloseableHttpClient httpClient = null;
if (useProxy) {
//设置代理IP、端口、协议
HttpHost proxy = new HttpHost(proxyHost, proxyPort, "http");
//把代理设置到请求配置
//setConnectTimeout:设置连接超时时间,单位毫秒。
//setConnectionRequestTimeout:设置从connect Manager获取Connection 超时时间,单位毫秒。这个属性是新加的属性,因为目前版本是可以共享连接池的。
//setSocketTimeout:请求获取数据的超时时间,单位毫秒。 如果访问一个接口,多少时间内无法返回数据,就直接放弃此次调用
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setConnectTimeout(CONNECTTIMEOUT)
.setSocketTimeout(SOCKETTIMEOUT)
.setConnectionRequestTimeout(CONNECTIONREQUESTTIMEOUT)
.setProxy(proxy)
.build();
//创建 HTTPClient 客户端
httpClient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
} else {
//setConnectTimeout:设置连接超时时间,单位毫秒。
//setConnectionRequestTimeout:设置从connect Manager获取Connection 超时时间,单位毫秒。这个属性是新加的属性,因为目前版本是可以共享连接池的。
//setSocketTimeout:请求获取数据的超时时间,单位毫秒。 如果访问一个接口,多少时间内无法返回数据,就直接放弃此次调用
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setConnectTimeout(CONNECTTIMEOUT)
.setSocketTimeout(SOCKETTIMEOUT)
.setConnectionRequestTimeout(CONNECTIONREQUESTTIMEOUT)
.build();
//创建 HTTPClient 客户端
httpClient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
}
return httpClient;
}
/**
* MAP类型数组转换成BasicNameValuePair类型
*
* @param properties MAP类型数组
* @return BasicNameValuePair类型数组
*/
private static BasicNameValuePair[] generatNameValuePair(Map<String, String> properties) {
BasicNameValuePair[] basicNameValuePairs = new BasicNameValuePair[properties.size()];
int i = 0;
for (Map.Entry<String, String> entry : properties.entrySet()) {
basicNameValuePairs[i++] = new BasicNameValuePair(entry.getKey(), entry.getValue());
}
return basicNameValuePairs;
}
}
创建一个名称为 my-project-server
的项目,该项目负责实现具体业务,以及提供服务。
pom.xml
内容如下:
<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">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>com.micromaplegroupId>
<artifactId>my-project-dependenciesartifactId>
<version>1.0.0-SNAPSHOTversion>
<relativePath>../my-project-dependencies/pom.xmlrelativePath>
parent>
<artifactId>my-project-serverartifactId>
<packaging>jarpackaging>
<name>my-project-servername>
<dependencies>
<dependency>
<groupId>com.micromaplegroupId>
<artifactId>my-project-commonartifactId>
<version>1.0.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-validationartifactId>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxmlartifactId>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<configuration>
<mainClass>mainClass>
configuration>
plugin>
plugins>
build>
project>
可以使用右侧的Maven
的 +
号来进行项目的托管。
创建 src/main/java
和 src/main/resource
目录
在 src/main/java
目录下创建包名,包名为:com.micromaple.my.project.server
在 src/main/resource
目录下创建application.yml
,内容如下:
# Spring配置
spring:
jackson:
#时间戳统一转换为指定格式
date-format: yyyy-MM-dd HH:mm:ss
# 时区修改为东8区
time-zone: GMT+8
server:
port: 8899
这里使用 Spring 提供的 MyBatis 包扫面注解
package com.micromaple.my.project.server;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan(value = "com.micromaple.my.project.server.mapper")
public class MyProjectServerApplication {
public static void main(String[] args) {
SpringApplication.run(MyProjectServerApplication.class, args);
}
}
在 pom.xml
中的 mainClass 指定该 Application
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<configuration>
<mainClass>com.micromaple.my.project.server.MyProjectServerApplicationmainClass>
configuration>
plugin>
plugins>
build>
在 src/main/resource
目录下创建logback-spring.xml
,内容如下:
<configuration>
<substitutionProperty name="logBase" value="./logs/" />
<substitutionProperty name="logName" value="my-project-server" />
<substitutionProperty name="logPatternExp" value="%date{YYYY-MM-dd HH:mm:ss.SSS} [%-5level] [%thread] %logger{9999} %L -=> %msg%n" />
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${logPatternExp}pattern>
encoder>
appender>
<appender name="rollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logBase}${logName}.logfile>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${logBase}${logName}-%d{yyyy-MM-dd}-%i.zipfileNamePattern>
<maxHistory>180maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>30MBmaxFileSize>
timeBasedFileNamingAndTriggeringPolicy>
rollingPolicy>
<encoder>
<pattern>${logPatternExp}pattern>
encoder>
appender>
<logger name="com.micromaple.my.project.server" level="DEBUG" />
<logger name="org.springframework" level="ERROR" />
<root level="DEBUG">
<appender-ref ref="console" />
<appender-ref ref="rollingFile" />
root>
configuration>
在application.yml
增加配置:
logging:
config: classpath:logback-spring.xml
在 src/main/resource
目录下创建application-druid.yml
,内容如下:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.110.135:3306/my-project?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
username: root
password: 123456
druid:
#连接池配置 初始化连接池的连接数量 大小,最小,最大
initial-size: 5
min-idle: 5
max-active: 20
#配置获取连接等待超时的时间
max-wait: 60000
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 30000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: true
test-on-return: false
# 是否缓存preparedStatement,也就是PSCache 官方建议MySQL下建议关闭 个人建议如果想用SQL防火墙 建议打开
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filter:
stat:
merge-sql: true
slow-sql-millis: 5000
#3.基础监控配置
web-stat-filter:
enabled: true
url-pattern: /*
#设置不统计哪些URL
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
session-stat-enable: true
session-stat-max-count: 100
stat-view-servlet:
enabled: true
# 数据监控访问路径
url-pattern: /druid/*
reset-enable: true
#设置监控页面的登录名和密码
login-username: admin
login-password: admin
allow: 127.0.0.1
在 application.yml
增加配置,内容如下:
# Spring配置
spring:
# 启用指定配置文件
#(文件名需满足application-{profile}.yml的格式)
profiles:
active: druid
application.yml
完整配置如下:
# Spring配置
spring:
jackson:
#时间戳统一转换为指定格式
date-format: yyyy-MM-dd HH:mm:ss
# 时区修改为东8区
time-zone: GMT+8
# 启用指定配置文件
#(文件名需满足application-{profile}.yml的格式)
profiles:
active: druid
server:
port: 8899
logging:
config: classpath:logback-spring.xml
创建一个名称为 my-project-generator
的项目,该项目负责通过数据库自动生成通用的增删改查。
pom.xml
内容如下:
<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">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>com.micromaplegroupId>
<artifactId>my-project-dependenciesartifactId>
<version>1.0.0-SNAPSHOTversion>
<relativePath>../my-project-dependencies/pom.xmlrelativePath>
parent>
<artifactId>my-project-generatorartifactId>
<packaging>jarpackaging>
<name>my-project-generatorname>
<dependencies>
<dependency>
<groupId>com.micromaplegroupId>
<artifactId>my-project-commonartifactId>
<version>1.0.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-mailartifactId>
dependency>
<dependency>
<groupId>org.apache.velocitygroupId>
<artifactId>velocity-engine-coreartifactId>
dependency>
<dependency>
<groupId>org.freemarkergroupId>
<artifactId>freemarkerartifactId>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-generatorartifactId>
dependency>
dependencies>
project>
可以使用右侧的Maven
的 +
号来进行项目的托管。
创建 src/main/java
和 src/main/resource
目录
在 src/main/java
目录下创建包名,包名为:com.micromaple.my.project.generator
。
创建代码生成类,内容如下:
package com.micromaple.my.project.generator;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.keywords.MySqlKeyWordsHandler;
import java.util.Collections;
/**
* 代码生成
* Title: GeneratorApplication
* Description:
*
* @author Micromaple
*/
public class GeneratorApplication {
public static void main(String[] args) {
String projectPath = System.getProperty("user.dir");
String finalProjectPath = projectPath + "/my-project-generator";
// 数据源配置
DataSourceConfig.Builder dataSourceConfig = new DataSourceConfig
.Builder(
"jdbc:mysql://192.168.110.135:3306/my-project?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8",
"root",
"123456")
.dbQuery(new MySqlQuery())
.typeConvert(new MySqlTypeConvert())
.keyWordsHandler(new MySqlKeyWordsHandler());
new StrategyConfig.Builder()
.serviceBuilder()
.formatServiceFileName("%sService")
.formatServiceImplFileName("%sServiceImp")
.build();
FastAutoGenerator.create(dataSourceConfig)
.globalConfig(builder -> {
builder.author("Micromaple") //设置作者
.commentDate("yyyy-MM-dd HH:mm:ss")//注释日期
.outputDir(finalProjectPath + "/src/main/java"); //指定输出目录
})
.packageConfig(builder -> {
builder.parent("com.micromaple.my.project.server")
.moduleName("") // 设置父包模块名
.entity("domain") //设置entity包名
//.other("model.dto") // 设置dto包名
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, finalProjectPath + "/src/main/resources/mapper")); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
builder.addInclude("sys_user") // 设置需要生成的表名
.addTablePrefix("tb_"); // 设置过滤表前缀
builder.entityBuilder().enableLombok();//开启 lombok 模型
builder.entityBuilder().enableTableFieldAnnotation();//开启生成实体时生成字段注解
builder.controllerBuilder().enableRestStyle();//开启生成@RestController 控制器
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
}
}
建表语句:
CREATE TABLE `sys_user` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
`code` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '编号',
`name` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '姓名',
`sex` varchar(2) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '性别',
`age` int DEFAULT NULL COMMENT '年龄',
`birthday` date DEFAULT NULL COMMENT '生日',
`mail` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '邮箱',
`created_date` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_date` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户表'
新增数据:
insert into `sys_user` (`code`, `name`, `sex`, `age`, `birthday`, `mail`, `created_date`, `updated_date`) values('admin','超级管理员','男','18','2004-01-01','[email protected]','2022-09-21 21:48:33',NULL);
执行 GeneratorApplication
类的 main 方法后,可以看到生成的代码,效果如下图:
将其拷贝到my-project-server
工程模块中,完整效果如下:
我们在 my-project-server
工程编写单元测试,测试生成的代码是否可用。
创建 src/test/java
目录,在该目录创建包 com.micromaple.my.project.server.service
;
接着创建测试类 SysUserServiceTest
,内容如下:
package com.micromaple.my.project.server.service;
import com.micromaple.my.project.server.MyProjectServerApplication;
import com.micromaple.my.project.server.domain.SysUser;
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 java.util.List;
@SpringBootTest(classes = MyProjectServerApplication.class)
@RunWith(SpringRunner.class)
public class SysUserServiceTest {
@Autowired
private ISysUserService sysUserService;
/**
* 测试新增
*/
@Test
public void addTest() {
SysUser sysUser = new SysUser();
sysUser.setCode("user");
sysUser.setName("用户");
sysUser.setSex("女");
sysUser.setAge(18);
boolean save = sysUserService.save(sysUser);
System.out.println(save);
// 输出 true 代表插入成功
}
/**
* 测试查询
*/
@Test
public void selectTest() {
List<SysUser> sysUsers = sysUserService.getBaseMapper().selectList(null);
for (SysUser sysUser : sysUsers) {
System.out.println(sysUser.getName());
}
/**
* 输出内容如下:
* 超级管理员
* 用户
*/
}
}
SysUserController 代码如下:
package com.micromaple.my.project.server.controller;
import com.micromaple.my.project.common.dto.BaseResult;
import com.micromaple.my.project.common.utils.MapperUtils;
import com.micromaple.my.project.server.domain.SysUser;
import com.micromaple.my.project.server.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
*
* 用户表 前端控制器
*
*
* @author Micromaple
* @since 2022-09-21 21:51:15
*/
@RestController
@RequestMapping("/sys-user")
public class SysUserController {
@Autowired
private ISysUserService sysUserService;
@GetMapping("/get/all")
public BaseResult getAll() {
List<SysUser> sysUsers = sysUserService.getBaseMapper().selectList(null);
return BaseResult.success(sysUsers);
}
}
启动 MyProjectServerApplication
服务,访问地址:
http://localhost:8899/sys-user/get/all
源码在 GitHub
和 码云
,持续更新中,别忘了 start
喔~
GitHub
https://github.com/micromaples/my-project
码云gitee
https://gitee.com/micromaple/my-project
读到这里,想必你已经知道了如何搭建一个Spring Boot项目,并整合其他技术栈,快跟着一起动手吧。别忘了三连支持博主呀~
我是微枫Micromaple,期待你的关注~