├── README.md ├── html └── echarts │ ├── demo-bar.html │ ├── demo-line1.html │ ├── demo-line2.html │ └── demo-pie.html ├── json ├── input.json └── inputSchema.json ├── lib └── mysql-connector-java-5.1.49.jar ├── params.json ├── pom.xml └── src ├── main ├── java │ └── cn │ │ └── eric │ │ └── jdktools │ │ ├── ToolsMain.java │ │ ├── base │ │ ├── InputProperties.java │ │ ├── Test.java │ │ └── TestChild.java │ │ ├── base64 │ │ └── Base64Utils.java │ │ ├── bean │ │ ├── BeanCopyUtils.java │ │ └── BeanToMapUtil.java │ │ ├── cache │ │ ├── ICache.java │ │ ├── caffeine │ │ │ ├── CaffeineCache.java │ │ │ └── CaffeineService.java │ │ ├── ehcache │ │ │ └── EhCacheUtil.java │ │ └── guava │ │ │ ├── GuavaCache.java │ │ │ └── GuavaService.java │ │ ├── chart │ │ └── EchartsData.java │ │ ├── classes │ │ └── PackageUtil.java │ │ ├── code │ │ ├── CodeUtil.java │ │ ├── OrderNoUtil.java │ │ ├── QRcodeUtils.java │ │ ├── RegExUtil.java │ │ ├── SnowflakeIdWorker.java │ │ └── VerificationCodeGeneration.java │ │ ├── collection │ │ └── CollectionAllUtils.java │ │ ├── common │ │ └── Config.java │ │ ├── compiler │ │ ├── ProcyonTest.java │ │ └── procyon-decompiler-0.5.36.jar │ │ ├── data │ │ ├── BigDecimalUtil.java │ │ ├── CreateJsonSchema.java │ │ ├── EscapeUtils.java │ │ └── NumUtil.java │ │ ├── date │ │ ├── DateTimeUtil.java │ │ └── DateUtil.java │ │ ├── db │ │ ├── DriverShim.java │ │ ├── DynamicLoadJDBC.java │ │ └── JDBCUtils.java │ │ ├── encrypt │ │ ├── AESUtil.java │ │ ├── CharTools.java │ │ ├── Escape.java │ │ ├── MD5Util.java │ │ └── RSAUtil.java │ │ ├── exception │ │ └── ExceptionUtil.java │ │ ├── file │ │ ├── ClazzUtils.java │ │ ├── Dom4jHelper.java │ │ ├── ExcelHanlder.java │ │ ├── ExcelUtil.java │ │ ├── FileHelper.java │ │ ├── FileUploadUtil.java │ │ ├── FileUtil.java │ │ ├── FtpUtil.java │ │ ├── MD5FileCheckUtil.java │ │ ├── PathsUtil.java │ │ ├── TarGzUtil.java │ │ ├── YamlUtil.java │ │ ├── ZipUtil.java │ │ └── jar │ │ │ ├── FatJarCreator.java │ │ │ ├── Launcher.java │ │ │ ├── MergeTest.java │ │ │ ├── fatjar_config.xml │ │ │ └── fatjar_合并jar包.txt │ │ ├── http │ │ ├── ApaHttpClientUtil.java │ │ ├── CookieUtil.java │ │ ├── HttpUtil.java │ │ ├── HttpUtils.java │ │ ├── IPUtils.java │ │ ├── MySSLProtocolSocketFactory.java │ │ ├── MyX509TrustManager.java │ │ ├── RestTemplateUtil.java │ │ ├── UrlUtil.java │ │ └── WebTools.java │ │ ├── image │ │ └── ImageUtils.java │ │ ├── jmh │ │ ├── StringBuilderRunner.java │ │ └── StringConnectBenchmark.java │ │ ├── json │ │ ├── EricAnnotator.java │ │ ├── JsonCompareResult.java │ │ ├── JsonObjectTest.java │ │ ├── JsonSchemaToJson.java │ │ ├── JsonSchemaUtil.java │ │ ├── JsonSchemaUtils.java │ │ ├── JsonToPojo.java │ │ ├── JsonToSchema.java │ │ ├── Model.java │ │ └── Property.java │ │ ├── loopcall │ │ ├── ConfigServer.java │ │ └── LoopWorker.java │ │ ├── other │ │ ├── EnumUtil.java │ │ └── MyBloomFilter.java │ │ ├── redis │ │ └── RedisUtil.java │ │ ├── spring │ │ └── SpringContextUtil.java │ │ ├── ssh │ │ ├── SSHHelper.java │ │ └── SSHResInfo.java │ │ ├── string │ │ ├── CharTools.java │ │ ├── StringHelper.java │ │ └── ValidateUtil.java │ │ ├── thread │ │ └── ThreadPoolMonitor.java │ │ ├── version │ │ └── VersionIncreaseUtil.java │ │ └── websocket │ │ ├── Message.java │ │ ├── Session.java │ │ ├── TextMessage.java │ │ └── WebSocketUtil.java └── resources │ ├── ehcache.xml │ ├── fatjar_config.xml │ ├── jdbc.properties │ └── templete │ ├── cid-component-java-example-1.0.0.jar │ ├── cid-component-project-java-common-1.2.0-SNAPSHOT.jar │ ├── ipaas-component-java-common-1.2.0-SNAPSHOT.jar │ └── ipaas-component-java8-sample-1.0.0.jar └── test └── java └── cn └── eric └── jdktools ├── CacheTest.java └── UseItFromJavaTest.java /README.md: -------------------------------------------------------------------------------- 1 | # JDKTools 2 | 基于JDK8 的工具类合集 maven项目(持续更新 目前60+个工具类) 3 | 4 | ## 目录结构 5 | 6 | ### base64 7 | Base64Utils           // 图片转base64 base64转图片
8 | 9 | ### bean 10 | BeanToMapUtil           // 实体bean 转成map
11 | BeanCopyUtils           // 实体bean深度拷贝
12 | ### chart 13 | EchartsData           // Echarts使用类 14 | 15 | ### classes 16 | PackageUtil           // 名称空间实用工具 17 | 18 | ### code 19 | CodeUtil          // code码生成工具
20 | OrderNoUtil          // 订单编号生成工具类
21 | QRcodeUtils          // 二维码工具类
22 | RegExUtil          // 正则表达式工具类
23 | SnowflakeIdWorker          // 雪花编码生成工具
24 | VerificationCodeGeneration          // 验证码生成工具
25 | 26 | ### collection 27 | CollectionAllUtils          // List Map Set 工具集合(未完成)
28 | 29 | ### common 30 | Config          // 读取配置文件工具类 31 | 32 | ### data 33 | BigDecimalUtil          // 金额计算工具类
34 | NumUtil          // 格式化数字工具类
35 | 36 | ### date 37 | DateUtil           // 线程安全的日期工具类
38 | DateTimeUtil           // 普通日期工具类
39 | 40 | ### db 41 | JDBCUtils           // JDBC工具类
42 | 43 | ### encrypt 44 | AESUtil           // AES加解密工具类
45 | CharTools           // 字符工具类
46 | Escape           // 编解码工具类
47 | MD5Util           // MD5工具类
48 | 49 | ### exception 50 | ExceptionUtil          // 异常处理工具类 获取异常信息栈里的具体信息
51 | 52 | ### file 53 | Dom4jHelper          // Dom4j工具类
54 | FileHelper          // 文件工具类 移动 复制
55 | FileUploadUtil          // 文件上传工具类
56 | FileUtil          // 文件工具类 常用的文件操作
57 | UploadHelper          // 异常处理工具类
58 | ExcelHanlder          // 普通Excel工具类
59 | ExcelUtil          // 阿里 EasyExcel工具类
60 | FtpUtil          // FTP工具类
61 | MD5FileCheckUtil          // MD5工具类
62 | TarGzUtils          // TAR包读取内部文件工具类
63 | YamlUtil          // YML文件工具类
64 | ZipUtil          // 解压缩工具类
65 | 66 | ### http 67 | HttpUtil          // http 和 https 工具类
68 | MyX509TrustManager          // HttpUtil的依赖类
69 | HttpUtils          // http 和 https 工具类2
70 | CookieUtil          // cookie操作工具类
71 | ApaHttpClientUtil          // http 和 https 工具类3
72 | MySSLProtocolSocketFactory          // ApaHttpClientUtil的依赖类
73 | IPUtils          // IP工具类
74 | RestTemplateUtil          // RestTemplate工具类
75 | UrlUtil          // url解析工具
76 | WebTools          // WEB开发常用工具类 特殊字符处理等
77 | 78 | ### image 79 | ImageUtils          // 图片处理工具类
80 | 81 | ### jmh 82 | 83 | ### json 84 | JsonSchemaUtil          // jsonschema对比工具类
85 | JsonSchemaUtils          // jsonschema工具类
86 | JSONUtils          // json工具类
87 | JsonToPojo          // json转pojo工具类
88 | JsonToSchema          // json转schema工具类
89 | 90 | 91 | ### other 92 | EnumUtil          // 枚举工具类
93 | MyBloomFilter          // 布隆过滤器
94 | 95 | ### redis 96 | RedisUtil          // Jedis工具类
97 | 98 | ### spring 99 | SpringContextUtil          // SpringContext工具类
100 | 101 | ### spring 102 | CharTools          // 字符编码工具类
103 | StringHelper          // 字符串工具类
104 | ValidateUtil          // 验证工具类(车牌、手机、邮箱,待补充)
105 | 106 | ### ssh 107 | SSHHelper          // SSH远程连接工具类
108 | 109 | ### string 110 | CharTools          // 字符编码工具集
111 | ValidateUtil          // 字符验证工具集
112 | 113 | ### thread 114 | ThreadPoolMonitor          // 线程池监控工具
115 | 116 | ### version 117 | VersionIncreaseUtil.java          // 版本号自增工具
118 | 119 | ### websocket 120 | WebSocketUtil          // WebSocket工具类
121 | 122 | -------------------------------------------------------------------------------- /html/echarts/demo-bar.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ECharts Demo 7 | 10 | 36 | 37 | 38 | 39 |
40 |
41 |

ECharts Java

42 | 43 |
44 |
45 |
46 |
47 | 48 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /html/echarts/demo-line1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ECharts Demo 7 | 10 | 36 | 37 | 38 | 39 |
40 |
41 |

ECharts Java

42 | 43 |
44 |
45 |
46 |
47 | 48 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /html/echarts/demo-line2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ECharts Demo 7 | 10 | 36 | 37 | 38 | 39 |
40 |
41 |

ECharts Java

42 | 43 |
44 |
45 |
46 |
47 | 48 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /html/echarts/demo-pie.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ECharts Demo 7 | 10 | 36 | 37 | 38 | 39 |
40 |
41 |

ECharts Java

