diff --git a/.gitignore b/.gitignore index 9abb443..23621d0 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,4 @@ build/ ### VS Code ### .vscode/ /logs/ -/cs-base/src/main/resources/git.properties +**/git.properties diff --git a/config/application-local.yml b/config/application-local.yml new file mode 100644 index 0000000..8de3de0 --- /dev/null +++ b/config/application-local.yml @@ -0,0 +1,110 @@ +server : + port : 9276 + servlet : + context-path: /cmhi + compression: + # 开启响应压缩 + enabled : true + mime-types : + - application/json # RESTful API JSON + # 进行压缩的最小体积 + min-response-size: 1KB + +# Crypto Configure +jasypt : + encryptor: + algorithm: PBEWITHHMACSHA512ANDAES_256 + password : + +spring : + mvc : + throw-exception-if-no-handler-found: true + web : + resources: + add-mappings: false + + jackson : + date-format : yyyy-MM-dd HH:mm:ss.SSS + timezone : GMT+8 + default-property-inclusion: non_null + mapper : + default-view-inclusion: true + deserialization : + fail-on-unknown-properties: false + + datasource: + #url : jdbc:mysql://xajhuang.com:3307/common_framework?serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&useUnicode=true + url : jdbc:mysql://localhost:3306/common_framework?serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&useUnicode=true + driver-class-name: com.mysql.cj.jdbc.Driver + #username : xajhuang + #password : wkj!nky5cjb!GMV6guq + username : root + password : aaaHuang1 + dbcp2 : + max-total : 128 + max-wait-millis : 10000 + max-idle : 32 + min-idle : 8 + initial-size : 8 + validation-query : SELECT 1 + test-while-idle : true + connection-properties: + characterEncoding: utf8 + + sql : + init: + encoding : utf8 + schema-locations: classpath:rbac/schema.sql + data-locations : classpath:rbac/data.sql + # ALWAYS/EMBEDDED/NEVER + mode : always + enabled : true + + +#mybatis +mybatis : + mapper-locations : classpath*:mappers/*.xml + type-aliases-package: com.cmhi.gds.pojo.entry + configuration : + default-enum-type-handler: com.cmhi.cf.common.CommonEnumHandler + +mybatis-flex: + global-config: + print-banner: false + +#pagehelper +pagehelper : + helper-dialect : mysql + reasonable : true + support-methods-arguments: true + pageSizeZero : true + params.count : countSql + +#config log +logging : + config: file:config/logback.xml +log4j : + logger: + org: + mybatis: info + +# swagger-ui custom path +springdoc : + swagger-ui: + path: /swagger-ui.html + +# JWT configure +jwt : + http-head : Authorization + secret-key : MTIzNDU2Nzg= + expire-time: 604800 + +# 字典配置 +system : + dict: + raw-value : true + cache : + enabled: true + controller: + enabled: false + prefix : /dict diff --git a/config/application-user.yml b/config/application-user.yml new file mode 100644 index 0000000..715cbf7 --- /dev/null +++ b/config/application-user.yml @@ -0,0 +1,18 @@ +common : + token-expired-of-seconds: 600 + allow-passwd-retry-times: 3 + show-sql-command : false + +protocol: + check-timestamp : true + timeout-of-seconds: 600 + crypto-type : 0 +#crypto-key: 12354 + +security: + ui: + white-list: + - method: GET + url : /swagger-ui/** + - method: GET + url : /v3/api-docs/** diff --git a/config/application.yml b/config/application.yml new file mode 100644 index 0000000..7be7511 --- /dev/null +++ b/config/application.yml @@ -0,0 +1,3 @@ +spring: + profiles: + active: local, user \ No newline at end of file diff --git a/config/logback.xml b/config/logback.xml new file mode 100644 index 0000000..bb7b8a1 --- /dev/null +++ b/config/logback.xml @@ -0,0 +1,108 @@ + + + + + + + + + [%d{yy-MM-dd HH:mm:ss:SSS}][%-5p][%c{0}][%M\(%L\)][%t]: %m%n + + + + + ${LOG_PATH}/biz.log + + ${LOG_PATH}/biz.log.%d{yyyyMMdd} + + + + [%d{yy-MM-dd HH:mm:ss:SSS}][%-5p][%c{0}][%M\(%L\)][%t]: %m%n + + + + ${LOG_PATH}/system.log + + ${LOG_PATH}/system.log.%d{yyyyMMdd} + + + + [%d{yy-MM-dd HH:mm:ss:SSS}][%-5p][%c{0}][%M\(%L\)][%t]: %m%n + + + + + ${LOG_PATH}/data.log + + ${LOG_PATH}/data.log.%d{yyyyMMdd} + + + + [%d{yy-MM-dd HH:mm:ss:SSS}][%-5p][%c{0}][%M\(%L\)][%t]: %m%n + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cs-base/pom.xml b/cs-base/pom.xml index 146fc07..0a3bc83 100644 --- a/cs-base/pom.xml +++ b/cs-base/pom.xml @@ -16,9 +16,12 @@ org.springframework.boot - spring-boot-starter + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-starter-web - org.springframework.boot spring-boot-starter-test @@ -28,15 +31,16 @@ com.houkunlin system-dict-starter - 1.5.0 + 1.5.1 - jakarta.servlet - jakarta.servlet-api - 6.0.0 - provided + org.jetbrains + annotations + 23.0.0 + + diff --git a/cs-base/src/main/java/com/cf/cs/base/CsBaseApplication.java b/cs-base/src/main/java/com/cf/cs/base/CsBaseApplication.java index 410ff39..d9725d3 100644 --- a/cs-base/src/main/java/com/cf/cs/base/CsBaseApplication.java +++ b/cs-base/src/main/java/com/cf/cs/base/CsBaseApplication.java @@ -3,9 +3,19 @@ package com.cf.cs.base; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +/** + * The type Cs base application. + * + * @author xajhuang @163.com + */ @SpringBootApplication public class CsBaseApplication { + /** + * The entry point of application. + * + * @param args the input arguments + */ public static void main(String[] args) { SpringApplication.run(CsBaseApplication.class, args); } diff --git a/cs-base/src/main/java/com/cf/cs/base/common/BaseEnum.java b/cs-base/src/main/java/com/cf/cs/base/common/BaseEnum.java index 8eabf6c..9b31d88 100644 --- a/cs-base/src/main/java/com/cf/cs/base/common/BaseEnum.java +++ b/cs-base/src/main/java/com/cf/cs/base/common/BaseEnum.java @@ -1,7 +1,22 @@ package com.cf.cs.base.common; +/** + * The interface Base enum. + * + * @author xajhuang @163.com + */ public interface BaseEnum { + /** + * Gets value. + * + * @return the value + */ Integer getValue(); + /** + * Gets description. + * + * @return the description + */ String getDescription(); } diff --git a/cs-base/src/main/java/com/cf/cs/base/common/CachePool.java b/cs-base/src/main/java/com/cf/cs/base/common/CachePool.java new file mode 100644 index 0000000..1654718 --- /dev/null +++ b/cs-base/src/main/java/com/cf/cs/base/common/CachePool.java @@ -0,0 +1,33 @@ +package com.cf.cs.base.common; + + +import lombok.Getter; + +/** + * The enum Cache pool. + * + * @author xajhuang @163.com + */ +@Getter +public enum CachePool { + /** + * Auth cache cache pool. + */ + AUTH_CACHE("AUTH_CACHE", 1800, 1000, 100), + /** + * Jwt cache cache pool. + */ + JWT_CACHE("JWT_CACHE", 3600, 2000, 200); + + private final String cacheName; + private final Integer defaultTimeout; + private final Integer maxPoolSize; + private final Integer defaultPoolSize; + + CachePool(String authCache, int timeout, int maxSize, int defSize) { + this.cacheName = authCache; + this.defaultTimeout = timeout; + this.maxPoolSize = maxSize; + this.defaultPoolSize = defSize; + } +} diff --git a/cs-base/src/main/java/com/cf/cs/base/common/CommonEnumHandler.java b/cs-base/src/main/java/com/cf/cs/base/common/CommonEnumHandler.java new file mode 100644 index 0000000..6f19fa6 --- /dev/null +++ b/cs-base/src/main/java/com/cf/cs/base/common/CommonEnumHandler.java @@ -0,0 +1,58 @@ +package com.cf.cs.base.common; + +import java.util.Arrays; +import java.util.List; + +/** + * The type Common enum handler. + * + * @param the type parameter + * @author xajhuang @163.com + */ +public final class CommonEnumHandler { + private final Class enumType; + private final List enums; + + /** + * Instantiates a new Common enum handler. + * + * @param type the type + */ + public CommonEnumHandler(Class type) { + if (type == null) { + throw new IllegalArgumentException("Type argument cannot be null"); + } + + this.enumType = type; + this.enums = Arrays.asList(type.getEnumConstants()); + } + + /** + * Code of e. + * + * @param the type parameter + * @param enumClass the enum class + * @param code the code + * @return the e + */ + public static & BaseEnum> E codeOf(Class enumClass, int code) { + E[] enumCodes = enumClass.getEnumConstants(); + + for (E e : enumCodes) { + if (e.getValue() == code) { + return e; + } + } + + return null; + } + + private E locateEnumStatus(int index) { + for (E e : enums) { + if (e.getValue() == index) { + return e; + } + } + throw new IllegalArgumentException(enumType.getName() + " unknown enumerated type index:" + index); + } +} diff --git a/cs-base/src/main/java/com/cf/cs/base/common/CommonStatus.java b/cs-base/src/main/java/com/cf/cs/base/common/CommonStatus.java new file mode 100644 index 0000000..d9f0372 --- /dev/null +++ b/cs-base/src/main/java/com/cf/cs/base/common/CommonStatus.java @@ -0,0 +1,52 @@ +package com.cf.cs.base.common; + +import com.houkunlin.system.dict.starter.DictEnum; +import com.houkunlin.system.dict.starter.json.DictType; + +/** + * The enum Common status. + * + * @author xajhuang @163.com + */ +@DictType(value = "CommonStatus", comment = "系统常用状态码") +public enum CommonStatus implements BaseEnum, DictEnum { + /** + * Normal common status. + */ + NORMAL(0, "正常"), + /** + * Locked common status. + */ + LOCKED(1, "已锁定"), + /** + * Disabled common status. + */ + DISABLED(2, "已禁用"), + /** + * Deleted common status. + */ + DELETED(3, "已删除"); + + private final Integer code; + private final String readme; + + CommonStatus(int code, String readme) { + this.code = code; + this.readme = readme; + } + + @Override + public Integer getValue() { + return this.code; + } + + @Override + public String getTitle() { + return this.readme; + } + + @Override + public String getDescription() { + return this.readme; + } +} diff --git a/cs-base/src/main/java/com/cf/cs/base/common/ConstValue.java b/cs-base/src/main/java/com/cf/cs/base/common/ConstValue.java new file mode 100644 index 0000000..88785ee --- /dev/null +++ b/cs-base/src/main/java/com/cf/cs/base/common/ConstValue.java @@ -0,0 +1,42 @@ +package com.cf.cs.base.common; + +/** + * The type Const value. + * + * @author xajhuang @163.com + */ +public class ConstValue { + /** + * The constant STRING_HTTP_AUTH_HEAD. + */ + public static final String STRING_HTTP_AUTH_HEAD = "Bearer "; + + /** + * The constant IP_ADDR_REG. + */ + public static final String IP_ADDR_REG = "^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}" + + "(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|^" + + "([\\da-fA-F]{1,4}:){6}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|^::" + + "([\\da-fA-F]{1,4}:){0,4}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|^" + + "([\\da-fA-F]{1,4}:):([\\da-fA-F]{1,4}:){0,3}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}" + + "(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|^([\\da-fA-F]{1,4}:){2}:([\\da-fA-F]{1,4}:){0,2}(" + + "(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|^([\\da-fA-F]{1,4}:){3}:" + + "([\\da-fA-F]{1,4}:){0,1}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|^" + + "([\\da-fA-F]{1,4}:){4}:((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|^" + + "([\\da-fA-F]{1,4}:){7}[\\da-fA-F]{1,4}$|^:((:[\\da-fA-F]{1,4}){1,6}|:)$|^[\\da-fA-F]{1,4}:((:[\\da-fA-F]{1," + + "4}){1,5}|:)$|^([\\da-fA-F]{1,4}:){2}((:[\\da-fA-F]{1,4}){1,4}|:)$|^([\\da-fA-F]{1,4}:){3}((:[\\da-fA-F]{1," + + "4}){1,3}|:)$|^([\\da-fA-F]{1,4}:){4}((:[\\da-fA-F]{1,4}){1,2}|:)$|^([\\da-fA-F]{1,4}:){5}:([\\da-fA-F]{1,4})" + + "?$|^([\\da-fA-F]{1,4}:){6}:$"; + + /** + * The type Protocol. + * + * @author xajhuang @163.com + */ + public static class Protocol { + /** + * The constant VERSION. + */ + public static final int VERSION = 1; + } +} diff --git a/cs-base/src/main/java/com/cf/cs/base/config/ObjectMapperProvider.java b/cs-base/src/main/java/com/cf/cs/base/config/ObjectMapperProvider.java new file mode 100644 index 0000000..f535f16 --- /dev/null +++ b/cs-base/src/main/java/com/cf/cs/base/config/ObjectMapperProvider.java @@ -0,0 +1,31 @@ +package com.cf.cs.base.config; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.jetbrains.annotations.NotNull; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +/** + * The type Object mapper provider. + * + * @author xajhuang @163.com + */ +@Component +public class ObjectMapperProvider implements ApplicationContextAware { + private static ApplicationContext context; + + @Override + public void setApplicationContext(@NotNull ApplicationContext applicationContext) { + ObjectMapperProvider.context = applicationContext; + } + + /** + * Gets mapper. + * + * @return the mapper + */ + public static ObjectMapper getMapper() { + return context.getBean(ObjectMapper.class); + } +} diff --git a/cs-base/src/main/java/com/cf/cs/base/exception/CommonErrorCodeException.java b/cs-base/src/main/java/com/cf/cs/base/exception/CommonErrorCodeException.java new file mode 100644 index 0000000..9ca5bac --- /dev/null +++ b/cs-base/src/main/java/com/cf/cs/base/exception/CommonErrorCodeException.java @@ -0,0 +1,49 @@ +package com.cf.cs.base.exception; + +import com.cf.cs.base.common.ErrorCode; + +/** + * The type Common error code exception. + * + * @author xajhuang @163.com + */ +public class CommonErrorCodeException extends RuntimeException{ + private final ErrorCode err; + + private final String[] description; + + /** + * Instantiates a new Common error code exception. + * + * @param err the err + */ + public CommonErrorCodeException(ErrorCode err) { + super(err.getDescription()); + this.err = err; + this.description = new String[] {err.getDescription()}; + } + + /** + * Instantiates a new Common error code exception. + * + * @param err the err + * @param readme the readme + */ + public CommonErrorCodeException(ErrorCode err, String readme) { + super(readme); + this.err = err; + this.description = new String[] {readme}; + } + + /** + * Instantiates a new Common error code exception. + * + * @param err the err + * @param readme the readme + */ + public CommonErrorCodeException(ErrorCode err, String[] readme) { + super(err.getDescription()); + this.err = err; + this.description = readme; + } +} diff --git a/cs-base/src/main/java/com/cf/cs/base/misc/HelperUtils.java b/cs-base/src/main/java/com/cf/cs/base/misc/HelperUtils.java new file mode 100644 index 0000000..d500ab8 --- /dev/null +++ b/cs-base/src/main/java/com/cf/cs/base/misc/HelperUtils.java @@ -0,0 +1,333 @@ +package com.cf.cs.base.misc; + + +import com.cf.cs.base.config.ObjectMapperProvider; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.servlet.ServletInputStream; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.ValidatorFactory; +import org.hibernate.validator.HibernateValidator; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * The type Helper utils. + * + * @author xajhuang @163.com + */ +public class HelperUtils { + /** + * The constant UN_EXPECT_REGEX_CHARS. + */ + public static final String UN_EXPECT_REGEX_CHARS = "^((?!(--|\\s|\\*|%|\\+|'|;])).)*$"; + + private static final ObjectMapper OBJ_MAPPER = ObjectMapperProvider.getMapper(); + + /** + * Truncate string string. + * + * @param orgString the org string + * @param maxLength the max length + * @return the string + */ + public static String truncateString(String orgString, int maxLength) { + if (!stringNotEmptyOrNull(orgString) || orgString.length() <= maxLength) { + return orgString; + } else { + return orgString.substring(0, maxLength - 4) + "..."; + } + } + + /** + * Bytes to hex string string. + * + * @param bArray the b array + * @return the string + */ + public static String bytesToHexString(byte[] bArray) { + StringBuilder sb = new StringBuilder(bArray.length); + String sTemp; + for (byte b : bArray) { + sTemp = Integer.toHexString(0xFF & b); + if (sTemp.length() < 2) { + sb.append(0); + } + sb.append(sTemp.toUpperCase()); + } + return sb.toString(); + } + + /** + * Convert string to gb 2312 byte [ ]. + * + * @param str the str + * @return the byte [ ] + * @throws UnsupportedEncodingException the unsupported encoding exception + */ + public static byte[] convertStringToGb2312(String str) throws UnsupportedEncodingException { + String utf8 = new String(str.getBytes(StandardCharsets.UTF_8)); + String unicode = new String(utf8.getBytes(), StandardCharsets.UTF_8); + String gbk = new String(unicode.getBytes("GB2312")); + return gbk.getBytes(); + } + + /** + * Input stream 2 string string. + * + * @param inputStream the input stream + * @return the string + * @throws IOException the io exception + */ + public static String inputStream2String(InputStream inputStream) throws IOException { + if (inputStream != null) { + final int bufferSize = 1024; + final char[] buffer = new char[bufferSize]; + final StringBuilder out = new StringBuilder(); + Reader in = new InputStreamReader(inputStream, StandardCharsets.UTF_8); + + int charsRead; + while ((charsRead = in.read(buffer, 0, buffer.length)) > 0) { + out.append(buffer, 0, charsRead); + } + + return out.toString(); + } else { + return ""; + } + } + + /** + * Gets timestamp milli second. + * + * @param dateTime the date time + * @return the timestamp milli second + */ + public static long getTimestampMilliSecond(String dateTime) { + return Timestamp.valueOf(dateTime).toInstant().toEpochMilli(); + } + + /** + * Gets current datetime. + * + * @return the current datetime + */ + public static String getCurrentDatetime() { + return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + } + + /** + * Gets json. + * + * @param the type parameter + * @param obj the obj + * @return the json + * @throws JsonProcessingException the json processing exception + */ + public static String getJson(T obj) throws JsonProcessingException { + return OBJ_MAPPER.writeValueAsString(obj); + } + + /** + * Get json bytes byte [ ]. + * + * @param the type parameter + * @param obj the obj + * @param charset the charset + * @return the byte [ ] + * @throws JsonProcessingException the json processing exception + */ + public static byte[] getJsonBytes(T obj, Charset charset) throws JsonProcessingException { + return OBJ_MAPPER.writeValueAsString(obj).getBytes(charset); + } + + /** + * Get json bytes byte [ ]. + * + * @param the type parameter + * @param obj the obj + * @return the byte [ ] + * @throws JsonProcessingException the json processing exception + */ + public static byte[] getJsonBytes(T obj) throws JsonProcessingException { + return OBJ_MAPPER.writeValueAsString(obj).getBytes(StandardCharsets.UTF_8); + } + + /** + * Json get object object. + * + * @param the type parameter + * @param json the json + * @param valueType the value type + * @return the object + * @throws JsonProcessingException the json processing exception + */ + public static Object jsonGetObject(String json, Class valueType) throws JsonProcessingException { + return OBJ_MAPPER.readValue(json, valueType); + } + + /** + * Json get object t. + * + * @param the type parameter + * @param is the is + * @param valueTypeRef the value type ref + * @return the t + * @throws IOException the io exception + */ + public static T jsonGetObject(ServletInputStream is, TypeReference valueTypeRef) throws IOException { + return OBJ_MAPPER.readValue(inputStream2String(is), valueTypeRef); + } + + /** + * Json get object t. + * + * @param the type parameter + * @param json the json + * @param valueTypeRef the value type ref + * @return the t + * @throws IOException the io exception + */ + public static T jsonGetObject(String json, TypeReference valueTypeRef) throws IOException { + return OBJ_MAPPER.readValue(json, valueTypeRef); + } + + /** + * Validate list. + * + * @param the type parameter + * @param t the t + * @param groups the groups + * @return the list + */ + public static List validate(T t, Class... groups) { + Set> set; + ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class) + .configure() + .failFast(false) + .buildValidatorFactory(); + + if (groups != null && groups.length > 0) { + set = validatorFactory.getValidator().validate(t, groups); + } else { + set = validatorFactory.getValidator().validate(t); + } + List validateError = new ArrayList<>(); + if (!set.isEmpty()) { + int index = 0; + for (ConstraintViolation val : set) { + validateError.add("[" + index++ + "]: " + val.getMessage()); + } + } + return validateError; + } + + /** + * String not empty or null boolean. + * + * @param str the str + * @return the boolean + */ + public static boolean stringNotEmptyOrNull(String str) { + return str != null && !str.isEmpty(); + } + + /** + * Meagre db string value string. + * + * @param str the str + * @return the string + */ + public static String meagreDbStringValue(String str) { + return stringNotEmptyOrNull(str) ? str : null; + } + + /** + * Gets http request headers. + * + * @param request the request + * @return the http request headers + * @throws JsonProcessingException the json processing exception + */ + public static String getHttpRequestHeaders(HttpServletRequest request) throws JsonProcessingException { + if (request != null) { + Map headerMap = new HashMap<>(15); + Enumeration enumeration = request.getHeaderNames(); + while (enumeration.hasMoreElements()) { + String name = enumeration.nextElement(); + String value = request.getHeader(name); + headerMap.put(name, value); + } + return getJson(headerMap); + } else { + return "{}"; + } + } + + /** + * Gets http request src ip. + * + * @param request the request + * @return the http request src ip + * @throws UnknownHostException the unknown host exception + */ + public static String getHttpRequestSrcIp(HttpServletRequest request) throws UnknownHostException { + String unknown = "unknown"; + String localhostIp = "127.0.0.1"; + // 客户端与服务器同为一台机器,获取的 ip 有时候是 ipv6 格式 + String localhostIpv6 = "0:0:0:0:0:0:0:1"; + String separator = ","; + + if (request == null) { + return "unknown"; + } + String ip = request.getHeader("x-forwarded-for"); + if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) { + ip = request.getHeader("X-Forwarded-For"); + } + if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) { + ip = request.getHeader("X-Real-IP"); + } + if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + if (localhostIp.equalsIgnoreCase(ip) || localhostIpv6.equalsIgnoreCase(ip)) { + // 根据网卡取本机配置的 IP + InetAddress iNet = InetAddress.getLocalHost(); + if (iNet != null) {ip = iNet.getHostAddress();} + } + } + // 对于通过多个代理的情况,分割出第一个 IP + if (ip != null && ip.length() > 15) { + if (ip.indexOf(separator) > 0) { + ip = ip.substring(0, ip.indexOf(separator)); + } + } + return localhostIpv6.equals(ip) ? localhostIp : ip; + } +} diff --git a/cs-base/src/main/java/com/cf/cs/base/misc/SpringBootBeanUtils.java b/cs-base/src/main/java/com/cf/cs/base/misc/SpringBootBeanUtils.java new file mode 100644 index 0000000..13ed196 --- /dev/null +++ b/cs-base/src/main/java/com/cf/cs/base/misc/SpringBootBeanUtils.java @@ -0,0 +1,57 @@ +package com.cf.cs.base.misc; + +import lombok.Getter; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +/** + * The type Spring boot bean utils. + * + * @author xajhuang @163.com + */ +@Component +public class SpringBootBeanUtils implements ApplicationContextAware { + @Getter + private static ApplicationContext applicationContext; + + /** + * Gets bean. + * + * @param name the name + * @return the bean + */ + public static Object getBean(String name) { + return getApplicationContext().getBean(name); + } + + /** + * Gets bean. + * + * @param the type parameter + * @param clazz the clazz + * @return the bean + */ + public static T getBean(Class clazz) { + return getApplicationContext().getBean(clazz); + } + + /** + * Gets bean. + * + * @param the type parameter + * @param name the name + * @param clazz the clazz + * @return the bean + */ + public static T getBean(String name, Class clazz) { + return getApplicationContext().getBean(name, clazz); + } + + @Override + public void setApplicationContext(@NotNull ApplicationContext applicationContext) throws BeansException { + SpringBootBeanUtils.applicationContext = applicationContext; + } +} diff --git a/cs-base/src/main/resources/application.properties b/cs-base/src/main/resources/application.properties deleted file mode 100644 index 8b13789..0000000 --- a/cs-base/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ - diff --git a/cs-crypto/pom.xml b/cs-crypto/pom.xml new file mode 100644 index 0000000..afe442b --- /dev/null +++ b/cs-crypto/pom.xml @@ -0,0 +1,29 @@ + + + 4.0.0 + + com.cf.cs + IntegrateService + 0.0.1-dev + + + cs-crypto + cs-crypto + cs-crypto + jar + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/cs-crypto/src/main/java/com/cf/cs/crypto/arithmetic/CryptoHelper.java b/cs-crypto/src/main/java/com/cf/cs/crypto/arithmetic/CryptoHelper.java new file mode 100644 index 0000000..1594e94 --- /dev/null +++ b/cs-crypto/src/main/java/com/cf/cs/crypto/arithmetic/CryptoHelper.java @@ -0,0 +1,221 @@ +package com.cf.cs.crypto.arithmetic; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Base64; + +/** + * The type Crypto helper. + * + * @author xajhuang @163.com + */ +public class CryptoHelper { + + private static final String AES_ALGORITHM_STR = "AES/ECB/PKCS5Padding"; + private static final String DES_ALGORITHM_STR = "DES/ECB/PKCS5Padding"; + + private CryptoHelper() { + throw new AssertionError("Instantiating utility class."); + } + + /** + * Base 64 decryption byte [ ]. + * + * @param ciphertext the ciphertext + * @return the byte [ ] + */ + public static byte[] base64Decryption(String ciphertext) { + return Base64.getDecoder().decode(ciphertext); + } + + /** + * Base 64 encryption string. + * + * @param plaintext the plaintext + * @return the string + */ + public static String base64Encryption(byte[] plaintext) { + return Base64.getEncoder().encodeToString(plaintext); + } + + /** + * Sha 256 encryption byte [ ]. + * + * @param plaintext the plaintext + * @return the byte [ ] + * @throws NoSuchAlgorithmException the no such algorithm exception + */ + public static byte[] sha256Encryption(String plaintext) throws NoSuchAlgorithmException { + MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); + messageDigest.update(plaintext.getBytes(StandardCharsets.UTF_8)); + return messageDigest.digest(); + } + + /** + * Md 5 encryption string. + * + * @param plaintext the plaintext + * @return the string + * @throws NoSuchAlgorithmException the no such algorithm exception + */ + public static String md5Encryption(String plaintext) throws NoSuchAlgorithmException { + MessageDigest messageDigest = MessageDigest.getInstance("MD5"); + messageDigest.update(plaintext.getBytes(StandardCharsets.UTF_8)); + return base64Encryption(messageDigest.digest()); + } + + /** + * Aes 128 encryption byte [ ]. + * + * @param plaintext the plaintext + * @param aesKey the aes key + * @return the byte [ ] + * @throws NoSuchAlgorithmException the no such algorithm exception + * @throws NoSuchPaddingException the no such padding exception + * @throws InvalidKeyException the invalid key exception + * @throws BadPaddingException the bad padding exception + * @throws IllegalBlockSizeException the illegal block size exception + */ + public static byte[] aes128Encryption(byte[] plaintext, + String aesKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, + BadPaddingException, IllegalBlockSizeException { + KeyGenerator keyGen = KeyGenerator.getInstance("AES"); + SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); + secureRandom.setSeed(aesKey.getBytes()); + + keyGen.init(128, secureRandom); + Cipher cipher = Cipher.getInstance(AES_ALGORITHM_STR); + SecretKeySpec key = new SecretKeySpec(keyGen.generateKey().getEncoded(), "AES"); + cipher.init(Cipher.ENCRYPT_MODE, key); + return cipher.doFinal(plaintext); + } + + /** + * Aes 128 decryption byte [ ]. + * + * @param ciphertext the ciphertext + * @param aesKey the aes key + * @return the byte [ ] + * @throws NoSuchAlgorithmException the no such algorithm exception + * @throws NoSuchPaddingException the no such padding exception + * @throws InvalidKeyException the invalid key exception + * @throws BadPaddingException the bad padding exception + * @throws IllegalBlockSizeException the illegal block size exception + */ + public static byte[] aes128Decryption(byte[] ciphertext, + String aesKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, + BadPaddingException, IllegalBlockSizeException { + KeyGenerator keyGen = KeyGenerator.getInstance("AES"); + SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); + secureRandom.setSeed(aesKey.getBytes()); + + keyGen.init(128, secureRandom); + Cipher cipher = Cipher.getInstance(AES_ALGORITHM_STR); + SecretKeySpec key = new SecretKeySpec(keyGen.generateKey().getEncoded(), "AES"); + cipher.init(Cipher.DECRYPT_MODE, key); + return cipher.doFinal(ciphertext); + } + + /** + * Aes 256 encryption byte [ ]. + * + * @param plaintext the plaintext + * @param aesKey the aes key + * @return the byte [ ] + * @throws NoSuchAlgorithmException the no such algorithm exception + * @throws NoSuchPaddingException the no such padding exception + * @throws InvalidKeyException the invalid key exception + * @throws BadPaddingException the bad padding exception + * @throws IllegalBlockSizeException the illegal block size exception + */ + public static byte[] aes256Encryption(byte[] plaintext, + String aesKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, + BadPaddingException, IllegalBlockSizeException { + Cipher cipher = Cipher.getInstance(AES_ALGORITHM_STR); + SecretKeySpec key = new SecretKeySpec(sha256Encryption(aesKey), "AES"); + cipher.init(Cipher.ENCRYPT_MODE, key); + return cipher.doFinal(plaintext); + } + + /** + * Aes 256 decryption byte [ ]. + * + * @param ciphertext the ciphertext + * @param aesKey the aes key + * @return the byte [ ] + * @throws NoSuchAlgorithmException the no such algorithm exception + * @throws NoSuchPaddingException the no such padding exception + * @throws InvalidKeyException the invalid key exception + * @throws BadPaddingException the bad padding exception + * @throws IllegalBlockSizeException the illegal block size exception + */ + public static byte[] aes256Decryption(byte[] ciphertext, + String aesKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, + BadPaddingException, IllegalBlockSizeException { + Cipher cipher = Cipher.getInstance(AES_ALGORITHM_STR); + SecretKeySpec key = new SecretKeySpec(sha256Encryption(aesKey), "AES"); + cipher.init(Cipher.DECRYPT_MODE, key); + return cipher.doFinal(ciphertext); + } + + /** + * Des decryption byte [ ]. + * + * @param ciphertext the ciphertext + * @param desKey the des key + * @return the byte [ ] + * @throws InvalidKeyException the invalid key exception + * @throws NoSuchAlgorithmException the no such algorithm exception + * @throws NoSuchPaddingException the no such padding exception + * @throws BadPaddingException the bad padding exception + * @throws IllegalBlockSizeException the illegal block size exception + */ + public static byte[] desDecryption(byte[] ciphertext, + String desKey) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, + BadPaddingException, IllegalBlockSizeException { + KeyGenerator keyGen = KeyGenerator.getInstance("DES"); + SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); + secureRandom.setSeed(desKey.getBytes()); + + keyGen.init(56, secureRandom); + Cipher cipher = Cipher.getInstance(DES_ALGORITHM_STR); + SecretKeySpec key = new SecretKeySpec(keyGen.generateKey().getEncoded(), "DES"); + cipher.init(Cipher.DECRYPT_MODE, key); + return cipher.doFinal(ciphertext); + } + + /** + * Des encryption byte [ ]. + * + * @param plaintext the plaintext + * @param desKey the des key + * @return the byte [ ] + * @throws InvalidKeyException the invalid key exception + * @throws NoSuchAlgorithmException the no such algorithm exception + * @throws NoSuchPaddingException the no such padding exception + * @throws BadPaddingException the bad padding exception + * @throws IllegalBlockSizeException the illegal block size exception + */ + public static byte[] desEncryption(byte[] plaintext, + String desKey) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, + BadPaddingException, IllegalBlockSizeException { + KeyGenerator keyGen = KeyGenerator.getInstance("DES"); + SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); + secureRandom.setSeed(desKey.getBytes()); + + keyGen.init(56, secureRandom); + Cipher cipher = Cipher.getInstance(DES_ALGORITHM_STR); + SecretKeySpec key = new SecretKeySpec(keyGen.generateKey().getEncoded(), "DES"); + cipher.init(Cipher.ENCRYPT_MODE, key); + return cipher.doFinal(plaintext); + } +} diff --git a/cs-crypto/src/test/java/com/cf/cs/crypto/CsCryptoApplicationTests.java b/cs-crypto/src/test/java/com/cf/cs/crypto/CsCryptoApplicationTests.java new file mode 100644 index 0000000..e2817bd --- /dev/null +++ b/cs-crypto/src/test/java/com/cf/cs/crypto/CsCryptoApplicationTests.java @@ -0,0 +1,13 @@ +package com.cf.cs.crypto; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class CsCryptoApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/cs-restful/pom.xml b/cs-restful/pom.xml index 04e1f61..328f631 100644 --- a/cs-restful/pom.xml +++ b/cs-restful/pom.xml @@ -28,6 +28,24 @@ spring-boot-starter-test test + + + org.springdoc + springdoc-openapi-starter-webmvc-api + 2.3.0 + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.3.0 + + + + com.cf.cs + cs-web + ${cs-package.version} + compile + diff --git a/cs-restful/src/main/java/com/cf/cs/restful/CsRestfulApplication.java b/cs-restful/src/main/java/com/cf/cs/restful/CsRestfulApplication.java index eb2e2c4..65a6770 100644 --- a/cs-restful/src/main/java/com/cf/cs/restful/CsRestfulApplication.java +++ b/cs-restful/src/main/java/com/cf/cs/restful/CsRestfulApplication.java @@ -3,9 +3,19 @@ package com.cf.cs.restful; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -@SpringBootApplication +/** + * The type Cs restful application. + * + * @author xajhuang @163.com + */ +@SpringBootApplication(scanBasePackages = {"com.cf.cs.base", "com.cf.cs.restful", "com.cf.cs.web"}) public class CsRestfulApplication { + /** + * The entry point of application. + * + * @param args the input arguments + */ public static void main(String[] args) { SpringApplication.run(CsRestfulApplication.class, args); } diff --git a/cs-restful/src/main/resources/application.properties b/cs-restful/src/main/resources/application.properties deleted file mode 100644 index 8b13789..0000000 --- a/cs-restful/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ - diff --git a/cs-web/pom.xml b/cs-web/pom.xml new file mode 100644 index 0000000..1e92245 --- /dev/null +++ b/cs-web/pom.xml @@ -0,0 +1,73 @@ + + + 4.0.0 + + com.cf.cs + IntegrateService + 0.0.1-dev + + + cs-web + cs-web + cs-web + jar + + + + org.springframework.boot + spring-boot-starter-cache + + + + com.github.ben-manes.caffeine + caffeine + 3.1.8 + + + + com.cf.cs + cs-base + ${cs-package.version} + compile + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + pl.project13.maven + git-commit-id-plugin + 4.9.10 + + + get-the-git-infos + + revision + + initialize + + + + false + false + true + yyyy-MM-dd'T'HH:mm:ssZ + true + ${project.basedir}/src/main/resources/git.properties + + + git.commit.message.* + git.commit.user.* + git.remote.origin.* + + + + + + + diff --git a/cs-web/src/main/java/com/cf/cs/web/CsWebApplication.java b/cs-web/src/main/java/com/cf/cs/web/CsWebApplication.java new file mode 100644 index 0000000..78bb860 --- /dev/null +++ b/cs-web/src/main/java/com/cf/cs/web/CsWebApplication.java @@ -0,0 +1,13 @@ +package com.cf.cs.web; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CsWebApplication { + + public static void main(String[] args) { + SpringApplication.run(CsWebApplication.class, args); + } + +} diff --git a/cs-web/src/main/java/com/cf/cs/web/configure/CacheConfigure.java b/cs-web/src/main/java/com/cf/cs/web/configure/CacheConfigure.java new file mode 100644 index 0000000..e5ed27d --- /dev/null +++ b/cs-web/src/main/java/com/cf/cs/web/configure/CacheConfigure.java @@ -0,0 +1,45 @@ +package com.cf.cs.web.configure; + +import com.cf.cs.base.common.CachePool; +import com.github.benmanes.caffeine.cache.Caffeine; +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cache.caffeine.CaffeineCache; +import org.springframework.cache.support.SimpleCacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * The type Cache configure. + * + * @author xajhuang @163.com + */ +@Configuration +@EnableCaching +public class CacheConfigure { + /** + * Cache manager cache manager. + * + * @return the cache manager + */ + @Bean("caffeineCacheManager") + public CacheManager cacheManager() { + SimpleCacheManager cacheManager = new SimpleCacheManager(); + List list = new ArrayList<>(); + //循环添加枚举类中自定义的缓存,可以自定义 + for (CachePool cacheEnum : CachePool.values()) { + list.add(new CaffeineCache(cacheEnum.getCacheName(), Caffeine.newBuilder() + .initialCapacity(cacheEnum.getDefaultPoolSize()) + .maximumSize(cacheEnum.getMaxPoolSize()) + .expireAfterAccess(cacheEnum.getDefaultTimeout(), TimeUnit.SECONDS) + .build())); + } + cacheManager.setCaches(list); + return cacheManager; + } + +} diff --git a/cs-web/src/main/java/com/cf/cs/web/configure/CommonConfigure.java b/cs-web/src/main/java/com/cf/cs/web/configure/CommonConfigure.java new file mode 100644 index 0000000..14f5c2e --- /dev/null +++ b/cs-web/src/main/java/com/cf/cs/web/configure/CommonConfigure.java @@ -0,0 +1,55 @@ +package com.cf.cs.web.configure; + +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import java.net.InetAddress; + +/** + * The type Common configure. + * + * @author xajhuang @163.com + */ +@Data +@ConfigurationProperties(prefix = "common") +@Configuration +@Slf4j +public class CommonConfigure { + @Resource + private ServerProperties serverProperties; + + private Integer tokenExpiredOfSeconds; + private Integer allowPasswdRetryTimes; + private boolean showSqlCommand; + + /** + * The constant BASEURL. + */ + public static String BASEURL; + /** + * The constant PROJECT_PREFIX_URL. + */ + public static String PROJECT_PREFIX_URL; + + @PostConstruct + private void initGlobalValue() { + log.info("Current: tokenExpiredOfSeconds = {}, allowPasswdRetryTimes = {}, showSqlCommand = {}", + tokenExpiredOfSeconds, allowPasswdRetryTimes, showSqlCommand); + + String addr = "localhost"; + try { + addr = InetAddress.getLocalHost().getHostAddress(); + } catch (Exception e) { + log.error("Unable get local ip address: {}", e.getMessage()); + } finally { + PROJECT_PREFIX_URL = serverProperties.getServlet().getContextPath(); + BASEURL = "http://" + addr + ":" + serverProperties.getPort() + serverProperties.getServlet().getContextPath(); + log.info("baseUrl: {}", BASEURL); + } + } +} diff --git a/cs-web/src/main/java/com/cf/cs/web/configure/ProjectGitVersionInfo.java b/cs-web/src/main/java/com/cf/cs/web/configure/ProjectGitVersionInfo.java new file mode 100644 index 0000000..3dbd7a1 --- /dev/null +++ b/cs-web/src/main/java/com/cf/cs/web/configure/ProjectGitVersionInfo.java @@ -0,0 +1,41 @@ +package com.cf.cs.web.configure; + +import jakarta.annotation.PostConstruct; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; + +/** + * The type Project git version info. + * + * @author xajhuang @163.com + */ +@Getter +@Setter +@Component +@Slf4j +@PropertySource("classpath:git.properties") +public class ProjectGitVersionInfo { + @Value("${git.commit.id}") + private String commitId; + @Value("${git.commit.id.describe}") + private String commitDescribe; + @Value("${git.commit.time}") + private String commitTime; + @Value("${git.closest.tag.name}") + private String tagName; + @Value("${git.build.time}") + private String buildTime; + + @Value("${git.branch}") + private String gitBranch; + + @PostConstruct + private void initGlobalValue() { + String version = buildTime + " " + commitId + " " + gitBranch + " " + tagName; + log.info("Version: {}", version.trim()); + } +} diff --git a/cs-web/src/main/java/com/cf/cs/web/setup/SystemInitial.java b/cs-web/src/main/java/com/cf/cs/web/setup/SystemInitial.java new file mode 100644 index 0000000..e4e7de4 --- /dev/null +++ b/cs-web/src/main/java/com/cf/cs/web/setup/SystemInitial.java @@ -0,0 +1,31 @@ +package com.cf.cs.web.setup; + +import com.cf.cs.web.configure.CommonConfigure; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + + +/** + * The type System initial. + * + * @author xajhuang@163.com + */ +@Component +@Slf4j +public class SystemInitial implements CommandLineRunner { + /** + * Run. + * + * @param args the args + */ + @Override + public void run(String... args) { + showOpenApiUrl(); + } + + private void showOpenApiUrl() { + + log.info("Access Online API Documents: {}/swagger-ui/index.html", CommonConfigure.BASEURL); + } +} diff --git a/cs-web/src/test/java/com/cf/cs/web/CsWebApplicationTests.java b/cs-web/src/test/java/com/cf/cs/web/CsWebApplicationTests.java new file mode 100644 index 0000000..2503192 --- /dev/null +++ b/cs-web/src/test/java/com/cf/cs/web/CsWebApplicationTests.java @@ -0,0 +1,13 @@ +package com.cf.cs.web; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class CsWebApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/pom.xml b/pom.xml index 9c6f813..9e8d250 100644 --- a/pom.xml +++ b/pom.xml @@ -24,6 +24,8 @@ cs-base + cs-crypto + cs-web cs-restful