42 | 43 |
44 |
45 |
46 |
47 | 48 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /json/input.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Virat", 3 | "sport": "cricket", 4 | "age": 25, 5 | "id": 121 6 | } -------------------------------------------------------------------------------- /json/inputSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "type" : "object", 3 | "title" : "Example Schema", 4 | "properties" : { 5 | "age" : { 6 | "type" : "integer", 7 | "description" : "Age in years", 8 | "minimum" : 0 9 | }, 10 | "firstName" : { 11 | "type" : "string" 12 | }, 13 | "lastName" : { 14 | "type" : "string" 15 | }, 16 | "department": { 17 | "type": "object", 18 | "title": "department", 19 | "properties": { 20 | "id": { 21 | "title": "部门id", 22 | "type": "integer" 23 | }, 24 | "name": { 25 | "title": "部门名称", 26 | "type": "string" 27 | } 28 | } 29 | } 30 | }, 31 | "description" : "this is a input model", 32 | "required" : [ "firstName", "lastName" ] 33 | } -------------------------------------------------------------------------------- /lib/mysql-connector-java-5.1.49.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EricLoveMia/JavaTools/1fe72617fac473a978f73136627e73a5c792c205/lib/mysql-connector-java-5.1.49.jar -------------------------------------------------------------------------------- /params.json: -------------------------------------------------------------------------------- 1 | {"ComponentSample":{"generalParameterJsonschema":"{\"$schema\":\"https://json-schema.org/draft/2019-09/schema\",\"type\":\"object\",\"properties\":{\"operate\":{\"type\":\"string\",\"title\":\"操作\",\"description\":\"操作类型 sum:求和 max:求最大值\"}}}","requestJsonschema":"{\"$schema\":\"https://json-schema.org/draft/2019-09/schema\",\"type\":\"object\",\"properties\":{\"caseOne\":{\"type\":\"number\",\"title\":\"操作数1\"},\"caseTwo\":{\"type\":\"number\",\"title\":\"操作数2\"}}}","responseJsonschema":"{\"$schema\":\"https://json-schema.org/draft/2019-09/schema\",\"type\":\"object\",\"properties\":{\"description\":{\"type\":\"string\",\"title\":\"结果说明\",\"description\":\"说明\"},\"resultPoint\":{\"type\":\"number\",\"title\":\"结果值\",\"description\":\"计算的结果\"}}}"},"ComponentSample2":{"generalParameterJsonschema":"{\"$schema\":\"https://json-schema.org/draft/2019-09/schema\",\"type\":\"object\",\"properties\":{\"operate\":{\"type\":\"string\",\"title\":\"操作\",\"description\":\"操作类型 sum:求和 max:求最大值\"}}}","requestJsonschema":"{\"$schema\":\"https://json-schema.org/draft/2019-09/schema\",\"type\":\"object\",\"properties\":{\"caseOne\":{\"type\":\"number\",\"title\":\"操作数1\"},\"caseTwo\":{\"type\":\"number\",\"title\":\"操作数2\"}}}","responseJsonschema":"{\"$schema\":\"https://json-schema.org/draft/2019-09/schema\",\"type\":\"object\",\"properties\":{\"description\":{\"type\":\"string\",\"title\":\"结果说明\",\"description\":\"说明\"},\"resultPoint\":{\"type\":\"number\",\"title\":\"结果值\",\"description\":\"计算的结果\"}}}"}} -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/ToolsMain.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools; 2 | 3 | /** 4 | * @author Eric 5 | * @version 1.0 6 | * @ClassName: ToolsMain 7 | * @Description: TODO 8 | * @company lsj 9 | * @date 2019/8/1 14:35 10 | **/ 11 | public class ToolsMain { 12 | 13 | public static void main(String[] args) { 14 | System.out.println("hello tools"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/base/InputProperties.java: -------------------------------------------------------------------------------- 1 | 2 | package cn.eric.jdktools.base; 3 | 4 | import com.fasterxml.jackson.annotation.*; 5 | 6 | import javax.annotation.Generated; 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | 11 | /** 12 | * 方法入参 13 | *

14 | * 方法入参的实体类 15 | * 16 | */ 17 | @JsonInclude(JsonInclude.Include.NON_NULL) 18 | @JsonPropertyOrder({ 19 | "age", 20 | "name" 21 | }) 22 | @Generated("jsonschema2pojo") 23 | public class InputProperties { 24 | 25 | /** 26 | * 年龄 27 | *

28 | * 填写年龄 29 | * 30 | */ 31 | @JsonProperty("age") 32 | @JsonPropertyDescription("\u586b\u5199\u5e74\u9f84") 33 | private Integer age; 34 | /** 35 | * 姓名 36 | *

37 | * 填写姓名 38 | * (Required) 39 | * 40 | */ 41 | @JsonProperty("name") 42 | @JsonPropertyDescription("\u586b\u5199\u59d3\u540d") 43 | private String name; 44 | @JsonIgnore 45 | private Map additionalProperties = new HashMap(); 46 | 47 | /** 48 | * 年龄 49 | *

50 | * 填写年龄 51 | * 52 | */ 53 | @JsonProperty("age") 54 | public Integer getAge() { 55 | return age; 56 | } 57 | 58 | /** 59 | * 年龄 60 | *

61 | * 填写年龄 62 | * 63 | */ 64 | @JsonProperty("age") 65 | public void setAge(Integer age) { 66 | this.age = age; 67 | } 68 | 69 | public InputProperties withAge(Integer age) { 70 | this.age = age; 71 | return this; 72 | } 73 | 74 | /** 75 | * 姓名 76 | *

77 | * 填写姓名 78 | * (Required) 79 | * 80 | */ 81 | @JsonProperty("name") 82 | public String getName() { 83 | return name; 84 | } 85 | 86 | /** 87 | * 姓名 88 | *

89 | * 填写姓名 90 | * (Required) 91 | * 92 | */ 93 | @JsonProperty("name") 94 | public void setName(String name) { 95 | this.name = name; 96 | } 97 | 98 | public InputProperties withName(String name) { 99 | this.name = name; 100 | return this; 101 | } 102 | 103 | @JsonAnyGetter 104 | public Map getAdditionalProperties() { 105 | return this.additionalProperties; 106 | } 107 | 108 | @JsonAnySetter 109 | public void setAdditionalProperty(String name, Object value) { 110 | this.additionalProperties.put(name, value); 111 | } 112 | 113 | public InputProperties withAdditionalProperty(String name, Object value) { 114 | this.additionalProperties.put(name, value); 115 | return this; 116 | } 117 | 118 | @Override 119 | public String toString() { 120 | StringBuilder sb = new StringBuilder(); 121 | sb.append(InputProperties.class.getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))).append('['); 122 | sb.append("age"); 123 | sb.append('='); 124 | sb.append(((this.age == null)?"":this.age)); 125 | sb.append(','); 126 | sb.append("name"); 127 | sb.append('='); 128 | sb.append(((this.name == null)?"":this.name)); 129 | sb.append(','); 130 | sb.append("additionalProperties"); 131 | sb.append('='); 132 | sb.append(((this.additionalProperties == null)?"":this.additionalProperties)); 133 | sb.append(','); 134 | if (sb.charAt((sb.length()- 1)) == ',') { 135 | sb.setCharAt((sb.length()- 1), ']'); 136 | } else { 137 | sb.append(']'); 138 | } 139 | return sb.toString(); 140 | } 141 | 142 | @Override 143 | public int hashCode() { 144 | int result = 1; 145 | result = ((result* 31)+((this.name == null)? 0 :this.name.hashCode())); 146 | result = ((result* 31)+((this.additionalProperties == null)? 0 :this.additionalProperties.hashCode())); 147 | result = ((result* 31)+((this.age == null)? 0 :this.age.hashCode())); 148 | return result; 149 | } 150 | 151 | @Override 152 | public boolean equals(Object other) { 153 | if (other == this) { 154 | return true; 155 | } 156 | if ((other instanceof InputProperties) == false) { 157 | return false; 158 | } 159 | InputProperties rhs = ((InputProperties) other); 160 | return ((((this.name == rhs.name)||((this.name!= null)&&this.name.equals(rhs.name)))&&((this.additionalProperties == rhs.additionalProperties)||((this.additionalProperties!= null)&&this.additionalProperties.equals(rhs.additionalProperties))))&&((this.age == rhs.age)||((this.age!= null)&&this.age.equals(rhs.age)))); 161 | } 162 | 163 | } 164 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/base/Test.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.base; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.fasterxml.jackson.annotation.JsonPropertyDescription; 5 | import io.swagger.v3.oas.annotations.media.Schema; 6 | 7 | /** 8 | * Company: 苏州渠成易销网络科技有限公司 9 | * 10 | * @version 1.0.0 11 | * @description: 测试 12 | * @author: 钱旭 13 | * @date: 2022-01-07 14:29 14 | **/ 15 | public class Test { 16 | // @JsonProperty(required = true,value = "name") 17 | // @JsonPropertyDescription("This is a property description") 18 | 19 | @Schema(title = "名称",description = "这是一个名称") 20 | private String name; 21 | 22 | // @JsonProperty(value = "child") 23 | // @JsonPropertyDescription("This is a property description") 24 | @Schema(title = "孩子",description = "这是一个孩子") 25 | private TestChild child; 26 | 27 | // @JsonCreator 28 | // public Test ( 29 | // @JsonProperty("name") String name, 30 | // @JsonProperty("child") TestChild child) { 31 | // this.name = name; 32 | // this.child = child; 33 | // } 34 | public String getName () { 35 | return name; 36 | } 37 | public TestChild getChild () { 38 | return child; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/base/TestChild.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.base; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.fasterxml.jackson.annotation.JsonPropertyDescription; 5 | 6 | /** 7 | * Company: 苏州渠成易销网络科技有限公司 8 | * 9 | * @version 1.0.0 10 | * @description: 测试子类 11 | * @author: 钱旭 12 | * @date: 2022-01-07 14:31 13 | **/ 14 | 15 | public class TestChild { 16 | @JsonProperty(required = true) 17 | @JsonPropertyDescription("这是一个孩子") 18 | private String childName; 19 | // @JsonCreator 20 | // public TestChild (@JsonProperty("childName") String childName) { 21 | // this.childName = childName; 22 | // } 23 | // 24 | public String getChildName () { 25 | return childName; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/base64/Base64Utils.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.base64; 2 | 3 | import sun.misc.BASE64Decoder; 4 | import sun.misc.BASE64Encoder; 5 | 6 | import javax.imageio.ImageIO; 7 | import java.awt.image.BufferedImage; 8 | import java.io.*; 9 | import java.net.HttpURLConnection; 10 | import java.net.URL; 11 | 12 | /** 13 | * @author Eric 14 | * @version 1.0 15 | * @ClassName: Base64Utils 16 | * @Description: TODO 17 | * @company lsj 18 | * @date 2018/11/16 15:33 19 | **/ 20 | public class Base64Utils { 21 | 22 | public static void main(String[] args) throws Exception { 23 | 24 | //本地图片地址 25 | String url = "C:\\Users\\Eric\\Pictures\\upload\\1.jpg"; 26 | //在线图片地址 27 | //String string = "http://bpic.588ku.com//element_origin_min_pic/17/03/03/7bf4480888f35addcf2ce942701c728a.jpg"; 28 | 29 | String str = Base64Utils.ImageToBase64ByLocal(url); 30 | 31 | //String ste = Base64Utils.ImageToBase64ByOnline(string); 32 | 33 | System.out.println(str); 34 | 35 | //Base64Utils.Base64ToImage(str,"C:/Users/Administrator/Desktop/test1.jpg"); 36 | 37 | //Base64Utils.Base64ToImage(ste, "C:/Users/Administrator/Desktop/test2.jpg"); 38 | } 39 | 40 | /** 41 | * 本地图片转换成base64字符串 42 | * @param imgFile 图片本地路径 43 | * @return 44 | * 45 | * @author ZHANGJL 46 | * @dateTime 2018-02-23 14:40:46 47 | */ 48 | public static String ImageToBase64ByLocal(String imgFile) {// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 49 | 50 | 51 | InputStream in = null; 52 | byte[] data = null; 53 | 54 | // 读取图片字节数组 55 | try { 56 | // new FileInputStream(new File(imgFile)); 57 | in = new FileInputStream(imgFile); 58 | 59 | data = new byte[in.available()]; 60 | in.read(data); 61 | in.close(); 62 | } catch (IOException e) { 63 | e.printStackTrace(); 64 | } 65 | // 对字节数组Base64编码 66 | BASE64Encoder encoder = new BASE64Encoder(); 67 | 68 | return encoder.encode(data);// 返回Base64编码过的字节数组字符串 69 | } 70 | 71 | public static String ImageToBase64ByLocal(File file) {// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 File类型 72 | InputStream in = null; 73 | byte[] data = null; 74 | 75 | // 读取图片字节数组 76 | try { 77 | in = new FileInputStream(file); 78 | // in = new FileInputStream(imgFile); 79 | 80 | data = new byte[in.available()]; 81 | in.read(data); 82 | in.close(); 83 | } catch (IOException e) { 84 | e.printStackTrace(); 85 | } 86 | // 对字节数组Base64编码 87 | BASE64Encoder encoder = new BASE64Encoder(); 88 | return encoder.encode(data);// 返回Base64编码过的字节数组字符串 89 | } 90 | 91 | 92 | /** 93 | * 在线图片转换成base64字符串 94 | * 95 | * @param imgURL 图片线上路径 96 | * @return 97 | * 98 | * @author ZHANGJL 99 | * @dateTime 2018-02-23 14:43:18 100 | */ 101 | public static String ImageToBase64ByOnline(String imgURL) { 102 | ByteArrayOutputStream data = new ByteArrayOutputStream(); 103 | try { 104 | // 创建URL 105 | URL url = new URL(imgURL); 106 | byte[] by = new byte[1024]; 107 | // 创建链接 108 | HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 109 | conn.setRequestMethod("GET"); 110 | conn.setConnectTimeout(5000); 111 | InputStream is = conn.getInputStream(); 112 | // 将内容读取内存中 113 | int len = -1; 114 | while ((len = is.read(by)) != -1) { 115 | data.write(by, 0, len); 116 | } 117 | // 关闭流 118 | is.close(); 119 | } catch (IOException e) { 120 | e.printStackTrace(); 121 | } 122 | // 对字节数组Base64编码 123 | BASE64Encoder encoder = new BASE64Encoder(); 124 | return encoder.encode(data.toByteArray()); 125 | } 126 | 127 | 128 | /** 129 | * base64字符串转换成图片 130 | * @param imgStr base64字符串 131 | * @param imgFilePath 图片存放路径 132 | * @return 133 | * 134 | * @author ZHANGJL 135 | * @dateTime 2018-02-23 14:42:17 136 | */ 137 | public static boolean Base64ToImage(String imgStr,String imgFilePath) { // 对字节数组字符串进行Base64解码并生成图片 138 | 139 | if (imgStr == null && imgStr.isEmpty()) // 图像数据为空 140 | return false; 141 | 142 | BASE64Decoder decoder = new BASE64Decoder(); 143 | try { 144 | // Base64解码 145 | byte[] b = decoder.decodeBuffer(imgStr); 146 | for (int i = 0; i < b.length; ++i) { 147 | if (b[i] < 0) {// 调整异常数据 148 | b[i] += 256; 149 | } 150 | } 151 | 152 | OutputStream out = new FileOutputStream(imgFilePath); 153 | out.write(b); 154 | out.flush(); 155 | out.close(); 156 | 157 | return true; 158 | } catch (Exception e) { 159 | return false; 160 | } 161 | 162 | } 163 | 164 | /** 165 | * 通过BufferedImage 转成 base64 166 | * @author Eric 167 | * @date 14:37 2019/2/25 168 | * @params image 169 | * @throws 170 | * @return java.lang.String 171 | **/ 172 | public static String ImageToBase64ByBuffered(BufferedImage image) throws IOException { 173 | 174 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 175 | ImageIO.write(image, "jpg", outputStream); 176 | BASE64Encoder encoder = new BASE64Encoder(); 177 | String base64Img = encoder.encode(outputStream.toByteArray()); 178 | 179 | return base64Img; 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/bean/BeanCopyUtils.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.bean; 2 | 3 | import java.io.*; 4 | import java.util.List; 5 | 6 | /** 7 | * @version 1.0.0 8 | * @description: 9 | * @author: eric 10 | * @date: 2022-08-05 17:04 11 | **/ 12 | public class BeanCopyUtils { 13 | 14 | /** 15 | * Desc: 深度拷贝 16 | * Author: Jack 17 | **/ 18 | public static List deepCopy(List srcList) throws IOException, ClassNotFoundException { 19 | //序列化 20 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 21 | ObjectOutputStream oos = new ObjectOutputStream(baos); 22 | oos.writeObject(srcList); 23 | 24 | //反序列化 25 | ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 26 | ObjectInputStream ois = new ObjectInputStream(bais); 27 | List desList = (List) ois.readObject(); 28 | return desList; 29 | } 30 | 31 | /** 32 | * Desc: 深度拷贝 33 | * Author: Jack 34 | **/ 35 | public static T deepCopy(T src) throws IOException, ClassNotFoundException { 36 | //序列化 37 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 38 | ObjectOutputStream oos = new ObjectOutputStream(baos); 39 | oos.writeObject(src); 40 | 41 | //反序列化 42 | ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 43 | ObjectInputStream ois = new ObjectInputStream(bais); 44 | T des = (T) ois.readObject(); 45 | return des; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/bean/BeanToMapUtil.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.bean; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.Modifier; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * @author Eric 10 | * @version 1.0 11 | * @ClassName: BeanToMapUtil 12 | * @Description: TODO 13 | * @company lsj 14 | * @date 2019/4/24 17:18 15 | **/ 16 | public class BeanToMapUtil { 17 | 18 | /** 19 | * 实体对象转成Map 20 | * @param obj 实体对象 21 | * @return 22 | */ 23 | public static Map object2Map(Object obj) { 24 | Map map = new HashMap<>(); 25 | if (obj == null) { 26 | return map; 27 | } 28 | Class clazz = obj.getClass(); 29 | Field[] fields = clazz.getDeclaredFields(); 30 | try { 31 | for (Field field : fields) { 32 | field.setAccessible(true); 33 | map.put(field.getName(), field.get(obj)); 34 | } 35 | } catch (Exception e) { 36 | e.printStackTrace(); 37 | } 38 | return map; 39 | } 40 | 41 | /** 42 | * 实体对象转成Map 43 | * @param obj 实体对象 string 44 | * @returnString 45 | */ 46 | public static Map object2MapString(Object obj) { 47 | Map map = new HashMap<>(); 48 | if (obj == null) { 49 | return map; 50 | } 51 | Class clazz = obj.getClass(); 52 | Field[] fields = clazz.getDeclaredFields(); 53 | try { 54 | for (Field field : fields) { 55 | field.setAccessible(true); 56 | map.put(field.getName(), field.get(obj).toString()); 57 | } 58 | } catch (Exception e) { 59 | e.printStackTrace(); 60 | } 61 | return map; 62 | } 63 | 64 | /** 65 | * Map转成实体对象 66 | * @param map map实体对象包含属性 67 | * @param clazz 实体对象类型 68 | * @return 69 | */ 70 | public static Object map2Object(Map map, Class clazz) { 71 | if (map == null) { 72 | return null; 73 | } 74 | Object obj = null; 75 | try { 76 | obj = clazz.newInstance(); 77 | 78 | Field[] fields = obj.getClass().getDeclaredFields(); 79 | for (Field field : fields) { 80 | int mod = field.getModifiers(); 81 | if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) { 82 | continue; 83 | } 84 | field.setAccessible(true); 85 | field.set(obj, map.get(field.getName())); 86 | } 87 | } catch (Exception e) { 88 | e.printStackTrace(); 89 | } 90 | return obj; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/cache/ICache.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.cache; 2 | 3 | import java.util.concurrent.Callable; 4 | import java.util.concurrent.ExecutionException; 5 | 6 | /** 7 | * Company: ClickPaaS 8 | * 9 | * @version 1.0.0 10 | * @description: 缓存公共接口 11 | * @author: 钱旭 12 | * @date: 2022-02-22 11:41 13 | **/ 14 | public interface ICache { 15 | 16 | /** 17 | * 通过key获取缓存中的value,若不存在直接返回null 18 | */ 19 | V getIfPresent(K key); 20 | 21 | /** 22 | * 添加缓存,若key存在,就覆盖旧值 23 | */ 24 | void put(K key, V value); 25 | 26 | /** 27 | * 删除该key关联的缓存 28 | */ 29 | void invalidate(K key); 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/cache/caffeine/CaffeineCache.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.cache.caffeine; 2 | 3 | import com.github.benmanes.caffeine.cache.Cache; 4 | import com.github.benmanes.caffeine.cache.Caffeine; 5 | 6 | import java.util.concurrent.TimeUnit; 7 | 8 | /** 9 | * Company: ClickPaaS 10 | * 11 | * @version 1.0.0 12 | * @description: caffeine工具 13 | * @author: 钱旭 14 | * @date: 2022-02-22 13:56 15 | **/ 16 | public class CaffeineCache { 17 | 18 | static final Cache manualCache; 19 | 20 | static { 21 | manualCache = Caffeine.newBuilder() 22 | .expireAfterWrite(10, TimeUnit.MINUTES) 23 | .maximumSize(10_000) 24 | .build(); 25 | } 26 | /** 27 | * 获取缓存 28 | * @param key 29 | * @return 30 | */ 31 | public static Object getById(Object key){ 32 | return manualCache.getIfPresent(key); 33 | } 34 | 35 | /** 36 | * 添加缓存 37 | * @param key 38 | * @param value 39 | */ 40 | public static void addById(Object key, Object value){ 41 | manualCache.put(key, value); 42 | } 43 | 44 | /** 45 | * 删除缓存 46 | * @param key 47 | */ 48 | public static void invalidate(Object key){ 49 | manualCache.invalidate(key); 50 | } 51 | 52 | } 53 | 54 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/cache/caffeine/CaffeineService.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.cache.caffeine; 2 | 3 | import cn.eric.jdktools.cache.ICache; 4 | 5 | import java.util.concurrent.Callable; 6 | import java.util.concurrent.ExecutionException; 7 | 8 | /** 9 | * Company: ClickPaaS 10 | * 11 | * @version 1.0.0 12 | * @description: caffeine缓存服务实现类 13 | * @author: 钱旭 14 | * @date: 2022-02-22 14:11 15 | **/ 16 | public class CaffeineService implements ICache { 17 | 18 | @Override 19 | public V getIfPresent(K key) { 20 | return (V) CaffeineCache.getById(key); 21 | } 22 | 23 | @Override 24 | public void put(K key, V value) { 25 | CaffeineCache.addById(key,value); 26 | } 27 | 28 | @Override 29 | public void invalidate(K key) { 30 | CaffeineCache.invalidate(key); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/cache/ehcache/EhCacheUtil.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.cache.ehcache; 2 | 3 | import net.sf.ehcache.Cache; 4 | import net.sf.ehcache.CacheManager; 5 | import net.sf.ehcache.Element; 6 | 7 | /** 8 | * Company: ClickPaaS 9 | * 10 | * @version 1.0.0 11 | * @description: ehcache工具 12 | * @author: 钱旭 13 | * @date: 2022-02-22 14:06 14 | **/ 15 | public class EhCacheUtil { 16 | 17 | /** 18 | * @Description: 获取缓存 19 | * @param cacheName 缓存名字 20 | * @return Cache 21 | * @Autor: Jason 22 | */ 23 | private static Cache getCache(String cacheName) { 24 | CacheManager cacheManager = CacheManager.getInstance(); 25 | if (null == cacheManager) { 26 | return null; 27 | } 28 | Cache cache = cacheManager.getCache(cacheName); 29 | if (null == cache) { 30 | return null; 31 | } 32 | return cache; 33 | } 34 | 35 | /** 36 | * @Description: 新增缓存记录 37 | * @param cacheName 缓存名字 38 | * @param key 缓存key 39 | * @Autor: Jason 40 | */ 41 | public static void put(String cacheName, String key, Object value) { 42 | Cache cache = getCache(cacheName); 43 | if (null != cache) { 44 | Element element = new Element(key, value); 45 | cache.put(element); 46 | } 47 | } 48 | 49 | /** 50 | * @Description: 删除缓存记录 51 | * @param cacheName 缓存名字 52 | * @param key 缓存key 53 | * @return boolean 是否成功删除 54 | * @Autor: Jason 55 | */ 56 | public static boolean remove(String cacheName, String key) { 57 | Cache cache = getCache(cacheName); 58 | if (null == cache) { 59 | return false; 60 | } 61 | return cache.remove(key); 62 | } 63 | 64 | /** 65 | * @Description: 删除全部缓存记录 66 | * @param cacheName 缓存名字 67 | * @Autor: Jason 68 | */ 69 | public static void removeAll(String cacheName) { 70 | Cache cache = getCache(cacheName); 71 | if (null != cache) { 72 | //logOnRemoveAllIfPinnedCache(); 73 | cache.removeAll(); 74 | } 75 | } 76 | 77 | /** 78 | * @Description: 获取缓存记录 79 | * @param cacheName 缓存名字 80 | * @param key 缓存key 81 | * @return Object 缓存记录数据Object 82 | * @Autor: Jason 83 | */ 84 | public static Object get(String cacheName, String key) { 85 | Cache cache = getCache(cacheName); 86 | if (null == cache) { 87 | return null; 88 | } 89 | Element cacheElement = cache.get(key); 90 | if (null == cacheElement) { 91 | return null; 92 | } 93 | return cacheElement.getObjectValue(); 94 | } 95 | 96 | 97 | } 98 | 99 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/cache/guava/GuavaCache.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.cache.guava; 2 | 3 | import com.google.common.cache.Cache; 4 | import com.google.common.cache.CacheBuilder; 5 | 6 | import java.util.concurrent.TimeUnit; 7 | 8 | /** 9 | * Company: ClickPaaS 10 | * 11 | * @version 1.0.0 12 | * @description: guava-cache工具类 13 | * @author: 钱旭 14 | * @date: 2022-02-22 13:59 15 | **/ 16 | public class GuavaCache { 17 | 18 | final static Cache manualCache = CacheBuilder.newBuilder() 19 | //设置cache的初始大小为10,要合理设置该值 20 | .initialCapacity(10) 21 | //设置并发数为5,即同一时间最多只能有5个线程往cache执行写入操作 22 | .concurrencyLevel(5) 23 | //设置cache中的数据在写入之后的存活时间为10秒 24 | .expireAfterWrite(10, TimeUnit.SECONDS) 25 | //构建cache实例 26 | .build(); 27 | 28 | /** 29 | * 获取缓存 30 | * @param key 31 | * @return 32 | */ 33 | public static Object getById(Object key){ 34 | return manualCache.getIfPresent(key); 35 | } 36 | 37 | 38 | /** 39 | * 添加缓存 40 | * @param key 41 | * @param value 42 | */ 43 | public static void addById(Object key, Object value){ 44 | manualCache.put(key, value); 45 | } 46 | 47 | /** 48 | * 删除缓存 49 | * @param key 50 | */ 51 | public static void invalidate(Object key){ 52 | manualCache.invalidate(key); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/cache/guava/GuavaService.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.cache.guava; 2 | 3 | import cn.eric.jdktools.cache.ICache; 4 | import cn.eric.jdktools.cache.caffeine.CaffeineCache; 5 | 6 | /** 7 | * Company: ClickPaaS 8 | * 9 | * @version 1.0.0 10 | * @description: caffeine缓存服务实现类 11 | * @author: 钱旭 12 | * @date: 2022-02-22 14:11 13 | **/ 14 | public class GuavaService implements ICache { 15 | 16 | @Override 17 | public V getIfPresent(K key) { 18 | return (V) GuavaCache.getById(key); 19 | } 20 | 21 | @Override 22 | public void put(K key, V value) { 23 | GuavaCache.addById(key,value); 24 | } 25 | 26 | @Override 27 | public void invalidate(K key) { 28 | GuavaCache.invalidate(key); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/code/CodeUtil.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright(c) Jade Techonologies Co., Ltd. 3 | */ 4 | package cn.eric.jdktools.code; 5 | 6 | import java.util.Random; 7 | 8 | /** 9 | * 随机产生数字和字母的字符串 10 | * @author Eric 11 | * @date 14:59 2019/8/1 12 | **/ 13 | public class CodeUtil 14 | { 15 | private static String[] numArr = {"0","1","2","3","4","5","6","7","8","9"}; 16 | private static String[] letArr = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"}; 17 | 18 | //new Random().nextInt(10)产生的是0-9的随机数 19 | 20 | /** 21 | * 产生六位随机数,每一位都可以是数字 22 | * @return 23 | */ 24 | public static String createPolicyViewCode() 25 | { 26 | String viewCode = ""; 27 | for(int i=1;i<=6;i++) 28 | { 29 | String code = numArr[new Random().nextInt(10)]; 30 | viewCode+=code; 31 | } 32 | return viewCode; 33 | } 34 | 35 | public static String createTransCode() 36 | { 37 | String viewCode = ""; 38 | for(int i=1;i<=6;i++) 39 | { 40 | String code = letArr[new Random().nextInt(26)]; 41 | viewCode+=code; 42 | } 43 | return viewCode; 44 | } 45 | 46 | public static void main(String[] args) 47 | { 48 | System.out.println(createPolicyViewCode()); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/code/OrderNoUtil.java: -------------------------------------------------------------------------------- 1 | 2 | package cn.eric.jdktools.code; 3 | 4 | import org.apache.commons.lang.time.DateUtils; 5 | import org.apache.log4j.Logger; 6 | 7 | import java.text.DateFormat; 8 | import java.text.DecimalFormat; 9 | import java.text.SimpleDateFormat; 10 | import java.util.Calendar; 11 | import java.util.Date; 12 | import java.util.Random; 13 | 14 | /* * 15 | *类名:OrderNoUtil 16 | *功能:生成订单号 17 | *详细:工具类,可以用作获取系统日期、订单编号等 18 | */ 19 | 20 | public class OrderNoUtil { 21 | private static Logger logger = Logger.getLogger(OrderNoUtil.class); 22 | 23 | /** 年月日时分秒(无下划线) yyyyMMddHHmmssSSS */ 24 | public static final String dt = "yyyyMMddHHmmssSSS"; 25 | /** 年月日时分秒(无下划线) yyyyMMddHHmmss */ 26 | public static final String dtLong = "yyyyMMddHHmmss"; 27 | 28 | /** 完整时间 yyyy-MM-dd HH:mm:ss */ 29 | public static final String simple = "yyyy-MM-dd HH:mm:ss"; 30 | 31 | /** 年月日(无下划线) yyyyMMdd */ 32 | public static final String dtShort = "yyyyMMdd"; 33 | 34 | public static final String normalFormat = "yyyy-MM-dd"; 35 | public static final SimpleDateFormat normalSF = new SimpleDateFormat(normalFormat); 36 | 37 | /** 38 | * 返回系统当前时间(精确到毫秒),作为一个唯一的订单编号 39 | * @return 40 | * 以yyyyMMddHHmmss为格式的当前系统时间 41 | */ 42 | public static String getOrderNum(){ 43 | Date date=new Date(); 44 | DateFormat df=new SimpleDateFormat(dt); 45 | return df.format(date); 46 | } 47 | /** 48 | * 生成订单编号 49 | * 返回系统当前时间(精确到毫秒)+6位随机数,作为一个唯一的订单编号 50 | * @return 51 | * 以yyyyMMddHHmmss为格式的当前系统时间 52 | */ 53 | public static String getOrderNumNew(){ 54 | return getSuffix("I"); 55 | } 56 | //预支付交易流水号 57 | public static String getTradeCode(){ 58 | return getSuffix("TR"); 59 | } 60 | public static String getPolicyNumNew() {return getSuffix("P");} 61 | public static String getAccountName() {return getSuffix("A");} 62 | public static String getAccName() {return getSuffix("AC");} 63 | public static String getTrOrderNo() {return getSuffix("TR");} 64 | 65 | /** 66 | * 活力商场 卡劵 接口 67 | */ 68 | public static String coupon(){ 69 | return getSuffix("COUPON"); 70 | } 71 | 72 | /** 73 | * 活力商场 卡劵批次导入 接口 74 | */ 75 | public static String couponImportBatch(){ 76 | return getSuffix("CIB"); 77 | } 78 | 79 | /** 80 | * 活力商场 卡劵批次导入 接口 81 | */ 82 | public static String cltTipImportBatch(){ 83 | return getSuffix("CTBATCh"); 84 | } 85 | 86 | //最新前缀 87 | private static String currPrefix = ""; 88 | //最新前缀,生成过的后缀列表 89 | private static String oldSuffix = ""; 90 | private static DateFormat df=new SimpleDateFormat("yyMMddHHmmssSSS"); 91 | private static DecimalFormat decF = new DecimalFormat("00"); 92 | private static Random rad=new Random(); 93 | 94 | 95 | /** 96 | * 返回一个唯唯一号 97 | * @param tag 98 | * @return 99 | */ 100 | public synchronized static String getSuffix(String tag) { 101 | String prefix = tag + df.format(new Date());// 前缀 102 | String suffix = decF.format(rad.nextInt(100));// 后缀 103 | if(prefix.equals(currPrefix)){//同一毫秒内 104 | if(oldSuffix.indexOf(suffix)>-1){//已经分配过 105 | try { 106 | Thread.sleep(1);//延时一毫秒 107 | } catch (Exception e) { 108 | logger.info("getSuffix",e); 109 | } 110 | prefix = tag + df.format(new Date());// 前缀 111 | currPrefix = prefix;//更改当前毫秒值 112 | suffix = decF.format(rad.nextInt(100));// 后缀 113 | oldSuffix="";//清空历史 后缀列表 114 | oldSuffix += ","+suffix; 115 | return prefix+suffix; 116 | }else{//生成的可用 117 | oldSuffix += ","+suffix;//添加到后缀列表中 118 | return prefix+suffix; 119 | } 120 | }else{ 121 | currPrefix = prefix;//更改当前毫秒值 122 | return prefix+suffix; 123 | } 124 | } 125 | 126 | public static int getDisHours(Date fromDate,Date toDate) 127 | { 128 | long from = fromDate.getTime(); 129 | long to = toDate.getTime(); 130 | int hours = (int) ((to - from)/(1000 * 60 * 60)); 131 | return hours; 132 | } 133 | 134 | /** 135 | * 获取以当前为基础时间,count需要添加的月数,dateNum为每一个月固定的日期 136 | * @param count 137 | * @param dateNum 138 | * @return 139 | * @throws Exception 140 | */ 141 | public static final Date getFixMonthDay(int count,int dateNum) throws Exception 142 | { 143 | SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 144 | Calendar c = Calendar.getInstance(); 145 | c.add(Calendar.MONTH, 0); 146 | c.set(Calendar.DAY_OF_MONTH, 1);//设置为1号,当前日期既为本月第一天 147 | Date date = c.getTime(); 148 | date = DateUtils.addMonths(date,count); 149 | date = DateUtils.addDays(date,dateNum-1); 150 | date = format.parse(format.format(date)); 151 | return date; 152 | } 153 | 154 | public static String getNormalFormat(Date date) 155 | { 156 | return normalSF.format(date); 157 | } 158 | 159 | /** 160 | * 获取当前日期,已yyyy-MM-dd格式返回 161 | * @return 162 | * @throws Exception 163 | */ 164 | public static final Date getCurrentDayDate() throws Exception 165 | { 166 | SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 167 | Date now = new Date(); 168 | return format.parse(format.format(now)); 169 | } 170 | 171 | } 172 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/code/RegExUtil.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.code; 2 | 3 | import java.util.*; 4 | import java.util.regex.*; 5 | 6 | /** 7 | * 这是个正则表达式应用类,用来匹配和替换字串用的 8 | * @author 9 | * @version 10 | */ 11 | 12 | public class RegExUtil { 13 | 14 | /** 15 | * 要求大小写都匹配正则表达式 16 | * @param pattern 正则表达式模式 17 | * @param str 要匹配的字串 18 | * @return boolean值 19 | * @since 1.0 20 | */ 21 | public static final boolean ereg(String pattern, String str) throws PatternSyntaxException 22 | { 23 | try 24 | { 25 | Pattern p = Pattern.compile(pattern); 26 | Matcher m = p.matcher(str); 27 | return m.find(); 28 | } 29 | catch (PatternSyntaxException e) 30 | { 31 | throw e; 32 | } 33 | } 34 | 35 | /** 36 | * 匹配且替换字串 37 | * @param pattern 正则表达式模式 38 | * @param newstr 要替换匹配到的新字串 39 | * @param str 原始字串 40 | * @return 匹配后的字符串 41 | * @since 1.0 42 | */ 43 | public static final String ereg_replace(String pattern, String newstr, String str) throws PatternSyntaxException 44 | { 45 | try 46 | { 47 | Pattern p = Pattern.compile(pattern); 48 | Matcher m = p.matcher(str); 49 | return m.replaceAll(newstr); 50 | } 51 | catch (PatternSyntaxException e) 52 | { 53 | throw e; 54 | } 55 | } 56 | 57 | /** 58 | * 主要用于模板中模块标记分析函数 把查找到的元素加到vector中 59 | * @param pattern 为正则表达式模式 60 | * @param str 原始字串 61 | * @return vector 62 | * @since 1.0 63 | */ 64 | public static final Vector splitTags2Vector(String pattern, String str) throws PatternSyntaxException 65 | { 66 | Vector vector = new Vector(); 67 | try { 68 | Pattern p = Pattern.compile(pattern); 69 | Matcher m = p.matcher(str); 70 | while (m.find()) 71 | { 72 | vector.add(ereg_replace("(\\[\\#)|(\\#\\])", "", m.group())); 73 | } 74 | return vector; 75 | } 76 | catch (PatternSyntaxException e) { 77 | throw e; 78 | } 79 | } 80 | 81 | /** 82 | * 模块标记分析函数 83 | * 功能主要是把查找到的元素加到String数组中 84 | * @param pattern 为正则表达式模式 85 | * @param str 原始字串 86 | * @since 1.0 87 | */ 88 | public static final String[] splitTags(String pattern, String str) 89 | { 90 | try { 91 | Pattern p = Pattern.compile(pattern); 92 | Matcher m = p.matcher(str); 93 | String[] array = new String[m.groupCount()]; 94 | int i = 0; 95 | while (m.find()) 96 | { 97 | array[i] = ereg_replace("(\\[\\#)|(\\#\\])", "", m.group()); 98 | i++; 99 | } 100 | return array; 101 | } 102 | catch (PatternSyntaxException e) { 103 | throw e; 104 | } 105 | } 106 | 107 | 108 | /** 109 | * 匹配所有符合模式要求的字串并加到矢量vector数组中 110 | * @param pattern 为正则表达式模式 111 | * @param str 原始字串 112 | * @return vector 113 | * @since 1.0 114 | */ 115 | public static final Vector regMatchAll2Vector(String pattern, String str) throws PatternSyntaxException 116 | { 117 | Vector vector = new Vector(); 118 | try 119 | { 120 | Pattern p = Pattern.compile(pattern); 121 | Matcher m = p.matcher(str); 122 | while (m.find()) 123 | { 124 | vector.add(m.group()); 125 | } 126 | return vector; 127 | } 128 | catch (PatternSyntaxException e) 129 | { 130 | throw e; 131 | } 132 | } 133 | 134 | /** 135 | * 匹配所有符合模式要求的字串并加到字符串数组中 136 | * @param pattern为正则表达式模式 137 | * @param str 原始字串 138 | * @return array 139 | * @since 1.0 140 | */ 141 | public static final String[] regMatchAll2Array(String pattern, String str) throws PatternSyntaxException 142 | { 143 | try 144 | { 145 | Pattern p = Pattern.compile(pattern); 146 | Matcher m = p.matcher(str); 147 | String[] array = new String[m.groupCount()]; 148 | int i = 0; 149 | while (m.find()) 150 | { 151 | array[i] = m.group(); 152 | i++; 153 | } 154 | return array; 155 | } 156 | catch (PatternSyntaxException e) 157 | { 158 | throw e; 159 | } 160 | } 161 | 162 | /** 163 | * 转义正则表达式字符(之所以需要将\和$字符用escapeDollarBackslash方法的方式是因为用repalceAll是不行的,简单的试试"$".repalceAll("\\$","\\\\$")你会发现这个调用会导致数组越界错误) 164 | * @param original 正则表达式 165 | * @return array 166 | * @since 1.0 167 | */ 168 | public static String escapeDollarBackslash(String original) { 169 | StringBuffer buffer=new StringBuffer(original.length()); 170 | for (int i=0;i 13 | * SnowFlake的结构如下(每部分用-分开):
14 | * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
15 | * 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0
16 | * 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截) 17 | * 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69
18 | * 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId
19 | * 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号
20 | * 加起来刚好64位,为一个Long型。
21 | * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。 22 | */ 23 | public class SnowflakeIdWorker { 24 | 25 | // ==============================Fields=========================================== 26 | /** 开始时间截 (2015-01-01) */ 27 | private final long twepoch = 1420041600000L; 28 | 29 | /** 机器id所占的位数 */ 30 | private final long workerIdBits = 5L; 31 | 32 | /** 数据标识id所占的位数 */ 33 | private final long datacenterIdBits = 5L; 34 | 35 | /** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */ 36 | private final long maxWorkerId = -1L ^ (-1L << workerIdBits); 37 | 38 | /** 支持的最大数据标识id,结果是31 */ 39 | private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); 40 | 41 | /** 序列在id中占的位数 */ 42 | private final long sequenceBits = 12L; 43 | 44 | /** 机器ID向左移12位 */ 45 | private final long workerIdShift = sequenceBits; 46 | 47 | /** 数据标识id向左移17位(12+5) */ 48 | private final long datacenterIdShift = sequenceBits + workerIdBits; 49 | 50 | /** 时间截向左移22位(5+5+12) */ 51 | private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; 52 | 53 | /** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */ 54 | private final long sequenceMask = -1L ^ (-1L << sequenceBits); 55 | 56 | /** 工作机器ID(0~31) */ 57 | private long workerId; 58 | 59 | /** 数据中心ID(0~31) */ 60 | private long datacenterId; 61 | 62 | /** 毫秒内序列(0~4095) */ 63 | private long sequence = 0L; 64 | 65 | /** 上次生成ID的时间截 */ 66 | private long lastTimestamp = -1L; 67 | 68 | //==============================Constructors===================================== 69 | /** 70 | * 构造函数 71 | * @param workerId 工作ID (0~31) 72 | * @param datacenterId 数据中心ID (0~31) 73 | */ 74 | public SnowflakeIdWorker(long workerId, long datacenterId) { 75 | if (workerId > maxWorkerId || workerId < 0) { 76 | throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); 77 | } 78 | if (datacenterId > maxDatacenterId || datacenterId < 0) { 79 | throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); 80 | } 81 | this.workerId = workerId; 82 | this.datacenterId = datacenterId; 83 | } 84 | 85 | // ==============================Methods========================================== 86 | /** 87 | * 获得下一个ID (该方法是线程安全的) 88 | * @return SnowflakeId 89 | */ 90 | public synchronized long nextId() { 91 | long timestamp = timeGen(); 92 | 93 | //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常 94 | if (timestamp < lastTimestamp) { 95 | throw new RuntimeException( 96 | String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); 97 | } 98 | 99 | //如果是同一时间生成的,则进行毫秒内序列 100 | if (lastTimestamp == timestamp) { 101 | sequence = (sequence + 1) & sequenceMask; 102 | //毫秒内序列溢出 103 | if (sequence == 0) { 104 | //阻塞到下一个毫秒,获得新的时间戳 105 | timestamp = tilNextMillis(lastTimestamp); 106 | } 107 | } 108 | //时间戳改变,毫秒内序列重置 109 | else { 110 | sequence = 0L; 111 | } 112 | 113 | //上次生成ID的时间截 114 | lastTimestamp = timestamp; 115 | 116 | //移位并通过或运算拼到一起组成64位的ID 117 | return ((timestamp - twepoch) << timestampLeftShift) // 118 | | (datacenterId << datacenterIdShift) // 119 | | (workerId << workerIdShift) // 120 | | sequence; 121 | } 122 | 123 | /** 124 | * 阻塞到下一个毫秒,直到获得新的时间戳 125 | * @param lastTimestamp 上次生成ID的时间截 126 | * @return 当前时间戳 127 | */ 128 | protected long tilNextMillis(long lastTimestamp) { 129 | long timestamp = timeGen(); 130 | while (timestamp <= lastTimestamp) { 131 | timestamp = timeGen(); 132 | } 133 | return timestamp; 134 | } 135 | 136 | /** 137 | * 返回以毫秒为单位的当前时间 138 | * @return 当前时间(毫秒) 139 | */ 140 | protected long timeGen() { 141 | return System.currentTimeMillis(); 142 | } 143 | 144 | //==============================Test============================================= 145 | /** 测试 */ 146 | public static void main(String[] args) { 147 | SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0, 0); 148 | for (int i = 0; i < 1000; i++) { 149 | long id = idWorker.nextId(); 150 | System.out.println(Long.toBinaryString(id)); 151 | System.out.println(id); 152 | } 153 | } 154 | } -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/code/VerificationCodeGeneration.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.code; 2 | 3 | import javax.imageio.ImageIO; 4 | import java.awt.*; 5 | import java.awt.image.BufferedImage; 6 | import java.awt.image.RenderedImage; 7 | import java.io.FileOutputStream; 8 | import java.io.OutputStream; 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | import java.util.Random; 12 | 13 | /** 14 | * 验证码生成 15 | */ 16 | public class VerificationCodeGeneration { 17 | 18 | /** 19 | * 定义图片的width 20 | */ 21 | private static int width = 90; 22 | /** 23 | * 定义图片的height 24 | */ 25 | private static int height = 20; 26 | /** 27 | * 定义图片上显示验证码的个数 28 | */ 29 | private static int codeCount = 4; 30 | private static int xx = 15; 31 | private static int fontHeight = 18; 32 | private static int codeY = 16; 33 | private static char[] codeSequence = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 34 | 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 35 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 36 | 'v', 'w', 'x', 'y', 'z'}; 37 | 38 | /** 39 | * 生成一个map集合 code为生成的验证码 codePic为生成的验证码BufferedImage对象 40 | * 41 | * @return 42 | */ 43 | public static Map generateCodeAndPic() { 44 | // 定义图像buffer 45 | BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 46 | Graphics gd = buffImg.getGraphics(); 47 | // 创建一个随机数生成器类 48 | Random random = new Random(); 49 | // 将图像填充为白色 50 | gd.setColor(Color.WHITE); 51 | gd.fillRect(0, 0, width, height); 52 | 53 | // 创建字体,字体的大小应该根据图片的高度来定。 54 | Font font = new Font("Fixedsys", Font.BOLD, fontHeight); 55 | // 设置字体。 56 | gd.setFont(font); 57 | 58 | // 画边框。 59 | gd.setColor(Color.BLACK); 60 | gd.drawRect(0, 0, width - 1, height - 1); 61 | 62 | // 随机产生40条干扰线,使图象中的认证码不易被其它程序探测到。 63 | gd.setColor(Color.BLACK); 64 | for (int i = 0; i < 10; i++) { 65 | int x = random.nextInt(width); 66 | int y = random.nextInt(height); 67 | int xl = random.nextInt(12); 68 | int yl = random.nextInt(12); 69 | gd.drawLine(x, y, x + xl, y + yl); 70 | } 71 | 72 | // randomCode用于保存随机产生的验证码,以便用户登录后进行验证。 73 | StringBuffer randomCode = new StringBuffer(); 74 | // int red = 0, green = 0, blue = 0; 75 | 76 | // 随机产生codeCount数字的验证码。 77 | for (int i = 0; i < codeCount; i++) { 78 | // 得到随机产生的验证码数字。 79 | String code = String.valueOf(codeSequence[random.nextInt(62)]); 80 | // 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。 81 | // red = random.nextInt(255); 82 | // green = random.nextInt(255); 83 | // blue = random.nextInt(255); 84 | 85 | // 用随机产生的颜色将验证码绘制到图像中。 86 | gd.setColor(Color.BLACK); 87 | gd.drawString(code, (i + 1) * xx, codeY); 88 | 89 | // 将产生的四个随机数组合在一起。 90 | randomCode.append(code); 91 | } 92 | gd.dispose(); 93 | Map map = new HashMap<>(16); 94 | // 存放验证码 95 | map.put("code", randomCode); 96 | // 存放生成的验证码BufferedImage对象 97 | map.put("codePic", buffImg); 98 | return map; 99 | } 100 | 101 | public static void main(String[] args) throws Exception { 102 | // 创建文件输出流对象 103 | OutputStream out = new FileOutputStream("E://test/" + System.currentTimeMillis() + ".jpg"); 104 | Map map = VerificationCodeGeneration.generateCodeAndPic(); 105 | ImageIO.write((RenderedImage) map.get("codePic"), "jpeg", out); 106 | System.out.println("验证码的值为:" + map.get("code")); 107 | System.out.println("验证码的值为:" + map.get("codePic")); 108 | } 109 | } -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/common/Config.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.common; 2 | 3 | import org.apache.log4j.Logger; 4 | import org.springframework.core.io.support.PropertiesLoaderUtils; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.io.IOException; 8 | import java.util.Calendar; 9 | import java.util.Properties; 10 | 11 | @Component 12 | public class Config { 13 | static Logger logger = Logger.getLogger(Config.class); 14 | private static Properties conf = new Properties(); 15 | 16 | /** 17 | * 根据状态得到对应的图标路径 18 | * @param pro_key 19 | * @return 20 | */ 21 | public static String getConfInfo(String pro_key){ 22 | try { 23 | conf = PropertiesLoaderUtils.loadAllProperties("redis.properties"); 24 | } catch (IOException e) { 25 | e.printStackTrace(); 26 | } 27 | return conf.getProperty(pro_key); 28 | } 29 | 30 | public static void main(String[] args) { 31 | // logger.info(getIconSrc("stay")); 32 | // logger.info(getColor("OCC")); 33 | String t1 = "00:00"; 34 | String t2 = "11:11"; 35 | String t3 = "12:12"; 36 | String t4 = "02:12"; 37 | logger.info(t2.compareTo(t1)); 38 | logger.info(t3.compareTo(t2)); 39 | logger.info(t1.compareTo(t3)); 40 | Calendar cal = Calendar.getInstance(); 41 | int curWeek = cal.get(Calendar.DAY_OF_WEEK)-1; 42 | logger.info(curWeek); 43 | // logger.info(isOpenSystem()); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/compiler/ProcyonTest.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.compiler; 2 | 3 | /** 4 | * Company: ClickPaaS 5 | * 6 | * @version 1.0.0 7 | * @description: procyon反编译 8 | * @author: 钱旭 9 | * @date: 2022-03-07 10:49 10 | **/ 11 | import java.io.IOException; 12 | import java.nio.file.Path; 13 | import java.nio.file.Paths; 14 | import java.util.Iterator; 15 | import java.util.List; 16 | 17 | import org.jboss.windup.decompiler.api.DecompilationFailure; 18 | import org.jboss.windup.decompiler.api.DecompilationListener; 19 | import org.jboss.windup.decompiler.api.DecompilationResult; 20 | import org.jboss.windup.decompiler.api.Decompiler; 21 | import org.jboss.windup.decompiler.procyon.ProcyonDecompiler; 22 | 23 | /** 24 | * Procyon 反编译测试 25 | * 26 | * @author https://github.com/niumoo 27 | * @date 2021/05/15 28 | */ 29 | public class ProcyonTest { 30 | public static void main(String[] args) throws IOException { 31 | Long time = procyon("decompiler.jar", "procyon_output_jar"); 32 | System.out.println(String.format("decompiler time: %dms", time)); 33 | } 34 | public static Long procyon(String source,String targetPath) throws IOException { 35 | long start = System.currentTimeMillis(); 36 | Path outDir = Paths.get(targetPath); 37 | Path archive = Paths.get(source); 38 | Decompiler dec = new ProcyonDecompiler(); 39 | DecompilationResult res = dec.decompileArchive(archive, outDir, new DecompilationListener() { 40 | public void decompilationProcessComplete() { 41 | System.out.println("decompilationProcessComplete"); 42 | } 43 | public void decompilationFailed(List inputPath, String message) { 44 | System.out.println("decompilationFailed"); 45 | } 46 | public void fileDecompiled(List inputPath, String outputPath) { 47 | } 48 | public boolean isCancelled() { 49 | return false; 50 | } 51 | }); 52 | 53 | if (!res.getFailures().isEmpty()) { 54 | StringBuilder sb = new StringBuilder(); 55 | sb.append("Failed decompilation of " + res.getFailures().size() + " classes: "); 56 | Iterator failureIterator = res.getFailures().iterator(); 57 | while (failureIterator.hasNext()) { 58 | DecompilationFailure dex = (DecompilationFailure)failureIterator.next(); 59 | sb.append(System.lineSeparator() + " ").append(dex.getMessage()); 60 | } 61 | System.out.println(sb.toString()); 62 | } 63 | System.out.println("Compilation results: " + res.getDecompiledFiles().size() + " succeeded, " + res.getFailures().size() + " failed."); 64 | dec.close(); 65 | Long end = System.currentTimeMillis(); 66 | return end - start; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/compiler/procyon-decompiler-0.5.36.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EricLoveMia/JavaTools/1fe72617fac473a978f73136627e73a5c792c205/src/main/java/cn/eric/jdktools/compiler/procyon-decompiler-0.5.36.jar -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/data/BigDecimalUtil.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.data; 2 | 3 | import java.math.BigDecimal; 4 | 5 | /** 6 | * 金额计算工具类 7 | */ 8 | public class BigDecimalUtil { 9 | 10 | private static final int DEF_DIV_SCALE = 10;//默认除法运算精度 11 | 12 | /** 13 | * 提供精确的加法运算。 14 | * 15 | * @param v1 被加数 16 | * @param v2 加数 17 | * @return 两个参数的和 18 | */ 19 | public static double add(double v1, double v2) { 20 | BigDecimal b1 = new BigDecimal(Double.toString(v1)); 21 | BigDecimal b2 = new BigDecimal(Double.toString(v2)); 22 | return b1.add(b2).doubleValue(); 23 | } 24 | 25 | /** 26 | * 提供精确的减法运算。 27 | * 28 | * @param v1 被减数 29 | * @param v2 减数 30 | * @return 两个参数的差 31 | */ 32 | public static double sub(double v1, double v2) { 33 | BigDecimal b1 = new BigDecimal(Double.toString(v1)); 34 | BigDecimal b2 = new BigDecimal(Double.toString(v2)); 35 | return b1.subtract(b2).doubleValue(); 36 | } 37 | 38 | /** 39 | * 提供精确的乘法运算。 40 | * 41 | * @param v1 被乘数 42 | * @param v2 乘数 43 | * @return 两个参数的积 44 | */ 45 | public static double mul(double v1, double v2) { 46 | BigDecimal b1 = new BigDecimal(Double.toString(v1)); 47 | BigDecimal b2 = new BigDecimal(Double.toString(v2)); 48 | return b1.multiply(b2).doubleValue(); 49 | } 50 | 51 | /** 52 | * 提供精确的乘法运算,参数String类型 53 | * @param v1 54 | * @param v2 55 | * @return 56 | */ 57 | public static int mulString(String v1,String v2){ 58 | BigDecimal b1 = new BigDecimal(v1); 59 | BigDecimal b2 = new BigDecimal(v2); 60 | return b1.multiply(b2).intValue(); 61 | } 62 | 63 | /** 64 | * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 65 | * 小数点以后10位,以后的数字四舍五入。 66 | * 67 | * @param v1 被除数 68 | * @param v2 除数 69 | * @return 两个参数的商 70 | */ 71 | public static double div(double v1, double v2) { 72 | return div(v1, v2, DEF_DIV_SCALE); 73 | } 74 | 75 | /** 76 | * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 77 | * 定精度,以后的数字四舍五入。 78 | * 79 | * @param v1 被除数 80 | * @param v2 除数 81 | * @param scale 表示表示需要精确到小数点以后几位。 82 | * @return 两个参数的商 83 | */ 84 | public static double div(double v1, double v2, int scale) { 85 | if (scale < 0) { 86 | throw new IllegalArgumentException( 87 | "The scale must be a positive integer or zero"); 88 | } 89 | BigDecimal b1 = new BigDecimal(Double.toString(v1)); 90 | BigDecimal b2 = new BigDecimal(Double.toString(v2)); 91 | return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); 92 | } 93 | 94 | /** 95 | * 提供精确的小数位四舍五入处理。 96 | * 97 | * @param v 需要四舍五入的数字 98 | * @param scale 小数点后保留几位 99 | * @return 四舍五入后的结果 100 | */ 101 | public static double round(double v, int scale) { 102 | if (scale < 0) { 103 | throw new IllegalArgumentException("The scale must be a positive integer or zero"); 104 | } 105 | BigDecimal b = new BigDecimal(Double.toString(v)); 106 | BigDecimal one = new BigDecimal("1"); 107 | return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); 108 | } 109 | 110 | public static void main(String[] args) 111 | { 112 | 113 | System.out.println("0.2 + 0.1 = "+(0.2 + 0.1)); 114 | System.out.println("0.3 - 0.1 = "+(0.3 - 0.1)); 115 | System.out.println("0.2 * 0.1 = "+(0.2 * 0.1)); 116 | System.out.println("0.3 / 0.1 = "+(0.3 / 0.1)); 117 | 118 | BigDecimal bigDecimal = new BigDecimal(2); 119 | BigDecimal bDouble = new BigDecimal(2.3); 120 | BigDecimal bString = new BigDecimal("2.3"); 121 | System.out.println("bigDecimal=" + bigDecimal); 122 | System.out.println("bDouble=" + bDouble); 123 | System.out.println("bString=" + bString); 124 | 125 | BigDecimal b1 = new BigDecimal(4959.78); 126 | BigDecimal b2 = new BigDecimal(100); 127 | System.out.println("double元转分最后结果:"+b1.multiply(b2).intValue()); 128 | 129 | BigDecimal b3 = new BigDecimal("4959.78"); 130 | BigDecimal b4 = new BigDecimal("100"); 131 | System.out.println("String元转分最后结果:"+b3.multiply(b4).intValue()); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/data/CreateJsonSchema.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.data; 2 | 3 | 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import com.fasterxml.jackson.databind.jsonschema.JsonSchema; 6 | import com.kjetland.jackson.jsonSchema.JsonSchemaGenerator; 7 | 8 | /** 9 | * Company: 苏州渠成易销网络科技有限公司 10 | * 11 | * @version 1.0.0 12 | * @description: test 13 | * @author: 钱旭 14 | * @date: 2022-01-07 17:18 15 | **/ 16 | public class CreateJsonSchema { 17 | 18 | // public static void main(String[] args){ 19 | // ObjectMapper mapper = new ObjectMapper(); 20 | // JsonSchemaGenerator schemaGen = new JsonSchemaGenerator(mapper); 21 | // JsonSchema schema = schemaGen.generateSchema(Test.class); 22 | // String toString = schema.get$schema(); 23 | // System.out.println(toString); 24 | // } 25 | 26 | // public static void main(String[] args) { 27 | // SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2019_09, OptionPreset.PLAIN_JSON); 28 | // SchemaGeneratorConfig config = configBuilder.build(); 29 | // SchemaGenerator generator = new SchemaGenerator(config); 30 | // JsonNode jsonSchema = generator.generateSchema(Test.class); 31 | // 32 | // System.out.println(jsonSchema.toString()); 33 | // } 34 | 35 | // public static void main(String[] args) { 36 | // //Swagger2Module module = new Swagger2Module(); 37 | // JacksonModule module = new JacksonModule(); 38 | // SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2019_09, OptionPreset.PLAIN_JSON) 39 | // .with(module); 40 | // SchemaGeneratorConfig config = configBuilder.build(); 41 | // SchemaGenerator generator = new SchemaGenerator(config); 42 | // JsonNode jsonSchema = generator.generateSchema(InputProperties.class); 43 | // 44 | // System.out.println(jsonSchema.toString()); 45 | // } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/data/EscapeUtils.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.data; 2 | 3 | 4 | import org.apache.commons.text.StringEscapeUtils; 5 | 6 | /** 7 | * Company: 苏州渠成易销网络科技有限公司 8 | * 9 | * @version 1.0.0 10 | * @description: 转义与反转义 11 | * @author: 钱旭 12 | * @date: 2022-01-20 10:13 13 | **/ 14 | public class EscapeUtils { 15 | 16 | public static void main(String[] args) { 17 | 18 | String json = StringEscapeUtils.unescapeEcmaScript("%22%7B%5C%22%24schema%5C%22%3A%5C%22https%3A//json-schema.org/draft/2019-09/schema%5C%22%2C%5C%22type%5C%22%3A%5C%22object%5C%22%2C%5C%22properties%5C%22%3A%7B%5C%22operate%5C%22%3A%7B%5C%22type%5C%22%3A%5C%22string%5C%22%2C%5C%22title%5C%22%3A%5C%22%u64CD%u4F5C%5C%22%2C%5C%22description%5C%22%3A%5C%22%u64CD%u4F5C%u7C7B%u578B%20sum%uFF1A%u6C42%u548C%20max%uFF1A%u6C42%u6700%u5927%u503C%5C%22%7D%7D%7D%22"); 19 | System.out.println(json); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/db/DriverShim.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.db; 2 | 3 | import java.sql.*; 4 | import java.util.Properties; 5 | import java.util.logging.Logger; 6 | 7 | /** 8 | * Company: ClickPaaS 9 | * 10 | * @version 1.0.0 11 | * @description: jdbc drivier 12 | * @author: 钱旭 13 | * @date: 2022-03-02 17:38 14 | **/ 15 | public class DriverShim implements Driver{ 16 | 17 | private Driver driver; 18 | DriverShim(Driver d) { this.driver = d; } 19 | public boolean acceptsURL(String u) throws SQLException { 20 | return this.driver.acceptsURL(u); 21 | } 22 | public Connection connect(String u, Properties p) throws SQLException { 23 | return this.driver.connect(u, p); 24 | } 25 | @Override 26 | public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { 27 | return this.driver.getPropertyInfo(url, info); 28 | } 29 | @Override 30 | public int getMajorVersion() { 31 | return this.driver.getMajorVersion(); 32 | } 33 | @Override 34 | public int getMinorVersion() { 35 | return this.driver.getMinorVersion(); 36 | } 37 | @Override 38 | public boolean jdbcCompliant() { 39 | return this.driver.jdbcCompliant(); 40 | } 41 | @Override 42 | public Logger getParentLogger() throws SQLFeatureNotSupportedException { 43 | return this.driver.getParentLogger(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/db/DynamicLoadJDBC.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.db; 2 | 3 | import org.slf4j.Logger; 4 | 5 | import java.net.URL; 6 | import java.net.URLClassLoader; 7 | import java.sql.*; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | import java.util.Properties; 11 | 12 | /** 13 | * Company: ClickPaaS 14 | * 15 | * @version 1.0.0 16 | * @description: 动态加载JDBC驱动 17 | * @author: 钱旭 18 | * @date: 2022-03-02 17:36 19 | **/ 20 | public class DynamicLoadJDBC { 21 | 22 | private static final String JDBC_URL = "jdbc:mysql://211.149.243.54:3306/tiger?serverTimezone=UTC&useSSL=false"; 23 | private static final String USER = "root"; 24 | private static final String PASSWORD = "123456"; 25 | private static final Map jdbcVersionMap = new HashMap(); 26 | private static final Map tmpDriverMap = new HashMap(); 27 | 28 | // 动态加载jdbc驱动 29 | private static void dynamicLoadJdbc(String mysqlJdbcFile) throws Exception { 30 | URL u = new URL("jar:file:lib/" + mysqlJdbcFile + "!/"); 31 | String classname = jdbcVersionMap.get(mysqlJdbcFile); 32 | URLClassLoader ucl = new URLClassLoader(new URL[] { u }); 33 | Driver d = (Driver)Class.forName(classname, true, ucl).newInstance(); 34 | DriverShim driver = new DriverShim(d); 35 | DriverManager.registerDriver(driver); 36 | tmpDriverMap.put(mysqlJdbcFile, driver); 37 | } 38 | 39 | // 每一次测试完卸载对应版本的jdbc驱动 40 | private static void dynamicUnLoadJdbc(String mysqlJdbcFile) throws SQLException { 41 | DriverManager.deregisterDriver(tmpDriverMap.get(mysqlJdbcFile)); 42 | } 43 | 44 | // 进行一次测试 45 | private static void testOneVersion(String mysqlJdbcFile) { 46 | 47 | System.out.println("start test mysql jdbc version : " + mysqlJdbcFile); 48 | 49 | try { 50 | dynamicLoadJdbc(mysqlJdbcFile); 51 | } catch (Exception e1) { 52 | e1.printStackTrace(); 53 | } 54 | 55 | Connection conn = null; 56 | try { 57 | conn = DriverManager.getConnection(JDBC_URL, USER, PASSWORD); 58 | Statement stmt = conn.createStatement(); 59 | ResultSet rs = stmt.executeQuery("select user()"); 60 | System.out.println("select user() output : "); 61 | while(rs.next()) { 62 | System.out.println(rs.getObject(1)); 63 | } 64 | rs = stmt.executeQuery("show tables"); 65 | System.out.println("show tables output : "); 66 | while(rs.next()) { 67 | System.out.println(rs.getObject(1)); 68 | } 69 | } catch (SQLException e) { 70 | e.printStackTrace(); 71 | } finally { 72 | if(conn != null) { 73 | try { 74 | conn.close(); 75 | } catch (SQLException e) { 76 | e.printStackTrace(); 77 | } 78 | } 79 | } 80 | 81 | try { 82 | dynamicUnLoadJdbc(mysqlJdbcFile); 83 | } catch (SQLException e) { 84 | e.printStackTrace(); 85 | } 86 | 87 | System.out.println("end !!!"); 88 | System.out.println(); 89 | } 90 | 91 | public static void main(String[] args) { 92 | 93 | //jdbcVersionMap.put("mysql-connector-java-6.0.3.jar", "com.mysql.cj.jdbc.Driver"); 94 | //jdbcVersionMap.put("mysql-connector-java-5.1.6.jar", "com.mysql.jdbc.Driver"); 95 | //jdbcVersionMap.put("mysql-connector-java-5.1.31.jar", "com.mysql.jdbc.Driver"); 96 | //jdbcVersionMap.put("mysql-connector-java-5.1.35.jar", "com.mysql.jdbc.Driver"); 97 | //jdbcVersionMap.put("mysql-connector-java-5.1.39.jar", "com.mysql.jdbc.Driver"); 98 | jdbcVersionMap.put("mysql-connector-java-5.1.49.jar", "com.mysql.jdbc.Driver"); 99 | 100 | for(String mysqlJdbcFile : jdbcVersionMap.keySet()) { 101 | testOneVersion(mysqlJdbcFile); 102 | } 103 | 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/db/JDBCUtils.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.db; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.FileNotFoundException; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.sql.Connection; 8 | import java.sql.DriverManager; 9 | import java.sql.PreparedStatement; 10 | import java.sql.ResultSet; 11 | import java.sql.SQLException; 12 | import java.util.Properties; 13 | 14 | /** 15 | * @author Eric 16 | * @version 1.0 17 | * @ClassName: JDBCUtils 18 | * @Description: TODO 19 | * @company lsj 20 | * @date 2019/8/1 16:25 21 | **/ 22 | public class JDBCUtils { 23 | private static final String driverClass; 24 | private static final String url; 25 | private static final String userName; 26 | private static final String passWord; 27 | 28 | static{ 29 | //获取配置文件内容 30 | Properties properties = null; 31 | try { 32 | InputStream is = new FileInputStream("src/jdbc.properties"); 33 | properties = new Properties(); 34 | properties.load(is); 35 | } catch (Exception e) { 36 | // TODO Auto-generated catch block 37 | e.printStackTrace(); 38 | } 39 | driverClass = properties.getProperty("driverClass"); 40 | url = properties.getProperty("url"); 41 | userName = properties.getProperty("userName"); 42 | passWord = properties.getProperty("passWord"); 43 | } 44 | 45 | 46 | //注册驱动 47 | public static void loadDriver() { 48 | try { 49 | Class.forName(driverClass); 50 | } catch (ClassNotFoundException e) { 51 | // TODO Auto-generated catch block 52 | e.printStackTrace(); 53 | } 54 | } 55 | 56 | //获得连接 57 | public static Connection getConnection() { 58 | Connection conn = null; 59 | try { 60 | loadDriver(); 61 | conn = DriverManager.getConnection(url, userName, passWord); 62 | } catch (SQLException e) { 63 | // TODO Auto-generated catch block 64 | e.printStackTrace(); 65 | } 66 | return conn; 67 | } 68 | 69 | public static void closeResource(ResultSet rs,PreparedStatement psmt,Connection conn) { 70 | if(rs != null) { 71 | try { 72 | rs.close(); 73 | } catch (SQLException e) { 74 | // TODO Auto-generated catch block 75 | e.printStackTrace(); 76 | } 77 | //垃圾回收尽快回收对象 78 | rs = null; 79 | } 80 | if(psmt != null) { 81 | try { 82 | psmt.close(); 83 | } catch (SQLException e) { 84 | // TODO Auto-generated catch block 85 | e.printStackTrace(); 86 | } 87 | psmt = null; 88 | } 89 | if(conn != null) { 90 | try { 91 | conn.close(); 92 | } catch (SQLException e) { 93 | // TODO Auto-generated catch block 94 | e.printStackTrace(); 95 | } 96 | conn = null; 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/encrypt/AESUtil.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.encrypt; 2 | 3 | import javax.crypto.Cipher; 4 | import javax.crypto.KeyGenerator; 5 | import javax.crypto.SecretKey; 6 | import javax.crypto.spec.SecretKeySpec; 7 | import java.io.UnsupportedEncodingException; 8 | import java.security.NoSuchAlgorithmException; 9 | import java.security.SecureRandom; 10 | import java.util.logging.Level; 11 | import java.util.logging.Logger; 12 | /** 13 | * @author Eric 14 | * @version 1.0 15 | * @ClassName: AESUtil 16 | * @Description: TODO 17 | * @company lsj 18 | * @date 2019/5/15 14:43 19 | **/ 20 | 21 | /** 22 | * @version V1.0 23 | * @desc AES 加密工具类 24 | */ 25 | public class AESUtil { 26 | 27 | private static final String KEY_ALGORITHM = "AES"; 28 | private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";//默认的加密算法 29 | 30 | /** 31 | * AES 加密操作 32 | * 33 | * @param content 待加密内容 34 | * @param password 加密密码 35 | * @return 返回Base64转码后的加密数据 36 | */ 37 | public static String encrypt(String content, String password) { 38 | try { 39 | Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);// 创建密码器 40 | 41 | byte[] byteContent = content.getBytes("utf-8"); 42 | 43 | cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(password));// 初始化为加密模式的密码器 44 | 45 | byte[] result = cipher.doFinal(byteContent);// 加密 46 | 47 | // return Base64.encodeBase64String(result);//通过Base64转码返回 48 | return parseByte2HexStr(result); 49 | } catch (Exception ex) { 50 | Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex); 51 | } 52 | 53 | return null; 54 | } 55 | 56 | /** 57 | * AES 解密操作 58 | * 59 | * @param content 60 | * @param password 61 | * @return 62 | */ 63 | public static String decrypt(String content, String password) { 64 | 65 | try { 66 | //实例化 67 | Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM); 68 | 69 | //使用密钥初始化,设置为解密模式 70 | cipher.init(Cipher.DECRYPT_MODE, getSecretKey(password)); 71 | 72 | //执行操作 73 | // byte[] result = cipher.doFinal(Base64.decodeBase64(content)); 74 | byte[] result = cipher.doFinal(parseHexStr2Byte(content)); 75 | return new String(result, "utf-8"); 76 | } catch (Exception ex) { 77 | Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex); 78 | } 79 | 80 | return null; 81 | } 82 | 83 | /** 84 | * 生成加密秘钥 85 | * 86 | * @return 87 | */ 88 | private static SecretKeySpec getSecretKey(final String password) { 89 | //返回生成指定算法密钥生成器的 KeyGenerator 对象 90 | KeyGenerator kg = null; 91 | 92 | try { 93 | SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); 94 | random.setSeed(password.getBytes()); 95 | kg = KeyGenerator.getInstance(KEY_ALGORITHM); 96 | // old kgen.init(128, new SecureRandom(key.getBytes())); 97 | // AES 要求密钥长度为 128 98 | kg.init(128, random); 99 | 100 | //生成一个密钥 101 | SecretKey secretKey = kg.generateKey(); 102 | // 转换为AES专用密钥 103 | return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM); 104 | } catch (NoSuchAlgorithmException ex) { 105 | Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex); 106 | } 107 | 108 | return null; 109 | } 110 | 111 | /** 112 | * @description 将二进制转换成16进制 113 | * 114 | * @param buf 115 | * @return 116 | */ 117 | public static String parseByte2HexStr(byte buf[]) { 118 | StringBuffer sb = new StringBuffer(); 119 | for (int i = 0; i < buf.length; i++) { 120 | String hex = Integer.toHexString(buf[i] & 0xFF); 121 | if (hex.length() == 1) { 122 | hex = '0' + hex; 123 | } 124 | sb.append(hex.toUpperCase()); 125 | } 126 | return sb.toString(); 127 | } 128 | 129 | /** 130 | * @description 将16进制转换为二进制 131 | * 132 | * @param hexStr 133 | * @return 134 | */ 135 | public static byte[] parseHexStr2Byte(String hexStr) { 136 | if (hexStr.length() < 1) 137 | return null; 138 | byte[] result = new byte[hexStr.length() / 2]; 139 | for (int i = 0; i < hexStr.length() / 2; i++) { 140 | int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16); 141 | int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16); 142 | result[i] = (byte) (high * 16 + low); 143 | } 144 | return result; 145 | } 146 | 147 | 148 | public static void main(String[] args) throws UnsupportedEncodingException { 149 | // NpQjlZSjByAW9hyuMwfZhA%3D%3D 150 | Integer id = 1; 151 | System.out.println("s:" + id.toString()); 152 | 153 | String s1 = AESUtil.encrypt(id.toString(), "lSj9102BX@2019"); 154 | System.out.println("s1:" + s1); 155 | // String encode = URLEncoder.encode(s1, "UTF-8"); 156 | // System.out.println("encode:" + encode); 157 | // 158 | // String decode = URLDecoder.decode(encode, "UTF-8"); 159 | // System.out.println("decode:" + decode); 160 | System.out.println("s2:"+AESUtil.decrypt(s1, "lSj9102BX@2019")); 161 | 162 | } 163 | 164 | } 165 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/encrypt/CharTools.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.encrypt; 2 | import java.io.UnsupportedEncodingException; 3 | 4 | /** 5 | *

Title:�ַ����빤����

6 | *

Description:

7 | *

Copyright: Copyright (c) 2007

8 | *

Company:

9 | * @author: 10 | * @version 1.0 11 | */ 12 | public class CharTools { 13 | 14 | /** 15 | * ת������ ISO-8859-1��GB2312 16 | * @param text 17 | * @return 18 | */ 19 | public static final String ISO2GB(String text) { 20 | String result = ""; 21 | try { 22 | result = new String(text.getBytes("ISO-8859-1"), "GB2312"); 23 | } 24 | catch (UnsupportedEncodingException ex) { 25 | result = ex.toString(); 26 | } 27 | return result; 28 | } 29 | 30 | /** 31 | * ת������ GB2312��ISO-8859-1 32 | * @param text 33 | * @return 34 | */ 35 | public static final String GB2ISO(String text) { 36 | String result = ""; 37 | try { 38 | result = new String(text.getBytes("GB2312"), "ISO-8859-1"); 39 | } 40 | catch (UnsupportedEncodingException ex) { 41 | ex.printStackTrace(); 42 | } 43 | return result; 44 | } 45 | /** 46 | * Utf8URL���� 47 | * @param s 48 | * @return 49 | */ 50 | public static final String Utf8URLencode(String text) { 51 | StringBuffer result = new StringBuffer(); 52 | 53 | for (int i = 0; i < text.length(); i++) { 54 | 55 | char c = text.charAt(i); 56 | if (c >= 0 && c <= 255) { 57 | result.append(c); 58 | }else { 59 | 60 | byte[] b = new byte[0]; 61 | try { 62 | b = Character.toString(c).getBytes("UTF-8"); 63 | }catch (Exception ex) { 64 | } 65 | 66 | for (int j = 0; j < b.length; j++) { 67 | int k = b[j]; 68 | if (k < 0) k += 256; 69 | result.append("%" + Integer.toHexString(k).toUpperCase()); 70 | } 71 | 72 | } 73 | } 74 | 75 | return result.toString(); 76 | } 77 | 78 | /** 79 | * Utf8URL���� 80 | * @param text 81 | * @return 82 | */ 83 | public static final String Utf8URLdecode(String text) { 84 | String result = ""; 85 | int p = 0; 86 | 87 | if (text!=null && text.length()>0){ 88 | text = text.toLowerCase(); 89 | p = text.indexOf("%e"); 90 | if (p == -1) return text; 91 | 92 | while (p != -1) { 93 | result += text.substring(0, p); 94 | text = text.substring(p, text.length()); 95 | if (text == "" || text.length() < 9) return result; 96 | 97 | result += CodeToWord(text.substring(0, 9)); 98 | text = text.substring(9, text.length()); 99 | p = text.indexOf("%e"); 100 | } 101 | 102 | } 103 | 104 | return result + text; 105 | } 106 | 107 | /** 108 | * utf8URL����ת�ַ� 109 | * @param text 110 | * @return 111 | */ 112 | private static final String CodeToWord(String text) { 113 | String result; 114 | 115 | if (Utf8codeCheck(text)) { 116 | byte[] code = new byte[3]; 117 | code[0] = (byte) (Integer.parseInt(text.substring(1, 3), 16) - 256); 118 | code[1] = (byte) (Integer.parseInt(text.substring(4, 6), 16) - 256); 119 | code[2] = (byte) (Integer.parseInt(text.substring(7, 9), 16) - 256); 120 | try { 121 | result = new String(code, "UTF-8"); 122 | }catch (UnsupportedEncodingException ex) { 123 | result = null; 124 | } 125 | } 126 | else { 127 | result = text; 128 | } 129 | 130 | return result; 131 | } 132 | 133 | /** 134 | * �����Ƿ���Ч 135 | * @param text 136 | * @return 137 | */ 138 | private static final boolean Utf8codeCheck(String text){ 139 | String sign = ""; 140 | if (text.startsWith("%e")) 141 | for (int i = 0, p = 0; p != -1; i++) { 142 | p = text.indexOf("%", p); 143 | if (p != -1) 144 | p++; 145 | sign += p; 146 | } 147 | return sign.equals("147-1"); 148 | } 149 | 150 | /** 151 | * �ж��Ƿ�Utf8Url���� 152 | * @param text 153 | * @return 154 | */ 155 | public static final boolean isUtf8Url(String text) { 156 | text = text.toLowerCase(); 157 | int p = text.indexOf("%"); 158 | if (p != -1 && text.length() - p > 9) { 159 | text = text.substring(p, p + 9); 160 | } 161 | return Utf8codeCheck(text); 162 | } 163 | 164 | /** 165 | * ���� 166 | * @param args 167 | */ 168 | public static void main(String[] args) { 169 | 170 | //CharTools charTools = new CharTools(); 171 | 172 | String url; 173 | 174 | url = "http://www.google.com/search?hl=zh-CN&newwindow=1&q=%E4%B8%AD%E5%9B%BD%E5%A4%A7%E7%99%BE%E7%A7%91%E5%9C%A8%E7%BA%BF%E5%85%A8%E6%96%87%E6%A3%80%E7%B4%A2&btnG=%E6%90%9C%E7%B4%A2&lr="; 175 | if(CharTools.isUtf8Url(url)){ 176 | System.out.println(CharTools.Utf8URLdecode(url)); 177 | }else{ 178 | //System.out.println(URLDecoder.decode(url)); 179 | } 180 | 181 | url = "http://www.baidu.com/baidu?word=%D6%D0%B9%FA%B4%F3%B0%D9%BF%C6%D4%DA%CF%DF%C8%AB%CE%C4%BC%EC%CB%F7&tn=myie2dg"; 182 | if(CharTools.isUtf8Url(url)){ 183 | System.out.println(CharTools.Utf8URLdecode(url)); 184 | }else{ 185 | //System.out.println(URLDecoder.decode(url)); 186 | } 187 | 188 | } 189 | 190 | } 191 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/encrypt/Escape.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.encrypt; 2 | 3 | public class Escape { 4 | private final static String[] hex = { "00", "01", "02", "03", "04", "05", 5 | "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F", "10", 6 | "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", 7 | "1C", "1D", "1E", "1F", "20", "21", "22", "23", "24", "25", "26", 8 | "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F", "30", "31", 9 | "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", 10 | "3D", "3E", "3F", "40", "41", "42", "43", "44", "45", "46", "47", 11 | "48", "49", "4A", "4B", "4C", "4D", "4E", "4F", "50", "51", "52", 12 | "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", 13 | "5E", "5F", "60", "61", "62", "63", "64", "65", "66", "67", "68", 14 | "69", "6A", "6B", "6C", "6D", "6E", "6F", "70", "71", "72", "73", 15 | "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", 16 | "7F", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", 17 | "8A", "8B", "8C", "8D", "8E", "8F", "90", "91", "92", "93", "94", 18 | "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F", 19 | "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA", 20 | "AB", "AC", "AD", "AE", "AF", "B0", "B1", "B2", "B3", "B4", "B5", 21 | "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF", "C0", 22 | "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", 23 | "CC", "CD", "CE", "CF", "D0", "D1", "D2", "D3", "D4", "D5", "D6", 24 | "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF", "E0", "E1", 25 | "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", 26 | "ED", "EE", "EF", "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", 27 | "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF" }; 28 | 29 | private final static byte[] val = { 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 30 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 31 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 32 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 33 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x01, 34 | 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x3F, 0x3F, 0x3F, 35 | 0x3F, 0x3F, 0x3F, 0x3F, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x3F, 36 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 37 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 38 | 0x3F, 0x3F, 0x3F, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x3F, 0x3F, 39 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 40 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 41 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 42 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 43 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 44 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 45 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 46 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 47 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 48 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 49 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 50 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 51 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 52 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F }; 53 | 54 | /** */ 55 | /** 56 | * 编码 57 | * 58 | * @param s 59 | * @return 60 | */ 61 | public static String escape(String s) { 62 | StringBuffer sbuf = new StringBuffer(); 63 | int len = s.length(); 64 | for (int i = 0; i < len; i++) { 65 | int ch = s.charAt(i); 66 | if ('A' <= ch && ch <= 'Z') { 67 | sbuf.append((char) ch); 68 | } else if ('a' <= ch && ch <= 'z') { 69 | sbuf.append((char) ch); 70 | } else if ('0' <= ch && ch <= '9') { 71 | sbuf.append((char) ch); 72 | } else if (ch == '-' || ch == '_' || ch == '.' || ch == '!' 73 | || ch == '~' || ch == '*' || ch == '\'' || ch == '(' 74 | || ch == ')') { 75 | sbuf.append((char) ch); 76 | } else if (ch <= 0x007F) { 77 | sbuf.append('%'); 78 | sbuf.append(hex[ch]); 79 | } else { 80 | sbuf.append('%'); 81 | sbuf.append('u'); 82 | sbuf.append(hex[(ch >>> 8)]); 83 | sbuf.append(hex[(0x00FF & ch)]); 84 | } 85 | } 86 | return sbuf.toString(); 87 | } 88 | 89 | /** */ 90 | /** 91 | * 解码 说明:本方法保证 不论参数s是否经过escape()编码,均能得到正确的“解码”结果 92 | * 93 | * @param s 94 | * @return 95 | */ 96 | public static String unescape(String s) { 97 | StringBuffer sbuf = new StringBuffer(); 98 | int i = 0; 99 | int len = s.length(); 100 | while (i < len) { 101 | int ch = s.charAt(i); 102 | if ('A' <= ch && ch <= 'Z') { 103 | sbuf.append((char) ch); 104 | } else if ('a' <= ch && ch <= 'z') { 105 | sbuf.append((char) ch); 106 | } else if ('0' <= ch && ch <= '9') { 107 | sbuf.append((char) ch); 108 | } else if (ch == '-' || ch == '_' || ch == '.' || ch == '!' 109 | || ch == '~' || ch == '*' || ch == '\'' || ch == '(' 110 | || ch == ')') { 111 | sbuf.append((char) ch); 112 | } else if (ch == '%') { 113 | int cint = 0; 114 | if ('u' != s.charAt(i + 1)) { 115 | cint = (cint << 4) | val[s.charAt(i + 1)]; 116 | cint = (cint << 4) | val[s.charAt(i + 2)]; 117 | i += 2; 118 | } else { 119 | cint = (cint << 4) | val[s.charAt(i + 2)]; 120 | cint = (cint << 4) | val[s.charAt(i + 3)]; 121 | cint = (cint << 4) | val[s.charAt(i + 4)]; 122 | cint = (cint << 4) | val[s.charAt(i + 5)]; 123 | i += 5; 124 | } 125 | sbuf.append((char) cint); 126 | } else { 127 | sbuf.append((char) ch); 128 | } 129 | i++; 130 | } 131 | return sbuf.toString(); 132 | } 133 | 134 | public static void main(String[] args) { 135 | String stest = "一声笑傲江湖之曲1234 abcd[]()<+>,.~\""; 136 | System.out.println(stest); 137 | System.out.println(escape(stest)); 138 | System.out.println(unescape(escape(stest))); 139 | } 140 | } -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/exception/ExceptionUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ------------------------------------------------------- 3 | * @FileName ExceptionUtil.java 4 | * @Description 异常处理工具类 5 | * @Author 00294476 6 | * @Copyright www.want-want.com Ltd. All rights reserved. 7 | * 注意:本内容仅限于旺旺集团内部传阅,禁止外泄以及用于其他商业目的 8 | * ------------------------------------------------------- 9 | */ 10 | package cn.eric.jdktools.exception; 11 | 12 | /** 13 | * @description 异常处理工具类 14 | * @author eric 15 | * @version V1.0.0 16 | */ 17 | public final class ExceptionUtil { 18 | 19 | /** 20 | * <获取异常信息栈里的具体信息> 21 | * 22 | * @param e 23 | * @return 24 | */ 25 | public static String getTrace(Exception e) { 26 | 27 | StringBuffer stringBuffer = new StringBuffer(e.toString() + "\n"); 28 | StackTraceElement[] messages = e.getStackTrace(); 29 | int length = messages.length; 30 | for (int i = 0; i < length; i++) { 31 | stringBuffer.append("\t" + messages[i].toString() + "\n"); 32 | } 33 | return stringBuffer.toString(); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/file/Dom4jHelper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package cn.eric.jdktools.file; 5 | 6 | import org.dom4j.*; 7 | import org.dom4j.io.OutputFormat; 8 | import org.dom4j.io.SAXReader; 9 | import org.dom4j.io.XMLWriter; 10 | 11 | import java.io.*; 12 | import java.net.URL; 13 | import java.util.Iterator; 14 | import java.util.List; 15 | 16 | /** 17 | * @author advance 18 | * 19 | */ 20 | public class Dom4jHelper { 21 | 22 | /** 23 | * 解析url xml文档 24 | * @param url 25 | * @return 26 | * @throws DocumentException 27 | */ 28 | public Document parse(URL url) throws DocumentException { 29 | SAXReader reader = new SAXReader(); 30 | Document document = reader.read(url); 31 | return document; 32 | } 33 | 34 | /** 35 | * 遍历解析文档 36 | * @param document 37 | */ 38 | public void treeWalk(Document document) { 39 | treeWalk( document.getRootElement() ); 40 | } 41 | 42 | /** 43 | * 遍历解析元素 44 | * @param element 45 | */ 46 | public void treeWalk(Element element) { 47 | for ( int i = 0, size = element.nodeCount(); i < size; i++ ) { 48 | Node node = element.node(i); 49 | if ( node instanceof Element ) { 50 | treeWalk( (Element) node ); 51 | } 52 | else { 53 | // 处理.... 54 | } 55 | } 56 | } 57 | 58 | /** 59 | * 解析文件,获得根元素 60 | * @param xmlPath 61 | * @param encoding 62 | * @return 63 | * @throws Exception 64 | */ 65 | public static Element parse(String xmlPath,String encoding)throws Exception{ 66 | //文件是否存在 67 | File file = new File(xmlPath); 68 | if(!file.exists()){ 69 | throw new Exception("找不到xml文件:"+xmlPath); 70 | } 71 | 72 | //解析 73 | SAXReader reader = new SAXReader(false); 74 | Document doc = reader.read(new FileInputStream(file),encoding); 75 | Element root = doc.getRootElement(); 76 | return root; 77 | } 78 | 79 | /** 80 | * 保存文档 81 | * @param doc 82 | * @param xmlPath 83 | * @param encoding 84 | * @throws Exception 85 | */ 86 | public static void save(Document doc,String xmlPath,String encoding)throws Exception{ 87 | OutputFormat format=OutputFormat.createPrettyPrint(); 88 | format.setEncoding(encoding); 89 | XMLWriter writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream(xmlPath),encoding),format); 90 | writer.write(doc); 91 | writer.flush(); 92 | writer.close(); 93 | } 94 | 95 | /** 96 | * 修改xml某节点的值 97 | * @param inputXml 原xml文件 98 | * @param nodes 要修改的节点 99 | * @param attributename 属性名称 100 | * @param value 新值 101 | * @param outXml 输出文件路径及文件名 如果输出文件为null,则默认为原xml文件 102 | */ 103 | public static void modifyDocument(File inputXml, String nodes, String attributename, String value, String outXml) { 104 | try { 105 | SAXReader saxReader = new SAXReader(); 106 | Document document = saxReader.read(inputXml); 107 | List list = document.selectNodes(nodes); 108 | Iterator iter = list.iterator(); 109 | while (iter.hasNext()) { 110 | Attribute attribute = (Attribute) iter.next(); 111 | if (attribute.getName().equals(attributename)) { 112 | attribute.setValue(value); 113 | } 114 | } 115 | XMLWriter output; 116 | if (outXml != null){ //指定输出文件 117 | output = new XMLWriter(new FileWriter(new File(outXml))); 118 | }else{ //输出文件为原文件 119 | output = new XMLWriter(new FileWriter(inputXml)); 120 | } 121 | output.write(document); 122 | output.close(); 123 | } 124 | 125 | catch (DocumentException e) { 126 | System.out.println(e.getMessage()); 127 | } catch (IOException e) { 128 | System.out.println(e.getMessage()); 129 | } 130 | } 131 | 132 | /** 133 | * xml转换为字符串 134 | * @param doc 135 | * @param encoding 136 | * @return 137 | * @throws Exception 138 | */ 139 | public static String toString(Document doc,String encoding)throws Exception{ 140 | OutputFormat format=OutputFormat.createPrettyPrint(); 141 | format.setEncoding(encoding); 142 | ByteArrayOutputStream byteOS=new ByteArrayOutputStream(); 143 | XMLWriter writer = new XMLWriter(new OutputStreamWriter(byteOS,encoding),format); 144 | writer.write(doc); 145 | writer.flush(); 146 | writer.close(); 147 | writer=null; 148 | 149 | return byteOS.toString(encoding); 150 | } 151 | /** 152 | * 字符串转换为Document 153 | * @param text 154 | * @return 155 | * @throws DocumentException 156 | */ 157 | public static Document str2Document(String text) throws DocumentException{ 158 | Document document = DocumentHelper.parseText(text); 159 | return document; 160 | } 161 | /** 162 | * @param args 163 | */ 164 | public static void main(String[] args) { 165 | // TODO Auto-generated method stub 166 | 167 | } 168 | 169 | } 170 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/file/ExcelHanlder.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.file; 2 | 3 | import org.apache.poi.ss.usermodel.VerticalAlignment; 4 | import org.apache.poi.xssf.usermodel.*; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | /** 10 | * @author Eric 11 | * @version 1.0 12 | * @ClassName: ExcelHanlder 13 | * @Description: TODO 14 | * @company lsj 15 | * @date 2019/4/24 15:53 16 | **/ 17 | public class ExcelHanlder { 18 | 19 | //默认高度 20 | private static short DEFAULT_ROW_HEIGHT = 400; 21 | //默认宽度 22 | private static int DEFAULT_CELL_WIDTH = 3000; 23 | 24 | 25 | /** 26 | * 27 | * @param book 工作簿对象,【可选】 28 | * @param hanlder 自定义类型处理【可选】 29 | * @param titles 标题 30 | * @param columns 列名(Map类型处理,自定义可选) 31 | * @param columnsWidth 宽度 32 | * @param height 行高 33 | * @param sheetTitle 表标题 34 | * @param datas 数据 35 | * @return 36 | */ 37 | @SuppressWarnings("all") 38 | public static XSSFWorkbook exportExcel(XSSFWorkbook book, ExcelTypeHanlder hanlder, String[] titles, String[] columns 39 | , Integer[] columnsWidth, Short height, String sheetTitle, List datas){ 40 | 41 | if(book==null){ 42 | book = new XSSFWorkbook(); 43 | } 44 | 45 | int size = DEFAULT_CELL_WIDTH; 46 | 47 | //列大小 48 | if(columnsWidth!=null&&columnsWidth.length==1){ 49 | size = columnsWidth[0]; 50 | } 51 | if(height==null){ 52 | height = DEFAULT_ROW_HEIGHT; 53 | } 54 | XSSFSheet sheet = book.createSheet(sheetTitle); 55 | int rowindex = 0; 56 | XSSFRow firstrow = sheet.createRow(rowindex); 57 | rowindex++; 58 | sheet.setDefaultColumnWidth(size); 59 | firstrow.setHeight(height); 60 | 61 | XSSFFont font = book.createFont(); 62 | font.setBold(true); 63 | XSSFCellStyle cellstyle = book.createCellStyle(); 64 | cellstyle.setFont(font); 65 | cellstyle.setVerticalAlignment(VerticalAlignment.CENTER); 66 | 67 | //标题 68 | if(titles!=null){ 69 | int index = 0; 70 | for (String title : titles) { 71 | XSSFCell cell = firstrow.createCell(index); 72 | cell.setCellStyle(cellstyle); 73 | cell.setCellValue(title); 74 | //列宽度设置 75 | if(columnsWidth==null||columnsWidth.length==0||columnsWidth.length==1){ 76 | sheet.setColumnWidth(cell.getColumnIndex(), size); 77 | }else{ 78 | if((columnsWidth.length-1)>=index){ 79 | sheet.setColumnWidth(cell.getColumnIndex(), columnsWidth[index]==null?size:columnsWidth[index]); 80 | }else{ 81 | sheet.setColumnWidth(cell.getColumnIndex(), size); 82 | } 83 | } 84 | index++; 85 | } 86 | } 87 | if(datas==null){ 88 | return book; 89 | } 90 | 91 | //写入数据 92 | for (Object data : datas) { 93 | 94 | //map 类型处理 95 | if(data instanceof Map){ 96 | Map map = (Map) data; 97 | XSSFRow row = sheet.createRow(rowindex); 98 | int i = 0; 99 | for (String column : columns) { 100 | XSSFCell cell = row.createCell(i); 101 | Object val = map.get(column); 102 | if(hanlder!=null&&val==null){ 103 | Object temp = hanlder.dataNullHander(column,map); 104 | cell.setCellValue(temp!=null?temp.toString():""); 105 | }else{ 106 | cell.setCellValue(val!=null?val.toString():""); 107 | } 108 | i++; 109 | } 110 | row.setHeight(DEFAULT_ROW_HEIGHT); 111 | rowindex++; 112 | }else{ 113 | //其他处理 114 | if(hanlder!=null){ 115 | Object obj = data; 116 | XSSFRow row = sheet.createRow(rowindex); 117 | hanlder.typeHanlder(data, row); 118 | rowindex++; 119 | } 120 | } 121 | } 122 | return book; 123 | } 124 | 125 | 126 | /** 127 | * 128 | * @param book 工作簿对象,【可选】 129 | * @param titles 标题 130 | * @param columns 列名(Map类型处理,自定义可选) 131 | * @param sheetTitle 表标题 132 | * @param datas 数据 133 | * @return 134 | */ 135 | public static XSSFWorkbook exportExcel(XSSFWorkbook book, String[] titles, String[] columns, String sheetTitle, List> datas){ 136 | return exportExcel(book, null, titles, columns,null,null, sheetTitle, datas); 137 | } 138 | 139 | /** 140 | * @param titles 标题 141 | * @param columns 列名(Map类型处理,自定义可选) 142 | * @param sheetTitle 表标题 143 | * @param datas 数据 144 | * @return 145 | */ 146 | @SuppressWarnings("all") 147 | public static XSSFWorkbook exportExcel(String[] titles, String[] columns, String sheetTitle, List> datas, ExcelTypeHanlder hanlder){ 148 | return exportExcel(null, hanlder, titles, columns,null,null, sheetTitle, datas); 149 | } 150 | 151 | public static XSSFWorkbook exportExcel(String[] titles, String[] columns, String sheetTitle, List> datas){ 152 | return exportExcel(null, null, titles, columns,null,null, sheetTitle, datas); 153 | } 154 | 155 | //自定义处理对象回调 156 | public static abstract class ExcelTypeHanlder{ 157 | //类型处理 158 | public void typeHanlder(T data, XSSFRow row){ 159 | 160 | } 161 | 162 | //空数据处理 163 | public Object dataNullHander(String column,T obj){ 164 | return null; 165 | } 166 | } 167 | 168 | 169 | } -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/file/FileHelper.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.file; 2 | 3 | /* 4 | * Static File routines. 5 | * Copyright (C) 2002 Stephen Ostermiller 6 | * http://ostermiller.org/contact.pl?regarding=Java+Utilities 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * See COPYING.TXT for details. 19 | */ 20 | 21 | import java.io.*; 22 | import java.text.MessageFormat; 23 | import java.util.Locale; 24 | import java.util.ResourceBundle; 25 | 26 | /** 27 | * Utilities for File manipulation. 28 | * More information about this class is available from ostermiller.org. 30 | * 31 | * @author Stephen Ostermiller http://ostermiller.org/contact.pl?regarding=Java+Utilities 32 | * @since ostermillerutils 1.00.00 33 | */ 34 | public class FileHelper { 35 | 36 | /** 37 | * Locale specific strings displayed to the user. 38 | * 39 | * @since ostermillerutils 1.00.00 40 | */ 41 | protected static ResourceBundle labels = ResourceBundle.getBundle("com.Ostermiller.util.FileHelper", Locale.getDefault()); 42 | 43 | 44 | /** 45 | * Move a file from one location to another. An attempt is made to rename 46 | * the file and if that fails, the file is copied and the old file deleted. 47 | * 48 | * If the destination file already exists, an exception will be thrown. 49 | * 50 | * @param from file which should be moved. 51 | * @param to desired destination of the file. 52 | * @throws IOException if an error occurs. 53 | * 54 | * @since ostermillerutils 1.00.00 55 | */ 56 | public static void move(File from, File to) throws IOException { 57 | move(from, to, false); 58 | } 59 | 60 | /** 61 | * Move a file from one location to another. An attempt is made to rename 62 | * the file and if that fails, the file is copied and the old file deleted. 63 | * 64 | * @param from file which should be moved. 65 | * @param to desired destination of the file. 66 | * @param overwrite If false, an exception will be thrown rather than overwrite a file. 67 | * @throws IOException if an error occurs. 68 | * 69 | * @since ostermillerutils 1.00.00 70 | */ 71 | public static void move(File from, File to, boolean overwrite) throws IOException { 72 | if (to.exists()){ 73 | if (overwrite){ 74 | if (!to.delete()){ 75 | throw new IOException( 76 | MessageFormat.format( 77 | labels.getString("deleteerror"), 78 | (Object[])new String[] { 79 | to.toString() 80 | } 81 | ) 82 | ); 83 | } 84 | } else { 85 | throw new IOException( 86 | MessageFormat.format( 87 | labels.getString("alreadyexistserror"), 88 | (Object[])new String[] { 89 | to.toString() 90 | } 91 | ) 92 | ); 93 | } 94 | } 95 | 96 | if (from.renameTo(to)) return; 97 | 98 | InputStream in = null; 99 | OutputStream out = null; 100 | try { 101 | in = new FileInputStream(from); 102 | out = new FileOutputStream(to); 103 | copy(in, out); 104 | in.close(); 105 | in = null; 106 | out.flush(); 107 | out.close(); 108 | out = null; 109 | if (!from.delete()){ 110 | throw new IOException( 111 | MessageFormat.format( 112 | labels.getString("deleteoriginalerror"), 113 | (Object[])new String[] { 114 | from.toString(), 115 | to.toString() 116 | } 117 | ) 118 | ); 119 | } 120 | } finally { 121 | if (in != null){ 122 | in.close(); 123 | in = null; 124 | } 125 | if (out != null){ 126 | out.flush(); 127 | out.close(); 128 | out = null; 129 | } 130 | } 131 | } 132 | 133 | /** 134 | * Buffer size when reading from input stream. 135 | * 136 | * @since ostermillerutils 1.00.00 137 | */ 138 | private final static int BUFFER_SIZE = 1024; 139 | 140 | /** 141 | * Copy the data from the input stream to the output stream. 142 | * 143 | * @param in data source 144 | * @param out data destination 145 | * @throws IOException in an input or output error occurs 146 | * 147 | * @since ostermillerutils 1.00.00 148 | */ 149 | private static void copy(InputStream in, OutputStream out) throws IOException { 150 | byte[] buffer = new byte[BUFFER_SIZE]; 151 | int read; 152 | while((read = in.read(buffer)) != -1){ 153 | out.write(buffer, 0, read); 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/file/MD5FileCheckUtil.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.file; 2 | 3 | import org.apache.commons.codec.binary.Hex; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import java.io.File; 8 | import java.io.FileInputStream; 9 | import java.io.InputStream; 10 | import java.security.MessageDigest; 11 | import java.security.NoSuchAlgorithmException; 12 | 13 | /** 14 | * @Author: eric 15 | * @Date: 2020/6/19 13:49 16 | */ 17 | public class MD5FileCheckUtil { 18 | 19 | private static final Logger LOGGER = LoggerFactory.getLogger(MD5FileCheckUtil.class); 20 | 21 | protected static char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', 22 | '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 23 | protected static MessageDigest messageDigest = null; 24 | 25 | static { 26 | try { 27 | messageDigest = MessageDigest.getInstance("MD5"); 28 | } catch (NoSuchAlgorithmException nsaex) { 29 | LOGGER.error("{}初始化失败,MessageDigest不支持MD5Util。", MD5FileCheckUtil.class.getName()); 30 | LOGGER.warn("", nsaex); 31 | } 32 | } 33 | 34 | /** 35 | * 生成字符串的md5校验值 36 | * 37 | * @param s 38 | * @return 39 | */ 40 | public static String getMD5String(String s) { 41 | return getMD5String(s.getBytes()); 42 | } 43 | 44 | /** 45 | * 判断字符串的md5校验码是否与一个已知的md5码相匹配 46 | * 47 | * @param password 要校验的字符串 48 | * @param md5PwdStr 已知的md5校验码 49 | * @return 50 | */ 51 | public static boolean checkPassword(String password, String md5PwdStr) { 52 | String s = getMD5String(password); 53 | return s.equals(md5PwdStr); 54 | } 55 | 56 | /** 57 | * 生成文件的md5校验值 58 | * 59 | * @param file 60 | * @return 61 | */ 62 | public static String getFileMD5String(File file) { 63 | try (InputStream fis = new FileInputStream(file)) { 64 | byte[] buffer = new byte[1024]; 65 | int numRead = 0; 66 | while ((numRead = fis.read(buffer)) > 0) { 67 | messageDigest.update(buffer, 0, numRead); 68 | } 69 | } catch (Exception ignored) { 70 | LOGGER.warn("", ignored); 71 | } 72 | return bufferToHex(messageDigest.digest()); 73 | } 74 | 75 | public static String getMD5String(byte[] bytes) { 76 | messageDigest.update(bytes); 77 | return bufferToHex(messageDigest.digest()); 78 | } 79 | 80 | private static String bufferToHex(byte[] bytes) { 81 | return bufferToHex(bytes, 0, bytes.length); 82 | } 83 | 84 | private static String bufferToHex(byte[] bytes, int m, int n) { 85 | StringBuilder stringBuffer = new StringBuilder(2 * n); 86 | int k = m + n; 87 | for (int l = m; l < k; l++) { 88 | appendHexPair(bytes[1], stringBuffer); 89 | } 90 | return stringBuffer.toString(); 91 | } 92 | 93 | private static void appendHexPair(byte bt, StringBuilder stringBuffer) { 94 | char c0 = hexDigits[(bt & 0xf0) >> 4]; 95 | // 取字节中高 4 位的数字转换, >>> 为逻辑右移,将符号位一起右移,此处未发现两种符号有何不同 96 | // 取字节中低 4 位的数字转换 97 | char c1 = hexDigits[bt & 0xf]; 98 | stringBuffer.append(c0); 99 | stringBuffer.append(c1); 100 | } 101 | 102 | /** 103 | * 获取文件的MD5值大小 104 | * 105 | * @param file 文件对象 106 | * @return 107 | */ 108 | public static String getMD5(File file) { 109 | try (FileInputStream fileInputStream = new FileInputStream(file)) { 110 | MessageDigest md5 = MessageDigest.getInstance("MD5"); 111 | byte[] buffer = new byte[8192]; 112 | int length = 0; 113 | while ((length = fileInputStream.read(buffer)) != -1) { 114 | md5.update(buffer, 0, length); 115 | } 116 | return new String(Hex.encodeHex(md5.digest())); 117 | } catch (Exception e) { 118 | LOGGER.error("file MD5 fail", e); 119 | return null; 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/file/PathsUtil.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.file; 2 | 3 | import cn.eric.jdktools.date.DateUtil; 4 | 5 | import java.io.IOException; 6 | import java.nio.file.*; 7 | import java.time.LocalDateTime; 8 | import java.util.ArrayList; 9 | import java.util.Date; 10 | import java.util.List; 11 | 12 | /** 13 | * @ClassName PathsUtil 14 | * @Description: TODO 15 | * @Author YCKJ2725 16 | * @Date 2021/11/5 17 | * @Version V1.0 18 | **/ 19 | public class PathsUtil { 20 | 21 | public static void main(String[] args) throws IOException { 22 | 23 | List packageList = new ArrayList<>(); 24 | packageList.add("SystemOut——213.log"); 25 | packageList.add("SystemOut.log"); 26 | String installerPathTarget = "D:\\data\\file"; 27 | // 检查并创建备份文件夹 28 | Path backPath = Paths.get(installerPathTarget, "backup" 29 | , DateUtil.format(new Date(), DateUtil.PATTERN_YYYYMMDD)); 30 | if (!Files.exists(backPath)) { 31 | Files.createDirectory(backPath); 32 | } 33 | // 获取所有的一键部署包 34 | Path dir = Paths.get(installerPathTarget); 35 | try (DirectoryStream stream = Files.newDirectoryStream(dir)) { 36 | for (Path path : stream) { 37 | // 找到就转移到备份文件夹中 38 | if (packageList.contains(path.getFileName().toString())) { 39 | System.out.println("begin to move path " + path.getFileName() + " to" + backPath.getFileName()); 40 | Files.move(path, backPath.resolve(path.getFileName().toString()), 41 | StandardCopyOption.REPLACE_EXISTING); 42 | // TODO 发送邮件 43 | } 44 | } 45 | } catch (IOException e) { 46 | 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/file/YamlUtil.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.file; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.yaml.snakeyaml.DumperOptions; 5 | import org.yaml.snakeyaml.Yaml; 6 | 7 | import java.io.*; 8 | import java.util.LinkedHashMap; 9 | import java.util.Map; 10 | 11 | /** 12 | * @program: YamlUtil 13 | * @description: yml配置处理工具 14 | * @author: YCKJ2725 15 | * @create: 2021/3/30 16 | **/ 17 | public class YamlUtil { 18 | 19 | /** 20 | * 功能描述: 21 | * 〈加载yml文件〉 22 | * 23 | * @return : java.util.Map 24 | * @params : [fileName] 25 | * @author : cwl 26 | * @date : 2019/10/22 13:52 27 | */ 28 | public static Map loadYaml(String fileName) throws FileNotFoundException { 29 | try (InputStream in = new FileInputStream(fileName)) { 30 | return StringUtils.isNotEmpty(fileName) ? (LinkedHashMap) new Yaml().load(in) : null; 31 | } catch (IOException e) { 32 | throw new RuntimeException(e.getMessage(), e); 33 | } 34 | } 35 | 36 | public static Map loadYamlString(String fileString) { 37 | return StringUtils.isNotEmpty(fileString) ? (LinkedHashMap) new Yaml().load(fileString) : null; 38 | } 39 | 40 | /** 41 | * 功能描述: 42 | * 〈往yml文件中写数据,数据为map〉 43 | * 44 | * @return : void 45 | * @params : [fileName, map] 46 | * @author : cwl 47 | * @date : 2019/10/22 13:52 48 | */ 49 | public static void dumpYaml(String fileName, Map map) throws IOException { 50 | if (StringUtils.isNotEmpty(fileName)) { 51 | FileWriter fileWriter = new FileWriter(new File(fileName)); 52 | DumperOptions options = new DumperOptions(); 53 | options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); 54 | Yaml yaml = new Yaml(options); 55 | yaml.dump(map, fileWriter); 56 | fileWriter.close(); 57 | } 58 | } 59 | 60 | /** 61 | * 功能描述: 62 | * 〈根据key查询yml中的数据〉 63 | * 64 | * @return : java.lang.Object 65 | * @params : [map, qualifiedKey] 66 | * @author : cwl 67 | * @date : 2019/10/22 13:53 68 | */ 69 | public static Object getProperty(Map map, Object qualifiedKey) { 70 | if (map != null && !map.isEmpty() && qualifiedKey != null) { 71 | String input = String.valueOf(qualifiedKey); 72 | if (!"".equals(input)) { 73 | if (input.contains(".")) { 74 | int index = input.indexOf("."); 75 | String left = input.substring(0, index); 76 | String right = input.substring(index + 1); 77 | return getProperty((Map) map.get(left), right); 78 | } else if (map.containsKey(input)) { 79 | return map.get(input); 80 | } else { 81 | return null; 82 | } 83 | } 84 | } 85 | return null; 86 | } 87 | 88 | /** 89 | * 功能描述: 90 | * 〈设置yml中的值〉 91 | * 92 | * @return : void 93 | * @params : [map, qualifiedKey, value] 94 | * @author : cwl 95 | * @date : 2019/10/22 13:53 96 | */ 97 | @SuppressWarnings("unchecked") 98 | public static void setProperty(Map map, Object qualifiedKey, Object value) { 99 | if (map != null && !map.isEmpty() && qualifiedKey != null) { 100 | String input = String.valueOf(qualifiedKey); 101 | if (!input.equals("")) { 102 | if (input.contains(".")) { 103 | int index = input.indexOf("."); 104 | String left = input.substring(0, index); 105 | String right = input.substring(index + 1); 106 | setProperty((Map) map.get(left), right, value); 107 | } else { 108 | ((Map) map).put(qualifiedKey, value); 109 | } 110 | } 111 | } 112 | } 113 | } 114 | 115 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/file/jar/FatJarCreator.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.file.jar; 2 | 3 | import java.io.*; 4 | import java.util.*; 5 | import java.util.jar.*; 6 | 7 | public class FatJarCreator { 8 | private final static String ASSETS_PREFIX = "assets/"; 9 | 10 | private Set entryName = new HashSet<>(); 11 | 12 | /** 13 | * @param jarsPath JAR路径的数组 14 | * @param output 新文件的合并路径 15 | * @return result 16 | */ 17 | public boolean create(ArrayList jarsPath, String assetPath, String output) { 18 | boolean result = true; 19 | //Manifest manifest = getManifest(); 20 | 21 | FileOutputStream fos = null; 22 | JarOutputStream jos = null; 23 | try { 24 | fos = new FileOutputStream(output); 25 | //jos = new JarOutputStream(fos, manifest); 26 | addFilesFromJars(jarsPath, jos); 27 | if(null != assetPath){ 28 | addAssets(new File(assetPath), ASSETS_PREFIX, jos); 29 | }else{ 30 | System.out.println("!!!Path of assets is null!!!"); 31 | } 32 | System.out.println("Create fat jar success"); 33 | } catch (IOException e1) { 34 | result = false; 35 | e1.printStackTrace(); 36 | } finally { 37 | try { 38 | if(null != jos){ 39 | jos.close(); 40 | } 41 | if(null != fos){ 42 | fos.close(); 43 | } 44 | } catch (IOException e) { 45 | e.printStackTrace(); 46 | } 47 | } 48 | 49 | return result; 50 | } 51 | 52 | 53 | /** 54 | * @param files JAR文件的路径 55 | * @param output 新文件的合并路径 56 | * @return result 57 | */ 58 | public boolean createByFile(List files, String assetPath, String output) { 59 | boolean result = true; 60 | Manifest manifest = getManifest(); 61 | 62 | FileOutputStream fos = null; 63 | JarOutputStream jos = null; 64 | try { 65 | fos = new FileOutputStream(output); 66 | jos = new JarOutputStream(fos, manifest); 67 | addFilesFromJars(files, jos); 68 | if(null != assetPath){ 69 | addAssets(new File(assetPath), ASSETS_PREFIX, jos); 70 | }else{ 71 | System.out.println("!!!Path of assets is null!!!"); 72 | } 73 | System.out.println("Create fat jar success"); 74 | } catch (IOException e1) { 75 | result = false; 76 | e1.printStackTrace(); 77 | } finally { 78 | try { 79 | if(null != jos){ 80 | jos.close(); 81 | } 82 | if(null != fos){ 83 | fos.close(); 84 | } 85 | } catch (IOException e) { 86 | e.printStackTrace(); 87 | } 88 | } 89 | 90 | return result; 91 | } 92 | 93 | private Manifest getManifest() { 94 | Manifest manifest = new Manifest(); 95 | Attributes attribute = manifest.getMainAttributes(); 96 | attribute.putValue("Manifest-Version", "1.0"); 97 | attribute.putValue("Created-By","Youku fat jar plugin"); 98 | attribute.putValue("Main-Class","com.clickpaas.cid.component.project.common.generate.Params"); 99 | return manifest; 100 | } 101 | 102 | private void addFilesFromJars(ArrayList jarsPath, JarOutputStream out) throws IOException { 103 | String jarPath = ""; 104 | for (int i = 0; i < jarsPath.size(); i++) { 105 | jarPath = jarsPath.get(i); 106 | if(!new File(jarPath).exists()){ 107 | System.out.println("!!!Create fat jar failed!!!"); 108 | System.out.println("Can't find "+jarPath); 109 | break; 110 | } 111 | System.out.println("JarName=" + jarPath); 112 | 113 | JarFile jarFile = new JarFile(jarPath); 114 | Enumeration entities = jarFile.entries(); 115 | 116 | while (entities.hasMoreElements()) { 117 | JarEntry entry = (JarEntry) entities.nextElement(); 118 | 119 | if (entry.isDirectory()) { 120 | continue; 121 | } 122 | 123 | InputStream in = jarFile.getInputStream(entry); 124 | copyData2Jar(in, out, entry.getName()); 125 | } 126 | 127 | jarFile.close(); 128 | } 129 | } 130 | 131 | 132 | private void addFilesFromJars(List jarsFiles, JarOutputStream out) throws IOException { 133 | File file; 134 | for (int i = 0; i < jarsFiles.size(); i++) { 135 | file = jarsFiles.get(i); 136 | if(!file.exists()){ 137 | System.out.println("!!!Create fat jar failed!!!"); 138 | System.out.println("Can't find " + file.getAbsolutePath()); 139 | break; 140 | } 141 | System.out.println("JarName=" + file.getAbsolutePath()); 142 | 143 | JarFile jarFile = new JarFile(file); 144 | Enumeration entities = jarFile.entries(); 145 | 146 | while (entities.hasMoreElements()) { 147 | JarEntry entry = (JarEntry) entities.nextElement(); 148 | //System.out.println(entry.getName()); 149 | if (entry.isDirectory() || entry.getName().toLowerCase().contains("manifest.mf")) { 150 | continue; 151 | } 152 | 153 | InputStream in = jarFile.getInputStream(entry); 154 | copyData2Jar(in, out, entry.getName()); 155 | } 156 | 157 | jarFile.close(); 158 | } 159 | } 160 | 161 | private void addAssets(File dir, String jarEntryPrefix, JarOutputStream out) throws IOException{ 162 | if(!dir.exists() || !dir.isDirectory()){ 163 | System.out.println("dir is not exist or is not a directory"); 164 | return; 165 | } 166 | 167 | File[] files = dir.listFiles(); 168 | for(File file : files){ 169 | addAssetFile(file, jarEntryPrefix, out); 170 | } 171 | } 172 | 173 | private void addAssetFile(File file, String jarEntryPrefix, JarOutputStream out) throws IOException{ 174 | System.out.println("asset file name is "+file.getName()); 175 | 176 | if (file.exists() && file.isFile()) { 177 | InputStream in = new FileInputStream(file); 178 | copyData2Jar(in, out, jarEntryPrefix+file.getName()); 179 | } else { 180 | addAssets(file, jarEntryPrefix+file.getName()+"/", out); 181 | } 182 | } 183 | 184 | private void copyData2Jar(InputStream in, JarOutputStream out, String newEntryName) throws IOException{ 185 | if(entryName.add(newEntryName)) { 186 | int bufferSize; 187 | byte[] buffer = new byte[1024]; 188 | 189 | out.putNextEntry(new JarEntry(newEntryName)); 190 | 191 | while ((bufferSize = in.read(buffer, 0, buffer.length)) != -1) { 192 | out.write(buffer, 0, bufferSize); 193 | } 194 | 195 | in.close(); 196 | out.closeEntry(); 197 | } 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/file/jar/Launcher.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.file.jar; 2 | 3 | import org.w3c.dom.Document; 4 | import org.w3c.dom.Element; 5 | import org.w3c.dom.Node; 6 | import org.w3c.dom.NodeList; 7 | import org.xml.sax.SAXException; 8 | 9 | import javax.xml.parsers.DocumentBuilder; 10 | import javax.xml.parsers.DocumentBuilderFactory; 11 | import javax.xml.parsers.ParserConfigurationException; 12 | import java.io.File; 13 | import java.io.IOException; 14 | import java.text.SimpleDateFormat; 15 | import java.util.ArrayList; 16 | import java.util.Date; 17 | 18 | /** 19 | * @author douyoumi 20 | * @email xinshou.cb@gmail.com 21 | * @date 2016-08-18 22 | */ 23 | public class Launcher { 24 | 25 | private final static String OUT_FILE_NAME_PREFIX = "base_"; 26 | private final static String OUT_FILE_NAME_SUFFIX = ".jar"; 27 | 28 | private static ArrayList jarsPath = new ArrayList(); 29 | private static String assetsPath; 30 | 31 | public static void main(String[] args){ 32 | String outFileName; 33 | FatJarCreator fatjarCreator = new FatJarCreator(); 34 | 35 | String userdir = System.getProperty("user.dir"); 36 | System.out.println("userdir=" +userdir); 37 | // if(!parse(userdir+"/fatjar_config.xml")){ 38 | // System.out.println("!!!Create fat jar failed!!!"); 39 | // return; 40 | // } 41 | jarsPath.add("/Users/eric/Documents/workplace/JavaTools-master/src/main/resources/templete/ipaas-component-java8-sample-1.0.0.jar"); 42 | jarsPath.add("/Users/eric/Documents/workplace/JavaTools-master/src/main/resources/templete/ipaas-component-java-common-1.2.0-SNAPSHOT.jar"); 43 | 44 | assetsPath = "/Users/eric/Documents/workplace/JavaTools-master/src/main/resources/assets"; 45 | 46 | String outDirPath = userdir+"/out/"; 47 | outFileName = outDirPath+getName(); 48 | File outDir = new File(outDirPath); 49 | if(!outDir.exists()){ 50 | outDir.mkdirs(); 51 | } 52 | 53 | if(fatjarCreator.create(jarsPath, assetsPath, outFileName)){ 54 | System.out.println("outFileName:"+outFileName); 55 | } 56 | } 57 | 58 | private static String getName(){ 59 | String name = null; 60 | 61 | Date date = new Date(); 62 | SimpleDateFormat dateformat = new SimpleDateFormat("MMddHHmm"); 63 | String dateSuffix = dateformat.format(date); 64 | 65 | name = OUT_FILE_NAME_PREFIX+dateSuffix+OUT_FILE_NAME_SUFFIX; 66 | 67 | return name; 68 | } 69 | 70 | // Load and parse XML file into DOM 71 | public static boolean parse(String filePath) { 72 | boolean result = true; 73 | jarsPath.clear(); 74 | Document document = null; 75 | 76 | try { 77 | DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 78 | document = builder.parse(new File(filePath)); 79 | 80 | Element rootElement = document.getDocumentElement(); 81 | 82 | NodeList nodes = rootElement.getChildNodes(); 83 | for (int i=0; i < nodes.getLength(); i++) 84 | { 85 | Node node = nodes.item(i); 86 | if(node.getNodeType() != Node.ELEMENT_NODE){ 87 | continue; 88 | } 89 | 90 | if ("jars".equals(node.getNodeName())) { 91 | 92 | NodeList nodeList = ((Element)node).getElementsByTagName("jar"); 93 | if(nodeList != null) { 94 | for (int j = 0 ; j < nodeList.getLength(); j++) { 95 | Element element = (Element)nodeList.item(j); 96 | jarsPath.add(element.getAttribute("path")); 97 | } 98 | } 99 | } else if("assets".equals(node.getNodeName())){ 100 | assetsPath = ((Element)node).getAttribute("path"); 101 | } 102 | } 103 | 104 | } catch (ParserConfigurationException e) { 105 | result = false; 106 | e.printStackTrace(); 107 | } catch (SAXException e) { 108 | result = false; 109 | e.printStackTrace(); 110 | } catch (IOException e) { 111 | result = false; 112 | e.printStackTrace(); 113 | } 114 | return result; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/file/jar/MergeTest.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.file.jar; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.text.SimpleDateFormat; 6 | import java.util.Arrays; 7 | import java.util.Date; 8 | import java.util.List; 9 | 10 | /** 11 | * Company: 苏州渠成易销网络科技有限公司 12 | * 13 | * @version 1.0.0 14 | * @description: jar包合并并执行的测试方法 15 | * @author: 钱旭 16 | * @date: 2022-01-13 18:29 17 | **/ 18 | public class MergeTest { 19 | private final static String OUT_FILE_NAME_PREFIX = "base_"; 20 | private final static String OUT_FILE_NAME_SUFFIX = ".jar"; 21 | 22 | 23 | public static void main(String[] args) throws IOException { 24 | String userdir = System.getProperty("user.dir"); 25 | System.out.println("userdir=" +userdir); 26 | 27 | String assetsPath = "/Users/eric/Documents/workplace/JavaTools-master/src/main/resources/assets"; 28 | FatJarCreator fatjarCreator = new FatJarCreator(); 29 | File fileOne = new File("/Users/eric/Documents/workplace/JavaTools-master/src/main/resources/templete/ipaas-component-java8-sample-1.0.0.jar"); 30 | File fileTwo = new File("/Users/eric/Documents/workplace/JavaTools-master/src/main/resources/templete/ipaas-component-java-common-1.2.0-SNAPSHOT.jar"); 31 | List files = Arrays.asList(fileOne, fileTwo); 32 | 33 | String outDirPath = userdir+"/out/"; 34 | String outFileName = outDirPath+getName(); 35 | File outDir = new File(outDirPath); 36 | if(!outDir.exists()){ 37 | outDir.mkdirs(); 38 | } 39 | if (fatjarCreator.createByFile(files,assetsPath,outFileName)) { 40 | System.out.println("outFileName:"+outFileName); 41 | } 42 | 43 | // 执行java -jar 方法 44 | String command = "java -jar " + outFileName + " " + outDirPath + "params.json" + " " + outFileName; 45 | System.out.println(command); 46 | Process exec = Runtime.getRuntime().exec(command); 47 | while (exec.isAlive()) { 48 | 49 | } 50 | exec.destroy(); 51 | //System.out.println("Process exitValue: " + exitVal); 52 | } 53 | 54 | 55 | private static String getName(){ 56 | String name = null; 57 | 58 | Date date = new Date(); 59 | SimpleDateFormat dateformat = new SimpleDateFormat("MMddHHmm"); 60 | String dateSuffix = dateformat.format(date); 61 | 62 | name = OUT_FILE_NAME_PREFIX+dateSuffix+OUT_FILE_NAME_SUFFIX; 63 | 64 | return name; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/file/jar/fatjar_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/file/jar/fatjar_合并jar包.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EricLoveMia/JavaTools/1fe72617fac473a978f73136627e73a5c792c205/src/main/java/cn/eric/jdktools/file/jar/fatjar_合并jar包.txt -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/http/ApaHttpClientUtil.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.http; 2 | 3 | import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler; 4 | import org.apache.commons.httpclient.HttpClient; 5 | import org.apache.commons.httpclient.methods.PostMethod; 6 | import org.apache.commons.httpclient.methods.StringRequestEntity; 7 | import org.apache.commons.httpclient.params.HttpMethodParams; 8 | import org.apache.commons.httpclient.protocol.Protocol; 9 | import org.apache.http.HttpStatus; 10 | import org.apache.log4j.Logger; 11 | 12 | import java.io.BufferedReader; 13 | import java.io.IOException; 14 | import java.io.InputStream; 15 | import java.io.InputStreamReader; 16 | 17 | /** 18 | * @author BinCain 19 | * @version V1.0 20 | * @Description: 使用apache工具类远程调用接口 21 | * @date 2017/11/14 0014 14:19 22 | */ 23 | public class ApaHttpClientUtil { 24 | 25 | /** 26 | * APACHE 处理日志工具类 27 | */ 28 | private static Logger logger = Logger.getLogger(ApaHttpClientUtil.class); 29 | 30 | /** 31 | * @return void 32 | * @method postBodyString 33 | * @author BinCain 34 | * @date 2017/11/14 0014 13:38 35 | * @Description: apache httpClient apply request(POST) 36 | */ 37 | public static String postBodyString(String reqUrl, String reqStr) throws Exception { 38 | 39 | // https 协议添加信任 40 | Protocol protocol = new Protocol("https", new MySSLProtocolSocketFactory(), 443); 41 | Protocol.registerProtocol("https", protocol); 42 | 43 | // 返回报文 44 | String resultStr; 45 | HttpClient httpClient = new HttpClient(); 46 | logger.info(reqUrl + " 调用开始========"); 47 | // todo 测试结束上生产时 需要根据实际业务需求进行设置 48 | // 等待连接时间 49 | // httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(3000); 50 | // 读取响应时间 51 | // httpClient.getHttpConnectionManager().getParams().setSoTimeout(5000); 52 | PostMethod postMethod = new PostMethod(reqUrl); 53 | postMethod.setRequestEntity(new StringRequestEntity(reqStr, "application/json", "UTF-8")); 54 | postMethod.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); 55 | postMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler()); 56 | int statusCode = httpClient.executeMethod(postMethod); 57 | // 注意:经测试 如果是这里报错500,基本上是参数不对或者请求URL错误 58 | if (statusCode != HttpStatus.SC_OK) 59 | logger.info(postMethod.getStatusLine()); 60 | // 获取返回体信息 61 | // 第一种方式(有长度限制) 62 | //resultStr = postMethod.getResponseBodyAsString(); 63 | // 第二种方式(返回流转成string,无长度限制) 64 | resultStr = convertStreamToString(postMethod.getResponseBodyAsStream()); 65 | 66 | if (postMethod != null) { 67 | postMethod.releaseConnection(); 68 | } 69 | logger.info(reqUrl + " 调用成功====end===="); 70 | return resultStr; 71 | } 72 | 73 | /** 74 | * trans InputStream to string 75 | */ 76 | public static String convertStreamToString(InputStream is) { 77 | /* 78 | * To convert the InputStream to String we use the BufferedReader.readLine() 79 | * method. We iterate until the BufferedReader return null which means 80 | * there's no more data to read. Each line will appended to a StringBuilder 81 | * and returned as String. 82 | */ 83 | BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 84 | StringBuilder sb = new StringBuilder(); 85 | String line; 86 | try { 87 | while ((line = reader.readLine()) != null) { 88 | sb.append(line); 89 | } 90 | } catch (IOException e) { 91 | logger.info(e.toString()); 92 | } finally { 93 | try { 94 | is.close(); 95 | } catch (IOException e) { 96 | logger.info(e.toString()); 97 | } 98 | } 99 | return sb.toString(); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/http/IPUtils.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.http; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | 9 | /** 10 | * IP地址 11 | */ 12 | public class IPUtils { 13 | 14 | private static Logger logger = LoggerFactory.getLogger(IPUtils.class); 15 | 16 | /** 17 | * 获取IP地址 18 | * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址 19 | * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址 20 | */ 21 | public static String getIpAddr(HttpServletRequest request) { 22 | String ip = null; 23 | try { 24 | ip = request.getHeader("x-forwarded-for"); 25 | if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { 26 | ip = request.getHeader("Proxy-Client-IP"); 27 | } 28 | if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 29 | ip = request.getHeader("WL-Proxy-Client-IP"); 30 | } 31 | if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { 32 | ip = request.getHeader("HTTP_CLIENT_IP"); 33 | } 34 | if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { 35 | ip = request.getHeader("HTTP_X_FORWARDED_FOR"); 36 | } 37 | if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { 38 | ip = request.getRemoteAddr(); 39 | } 40 | } catch (Exception e) { 41 | logger.error("IPUtils ERROR ", e); 42 | } 43 | // 使用代理,则获取第一个IP地址 44 | if (StringUtils.isNotEmpty(ip) && ip.length() > 15) { 45 | if (ip.indexOf(",") > 0) { 46 | ip = ip.substring(0, ip.indexOf(",")); 47 | } 48 | } 49 | return ip; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/http/MySSLProtocolSocketFactory.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.http; 2 | 3 | import org.apache.commons.httpclient.ConnectTimeoutException; 4 | import org.apache.commons.httpclient.params.HttpConnectionParams; 5 | import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; 6 | 7 | import javax.net.SocketFactory; 8 | import javax.net.ssl.SSLContext; 9 | import javax.net.ssl.TrustManager; 10 | import javax.net.ssl.X509TrustManager; 11 | import java.io.IOException; 12 | import java.net.*; 13 | import java.security.KeyManagementException; 14 | import java.security.NoSuchAlgorithmException; 15 | import java.security.cert.CertificateException; 16 | import java.security.cert.X509Certificate; 17 | 18 | /** 19 | * @author BinCain 20 | * @version V1.0 21 | * @Description: 22 | * @date 2018/4/9 0009 16:27 23 | */ 24 | public class MySSLProtocolSocketFactory implements ProtocolSocketFactory { 25 | 26 | private SSLContext sslcontext = null; 27 | 28 | private SSLContext createSSLContext() { 29 | SSLContext sslcontext = null; 30 | try { 31 | sslcontext = SSLContext.getInstance("SSL"); 32 | sslcontext.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom()); 33 | } catch (NoSuchAlgorithmException e) { 34 | e.printStackTrace(); 35 | } catch (KeyManagementException e) { 36 | e.printStackTrace(); 37 | } 38 | return sslcontext; 39 | } 40 | 41 | private SSLContext getSSLContext() { 42 | if (this.sslcontext == null) { 43 | this.sslcontext = createSSLContext(); 44 | } 45 | return this.sslcontext; 46 | } 47 | 48 | public Socket createSocket(Socket socket, String host, int port, boolean autoClose) 49 | throws IOException, UnknownHostException { 50 | return getSSLContext().getSocketFactory().createSocket( 51 | socket, 52 | host, 53 | port, 54 | autoClose 55 | ); 56 | } 57 | 58 | @Override 59 | public Socket createSocket(String host, int port) throws IOException, 60 | UnknownHostException { 61 | return getSSLContext().getSocketFactory().createSocket( 62 | host, 63 | port 64 | ); 65 | } 66 | 67 | 68 | @Override 69 | public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) 70 | throws IOException, UnknownHostException { 71 | return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort); 72 | } 73 | 74 | @Override 75 | public Socket createSocket(String host, int port, InetAddress localAddress, 76 | int localPort, HttpConnectionParams params) throws IOException, 77 | UnknownHostException, ConnectTimeoutException { 78 | if (params == null) { 79 | throw new IllegalArgumentException("Parameters may not be null"); 80 | } 81 | int timeout = params.getConnectionTimeout(); 82 | SocketFactory socketfactory = getSSLContext().getSocketFactory(); 83 | if (timeout == 0) { 84 | return socketfactory.createSocket(host, port, localAddress, localPort); 85 | } else { 86 | Socket socket = socketfactory.createSocket(); 87 | SocketAddress localaddr = new InetSocketAddress(localAddress, localPort); 88 | SocketAddress remoteaddr = new InetSocketAddress(host, port); 89 | socket.bind(localaddr); 90 | socket.connect(remoteaddr, timeout); 91 | return socket; 92 | } 93 | } 94 | 95 | /** 96 | * 自定义私有类 97 | */ 98 | private static class TrustAnyTrustManager implements X509TrustManager { 99 | 100 | @Override 101 | public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 102 | } 103 | 104 | @Override 105 | public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 106 | } 107 | 108 | @Override 109 | public X509Certificate[] getAcceptedIssuers() { 110 | return new X509Certificate[]{}; 111 | } 112 | } 113 | 114 | 115 | } -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/http/MyX509TrustManager.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.http; 2 | 3 | import javax.net.ssl.X509TrustManager; 4 | import java.security.cert.CertificateException; 5 | import java.security.cert.X509Certificate; 6 | 7 | /** 8 | * @author Eric 9 | * @version 1.0 10 | * @ClassName: MyX509TrustManager 11 | * @Description: TODO 12 | * @company lsj 13 | * @date 2019/2/20 10:46 14 | **/ 15 | public class MyX509TrustManager implements X509TrustManager { 16 | 17 | // 检查客户端证书 18 | @Override 19 | public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 20 | } 21 | 22 | // 检查服务器端证书 23 | @Override 24 | public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 25 | } 26 | 27 | // 返回受信任的X509证书数组 28 | @Override 29 | public X509Certificate[] getAcceptedIssuers() { 30 | return null; 31 | } 32 | } -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/http/RestTemplateUtil.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.http; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.JSONObject; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.http.HttpEntity; 8 | import org.springframework.http.HttpHeaders; 9 | import org.springframework.http.HttpMethod; 10 | import org.springframework.http.ResponseEntity; 11 | import org.springframework.stereotype.Component; 12 | import org.springframework.web.client.RestClientException; 13 | import org.springframework.web.client.RestTemplate; 14 | 15 | import javax.annotation.Resource; 16 | import java.io.IOException; 17 | import java.io.InputStream; 18 | 19 | //import org.springframework.core.io.Resource; 20 | 21 | /** 22 | * RestTemplateUtil 工具类 23 | * 24 | * @author YCKJ3213 25 | */ 26 | @Component 27 | public class RestTemplateUtil { 28 | 29 | private static final Logger LOGGER = LoggerFactory.getLogger(RestTemplateUtil.class); 30 | 31 | @Resource 32 | private RestTemplate restTemplate; 33 | 34 | /** 35 | * 封装请求头 36 | * 37 | * @param header 38 | * @return 39 | */ 40 | private static HttpHeaders getHttpHeaders(JSONObject header) { 41 | HttpHeaders httpHeaders = new HttpHeaders(); 42 | httpHeaders.add("Accept", "application/json"); 43 | httpHeaders.add("Content-Encoding", "UTF-8"); 44 | httpHeaders.add("Content-Type", "application/json; charset=UTF-8"); 45 | if (header != null) { 46 | for (String key : header.keySet()) { 47 | httpHeaders.add(key, header.get(key).toString()); 48 | } 49 | } 50 | return httpHeaders; 51 | } 52 | 53 | /** 54 | * get请求 55 | * 56 | * @param url 57 | * @param header 58 | * @param data 59 | * @return 60 | */ 61 | public T get(String url, JSONObject header, String data, Class type) { 62 | return get(url, header, data, type, true); 63 | } 64 | 65 | public T get(String url, JSONObject header, String data, Class type, boolean printErrorLog) { 66 | try { 67 | ResponseEntity response = restTemplate 68 | .exchange(url, HttpMethod.GET, new HttpEntity(data, getHttpHeaders(header)), JSONObject.class); 69 | JSONObject result = response.getBody(); 70 | result.put("status", response.getStatusCodeValue()); 71 | LOGGER.debug("REST-GET结果, result->{}", result); 72 | return JSON.parseObject(result.toJSONString(), type); 73 | } catch (Exception e) { 74 | if (printErrorLog) { 75 | LOGGER.warn("get请求失败,请求地址为{},请求参数为{}", url, data); 76 | } 77 | } 78 | return null; 79 | } 80 | 81 | /** 82 | * get 请求 83 | * 84 | * @param url 85 | * @param type 86 | * @param 87 | * @return 88 | */ 89 | public T get(String url, Class type) { 90 | try { 91 | ResponseEntity response = restTemplate.getForEntity(url, type); 92 | T result = response.getBody(); 93 | LOGGER.debug("REST-GET结果, result->{}", result); 94 | return result; 95 | } catch (Exception e) { 96 | LOGGER.warn("get请求失败,请求地址为{}", url, e); 97 | } 98 | return null; 99 | } 100 | 101 | public String get(String url) { 102 | try { 103 | return restTemplate.getForObject(url, String.class); 104 | } catch (RestClientException e) { 105 | LOGGER.warn("get请求失败,请求地址为{}", url, e); 106 | return null; 107 | } 108 | } 109 | 110 | public InputStream getForStream(String url) { 111 | try { 112 | ResponseEntity entity = restTemplate.getForEntity(url, org.springframework.core.io.Resource.class); 113 | return entity.getBody().getInputStream(); 114 | } catch (RestClientException | IOException e) { 115 | LOGGER.warn("get请求失败,请求地址为{}", url, e); 116 | return null; 117 | } 118 | } 119 | 120 | /** 121 | * post请求 122 | * 123 | * @param url 124 | * @param header 125 | * @param data 126 | * @return 127 | */ 128 | public T post(String url, JSONObject header, String data, Class type) { 129 | 130 | try { 131 | ResponseEntity response = restTemplate 132 | .exchange(url, HttpMethod.POST, new HttpEntity(data, getHttpHeaders(header)), JSONObject.class); 133 | JSONObject result = response.getBody(); 134 | result.put("status", response.getStatusCodeValue()); 135 | LOGGER.debug("REST-POST结果, result->{}", result); 136 | return JSON.parseObject(result.toJSONString(), type); 137 | } catch (Exception e) { 138 | LOGGER.warn("post请求失败,请求地址为{},请求参数为{}", url, data, e); 139 | } 140 | return null; 141 | } 142 | 143 | /** 144 | * put请求 145 | * 146 | * @param url 147 | * @param header 148 | * @param data 149 | * @return 150 | */ 151 | public T put(String url, JSONObject header, String data, Class type) { 152 | 153 | try { 154 | ResponseEntity response = restTemplate 155 | .exchange(url, HttpMethod.PUT, new HttpEntity(data, getHttpHeaders(header)), JSONObject.class); 156 | JSONObject result = response.getBody(); 157 | result.put("status", response.getStatusCodeValue()); 158 | LOGGER.debug("REST-POST结果, result->{}", result); 159 | return JSON.parseObject(result.toJSONString(), type); 160 | } catch (Exception e) { 161 | LOGGER.warn("post请求失败,请求地址为{},请求参数为{}", url, data, e); 162 | } 163 | return null; 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/http/UrlUtil.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.http; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * @author by liaohanhan 8 | * @classname UrlUtil 9 | * @description url解析工具 10 | * @date 2019/3/26 5:09 PM 11 | */ 12 | public class UrlUtil { 13 | 14 | public static class UrlEntity { 15 | /** 16 | * 基础url 17 | */ 18 | public String baseUrl; 19 | /** 20 | * url参数 21 | */ 22 | public Map params; 23 | } 24 | 25 | /** 26 | * 解析url 27 | * 28 | * @param url 29 | * @return 30 | */ 31 | public static UrlEntity parse(String url) { 32 | UrlEntity entity = new UrlEntity(); 33 | if (url == null) { 34 | return entity; 35 | } 36 | url = url.trim(); 37 | if (url.equals("")) { 38 | return entity; 39 | } 40 | String[] urlParts = url.split("\\?"); 41 | entity.baseUrl = urlParts[0]; 42 | //没有参数 43 | if (urlParts.length == 1) { 44 | return entity; 45 | } 46 | //有参数 47 | String[] params = urlParts[1].split("&"); 48 | entity.params = new HashMap<>(); 49 | for (String param : params) { 50 | String[] keyValue = param.split("="); 51 | entity.params.put(keyValue[0], keyValue[1]); 52 | } 53 | 54 | return entity; 55 | } 56 | 57 | /** 58 | * 测试 59 | * 60 | * @param args 61 | */ 62 | public static void main(String[] args) { 63 | UrlEntity entity = parse(null); 64 | System.out.println(entity.baseUrl + "\n" + entity.params); 65 | entity = parse("http://www.123.com"); 66 | System.out.println(entity.baseUrl + "\n" + entity.params); 67 | entity = parse("http://www.123.com?id=1"); 68 | System.out.println(entity.baseUrl + "\n" + entity.params); 69 | entity = parse("https://mcar.tpi.cntaiping.com/mall/dispatch/order/payCallback?orderNo=5fc8c0d9-d0de-44cd-992e-3cc24df4807a&status=P_E&userCode=15266551100&clientName=H024003"); 70 | System.out.println(entity.baseUrl + "\n" + entity.params); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/jmh/StringBuilderRunner.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.jmh; 2 | 3 | /** 4 | * coder4j.cn 5 | * Copyright (C) 2013-2018 All Rights Reserved. 6 | */ 7 | import org.openjdk.jmh.annotations.Mode; 8 | import org.openjdk.jmh.runner.Runner; 9 | import org.openjdk.jmh.runner.RunnerException; 10 | import org.openjdk.jmh.runner.options.Options; 11 | import org.openjdk.jmh.runner.options.OptionsBuilder; 12 | 13 | /** 14 | * @author buhao 15 | * @version StringBuilderRunner.java, v 0.1 2018-12-25 09:53 buhao 16 | */ 17 | public class StringBuilderRunner { 18 | 19 | public static void main( String[] args ) throws RunnerException { 20 | Options opt = new OptionsBuilder() 21 | // 导入要测试的类 22 | .include(StringConnectBenchmark.class.getSimpleName()) 23 | // 预热5轮 24 | .warmupIterations(5) 25 | // 度量10轮 26 | .measurementIterations(10) 27 | .mode(Mode.Throughput) 28 | .forks(3) 29 | .build(); 30 | 31 | new Runner(opt).run(); 32 | 33 | 34 | } 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/jmh/StringConnectBenchmark.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.jmh; 2 | 3 | /** 4 | * coder4j.cn 5 | * Copyright (C) 2013-2018 All Rights Reserved. 6 | */ 7 | 8 | import org.openjdk.jmh.annotations.Benchmark; 9 | 10 | /** 11 | * @author buhao 12 | * @version StringConnectBenchmark.java, v 0.1 2018-12-25 09:29 buhao 13 | */ 14 | public class StringConnectBenchmark { 15 | 16 | /** 17 | * 字符串拼接之 StringBuilder 基准测试 18 | */ 19 | @Benchmark 20 | public void testStringBuilder() { 21 | print(new StringBuilder().append(1).append(2).append(3).toString()); 22 | } 23 | 24 | /** 25 | * 字符串拼接之直接相加基准测试 26 | */ 27 | @Benchmark 28 | public void testStringAdd() { 29 | print(new String()+ 1 + 2 + 3); 30 | } 31 | 32 | /** 33 | * 字符串拼接之String Concat基准测试 34 | */ 35 | @Benchmark 36 | public void testStringConcat() { 37 | print(new String().concat("1").concat("2").concat("3")); 38 | } 39 | 40 | /** 41 | * 字符串拼接之 StringBuffer 基准测试 42 | */ 43 | @Benchmark 44 | public void testStringBuffer() { 45 | print(new StringBuffer().append(1).append(2).append(3).toString()); 46 | } 47 | 48 | /** 49 | * 字符串拼接之 StringFormat 基准测试 50 | */ 51 | @Benchmark 52 | public void testStringFormat(){ 53 | print(String.format("%s%s%s", 1, 2, 3)); 54 | } 55 | 56 | public void print(String str) { 57 | 58 | } 59 | } 60 | 61 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/json/EricAnnotator.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.json; 2 | 3 | import cn.eric.jdktools.date.DateUtil; 4 | import com.fasterxml.jackson.annotation.*; 5 | import com.fasterxml.jackson.databind.JsonNode; 6 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 7 | import com.sun.codemodel.*; 8 | import org.apache.commons.lang3.StringUtils; 9 | import org.jsonschema2pojo.AbstractAnnotator; 10 | import org.jsonschema2pojo.GenerationConfig; 11 | import org.jsonschema2pojo.rules.FormatRule; 12 | 13 | import java.util.*; 14 | 15 | /** 16 | * Company: ClickPaaS 17 | * 18 | * @version 1.0.0 19 | * @description: 20 | * @author: 钱旭 21 | * @date: 2022-09-09 11:46 22 | **/ 23 | public class EricAnnotator extends AbstractAnnotator { 24 | 25 | private List requiredList = new ArrayList<>(); 26 | 27 | public EricAnnotator(GenerationConfig generationConfig) { 28 | super(generationConfig); 29 | } 30 | 31 | // public void propertyOrder(JDefinedClass clazz, JsonNode propertiesNode) { 32 | // JAnnotationArrayMember annotationValue = clazz.annotate(JsonPropertyOrder.class).paramArray("value"); 33 | // Iterator properties = propertiesNode.fieldNames(); 34 | // 35 | // while(properties.hasNext()) { 36 | // annotationValue.param((String)properties.next()); 37 | // } 38 | // 39 | // } 40 | 41 | public void propertyField(JFieldVar field, JDefinedClass clazz, String propertyName, JsonNode propertyNode) { 42 | JAnnotationUse value = field.annotate(Property.class).param("value", propertyName); 43 | if (propertyNode.has("description")) { 44 | value.param("description", propertyNode.get("description").asText()); 45 | } 46 | if (propertyNode.has("title")) { 47 | value.param("title", propertyNode.get("title").asText()); 48 | } 49 | if (requiredList.contains(propertyName)) { 50 | value.param("required", true); 51 | } 52 | } 53 | 54 | public void propertyInclusion(JDefinedClass clazz, JsonNode schema) { 55 | JAnnotationUse model = clazz.annotate(Model.class).param("date", DateUtil.format(new Date(), DateUtil.PATTERN_YYYY_MM_DD_HHMMSS)); 56 | // title 57 | JsonNode title = schema.get("title"); 58 | if(title != null){ 59 | model.param("name",title.asText()); 60 | } 61 | 62 | // title 63 | JsonNode description = schema.get("description"); 64 | if(description != null){ 65 | model.param("description",title.asText()); 66 | } 67 | 68 | // required 69 | JsonNode required = schema.get("required"); 70 | if(required != null){ 71 | requiredList = new ArrayList<>(); 72 | int size = required.size(); 73 | for (int i = 0; i < size; i++) { 74 | JsonNode jsonNode = required.get(i); 75 | String text = jsonNode.asText(); 76 | requiredList.add(text); 77 | } 78 | 79 | } 80 | } 81 | 82 | 83 | 84 | // public void propertyGetter(JMethod getter, String propertyName) { 85 | // getter.annotate(Property.class).param("value", propertyName); 86 | // } 87 | // 88 | // public void propertySetter(JMethod setter, String propertyName) { 89 | // setter.annotate(Property.class).param("value", propertyName); 90 | // } 91 | 92 | // public void dateField(JFieldVar field, JsonNode node) { 93 | // String pattern = null; 94 | // if (node.has("customDatePattern")) { 95 | // pattern = node.get("customDatePattern").asText(); 96 | // } else if (node.has("customPattern")) { 97 | // pattern = node.get("customPattern").asText(); 98 | // } else if (StringUtils.isNotEmpty(this.getGenerationConfig().getCustomDatePattern())) { 99 | // pattern = this.getGenerationConfig().getCustomDatePattern(); 100 | // } else if (this.getGenerationConfig().isFormatDates()) { 101 | // pattern = FormatRule.ISO_8601_DATE_FORMAT; 102 | // } 103 | // 104 | // if (pattern != null && !field.type().fullName().equals("java.lang.String")) { 105 | // field.annotate(JsonFormat.class).param("shape", JsonFormat.Shape.STRING).param("pattern", pattern); 106 | // } 107 | // 108 | // } 109 | 110 | // public void dateTimeField(JFieldVar field, JsonNode node) { 111 | // String timezone = node.has("customTimezone") ? node.get("customTimezone").asText() : "UTC"; 112 | // String pattern = null; 113 | // if (node.has("customDateTimePattern")) { 114 | // pattern = node.get("customDateTimePattern").asText(); 115 | // } else if (node.has("customPattern")) { 116 | // pattern = node.get("customPattern").asText(); 117 | // } else if (StringUtils.isNotEmpty(this.getGenerationConfig().getCustomDateTimePattern())) { 118 | // pattern = this.getGenerationConfig().getCustomDateTimePattern(); 119 | // } else if (this.getGenerationConfig().isFormatDateTimes()) { 120 | // pattern = FormatRule.ISO_8601_DATETIME_FORMAT; 121 | // } 122 | // 123 | // if (pattern != null && !field.type().fullName().equals("java.lang.String")) { 124 | // field.annotate(JsonFormat.class).param("shape", Shape.STRING).param("pattern", pattern).param("timezone", timezone); 125 | // } 126 | // 127 | // } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/json/JsonCompareResult.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.json; 2 | 3 | /** 4 | * Company: ClickPaaS 5 | * 6 | * @version 1.0.0 7 | * @description: jsonschema比较返回数据封装 8 | * @author: 钱旭 9 | * @date: 2022-02-21 16:15 10 | **/ 11 | public class JsonCompareResult { 12 | 13 | private String defect; 14 | private String change; 15 | private String extra; 16 | 17 | public String getDefect() { 18 | return defect; 19 | } 20 | 21 | public void setDefect(String defect) { 22 | this.defect = defect; 23 | } 24 | 25 | public String getChange() { 26 | return change; 27 | } 28 | 29 | public void setChange(String change) { 30 | this.change = change; 31 | } 32 | 33 | public String getExtra() { 34 | return extra; 35 | } 36 | 37 | public void setExtra(String extra) { 38 | this.extra = extra; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/json/JsonObjectTest.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.json; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.JSONObject; 5 | import com.google.gson.JsonObject; 6 | import lombok.Data; 7 | 8 | /** 9 | * Company: ClickPaaS 10 | * 11 | * @version 1.0.0 12 | * @description: 13 | * @author: 钱旭 14 | * @date: 2022-10-09 09:30 15 | **/ 16 | public class JsonObjectTest { 17 | 18 | 19 | public static void main(String[] args) { 20 | Test test = JSONObject.parseObject("{\"id\":\"1111111111\",\"body\":{\"isDeleted\":\"0\"}}", Test.class); 21 | 22 | 23 | JSONObject toJSON = (JSONObject) JSONObject.toJSON(test.getBody()); 24 | toJSON.put("age",23); 25 | toJSON.put("desc","222"); 26 | 27 | System.out.println(JSON.toJSONString(test)); 28 | 29 | } 30 | 31 | 32 | @Data 33 | static class Test { 34 | 35 | String id; 36 | 37 | Object body; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/json/JsonSchemaToJson.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.json; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.fasterxml.jackson.databind.JsonNode; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | import com.saasquatch.jsonschemainferrer.AdditionalPropertiesPolicies; 7 | import com.saasquatch.jsonschemainferrer.JsonSchemaInferrer; 8 | import com.saasquatch.jsonschemainferrer.RequiredPolicies; 9 | import com.saasquatch.jsonschemainferrer.SpecVersion; 10 | 11 | import java.util.Arrays; 12 | 13 | /** 14 | * @version 1.0.0 15 | * @description: jsonSchemma转json 16 | * @author: eric 17 | * @date: 2022-10-31 19:00 18 | **/ 19 | public class JsonSchemaToJson { 20 | 21 | private static final ObjectMapper mapper = new ObjectMapper(); 22 | private static final JsonSchemaInferrer inferrer = JsonSchemaInferrer.newBuilder() 23 | .setSpecVersion(SpecVersion.DRAFT_04) 24 | .setAdditionalPropertiesPolicy(AdditionalPropertiesPolicies.noOp()) 25 | .setRequiredPolicy(RequiredPolicies.noOp()) 26 | .build(); 27 | 28 | 29 | public static void main(String[] args) throws JsonProcessingException { 30 | 31 | final JsonNode sample1 = mapper.readTree( 32 | "{\"🙈\":\"https://saasquatch.com\",\"🙉\":[-1.5,2,\"hello@saasquat.ch\",false],\"🙊\":3,\"weekdays\":[\"MONDAY\",\"TUESDAY\"]}"); 33 | final JsonNode sample2 = mapper.readTree( 34 | "{\"🙈\":1,\"🙉\":{\"🐒\":true,\"🐵\":[2,\"1234:5678::\"],\"🍌\":null},\"🙊\":null,\"months\":[\"JANUARY\",\"FEBRUARY\"]}"); 35 | final JsonNode resultForSample1 = inferrer.inferForSample(sample1); 36 | final JsonNode resultForSample1And2 = 37 | inferrer.inferForSamples(Arrays.asList(sample1, sample2)); 38 | for (JsonNode j : Arrays.asList(sample1, sample2, resultForSample1, resultForSample1And2)) { 39 | System.out.println(mapper.writeValueAsString(j)); 40 | } 41 | 42 | 43 | 44 | } 45 | 46 | 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/json/JsonToPojo.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.json; 2 | 3 | import java.io.File; 4 | 5 | import java.io.IOException; 6 | import java.net.URL; 7 | 8 | import org.jsonschema2pojo.*; 9 | import org.jsonschema2pojo.rules.RuleFactory; 10 | import com.sun.codemodel.JCodeModel; 11 | 12 | /** 13 | * Company: ClickPaaS 14 | * 15 | * @version 1.0.0 16 | * @description: 17 | * @author: 钱旭 18 | * @date: 2022-09-09 10:56 19 | **/ 20 | public class JsonToPojo { 21 | /** 22 | * @param args 23 | */ 24 | 25 | public static void main(String[] args) { 26 | 27 | String packageName = "cn.eric.jdktools"; 28 | File inputJson = new File("json/inputSchema.json"); 29 | File outputPojoDirectory = new File("json" + File.separator + "convertedPojo"); 30 | outputPojoDirectory.mkdirs(); 31 | 32 | try { 33 | new JsonToPojo().convert2JSON(inputJson.toURI().toURL(), outputPojoDirectory, packageName, inputJson.getName().replace(".json", "")); 34 | } catch (IOException e) { 35 | // TODO Auto-generated catch block 36 | System.out.println("Encountered issue while converting to pojo: " + e.getMessage()); 37 | e.printStackTrace(); 38 | } 39 | } 40 | 41 | public void convert2JSON(URL inputJson, File outputPojoDirectory, String packageName, String className) throws 42 | IOException { 43 | 44 | JCodeModel codeModel = new JCodeModel(); 45 | URL source = inputJson; 46 | GenerationConfig config = new DefaultGenerationConfig() { 47 | // @Override 48 | // public boolean isGenerateBuilders() { // set config option by overriding method 49 | // return true; 50 | // } 51 | @Override 52 | public boolean isGenerateBuilders() { // set config option by overriding method 53 | return false; 54 | } 55 | 56 | @Override 57 | public boolean isIncludeHashcodeAndEquals() { 58 | return false; 59 | } 60 | 61 | @Override 62 | public boolean isIncludeToString() { 63 | return false; 64 | } 65 | 66 | @Override 67 | public boolean isIncludeAdditionalProperties() { 68 | return false; 69 | } 70 | 71 | public SourceType getSourceType(){ 72 | return SourceType.JSONSCHEMA; 73 | } 74 | }; 75 | 76 | SchemaMapper mapper = new SchemaMapper(new RuleFactory(config, new EricAnnotator(config), new SchemaStore()), new SchemaGenerator()); 77 | mapper.generate(codeModel,className,packageName,source); 78 | codeModel.build(outputPojoDirectory); 79 | } 80 | } -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/json/JsonToSchema.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.json; 2 | 3 | import com.fasterxml.jackson.databind.JsonNode; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import com.saasquatch.jsonschemainferrer.AdditionalPropertiesPolicies; 6 | import com.saasquatch.jsonschemainferrer.JsonSchemaInferrer; 7 | import com.saasquatch.jsonschemainferrer.RequiredPolicies; 8 | import com.saasquatch.jsonschemainferrer.SpecVersion; 9 | 10 | import java.util.Arrays; 11 | 12 | /** 13 | * @version 1.0.0 14 | * @description: 15 | * @author: eric 16 | * @date: 2022-09-20 16:02 17 | **/ 18 | public class JsonToSchema { 19 | 20 | private static final ObjectMapper mapper = new ObjectMapper(); 21 | private static final JsonSchemaInferrer inferrer = JsonSchemaInferrer.newBuilder() 22 | .setSpecVersion(SpecVersion.DRAFT_04) 23 | .setAdditionalPropertiesPolicy(AdditionalPropertiesPolicies.noOp()) 24 | .setRequiredPolicy(RequiredPolicies.noOp()) 25 | .build(); 26 | 27 | 28 | 29 | public static void main(String[] args) throws Exception { 30 | // final JsonNode sample1 = mapper.readTree( 31 | // "{\"code\":200,\"message\":\"测试通过\",\"data\":{\"data1\":\"test\",\"data2\":[\"test1\",\"test2\"]}}{\"code\":200,\"message\":\"测试通过\",\"data\":[ {\"data1\":\"test\" }]}{ \"code\":200, \"message\":\"测试通过\", \"data\":{ \"data1\":\"test\", \"data2\":[{ \"object1\":{ \"stu_id\":\"123\", \"stu_name\":\"张三\"}},{ \"object2\":{ \"work_id\":\"456\",\"work_name\":\"李四\"}} ] }}"); 32 | // final JsonNode resultForSample1 = inferrer.inferForSample(sample1); 33 | // for (JsonNode j : Arrays.asList(sample1, resultForSample1)) { 34 | // System.out.println(mapper.writeValueAsString(j)); 35 | // } 36 | 37 | 38 | 39 | final JsonNode sample3 = mapper.readTree( 40 | "{\"code\":200,\"message\":\"测试通过\",\"data\":{\"data1\":\"test\",\"data2\":[{\"test1\":\"111\",\"test2\":\"111\"}]}}{\"code\":200,\"message\":\"测试通过\",\"data\":[ {\"data1\":\"test\" }]}{ \"code\":200, \"message\":\"测试通过\", \"data\":{ \"data1\":\"test\", \"data2\":[{ \"object1\":{ \"stu_id\":\"123\", \"stu_name\":\"张三\"}},{ \"object2\":{ \"work_id\":\"456\",\"work_name\":\"李四\"}} ] }}"); 41 | final JsonNode resultForSample3 = inferrer.inferForSample(sample3); 42 | for (JsonNode j : Arrays.asList(sample3, resultForSample3)) { 43 | System.out.println(mapper.writeValueAsString(j)); 44 | } 45 | 46 | 47 | // final JsonNode sample1 = mapper.readTree( 48 | // "{\"🙈\":\"https://saasquatch.com\",\"🙉\":[-1.5,2,\"hello@saasquat.ch\",false],\"🙊\":3,\"weekdays\":[\"MONDAY\",\"TUESDAY\"]}"); 49 | // final JsonNode sample2 = mapper.readTree( 50 | // "{\"🙈\":1,\"🙉\":{\"🐒\":true,\"🐵\":[2,\"1234:5678::\"],\"🍌\":null},\"🙊\":null,\"months\":[\"JANUARY\",\"FEBRUARY\"]}"); 51 | // final JsonNode resultForSample1 = inferrer.inferForSample(sample1); 52 | // final JsonNode resultForSample1And2 = 53 | // inferrer.inferForSamples(Arrays.asList(sample1, sample2)); 54 | // for (JsonNode j : Arrays.asList(sample1, sample2, resultForSample1, resultForSample1And2)) { 55 | // System.out.println(mapper.writeValueAsString(j)); 56 | // } 57 | 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/json/Model.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.json; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * Company: ClickPaaS 7 | * 8 | * @version 1.0.0 9 | * @description: entity class basic annotation 10 | * @author: qianxu 11 | * @date: 2022-09-06 10:19 12 | **/ 13 | @Target(ElementType.TYPE) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Documented 16 | public @interface Model { 17 | 18 | /** 19 | * the name of class 20 | */ 21 | String name() default ""; 22 | 23 | /** 24 | * Date when the entity class was created. 25 | */ 26 | String date() default ""; 27 | 28 | /** 29 | * any comments that may want to include in the generated code. 30 | */ 31 | String comments() default ""; 32 | 33 | /** 34 | * Provides an example of the schema. 35 | **/ 36 | String example() default ""; 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/json/Property.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.json; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Company: ClickPaaS 10 | * 11 | * @version 1.0.0 12 | * @description: prperties annotation 13 | * @author: qianxu 14 | * @date: 2022-09-06 10:03 15 | **/ 16 | @Target(ElementType.FIELD) 17 | @Retention(RetentionPolicy.RUNTIME) 18 | public @interface Property { 19 | 20 | /** 21 | * The value of the schema or property. 22 | **/ 23 | String value() default ""; 24 | 25 | /** 26 | * A title to explain the purpose of the schema. 27 | **/ 28 | String title() default ""; 29 | 30 | /** 31 | * A description of the schema. 32 | **/ 33 | String description() default ""; 34 | 35 | /** 36 | * Mandates that the annotated item is required or not. 37 | * Temporarily closed 38 | **/ 39 | boolean required() default false; 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/loopcall/ConfigServer.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.loopcall; 2 | 3 | import com.google.common.collect.HashMultimap; 4 | import com.google.common.collect.Multimap; 5 | import com.google.common.collect.Multimaps; 6 | import com.google.common.util.concurrent.ThreadFactoryBuilder; 7 | import lombok.Data; 8 | import lombok.SneakyThrows; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.springframework.boot.SpringApplication; 11 | import org.springframework.boot.autoconfigure.SpringBootApplication; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | import javax.servlet.AsyncContext; 16 | import javax.servlet.http.HttpServletRequest; 17 | import javax.servlet.http.HttpServletResponse; 18 | import java.util.Collection; 19 | import java.util.concurrent.ScheduledExecutorService; 20 | import java.util.concurrent.ScheduledThreadPoolExecutor; 21 | import java.util.concurrent.ThreadFactory; 22 | import java.util.concurrent.TimeUnit; 23 | 24 | /** 25 | * @version 1.0.0 26 | * @description: 27 | * @author: 钱旭 28 | * @date: 2022-08-31 14:19 29 | **/ 30 | @RestController 31 | @Slf4j 32 | @SpringBootApplication 33 | public class ConfigServer { 34 | 35 | @Data 36 | private static class AsyncTask { 37 | // 长轮询请求的上下文,包含请求和响应体 38 | private AsyncContext asyncContext; 39 | // 超时标记 40 | private boolean timeout; 41 | 42 | public AsyncTask(AsyncContext asyncContext, boolean timeout) { 43 | this.asyncContext = asyncContext; 44 | this.timeout = timeout; 45 | } 46 | } 47 | 48 | // guava 提供的多值 Map,一个 key 可以对应多个 value 49 | private Multimap dataIdContext = Multimaps.synchronizedSetMultimap(HashMultimap.create()); 50 | 51 | private ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("longPolling-timeout-checker-%d") 52 | .build(); 53 | private ScheduledExecutorService timeoutChecker = new ScheduledThreadPoolExecutor(1, threadFactory); 54 | 55 | // 配置监听接入点 56 | @RequestMapping("/listener") 57 | public void addListener(HttpServletRequest request, HttpServletResponse response) { 58 | 59 | String dataId = request.getParameter("dataId"); 60 | 61 | // 开启异步!!! 62 | AsyncContext asyncContext = request.startAsync(request, response); 63 | AsyncTask asyncTask = new AsyncTask(asyncContext, true); 64 | 65 | // 维护 dataId 和异步请求上下文的关联 66 | dataIdContext.put(dataId, asyncTask); 67 | 68 | // 启动定时器,30s 后写入 304 响应 69 | timeoutChecker.schedule(() -> { 70 | if (asyncTask.isTimeout()) { 71 | dataIdContext.remove(dataId, asyncTask); 72 | response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); 73 | // 标志此次异步线程完成结束!!! 74 | asyncContext.complete(); 75 | } 76 | }, 30000, TimeUnit.MILLISECONDS); 77 | } 78 | 79 | // 配置发布接入点 80 | @RequestMapping("/publishConfig") 81 | @SneakyThrows 82 | public String publishConfig(String dataId, String configInfo) { 83 | log.info("publish configInfo dataId: [{}], configInfo: {}", dataId, configInfo); 84 | Collection asyncTasks = dataIdContext.removeAll(dataId); 85 | for (AsyncTask asyncTask : asyncTasks) { 86 | asyncTask.setTimeout(false); 87 | HttpServletResponse response = (HttpServletResponse) asyncTask.getAsyncContext().getResponse(); 88 | response.setStatus(HttpServletResponse.SC_OK); 89 | response.getWriter().println(configInfo); 90 | asyncTask.getAsyncContext().complete(); 91 | } 92 | return "success"; 93 | } 94 | 95 | public static void main(String[] args) { 96 | SpringApplication.run(ConfigServer.class, args); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/loopcall/LoopWorker.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.loopcall; 2 | 3 | import lombok.SneakyThrows; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.apache.http.client.config.RequestConfig; 6 | import org.apache.http.client.methods.CloseableHttpResponse; 7 | import org.apache.http.client.methods.HttpGet; 8 | import org.apache.http.impl.client.CloseableHttpClient; 9 | import org.apache.http.impl.client.HttpClientBuilder; 10 | 11 | import java.io.BufferedReader; 12 | import java.io.IOException; 13 | import java.io.InputStreamReader; 14 | import java.util.concurrent.Executors; 15 | import java.util.concurrent.ScheduledExecutorService; 16 | 17 | /** 18 | * Company: ClickPaaS 19 | * 20 | * @version 1.0.0 21 | * @description: 22 | * @author: eric 23 | * @date: 2022-08-31 14:07 24 | **/ 25 | @Slf4j 26 | public class LoopWorker { 27 | 28 | private CloseableHttpClient httpClient; 29 | private ScheduledExecutorService executorService; 30 | 31 | public LoopWorker(String url, String dataId) { 32 | this.executorService = Executors.newSingleThreadScheduledExecutor(runnable -> { 33 | Thread thread = new Thread(runnable); 34 | thread.setName("client.worker.executor-%d"); 35 | thread.setDaemon(true); 36 | return thread; 37 | }); 38 | // ① httpClient 客户端超时时间要大于长轮询约定的超时时间 39 | RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(40000).build(); 40 | this.httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build(); 41 | 42 | executorService.execute(new LongPollingRunnable(url, dataId)); 43 | } 44 | 45 | class LongPollingRunnable implements Runnable { 46 | 47 | private final String url; 48 | private final String dataId; 49 | 50 | public LongPollingRunnable(String url, String dataId) { 51 | this.url = url; 52 | this.dataId = dataId; 53 | } 54 | 55 | @SneakyThrows 56 | @Override 57 | public void run() { 58 | String endpoint = url + "?dataId=" + dataId; 59 | log.info("endpoint: {}", endpoint); 60 | HttpGet request = new HttpGet(endpoint); 61 | CloseableHttpResponse response = httpClient.execute(request); 62 | switch (response.getStatusLine().getStatusCode()) { 63 | case 200: { 64 | BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity() 65 | .getContent())); 66 | StringBuilder result = new StringBuilder(); 67 | String line; 68 | while ((line = rd.readLine()) != null) { 69 | result.append(line); 70 | } 71 | response.close(); 72 | String configInfo = result.toString(); 73 | log.info("dataId: [{}] changed, receive configInfo: {}", dataId, configInfo); 74 | break; 75 | } 76 | // ② 304 响应码标记配置未变更 77 | case 304: { 78 | log.info("longPolling dataId: [{}] once finished, configInfo is unchanged, longPolling again", dataId); 79 | break; 80 | } 81 | default: { 82 | throw new RuntimeException("unExcepted HTTP status code"); 83 | } 84 | } 85 | executorService.execute(this); 86 | } 87 | } 88 | 89 | public static void main(String[] args) throws IOException { 90 | 91 | new LoopWorker("http://127.0.0.1:8080/listener", "user"); 92 | System.in.read(); 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/other/EnumUtil.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.other; 2 | 3 | import org.apache.commons.lang3.EnumUtils; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import java.lang.reflect.Method; 8 | import java.util.List; 9 | 10 | /** 11 | * @ClassName EnumUtil 12 | * @Description: 枚举工具类 13 | * @Author eric 14 | * @Date 2021/5/19 15 | * @Version V1.0 16 | **/ 17 | public class EnumUtil { 18 | 19 | private static final Logger logger = LoggerFactory.getLogger(EnumUtil.class); 20 | 21 | /** 22 | * 判断某个枚举是否包某个code值 23 | * 24 | * @param enumClass 需要判断是否存在那个枚举类中 25 | * @param code 需要判断的值 26 | * @return 包含返回true,否则返回false 27 | */ 28 | public static boolean isInclude(Class enumClass, int code) { 29 | List enumList = EnumUtils.getEnumList(enumClass); 30 | for (int i = 0; i < enumList.size(); i++) { 31 | Object en = enumList.get(i); 32 | Class enClass = en.getClass(); 33 | try { 34 | // 需要与枚举类方法对应 35 | Method method = enClass.getMethod("getCode"); 36 | Object invoke = method.invoke(en); 37 | if (Integer.parseInt(invoke.toString()) == code) { 38 | return true; 39 | } 40 | } catch (Exception e) { 41 | logger.error("枚举执行getCode方法失败...", e); 42 | } 43 | } 44 | return false; 45 | } 46 | 47 | /** 48 | * 判断某个枚举是否包某个code值 49 | * 50 | * @param enumClass 需要判断是否存在那个枚举类中 51 | * @param code 需要判断的值 52 | * @return 包含返回true,否则返回false 53 | */ 54 | public static boolean isInclude(Class enumClass, String code) { 55 | List enumList = EnumUtils.getEnumList(enumClass); 56 | for (int i = 0; i < enumList.size(); i++) { 57 | Object en = enumList.get(i); 58 | Class enClass = en.getClass(); 59 | try { 60 | // 需要与枚举类方法对应 61 | Method method = enClass.getMethod("getCode"); 62 | Object invoke = method.invoke(en); 63 | if (invoke.toString().equals(code)) { 64 | return true; 65 | } 66 | } catch (Exception e) { 67 | logger.error("枚举执行getCode方法失败...", e); 68 | } 69 | } 70 | return false; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/other/MyBloomFilter.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.other; 2 | 3 | /** 4 | * @author Eric 5 | * @version 1.0 6 | * @ClassName: MyBloomFilter 7 | * @Description: 布隆过滤器 8 | * @date 2018/11/30 10:17 9 | **/ 10 | public class MyBloomFilter { 11 | 12 | private int[] array; 13 | 14 | private int arraySize; 15 | 16 | public MyBloomFilter(){} 17 | 18 | public MyBloomFilter(int arraySize ){ 19 | this.arraySize = arraySize; 20 | array = new int[arraySize]; 21 | } 22 | 23 | public void add(String a){ 24 | int hash$1 = hashcode_1(a + ""); 25 | int hash$2 = hashcode_2(a + ""); 26 | int hash$3 = hashcode_3(a + ""); 27 | 28 | array[hash$1%arraySize] = 1; 29 | array[hash$2%arraySize] = 1; 30 | array[hash$3%arraySize] = 1; 31 | } 32 | 33 | public boolean check(String b) { 34 | int hash$1 = hashcode_1(b + ""); 35 | int hash$2 = hashcode_2(b + ""); 36 | int hash$3 = hashcode_3(b + ""); 37 | 38 | if(array[hash$1%arraySize] == 1 && array[hash$2%arraySize] == 1 39 | && array[hash$3%arraySize] == 1){ 40 | return true; 41 | } 42 | return false; 43 | } 44 | 45 | 46 | /** 47 | * hash 算法1 48 | * @param key 49 | * @return 50 | */ 51 | private int hashcode_1(String key) { 52 | int hash = 0; 53 | int i; 54 | for (i = 0; i < key.length(); ++i) { 55 | hash = 33 * hash + key.charAt(i); 56 | } 57 | return Math.abs(hash); 58 | } 59 | /** 60 | * hash 算法2 61 | * @param data 62 | * @return 63 | */ 64 | private int hashcode_2(String data) { 65 | final int p = 16777619; 66 | int hash = (int) 2166136261L; 67 | for (int i = 0; i < data.length(); i++) { 68 | hash = (hash ^ data.charAt(i)) * p; 69 | } 70 | hash += hash << 13; 71 | hash ^= hash >> 7; 72 | hash += hash << 3; 73 | hash ^= hash >> 17; 74 | hash += hash << 5; 75 | return Math.abs(hash); 76 | } 77 | /** 78 | * hash 算法3 79 | * @param key 80 | * @return 81 | */ 82 | private int hashcode_3(String key) { 83 | int hash, i; 84 | for (hash = 0, i = 0; i < key.length(); ++i) { 85 | hash += key.charAt(i); 86 | hash += (hash << 10); 87 | hash ^= (hash >> 6); 88 | } 89 | hash += (hash << 3); 90 | hash ^= (hash >> 11); 91 | hash += (hash << 15); 92 | return Math.abs(hash); 93 | } 94 | 95 | public static void main(String[] args) { 96 | 97 | long timebegin = System.currentTimeMillis(); 98 | MyBloomFilter filter = new MyBloomFilter(100000000); 99 | for (int i = 0; i < 10000000; i++) { 100 | filter.add(i + ""); 101 | } 102 | System.out.println(filter.check(4 + "")); 103 | System.out.println(filter.check(67 + "")); 104 | System.out.println(filter.check(267 + "")); 105 | System.out.println(filter.check(22267 + "")); 106 | System.out.println(filter.check(99999 + "")); 107 | System.out.println(filter.check(488999992 + "")); 108 | 109 | long end = System.currentTimeMillis(); 110 | System.out.println("执行时间:" + (end - timebegin)); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/spring/SpringContextUtil.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.spring; 2 | 3 | import org.springframework.beans.BeansException; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.context.ApplicationContext; 6 | import org.springframework.context.ApplicationContextAware; 7 | import org.springframework.stereotype.Component; 8 | 9 | /** 10 | * @author Eric 11 | * @version 1.0 12 | * @ClassName: SpringContextUtil 13 | * @Description: TODO 14 | * @company lsj 15 | * @date 2019/1/14 16:48 16 | **/ 17 | @Component 18 | public class SpringContextUtil implements ApplicationContextAware { 19 | 20 | /** Spring应用上下文环境 */ 21 | @Autowired 22 | private static ApplicationContext applicationContext; 23 | 24 | /** 25 | * 实现ApplicationContextAware接口的回调方法。设置上下文环境 26 | * @param applicationContext 27 | */ 28 | @Override 29 | public void setApplicationContext(ApplicationContext applicationContext) { 30 | SpringContextUtil.applicationContext = applicationContext; 31 | } 32 | 33 | /** 34 | * @return ApplicationContext 35 | */ 36 | public static ApplicationContext getApplicationContext() { 37 | return applicationContext; 38 | } 39 | 40 | /** 41 | * 获取对象 42 | * 43 | * @param name 44 | * @return Object 45 | * @throws BeansException 46 | */ 47 | public static Object getBean(String name) throws BeansException { 48 | return applicationContext.getBean(name); 49 | } 50 | 51 | 52 | } 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/ssh/SSHResInfo.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.ssh; 2 | 3 | /** 4 | * @author 牵手无奈 5 | * @version V1.0 6 | * @date 2016年12月1日上午11:19:47 7 | */ 8 | public class SSHResInfo { 9 | private int exitStuts;//返回状态码 (在linux中可以通过 echo $? 可知每步执行令执行的状态码) 10 | private String outRes;//标准正确输出流内容 11 | private String errRes;//标准错误输出流内容 12 | 13 | 14 | public SSHResInfo(int exitStuts, String outRes, String errRes) { 15 | super(); 16 | this.exitStuts = exitStuts; 17 | this.outRes = outRes; 18 | this.errRes = errRes; 19 | } 20 | 21 | public SSHResInfo() { 22 | super(); 23 | } 24 | 25 | public int getExitStuts() { 26 | return exitStuts; 27 | } 28 | 29 | public void setExitStuts(int exitStuts) { 30 | this.exitStuts = exitStuts; 31 | } 32 | 33 | public String getOutRes() { 34 | return outRes; 35 | } 36 | 37 | public void setOutRes(String outRes) { 38 | this.outRes = outRes; 39 | } 40 | 41 | public String getErrRes() { 42 | return errRes; 43 | } 44 | 45 | public void setErrRes(String errRes) { 46 | this.errRes = errRes; 47 | } 48 | 49 | /** 50 | * 当exitStuts=0 && errRes="" &&outREs=""返回true 51 | * 52 | * @return 53 | */ 54 | public boolean isEmptySuccess() { 55 | return this.getExitStuts() == 0 && "".equals(this.getErrRes()) && "".equals(this.getOutRes()); 56 | } 57 | 58 | @Override 59 | public String toString() { 60 | return "SSHResInfo [exitStuts=" + exitStuts + ", outRes=" + outRes + ", errRes=" + errRes + "]"; 61 | } 62 | 63 | public void clear() { 64 | exitStuts = 0; 65 | outRes = errRes = null; 66 | } 67 | } -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/string/CharTools.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.string; 2 | import java.io.UnsupportedEncodingException; 3 | 4 | /** 5 | *

Title:字符编码工具类

6 | *

Description:

7 | *

Copyright: Copyright (c) 2007

8 | *

Company:

9 | * @author: 10 | * @version 1.0 11 | */ 12 | public class CharTools { 13 | 14 | /** 15 | * 转换编码 ISO-8859-1到GB2312 16 | * @param text 17 | * @return 18 | */ 19 | public static final String ISO2GB(String text) { 20 | String result = ""; 21 | try { 22 | result = new String(text.getBytes("ISO-8859-1"), "GB2312"); 23 | } 24 | catch (UnsupportedEncodingException ex) { 25 | result = ex.toString(); 26 | } 27 | return result; 28 | } 29 | 30 | /** 31 | * 转换编码 GB2312到ISO-8859-1 32 | * @param text 33 | * @return 34 | */ 35 | public static final String GB2ISO(String text) { 36 | String result = ""; 37 | try { 38 | result = new String(text.getBytes("GB2312"), "ISO-8859-1"); 39 | } 40 | catch (UnsupportedEncodingException ex) { 41 | ex.printStackTrace(); 42 | } 43 | return result; 44 | } 45 | /** 46 | * Utf8URL编码 47 | * @param s 48 | * @return 49 | */ 50 | public static final String Utf8URLencode(String text) { 51 | StringBuffer result = new StringBuffer(); 52 | 53 | for (int i = 0; i < text.length(); i++) { 54 | 55 | char c = text.charAt(i); 56 | if (c >= 0 && c <= 255) { 57 | result.append(c); 58 | }else { 59 | 60 | byte[] b = new byte[0]; 61 | try { 62 | b = Character.toString(c).getBytes("UTF-8"); 63 | }catch (Exception ex) { 64 | } 65 | 66 | for (int j = 0; j < b.length; j++) { 67 | int k = b[j]; 68 | if (k < 0) k += 256; 69 | result.append("%" + Integer.toHexString(k).toUpperCase()); 70 | } 71 | 72 | } 73 | } 74 | 75 | return result.toString(); 76 | } 77 | 78 | /** 79 | * Utf8URL解码 80 | * @param text 81 | * @return 82 | */ 83 | public static final String Utf8URLdecode(String text) { 84 | String result = ""; 85 | int p = 0; 86 | 87 | if (text!=null && text.length()>0){ 88 | text = text.toLowerCase(); 89 | p = text.indexOf("%e"); 90 | if (p == -1) return text; 91 | 92 | while (p != -1) { 93 | result += text.substring(0, p); 94 | text = text.substring(p, text.length()); 95 | if (text == "" || text.length() < 9) return result; 96 | 97 | result += CodeToWord(text.substring(0, 9)); 98 | text = text.substring(9, text.length()); 99 | p = text.indexOf("%e"); 100 | } 101 | 102 | } 103 | 104 | return result + text; 105 | } 106 | 107 | /** 108 | * utf8URL编码转字符 109 | * @param text 110 | * @return 111 | */ 112 | private static final String CodeToWord(String text) { 113 | String result; 114 | 115 | if (Utf8codeCheck(text)) { 116 | byte[] code = new byte[3]; 117 | code[0] = (byte) (Integer.parseInt(text.substring(1, 3), 16) - 256); 118 | code[1] = (byte) (Integer.parseInt(text.substring(4, 6), 16) - 256); 119 | code[2] = (byte) (Integer.parseInt(text.substring(7, 9), 16) - 256); 120 | try { 121 | result = new String(code, "UTF-8"); 122 | }catch (UnsupportedEncodingException ex) { 123 | result = null; 124 | } 125 | } 126 | else { 127 | result = text; 128 | } 129 | 130 | return result; 131 | } 132 | 133 | /** 134 | * 编码是否有效 135 | * @param text 136 | * @return 137 | */ 138 | private static final boolean Utf8codeCheck(String text){ 139 | String sign = ""; 140 | if (text.startsWith("%e")) 141 | for (int i = 0, p = 0; p != -1; i++) { 142 | p = text.indexOf("%", p); 143 | if (p != -1) 144 | p++; 145 | sign += p; 146 | } 147 | return sign.equals("147-1"); 148 | } 149 | 150 | /** 151 | * 判断是否Utf8Url编码 152 | * @param text 153 | * @return 154 | */ 155 | public static final boolean isUtf8Url(String text) { 156 | text = text.toLowerCase(); 157 | int p = text.indexOf("%"); 158 | if (p != -1 && text.length() - p > 9) { 159 | text = text.substring(p, p + 9); 160 | } 161 | return Utf8codeCheck(text); 162 | } 163 | 164 | /** 165 | * 测试 166 | * @param args 167 | */ 168 | public static void main(String[] args) { 169 | 170 | //CharTools charTools = new CharTools(); 171 | 172 | String url; 173 | 174 | url = "http://www.google.com/search?hl=zh-CN&newwindow=1&q=%E4%B8%AD%E5%9B%BD%E5%A4%A7%E7%99%BE%E7%A7%91%E5%9C%A8%E7%BA%BF%E5%85%A8%E6%96%87%E6%A3%80%E7%B4%A2&btnG=%E6%90%9C%E7%B4%A2&lr="; 175 | if(CharTools.isUtf8Url(url)){ 176 | System.out.println(CharTools.Utf8URLdecode(url)); 177 | }else{ 178 | //System.out.println(URLDecoder.decode(url)); 179 | } 180 | 181 | url = "http://www.baidu.com/baidu?word=%D6%D0%B9%FA%B4%F3%B0%D9%BF%C6%D4%DA%CF%DF%C8%AB%CE%C4%BC%EC%CB%F7&tn=myie2dg"; 182 | if(CharTools.isUtf8Url(url)){ 183 | System.out.println(CharTools.Utf8URLdecode(url)); 184 | }else{ 185 | //System.out.println(URLDecoder.decode(url)); 186 | } 187 | 188 | } 189 | 190 | } 191 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/thread/ThreadPoolMonitor.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.thread; 2 | 3 | import com.google.common.util.concurrent.ThreadFactoryBuilder; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import java.util.concurrent.Executors; 8 | import java.util.concurrent.LinkedBlockingQueue; 9 | import java.util.concurrent.ThreadPoolExecutor; 10 | import java.util.concurrent.TimeUnit; 11 | import java.util.stream.IntStream; 12 | 13 | /** 14 | * @version 1.0.0 15 | * @description: 线程池监控 16 | * @author: eric 17 | * @date: 2022-07-08 18:10 18 | **/ 19 | public class ThreadPoolMonitor { 20 | 21 | private final static Logger log = LoggerFactory.getLogger(ThreadPoolMonitor.class); 22 | 23 | private static final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 0, 24 | TimeUnit.SECONDS, new LinkedBlockingQueue<>(100), 25 | new ThreadFactoryBuilder().setNameFormat("my_thread_pool_%d").build(), new ThreadPoolExecutor.DiscardOldestPolicy()); 26 | 27 | public static void main(String[] args) { 28 | // 每秒输出一次线程池的使用情况 29 | printThreadPoolState(); 30 | // 模拟任务执行 31 | IntStream.rangeClosed(0, 20).forEach(i -> { 32 | // 每100毫秒,执行一个任务 33 | try { 34 | TimeUnit.MILLISECONDS.sleep(100); 35 | } catch (InterruptedException e) { 36 | e.printStackTrace(); 37 | } 38 | // 每个处理一个任务耗时5秒 39 | threadPool.submit(() -> { 40 | try { 41 | TimeUnit.SECONDS.sleep(5); 42 | } catch (InterruptedException e) { 43 | e.printStackTrace(); 44 | } 45 | }); 46 | }); 47 | } 48 | 49 | private static void printThreadPoolState() { 50 | Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> { 51 | System.out.println("Pool Size: " + threadPool.getPoolSize()); 52 | System.out.println("Active Thread Count: " + threadPool.getActiveCount()); 53 | System.out.println("Task Queue Size: " + threadPool.getQueue().size()); 54 | System.out.println("Completed Task Count: " + threadPool.getCompletedTaskCount()); 55 | System.out.println("---------------"); 56 | }, 0, 1, TimeUnit.SECONDS); 57 | } 58 | } 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/main/java/cn/eric/jdktools/version/VersionIncreaseUtil.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools.version; 2 | 3 | import com.google.common.base.Joiner; 4 | import com.google.common.base.Splitter; 5 | import org.apache.commons.lang.StringUtils; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @version 1.0.0 11 | * @description: 版本号递增工具 12 | * @author: eric 13 | * @date: 2022-02-07 10:12 14 | **/ 15 | public class VersionIncreaseUtil { 16 | 17 | public static String upgradeVersion(String version) { 18 | String upgradeVsersion; 19 | if (StringUtils.isEmpty(version)) { 20 | version = "1.0.0"; 21 | } 22 | //将版本号拆解成整数数组 23 | List strArr = Splitter.on(".").splitToList(version); 24 | Integer[] ints = new Integer[strArr.size()]; 25 | for (int i = 0; i SESSION_USER_MAP = new ConcurrentHashMap<>(); 36 | /** 37 | * 用户与 Session 的映射 38 | */ 39 | private static final Map USER_SESSION_MAP = new ConcurrentHashMap<>(); 40 | 41 | /** 42 | * 添加 Session 。在这个方法中,会添加用户和 Session 之间的映射 43 | * 44 | * @param session Session 45 | * @param user 用户 46 | */ 47 | public static void addSession(Session session, String user) { 48 | // 更新 USER_SESSION_MAP 49 | USER_SESSION_MAP.put(user, session); 50 | // 更新 SESSION_USER_MAP 51 | SESSION_USER_MAP.put(session, user); 52 | } 53 | 54 | /** 55 | * 移除 Session 。 56 | * 57 | * @param session Session 58 | */ 59 | public static void removeSession(Session session) { 60 | // 从 SESSION_USER_MAP 中移除 61 | String user = SESSION_USER_MAP.remove(session); 62 | // 从 USER_SESSION_MAP 中移除 63 | if (user != null && user.length() > 0) { 64 | USER_SESSION_MAP.remove(user); 65 | } 66 | } 67 | 68 | // ========== 消息相关 ========== 69 | 70 | /** 71 | * 广播发送消息给所有在线用户 72 | * 73 | * @param type 消息类型 74 | * @param message 消息体 75 | * @param 消息类型 76 | */ 77 | public static void broadcast(String type, T message) { 78 | // 创建消息 79 | TextMessage textMessage = buildTextMessage(type, message); 80 | // 遍历 SESSION_USER_MAP ,进行逐个发送 81 | for (Session session : SESSION_USER_MAP.keySet()) { 82 | sendTextMessage(session, textMessage); 83 | } 84 | } 85 | 86 | /** 87 | * 发送消息给单个用户的 Session 88 | * 89 | * @param session Session 90 | * @param type 消息类型 91 | * @param message 消息体 92 | * @param 消息类型 93 | */ 94 | public static void send(Session session, String type, T message) { 95 | // 创建消息 96 | TextMessage textMessage = buildTextMessage(type, message); 97 | // 遍历给单个 Session ,进行逐个发送 98 | sendTextMessage(session, textMessage); 99 | } 100 | 101 | /** 102 | * 发送消息给指定用户 103 | * 104 | * @param user 指定用户 105 | * @param type 消息类型 106 | * @param message 消息体 107 | * @param 消息类型 108 | * @return 发送是否成功你那个 109 | */ 110 | public static boolean send(String user, String type, T message) { 111 | // 获得用户对应的 Session 112 | Session session = USER_SESSION_MAP.get(user); 113 | if (session == null) { 114 | LOGGER.error("[send][user({}) 不存在对应的 session]", user); 115 | return false; 116 | } 117 | // 发送消息 118 | send(session, type, message); 119 | return true; 120 | } 121 | 122 | /** 123 | * 构建完整的消息 124 | * 125 | * @param type 消息类型 126 | * @param message 消息体 127 | * @param 消息类型 128 | * @return 消息 129 | */ 130 | private static TextMessage buildTextMessage(String type, T message) { 131 | JSONObject messageObject = new JSONObject(); 132 | messageObject.put("type", type); 133 | messageObject.put("body", message); 134 | return new TextMessage(messageObject.toString()); 135 | } 136 | 137 | /** 138 | * 真正发送消息 139 | * 140 | * @param session Session 141 | * @param textMessage 消息 142 | */ 143 | private static void sendTextMessage(Session session, TextMessage textMessage) { 144 | if (session == null) { 145 | LOGGER.error("[sendTextMessage][session 为 null]"); 146 | return; 147 | } 148 | try { 149 | session.sendMessage(textMessage); 150 | } catch (IOException e) { 151 | LOGGER.error("[sendTextMessage][session({}) 发送消息{}) 发生异常", 152 | session, textMessage, e); 153 | } 154 | } 155 | 156 | } 157 | -------------------------------------------------------------------------------- /src/main/resources/ehcache.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 17 | 18 | 19 | 20 | 21 | 28 | -------------------------------------------------------------------------------- /src/main/resources/fatjar_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/main/resources/jdbc.properties: -------------------------------------------------------------------------------- 1 | driverClass= 2 | url= 3 | userName= 4 | passWord= -------------------------------------------------------------------------------- /src/main/resources/templete/cid-component-java-example-1.0.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EricLoveMia/JavaTools/1fe72617fac473a978f73136627e73a5c792c205/src/main/resources/templete/cid-component-java-example-1.0.0.jar -------------------------------------------------------------------------------- /src/main/resources/templete/cid-component-project-java-common-1.2.0-SNAPSHOT.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EricLoveMia/JavaTools/1fe72617fac473a978f73136627e73a5c792c205/src/main/resources/templete/cid-component-project-java-common-1.2.0-SNAPSHOT.jar -------------------------------------------------------------------------------- /src/main/resources/templete/ipaas-component-java-common-1.2.0-SNAPSHOT.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EricLoveMia/JavaTools/1fe72617fac473a978f73136627e73a5c792c205/src/main/resources/templete/ipaas-component-java-common-1.2.0-SNAPSHOT.jar -------------------------------------------------------------------------------- /src/main/resources/templete/ipaas-component-java8-sample-1.0.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EricLoveMia/JavaTools/1fe72617fac473a978f73136627e73a5c792c205/src/main/resources/templete/ipaas-component-java8-sample-1.0.0.jar -------------------------------------------------------------------------------- /src/test/java/cn/eric/jdktools/CacheTest.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools; 2 | 3 | import cn.eric.jdktools.cache.ICache; 4 | import cn.eric.jdktools.cache.caffeine.CaffeineService; 5 | import cn.eric.jdktools.cache.guava.GuavaService; 6 | 7 | /** 8 | * Company: ClickPaaS 9 | * 10 | * @version 1.0.0 11 | * @description: 缓存测试 12 | * @author: 钱旭 13 | * @date: 2022-02-22 14:10 14 | **/ 15 | public class CacheTest { 16 | 17 | public static void main(String[] args) { 18 | ICache cache = new CaffeineService<>(); 19 | 20 | cache.put("test","test"); 21 | String test = cache.getIfPresent("test"); 22 | System.out.println(test); 23 | 24 | 25 | ICache cacheG = new GuavaService<>(); 26 | 27 | cacheG.put("test","test"); 28 | String testG = cacheG.getIfPresent("test"); 29 | System.out.println(testG); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/cn/eric/jdktools/UseItFromJavaTest.java: -------------------------------------------------------------------------------- 1 | package cn.eric.jdktools; 2 | 3 | import cn.eric.jdktools.base.Test; 4 | import com.fasterxml.jackson.databind.JsonNode; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | //import com.kjetland.jackson.jsonSchema.JsonSchemaConfig; 7 | //import com.kjetland.jackson.jsonSchema.JsonSchemaGenerator; 8 | //import com.kjetland.jackson.jsonSchema.SubclassesResolver; 9 | //import com.kjetland.jackson.jsonSchema.SubclassesResolverImpl; 10 | 11 | import java.time.OffsetDateTime; 12 | import java.util.*; 13 | 14 | public class UseItFromJavaTest { 15 | 16 | static class MyJavaPojo { 17 | public String name; 18 | } 19 | 20 | public UseItFromJavaTest() { 21 | // // Just make sure it compiles 22 | // ObjectMapper objectMapper = new ObjectMapper(); 23 | // JsonSchemaGenerator g1 = new JsonSchemaGenerator(objectMapper); 24 | // // TODO - This is not very beautiful from Java - Need to improve Java API 25 | // JsonNode jsonNode; 26 | // jsonNode = g1.generateJsonSchema(Test.class); 27 | // //g1.generateJsonSchema(MyJavaPojo.class, "My title", "My description"); 28 | // 29 | // //g1.generateJsonSchema(objectMapper.constructType(MyJavaPojo.class)); 30 | // //g1.generateJsonSchema(objectMapper.constructType(MyJavaPojo.class), "My title", "My description"); 31 | // 32 | // String s = jsonNode.toString(); 33 | // System.out.println(s); 34 | // // Create custom JsonSchemaConfig from java 35 | // Map customMapping = new HashMap<>(); 36 | // customMapping.put(OffsetDateTime.class.getName(), "date-time"); 37 | // JsonSchemaConfig config = JsonSchemaConfig.create( 38 | // true, 39 | // Optional.of("A"), 40 | // false, 41 | // false, 42 | // true, 43 | // true, 44 | // true, 45 | // true, 46 | // true, 47 | // customMapping, 48 | // false, 49 | // new HashSet<>(), 50 | // new HashMap<>(), 51 | // new HashMap<>(), 52 | // null, 53 | // true, 54 | // null); 55 | // JsonSchemaGenerator g2 = new JsonSchemaGenerator(objectMapper, config); 56 | // jsonNode = g2.generateJsonSchema(Test.class); 57 | // System.out.println(jsonNode.toString()); 58 | // // Config SubclassesResolving 59 | // 60 | // final SubclassesResolver subclassesResolver = new SubclassesResolverImpl() 61 | // .withClassesToScan(Arrays.asList( 62 | // "this.is.myPackage" 63 | // )); 64 | 65 | 66 | } 67 | 68 | 69 | public static void main(String[] args) { 70 | UseItFromJavaTest test = new UseItFromJavaTest(); 71 | } 72 | } 73 | --------------------------------------------------------------------------------