8174f2d0 by lv

0 parents
Showing 1000 changed files with 4889 additions and 0 deletions

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

This diff is collapsed. Click to expand it.
1 ## 引言
2
3 JeeSite 是一个 Java EE 企业级快速开发平台,基于经典技术组合(Spring Boot、Spring MVC、Apache Shiro、MyBatis、Beetl、Bootstrap、AdminLTE)采用经典开发模式,让初学者能够更快的入门并投入到团队开发中去。在线代码生成功能,包括核心模块如:组织机构、角色用户、菜单及按钮授权、数据权限、系统参数、内容管理、工作流等。采用松耦合设计;界面无刷新,一键换肤;众多账号安全设置,密码策略;在线定时任务配置;支持集群,支持SAAS;支持多数据源;支持微服务。
4
5 JeeSite 快速开发平台的主要目的是能够让初级的研发人员快速的开发出复杂的业务功能(经典架构会的人多),让开发者注重专注业务,其余有平台来封装技术细节,降低技术难度,从而节省人力成本,缩短项目周期,提高软件安全质量。
6
7 JeeSite 1.x 自 2013 年发布以来已被广大爱好者用到了企业、政府、医疗、金融、互联网等各个领域中,JeeSite 依架构简单精良、易于扩展、大众思维的设计模式,深入开发者的内心,并得到一致好评,于[2016](http://www.oschina.net/project/top_cn_2016?sort=1)[2017](http://www.oschina.net/project/top_cn_2017?sort=1)连续两年获得开源中国《最受欢迎中国开源软件》奖杯,期间也帮助了不少刚毕业的大学生作为入门教材,快速的去实践。
8
9 JeeSite 4.x 的升级,作者结合了多年总结和经验,以及各方面的应用案例,对架构完成了一次全部重构,也纳入很多新的思想。不管是从开发者模式、底层架构、逻辑处理还是到用户界面,用户交互体验上都有很大的进步,在不忘学习成本、提高开发效率的情况下,安全方面也做和很多工作,包括:身份认证、密码策略、安全审计、日志收集。
10
11 ### 4.x 的新特性及优势:<http://jeesite.com/?t=281645>
12
13 ## 技术选型
14
15 * 主框架:Spring Boot 2.0、Spring Framework 5.0、Apache Shiro 1.4、J2Cache
16 * 持久层:Apache MyBatis 3.4、Hibernate Validation 6.0、Alibaba Druid 1.1
17 * 视图层:Spring MVC 5.0、Beetl 2.9 替换JSP、Bootstrap 3.3、AdminLTE 2.4
18 * 前端组件:jQuery 1.12、jqGrid 4.7、layer 3.0、zTree 3.5、jquery-validation
19 * 工具组件:Apache Commons、Logback 1.1、Jackson 2.8、POI 3.14、Quartz 2.2
20 * 技术选型详情:<http://jeesite.com/?t=273599>
21
22 ## 内置功能
23
24 * <http://jeesite.com/?t=270187>
25
26 ## 生态系统
27
28 * 分布式微服务系统(Spring Cloud):<https://gitee.com/thinkgem/jeesite4-cloud>
29 * JFlow工作流引擎:<https://gitee.com/thinkgem/jeesite4-jflow><http://ccflow.org>
30 * 内容管理模块(CMS):<https://gitee.com/thinkgem/jeesite4-cms>【敬请期待】
31
32 ## 快速体验
33
34 ### 在线演示
35
36 1. 地址:<http://demo.jeesite.com/>
37 2. 账号:system
38 3. 密码:admin
39
40 ### 本地运行
41
42 1. 环境准备:`JDK 1.8``Maven 3.3``MySQL 5.7`
43 2. 下载源码:<https://gitee.com/thinkgem/jeesite4/attach_files>
44 3. 打开文件:/web`/src/main/resources/config/application.yml` 配置JDBC连接
45 4. 执行脚本:/web`/bin/init-data.bat` 初始化数据库
46 5. 执行脚本:/web`/bin/run-tomcat.bat` 启动服务即可
47 6. 浏览器访问:<http://127.0.0.1:8980/js/> 账号 system 密码 admin
48 7. 部署常见问题:<http://jeesite.com/?t=284210>
49
50 ### 开发环境
51
52 1. 部署运行:<http://jeesite.com/?t=267354>
53 2. 常见问题:<http://jeesite.com/?t=284210>
54
55 ## 在线文档
56
57 * <http://docs.jeesite.com>
58
59 ## 授权协议声明
60
61 1. 已开源的代码,授权协议采用 AGPL v3 + Apache Licence v2 进行发行。
62 2. 您可以免费使用、修改和衍生代码,但不允许修改后和衍生的代码做为闭源软件发布。
63 3. 修改后和衍生的代码必须也按照AGPL协议进行流通,对修改后和衍生的代码必须向社会公开。
64 4. 如果您修改了代码,需要在被修改的文件中进行说明,并遵守代码格式规范,帮助他人更好的理解您的用意。
65 5. 在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议、版权声明和其他原作者规定需要包含的说明(请尊重原作者的著作权,不要删除或修改文件中的`@author`信息)。
66 6. 您可以应用于商业软件,但必须遵循以上条款原则(请协助改进本作品)。
67 7. 关系平台的发展战略考虑,底层部分代码暂未开源,但这不影响您的二次开发。
68 8. 请知悉社区版,用户数不可超过100个,最大允许20个用户同时在线(不含匿名)。
69
70 ## 技术服务与支持
71
72 * 没有资金的支撑就很难得到发展,特别是一个好的产品,如果 JeeSite 帮助了您,请为我们点赞。支持我们,您可以得到一些回报,有了这些我们会把公益事业做的更好,回报社区和社会,请给我们一些动力吧,在此非常感谢已支持我们的朋友!
73 * **联系方式(官方商务)QQ:[1766571055](http://sighttp.qq.com/msgrd?v=1&uin=1766571055)**
74 * 技术服务支持网页:<http://s.jeesite.com>
75
76 # 技术交流方式
77
78 * QQ 群号:`127515876``209330483``223507718``709534275``730390092``183903863(外包)`
79 * 问题反馈:<https://gitee.com/thinkgem/jeesite4/issues>  [【新手必读】](http://www.dianbo.org/9238/stone/tiwendezhihui.htm)
80 * 码云Gitee:<https://gitee.com/thinkgem/jeesite4>
81 * GitHub:<https://github.com/thinkgem/jeesite4>
82 * 作者博客:<https://my.oschina.net/thinkgem>
83 * **技术服务:**<http://s.jeesite.com>
84 * 官方网站:<http://jeesite.com>
85 * 官方论坛:<http://jeesite.net>
86 * 微信公众号:
87
88 ![JeeSite4微信公众号](https://static.oschina.net/uploads/space/2018/0302/145133_OGZf_941661.jpg "JeeSite4微信公众号")
89
90 ## 今后如何升级?
91
92 尽量不修改web项目以外的源码项目,如 jeesite-common、jeesite-modele-core,如果修改了,请 Pull Requests 上来,否则代码编码将与官方不同步,将对你的日后升级带来困难。
93
94 JeeSite的小版本(4.1.x)升级是非常便捷的,你只需要将 pom.xml 文件中的 parent.version 版本修改到最新版本即可,同版本下你可进行 Maven 快照强制更新,即可将最新版的依赖 jar 更新到本地,下面以 Eclipse 举例,介绍如何操作:
95
96 在 web 项目上右键,选择菜单 -> Maven -> Update Project...(或按Alt+F5) -> 点击 Select All 按钮 -> 选择 Force Update of Snapshots/Releases 复选框 -> 点击OK按钮即可。
97
98 如果您修改了其它依赖模块代码,这时你需要利用 Git 版本控制工具,与官方仓库代码进行同步,合并代码即可。
99
100 如果进行相对大的版本(4.x.x)升级这里我们会附加一个声明,帮助你进行迁移操作,更新日志:<http://jeesite.com/?t=273830>
101
102 # Git 全局设置技巧
103
104 ```
105 1、提交检出均不转换换行符
106
107 git config --global core.autocrlf false
108
109 2、拒绝提交包含混合换行符的文件
110
111 git config --global core.safecrlf true
112 ```
...\ No newline at end of file ...\ No newline at end of file
1 eclipse.preferences.version=1
2 encoding//src/main/java=UTF-8
3 encoding//src/main/resources=UTF-8
4 encoding//src/test/java=UTF-8
5 encoding/<project>=UTF-8
1 eclipse.preferences.version=1
2 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
3 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
4 org.eclipse.jdt.core.compiler.compliance=1.8
5 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
6 org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
7 org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
8 org.eclipse.jdt.core.compiler.source=1.8
1 activeProfiles=
2 eclipse.preferences.version=1
3 resolveWorkspaceProjects=true
4 version=1
1 <?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
2 <wb-module deploy-name="jeesite-common">
3 <wb-resource deploy-path="/" source-path="/src/main/java"/>
4 <wb-resource deploy-path="/" source-path="/src/main/resources"/>
5 </wb-module>
6 </project-modules>
1 <?xml version="1.0" encoding="UTF-8"?>
2 <faceted-project>
3 <installed facet="jst.utility" version="1.0"/>
4 <installed facet="java" version="1.8"/>
5 </faceted-project>
1 disabled=06target
2 eclipse.preferences.version=1
1 @echo off
2 rem /**
3 rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
4 rem *
5 rem * Author: ThinkGem@163.com
6 rem */
7 echo.
8 echo [信息] 部署工程版本到Nexus服务器。
9 echo.
10
11 %~d0
12 cd %~dp0
13
14 cd ..
15 call mvn clean deploy -Dmaven.test.skip=true -Pdeploy
16
17 pause
...\ No newline at end of file ...\ No newline at end of file
1 @echo off
2 rem /**
3 rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
4 rem *
5 rem * Author: ThinkGem@163.com
6 rem */
7 echo.
8 echo [信息] 编译工程Javadoc,生成jar包文件。
9 echo.
10
11 %~d0
12 cd %~dp0
13
14 cd ..
15 call mvn clean package -Pjavadoc
16
17 pause
...\ No newline at end of file ...\ No newline at end of file
1 @echo off
2 rem /**
3 rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
4 rem *
5 rem * Author: ThinkGem@163.com
6 rem */
7 echo.
8 echo [信息] 打包安装工程,生成jar包文件。
9 echo.
10
11 %~d0
12 cd %~dp0
13
14 cd ..
15 call mvn clean install -Dmaven.test.skip=true -Ppackage
16
17 pause
...\ No newline at end of file ...\ No newline at end of file
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4 <modelVersion>4.0.0</modelVersion>
5
6 <parent>
7 <groupId>com.jeesite</groupId>
8 <artifactId>jeesite-parent</artifactId>
9 <version>4.1.5-SNAPSHOT</version>
10 <relativePath>../parent/pom.xml</relativePath>
11 </parent>
12
13 <artifactId>jeesite-common</artifactId>
14 <packaging>jar</packaging>
15
16 <name>JeeSite Common</name>
17 <url>http://jeesite.com</url>
18 <inceptionYear>2013-Now</inceptionYear>
19
20 <properties>
21
22 </properties>
23
24 <dependencies>
25
26 <!-- Apache Commons -->
27 <dependency>
28 <groupId>org.apache.commons</groupId>
29 <artifactId>commons-lang3</artifactId>
30 </dependency>
31 <dependency>
32 <groupId>commons-codec</groupId>
33 <artifactId>commons-codec</artifactId>
34 </dependency>
35 <dependency>
36 <groupId>commons-io</groupId>
37 <artifactId>commons-io</artifactId>
38 <version>${commons-io.version}</version>
39 </dependency>
40 <dependency>
41 <groupId>commons-fileupload</groupId>
42 <artifactId>commons-fileupload</artifactId>
43 <version>${commons-fileupload.version}</version>
44 </dependency>
45 <dependency>
46 <groupId>commons-beanutils</groupId>
47 <artifactId>commons-beanutils</artifactId>
48 <version>${commons-beanutils.version}</version>
49 </dependency>
50 <dependency>
51 <groupId>org.apache.commons</groupId>
52 <artifactId>commons-text</artifactId>
53 <version>${commons-text.version}</version>
54 </dependency>
55
56 <!-- Apache Tools Ant Tar Zip -->
57 <dependency>
58 <groupId>org.apache.ant</groupId>
59 <artifactId>ant</artifactId>
60 <version>${ant.version}</version>
61 </dependency>
62
63 <!-- Java serialization -->
64 <dependency>
65 <groupId>de.ruedigermoeller</groupId>
66 <artifactId>fst</artifactId>
67 <version>${fst.version}</version>
68 </dependency>
69
70 <!-- Json in java -->
71 <dependency>
72 <groupId>org.json</groupId>
73 <artifactId>json</artifactId>
74 <version>${json.version}</version>
75 </dependency>
76
77 <!-- Jackson json -->
78 <dependency>
79 <groupId>com.fasterxml.jackson.core</groupId>
80 <artifactId>jackson-core</artifactId>
81 </dependency>
82 <dependency>
83 <groupId>com.fasterxml.jackson.core</groupId>
84 <artifactId>jackson-databind</artifactId>
85 </dependency>
86 <dependency>
87 <groupId>com.fasterxml.jackson.dataformat</groupId>
88 <artifactId>jackson-dataformat-xml</artifactId>
89 </dependency>
90
91 <!-- Java xml -->
92 <dependency>
93 <groupId>dom4j</groupId>
94 <artifactId>dom4j</artifactId>
95 </dependency>
96
97 <!-- XPath xml -->
98 <dependency>
99 <groupId>jaxen</groupId>
100 <artifactId>jaxen</artifactId>
101 </dependency>
102
103 <!-- Snake YAML -->
104 <dependency>
105 <groupId>org.yaml</groupId>
106 <artifactId>snakeyaml</artifactId>
107 </dependency>
108
109 <!-- Apache HTTP -->
110 <dependency>
111 <groupId>org.apache.httpcomponents</groupId>
112 <artifactId>httpclient</artifactId>
113 </dependency>
114
115 <!-- Jsoup HTTP -->
116 <dependency>
117 <groupId>org.jsoup</groupId>
118 <artifactId>jsoup</artifactId>
119 <version>${jsoup.version}</version>
120 </dependency>
121
122 <!-- Email -->
123 <dependency>
124 <groupId>org.apache.commons</groupId>
125 <artifactId>commons-email</artifactId>
126 <version>${commons-email.version}</version>
127 </dependency>
128 <dependency>
129 <groupId>javax.activation</groupId>
130 <artifactId>activation</artifactId>
131 <version>${activation.version}</version>
132 </dependency>
133
134 <!-- User Agent -->
135 <dependency>
136 <groupId>eu.bitwalker</groupId>
137 <artifactId>UserAgentUtils</artifactId>
138 <version>${UserAgentUtils.version}</version>
139 </dependency>
140
141 <!-- 图片Meta获取
142 <dependency>
143 <groupId>com.drewnoakes</groupId>
144 <artifactId>metadata-extractor</artifactId>
145 <version>${metadata-extractor.version}</version>
146 </dependency> -->
147 <!-- 缩略图工具 -->
148 <dependency>
149 <groupId>net.coobird</groupId>
150 <artifactId>thumbnailator</artifactId>
151 <version>${thumbnailator.version}</version>
152 </dependency>
153 <!-- 支持CMYK图片 -->
154 <dependency>
155 <groupId>com.twelvemonkeys.imageio</groupId>
156 <artifactId>imageio-jpeg</artifactId>
157 <version>${twelvemonkeys.version}</version>
158 </dependency>
159 <!-- 图片验证码生成 -->
160 <dependency>
161 <groupId>com.bladejava</groupId>
162 <artifactId>blade-patchca</artifactId>
163 <version>${blade-patchca.version}</version>
164 </dependency>
165 <!-- File MimeType ContentType -->
166 <dependency>
167 <groupId>net.sf.jmimemagic</groupId>
168 <artifactId>jmimemagic</artifactId>
169 <version>${jmimemagic.version}</version>
170 <exclusions>
171 <exclusion>
172 <groupId>xerces</groupId>
173 <artifactId>xercesImpl</artifactId>
174 </exclusion>
175 <exclusion>
176 <groupId>org.codehaus.jackson</groupId>
177 <artifactId>jackson-xc</artifactId>
178 </exclusion>
179 <exclusion>
180 <groupId>org.codehaus.jackson</groupId>
181 <artifactId>jackson-jaxrs</artifactId>
182 </exclusion>
183 <exclusion>
184 <artifactId>log4j</artifactId>
185 <groupId>log4j</groupId>
186 </exclusion>
187 </exclusions>
188 </dependency>
189
190 <!-- 条形码、二维码生成 -->
191 <dependency>
192 <groupId>com.google.zxing</groupId>
193 <artifactId>core</artifactId>
194 <version>${zxing.version}</version>
195 </dependency>
196 <dependency>
197 <groupId>com.google.zxing</groupId>
198 <artifactId>javase</artifactId>
199 <version>${zxing.version}</version>
200 </dependency>
201
202 <!-- POI Office Tools -->
203 <dependency>
204 <groupId>org.apache.poi</groupId>
205 <artifactId>poi</artifactId>
206 <version>${poi.version}</version>
207 <exclusions>
208 <exclusion>
209 <artifactId>commons-codec</artifactId>
210 <groupId>commons-codec</groupId>
211 </exclusion>
212 </exclusions>
213 </dependency>
214 <dependency>
215 <groupId>org.apache.poi</groupId>
216 <artifactId>poi-ooxml</artifactId>
217 <version>${poi.version}</version>
218 </dependency>
219 <dependency>
220 <groupId>org.apache.poi</groupId>
221 <artifactId>poi-ooxml-schemas</artifactId>
222 <version>${poi.version}</version>
223 </dependency>
224 <dependency>
225 <groupId>org.apache.poi</groupId>
226 <artifactId>poi-scratchpad</artifactId>
227 <version>${poi.version}</version>
228 </dependency>
229
230 <!-- pinyin4j -->
231 <dependency>
232 <groupId>com.belerweb</groupId>
233 <artifactId>pinyin4j</artifactId>
234 <version>${pinyin4j.version}</version>
235 </dependency>
236
237 <!-- Logging begin -->
238 <dependency>
239 <groupId>org.slf4j</groupId>
240 <artifactId>slf4j-api</artifactId>
241 </dependency>
242 <!-- common-logging 实际调用 slf4j -->
243 <dependency>
244 <groupId>org.slf4j</groupId>
245 <artifactId>jcl-over-slf4j</artifactId>
246 </dependency>
247 <!-- jdk logging 实际调用 slf4j -->
248 <dependency>
249 <groupId>org.slf4j</groupId>
250 <artifactId>jul-to-slf4j</artifactId>
251 </dependency>
252 <!-- log4j 实际调用 slf4j -->
253 <dependency>
254 <groupId>org.slf4j</groupId>
255 <artifactId>log4j-over-slf4j</artifactId>
256 </dependency>
257 <!-- slf4j logback 实现 -->
258 <dependency>
259 <groupId>ch.qos.logback</groupId>
260 <artifactId>logback-classic</artifactId>
261 </dependency>
262 <!-- Logging end -->
263
264 <!-- Spring begin -->
265 <dependency>
266 <groupId>org.springframework</groupId>
267 <artifactId>spring-beans</artifactId>
268 </dependency>
269 <dependency>
270 <groupId>org.springframework</groupId>
271 <artifactId>spring-web</artifactId>
272 <optional>true</optional>
273 </dependency>
274 <dependency>
275 <groupId>org.springframework.boot</groupId>
276 <artifactId>spring-boot</artifactId>
277 <optional>true</optional>
278 </dependency>
279 <!-- Spring end -->
280
281 <!-- JUnit Test -->
282 <dependency>
283 <groupId>junit</groupId>
284 <artifactId>junit</artifactId>
285 </dependency>
286 <dependency>
287 <groupId>org.springframework</groupId>
288 <artifactId>spring-test</artifactId>
289 </dependency>
290
291 </dependencies>
292
293 <build>
294 <plugins>
295
296 </plugins>
297 </build>
298
299 <developers>
300 <developer>
301 <id>thinkgem</id>
302 <name>WangZhen</name>
303 <email>thinkgem at 163.com</email>
304 <roles><role>Project lead</role></roles>
305 <timezone>+8</timezone>
306 </developer>
307 </developers>
308
309 <organization>
310 <name>JeeSite</name>
311 <url>http://jeesite.com</url>
312 </organization>
313
314 </project>
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.callback;
5
6 /**
7 * 方法回调接口
8 * @author ThinkGem
9 */
10 public interface MethodCallback {
11
12 Object execute(Object... params);
13
14 }
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.codec;
5
6 import java.io.UnsupportedEncodingException;
7 import java.security.GeneralSecurityException;
8 import java.security.SecureRandom;
9
10 import javax.crypto.Cipher;
11 import javax.crypto.KeyGenerator;
12 import javax.crypto.SecretKey;
13 import javax.crypto.spec.IvParameterSpec;
14 import javax.crypto.spec.SecretKeySpec;
15
16 import com.jeesite.common.lang.ExceptionUtils;
17
18 /**
19 * AES加密解密工具类
20 * @author ThinkGem
21 */
22 public class AesUtils {
23
24 private static final String AES = "AES";
25 private static final String AES_CBC = "AES/CBC/PKCS5Padding";
26 private static final int DEFAULT_AES_KEYSIZE = 128; // 生成AES密钥, 默认长度为128位(16字节).
27 private static final int DEFAULT_IVSIZE = 16; // 生成随机向量, 默认大小为cipher.getBlockSize(), 16字节
28 private static final SecureRandom RANDOM = new SecureRandom(); // 用于 生成 generateIV随机数对象
29
30 private static final String DEFAULT_URL_ENCODING = "UTF-8";
31 private static final byte[] DEFAULT_KEY = new byte[]{-97,88,-94,9,70,-76,126,25,0,3,-20,113,108,28,69,125};
32
33 /**
34 * 生成AES密钥,返回字节数组, 默认长度为128位(16字节).
35 */
36 public static String genKeyString() {
37 return EncodeUtils.encodeHex(genKey(DEFAULT_AES_KEYSIZE));
38 }
39
40 /**
41 * 使用AES加密原始字符串.
42 *
43 * @param input 原始输入字符数组
44 */
45 public static String encode(String input) {
46 try {
47 return EncodeUtils.encodeHex(encode(input.getBytes(DEFAULT_URL_ENCODING), DEFAULT_KEY));
48 } catch (UnsupportedEncodingException e) {
49 return "";
50 }
51 }
52
53 /**
54 * 使用AES加密原始字符串.
55 *
56 * @param input 原始输入字符数组
57 * @param key 符合AES要求的密钥
58 */
59 public static String encode(String input, String key) {
60 try {
61 return EncodeUtils.encodeHex(encode(input.getBytes(DEFAULT_URL_ENCODING), EncodeUtils.decodeHex(key)));
62 } catch (UnsupportedEncodingException e) {
63 return "";
64 }
65 }
66
67 /**
68 * 使用AES解密字符串, 返回原始字符串.
69 *
70 * @param input Hex编码的加密字符串
71 */
72 public static String decode(String input) {
73 try {
74 return new String(decode(EncodeUtils.decodeHex(input), DEFAULT_KEY), DEFAULT_URL_ENCODING);
75 } catch (UnsupportedEncodingException e) {
76 return "";
77 }
78 }
79
80 /**
81 * 使用AES解密字符串, 返回原始字符串.
82 *
83 * @param input Hex编码的加密字符串
84 * @param key 符合AES要求的密钥
85 */
86 public static String decode(String input, String key) {
87 try {
88 return new String(decode(EncodeUtils.decodeHex(input), EncodeUtils.decodeHex(key)), DEFAULT_URL_ENCODING);
89 } catch (UnsupportedEncodingException e) {
90 return "";
91 }
92 }
93
94 /**
95 * 生成AES密钥,返回字节数组, 默认长度为128位(16字节).
96 */
97 public static byte[] genKey() {
98 return genKey(DEFAULT_AES_KEYSIZE);
99 }
100
101 /**
102 * 生成AES密钥,可选长度为128,192,256位.
103 */
104 public static byte[] genKey(int keysize) {
105 try {
106 KeyGenerator keyGenerator = KeyGenerator.getInstance(AES);
107 keyGenerator.init(keysize);
108 SecretKey secretKey = keyGenerator.generateKey();
109 return secretKey.getEncoded();
110 } catch (GeneralSecurityException e) {
111 throw ExceptionUtils.unchecked(e);
112 }
113 }
114
115 /**
116 * 生成随机向量,默认大小为cipher.getBlockSize(), 16字节.
117 */
118 public static byte[] genIV() {
119 byte[] bytes = new byte[DEFAULT_IVSIZE];
120 RANDOM.nextBytes(bytes);
121 return bytes;
122 }
123
124 /**
125 * 使用AES加密原始字符串.
126 *
127 * @param input 原始输入字符数组
128 * @param key 符合AES要求的密钥
129 */
130 public static byte[] encode(byte[] input, byte[] key) {
131 return aes(input, key, Cipher.ENCRYPT_MODE);
132 }
133
134 /**
135 * 使用AES加密原始字符串.
136 *
137 * @param input 原始输入字符数组
138 * @param key 符合AES要求的密钥
139 * @param iv 初始向量
140 */
141 public static byte[] encode(byte[] input, byte[] key, byte[] iv) {
142 return aes(input, key, iv, Cipher.ENCRYPT_MODE);
143 }
144
145 /**
146 * 使用AES解密字符串, 返回原始字符串.
147 *
148 * @param input Hex编码的加密字符串
149 * @param key 符合AES要求的密钥
150 */
151 public static byte[] decode(byte[] input, byte[] key) {
152 return aes(input, key, Cipher.DECRYPT_MODE);
153 }
154
155 /**
156 * 使用AES解密字符串, 返回原始字符串.
157 *
158 * @param input Hex编码的加密字符串
159 * @param key 符合AES要求的密钥
160 * @param iv 初始向量
161 */
162 public static byte[] decode(byte[] input, byte[] key, byte[] iv) {
163 return aes(input, key, iv, Cipher.DECRYPT_MODE);
164 }
165
166 /**
167 * 使用AES加密或解密无编码的原始字节数组, 返回无编码的字节数组结果.
168 *
169 * @param input 原始字节数组
170 * @param key 符合AES要求的密钥
171 * @param mode Cipher.ENCRYPT_MODE 或 Cipher.DECRYPT_MODE
172 */
173 private static byte[] aes(byte[] input, byte[] key, int mode) {
174 try {
175 SecretKey secretKey = new SecretKeySpec(key, AES);
176 Cipher cipher = Cipher.getInstance(AES);
177 cipher.init(mode, secretKey);
178 return cipher.doFinal(input);
179 } catch (GeneralSecurityException e) {
180 throw ExceptionUtils.unchecked(e);
181 }
182 }
183
184 /**
185 * 使用AES加密或解密无编码的原始字节数组, 返回无编码的字节数组结果.
186 *
187 * @param input 原始字节数组
188 * @param key 符合AES要求的密钥
189 * @param iv 初始向量
190 * @param mode Cipher.ENCRYPT_MODE 或 Cipher.DECRYPT_MODE
191 */
192 private static byte[] aes(byte[] input, byte[] key, byte[] iv, int mode) {
193 try {
194 SecretKey secretKey = new SecretKeySpec(key, AES);
195 IvParameterSpec ivSpec = new IvParameterSpec(iv);
196 Cipher cipher = Cipher.getInstance(AES_CBC);
197 cipher.init(mode, secretKey, ivSpec);
198 return cipher.doFinal(input);
199 } catch (GeneralSecurityException e) {
200 throw ExceptionUtils.unchecked(e);
201 }
202 }
203
204 // public static void main(String[] args) {
205 //
206 // String s = "hello word!";
207 // System.out.println(s);
208 //
209 // String k = genKeyString();
210 // System.out.println(k);
211 // String ss = encode(s, k);
212 // System.out.println(ss);
213 // String sss = decode(ss, k);
214 // System.out.println(sss);
215 //
216 // }
217
218 }
...\ No newline at end of file ...\ No newline at end of file
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.codec;
5
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.security.GeneralSecurityException;
9 import java.security.MessageDigest;
10 import java.security.SecureRandom;
11
12 import org.apache.commons.lang3.Validate;
13
14 import com.jeesite.common.lang.ExceptionUtils;
15
16 /**
17 * 不可逆加密工具类
18 * @author ThinkGem
19 */
20 public class DigestUtils {
21
22 private static SecureRandom random = new SecureRandom();
23
24 /**
25 * 生成随机的Byte[]作为salt密钥.
26 * @param numBytes byte数组的大小
27 */
28 public static byte[] genSalt(int numBytes) {
29 Validate.isTrue(numBytes > 0, "numBytes argument must be a positive integer (1 or larger)", numBytes);
30 byte[] bytes = new byte[numBytes];
31 random.nextBytes(bytes);
32 return bytes;
33 }
34
35 /**
36 * 对字符串进行散列, 支持md5与sha1算法.
37 * @param input 需要散列的字符串
38 * @param algorithm 散列算法("SHA-1"、"MD5")
39 * @param salt
40 * @param iterations 迭代次数
41 * @return
42 */
43 public static byte[] digest(byte[] input, String algorithm, byte[] salt, int iterations) {
44 try {
45 MessageDigest digest = MessageDigest.getInstance(algorithm);
46
47 if (salt != null) {
48 digest.update(salt);
49 }
50
51 byte[] result = digest.digest(input);
52
53 for (int i = 1; i < iterations; i++) {
54 digest.reset();
55 result = digest.digest(result);
56 }
57 return result;
58 } catch (GeneralSecurityException e) {
59 throw ExceptionUtils.unchecked(e);
60 }
61 }
62
63 /**
64 * 对文件进行sha1散列.
65 * @param input 需要散列的流
66 * @param algorithm 散列算法("SHA-1"、"MD5")
67 */
68 public static byte[] digest(InputStream input, String algorithm) throws IOException {
69 try {
70 MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
71 int bufferLength = 8 * 1024;
72 byte[] buffer = new byte[bufferLength];
73 int read = input.read(buffer, 0, bufferLength);
74
75 while (read > -1) {
76 messageDigest.update(buffer, 0, read);
77 read = input.read(buffer, 0, bufferLength);
78 }
79
80 return messageDigest.digest();
81 } catch (GeneralSecurityException e) {
82 throw ExceptionUtils.unchecked(e);
83 }
84 }
85
86 }
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.codec;
5
6 import java.io.File;
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.io.UnsupportedEncodingException;
10
11 import org.apache.commons.io.FileUtils;
12 import org.apache.commons.lang3.StringUtils;
13
14 import com.jeesite.common.io.IOUtils;
15
16 /**
17 * MD5不可逆加密工具类
18 * @author ThinkGem
19 */
20 public class Md5Utils {
21
22 private static final String MD5 = "MD5";
23 private static final String DEFAULT_ENCODING = "UTF-8";
24
25 /**
26 * 对输入字符串进行md5散列.
27 * @param input 加密字符串
28 */
29 public static String md5(String input) {
30 return md5(input, 1);
31 }
32
33 /**
34 * 对输入字符串进行md5散列.
35 * @param input 加密字符串
36 * @param iterations 迭代次数
37 */
38 public static String md5(String input, int iterations) {
39 try {
40 return EncodeUtils.encodeHex(DigestUtils.digest(input.getBytes(DEFAULT_ENCODING), MD5, null, iterations));
41 } catch (UnsupportedEncodingException e) {
42 return StringUtils.EMPTY;
43 }
44 }
45
46 /**
47 * 对输入字符串进行md5散列.
48 * @param input 加密字符串
49 */
50 public static byte[] md5(byte[] input) {
51 return md5(input, 1);
52 }
53
54 /**
55 * 对输入字符串进行md5散列.
56 * @param input 加密字符串
57 * @param iterations 迭代次数
58 */
59 public static byte[] md5(byte[] input, int iterations) {
60 return DigestUtils.digest(input, MD5, null, iterations);
61 }
62
63 /**
64 * 对文件进行md5散列.
65 */
66 public static byte[] md5(InputStream input) throws IOException {
67 return DigestUtils.digest(input, MD5);
68 }
69
70 /**
71 * 获取文件的MD5值
72 */
73 public static String md5File(File file) {
74 return md5File(file, -1);
75 }
76
77 /**
78 * 获取文件的MD5值,支持获取文件部分的MD5值
79 * uploader.md5File(file, 0, 10 * 1024 * 1024)
80 */
81 public static String md5File(File file, int size) {
82 if (file != null && file.exists()){
83 try (InputStream in = FileUtils.openInputStream(file)){
84 byte[] bytes = null;
85 if (size != -1 && file.length() >= size){
86 bytes = IOUtils.toByteArray(in, size);
87 }else{
88 bytes = IOUtils.toByteArray(in);
89 }
90 return EncodeUtils.encodeHex(md5(bytes));
91 } catch (IOException e) {
92 return StringUtils.EMPTY;
93 }
94 }
95 return StringUtils.EMPTY;
96 }
97
98 }
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.codec;
5
6 import java.io.IOException;
7 import java.io.InputStream;
8
9 /**
10 * SHA-1不可逆加密工具类
11 * @author ThinkGem
12 */
13 public class Sha1Utils {
14
15 private static final String SHA1 = "SHA-1";
16
17 /**
18 * 生成随机的Byte[]作为salt密钥.
19 * @param numBytes byte数组的大小
20 */
21 public static byte[] genSalt(int numBytes) {
22 return DigestUtils.genSalt(numBytes);
23 }
24
25 /**
26 * 对输入字符串进行sha1散列.
27 */
28 public static byte[] sha1(byte[] input) {
29 return DigestUtils.digest(input, SHA1, null, 1);
30 }
31
32 /**
33 * 对输入字符串进行sha1散列.
34 */
35 public static byte[] sha1(byte[] input, byte[] salt) {
36 return DigestUtils.digest(input, SHA1, salt, 1);
37 }
38
39 /**
40 * 对输入字符串进行sha1散列.
41 */
42 public static byte[] sha1(byte[] input, byte[] salt, int iterations) {
43 return DigestUtils.digest(input, SHA1, salt, iterations);
44 }
45
46 /**
47 * 对文件进行sha1散列.
48 */
49 public static byte[] sha1(InputStream input) throws IOException {
50 return DigestUtils.digest(input, SHA1);
51 }
52
53 }
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.collect;
5
6 import java.lang.reflect.InvocationTargetException;
7 import java.util.ArrayList;
8 import java.util.Collection;
9 import java.util.Comparator;
10 import java.util.EnumMap;
11 import java.util.HashMap;
12 import java.util.IdentityHashMap;
13 import java.util.LinkedHashMap;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.SortedMap;
17 import java.util.TreeMap;
18 import java.util.concurrent.ConcurrentHashMap;
19 import java.util.concurrent.ConcurrentMap;
20
21 import org.apache.commons.beanutils.BeanUtils;
22 import org.apache.commons.beanutils.PropertyUtils;
23
24 import com.jeesite.common.lang.StringUtils;
25
26 /**
27 * Map工具类,实现 Map <-> Bean 互相转换
28 * @author ThinkGem
29 * @version 2015-01-15
30 */
31 public class MapUtils extends org.apache.commons.collections.MapUtils {
32
33 public static <K, V> HashMap<K, V> newHashMap() {
34 return new HashMap<K, V>();
35 }
36
37 public static <K, V> HashMap<K, V> newHashMap(int initialCapacity) {
38 return new HashMap<K, V>(initialCapacity);
39 }
40
41 public static <K, V> HashMap<K, V> newHashMap(Map<? extends K, ? extends V> map) {
42 return new HashMap<K, V>(map);
43 }
44
45 public static <K, V> LinkedHashMap<K, V> newLinkedHashMap() {
46 return new LinkedHashMap<K, V>();
47 }
48
49 public static <K, V> LinkedHashMap<K, V> newLinkedHashMap(Map<? extends K, ? extends V> map) {
50 return new LinkedHashMap<K, V>(map);
51 }
52
53 public static <K, V> ConcurrentMap<K, V> newConcurrentMap() {
54 return new ConcurrentHashMap<K, V>();
55 }
56
57 @SuppressWarnings("rawtypes")
58 public static <K extends Comparable, V> TreeMap<K, V> newTreeMap() {
59 return new TreeMap<K, V>();
60 }
61
62 public static <K, V> TreeMap<K, V> newTreeMap(SortedMap<K, ? extends V> map) {
63 return new TreeMap<K, V>(map);
64 }
65
66 public static <C, K extends C, V> TreeMap<K, V> newTreeMap(Comparator<C> comparator) {
67 return new TreeMap<K, V>(comparator);
68 }
69
70 public static <K extends Enum<K>, V> EnumMap<K, V> newEnumMap(Class<K> type) {
71 return new EnumMap<K, V>((type));
72 }
73
74 public static <K extends Enum<K>, V> EnumMap<K, V> newEnumMap(Map<K, ? extends V> map) {
75 return new EnumMap<K, V>(map);
76 }
77
78 public static <K, V> IdentityHashMap<K, V> newIdentityHashMap() {
79 return new IdentityHashMap<K, V>();
80 }
81
82 /**
83 * List<Map<String, V>转换为List<T>
84 * @param clazz
85 * @param list
86 */
87 public static <T, V> List<T> toObjectList(Class<T> clazz, List<HashMap<String, V>> list) throws IllegalAccessException,
88 InvocationTargetException, NoSuchMethodException, InstantiationException {
89 List<T> retList = new ArrayList<T>();
90 if (list != null && !list.isEmpty()) {
91 for (HashMap<String, V> m : list) {
92 retList.add(toObject(clazz, m));
93 }
94 }
95 return retList;
96 }
97
98 /**
99 * 将Map转换为Object
100 * @param clazz 目标对象的类
101 * @param map 待转换Map
102 */
103 public static <T, V> T toObject(Class<T> clazz, Map<String, V> map) throws InstantiationException, IllegalAccessException,
104 InvocationTargetException {
105 T object = clazz.newInstance();
106 return toObject(object, map);
107 }
108
109 /**
110 * 将Map转换为Object
111 * @param clazz 目标对象的类
112 * @param map 待转换Map
113 * @param toCamelCase 是否去掉下划线
114 */
115 public static <T, V> T toObject(Class<T> clazz, Map<String, V> map, boolean toCamelCase) throws InstantiationException, IllegalAccessException,
116 InvocationTargetException {
117 T object = clazz.newInstance();
118 return toObject(object, map, toCamelCase);
119 }
120
121 /**
122 * 将Map转换为Object
123 * @param clazz 目标对象的类
124 * @param map 待转换Map
125 */
126 public static <T, V> T toObject(T object, Map<String, V> map) throws InstantiationException, IllegalAccessException, InvocationTargetException {
127 return toObject(object, map, false);
128 }
129
130 /**
131 * 将Map转换为Object
132 * @param object 目标对象的类
133 * @param map 待转换Map
134 * @param toCamelCase 是否采用驼峰命名法转换
135 */
136 public static <T, V> T toObject(T object, Map<String, V> map, boolean toCamelCase) throws InstantiationException, IllegalAccessException,
137 InvocationTargetException {
138 if (toCamelCase) {
139 map = toCamelCaseMap(map);
140 }
141 BeanUtils.populate(object, map);
142 return object;
143 }
144
145 /**
146 * 对象转Map
147 * @param object 目标对象
148 * @return 转换出来的值都是String
149 */
150 public static Map<String, String> toMap(Object object) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
151 return BeanUtils.describe(object);
152 }
153
154 /**
155 * 对象转Map
156 * @param object 目标对象
157 * @return 转换出来的值类型是原类型
158 */
159 public static Map<String, Object> toNavMap(Object object) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
160 return PropertyUtils.describe(object);
161 }
162
163 /**
164 * 转换为Collection<Map<K, V>>
165 * @param collection 待转换对象集合
166 * @return 转换后的Collection<Map<K, V>>
167 * @throws IllegalAccessException
168 * @throws InvocationTargetException
169 * @throws NoSuchMethodException
170 */
171 public static <T> Collection<Map<String, String>> toMapList(Collection<T> collection) throws IllegalAccessException, InvocationTargetException,
172 NoSuchMethodException {
173 List<Map<String, String>> retList = new ArrayList<Map<String, String>>();
174 if (collection != null && !collection.isEmpty()) {
175 for (Object object : collection) {
176 Map<String, String> map = toMap(object);
177 retList.add(map);
178 }
179 }
180 return retList;
181 }
182
183 /**
184 * 转换为Collection,同时为字段做驼峰转换<Map<K, V>>
185 * @param collection 待转换对象集合
186 * @return 转换后的Collection<Map<K, V>>
187 * @throws IllegalAccessException
188 * @throws InvocationTargetException
189 * @throws NoSuchMethodException
190 */
191 public static <T> Collection<Map<String, String>> toMapListForFlat(Collection<T> collection) throws IllegalAccessException,
192 InvocationTargetException, NoSuchMethodException {
193 List<Map<String, String>> retList = new ArrayList<Map<String, String>>();
194 if (collection != null && !collection.isEmpty()) {
195 for (Object object : collection) {
196 Map<String, String> map = toMapForFlat(object);
197 retList.add(map);
198 }
199 }
200 return retList;
201 }
202
203 /**
204 * 转换成Map并提供字段命名驼峰转平行
205 * @param clazz 目标对象所在类
206 * @param object 目标对象
207 * @param map 待转换Map
208 * @throws NoSuchMethodException
209 * @throws InvocationTargetException
210 * @throws IllegalAccessException
211 */
212 public static Map<String, String> toMapForFlat(Object object) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
213 Map<String, String> map = toMap(object);
214 return toUnderlineStringMap(map);
215 }
216
217 /**
218 * 将Map的Keys去下划线<br>
219 * (例:branch_no -> branchNo )<br>
220 * @param map 待转换Map
221 * @return
222 */
223 public static <V> Map<String, V> toCamelCaseMap(Map<String, V> map) {
224 Map<String, V> newMap = new HashMap<String, V>();
225 for (String key : map.keySet()) {
226 safeAddToMap(newMap, StringUtils.camelCase(key), map.get(key));
227 }
228 return newMap;
229 }
230
231 /**
232 * 将Map的Keys转译成下划线格式的<br>
233 * (例:branchNo -> branch_no)<br>
234 * @param map 待转换Map
235 * @return
236 */
237 public static <V> Map<String, V> toUnderlineStringMap(Map<String, V> map) {
238 Map<String, V> newMap = new HashMap<String, V>();
239 for (String key : map.keySet()) {
240 newMap.put(StringUtils.uncamelCase(key), map.get(key));
241 }
242 return newMap;
243 }
244
245 }
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.collect;
5
6 import java.util.Collection;
7 import java.util.Collections;
8 import java.util.Comparator;
9 import java.util.HashSet;
10 import java.util.Iterator;
11 import java.util.LinkedHashSet;
12 import java.util.Set;
13 import java.util.TreeSet;
14 import java.util.concurrent.ConcurrentHashMap;
15 import java.util.concurrent.CopyOnWriteArraySet;
16
17 /**
18 * Set工具类
19 * @author ThinkGem
20 * @version 2015-01-15
21 */
22 public class SetUtils extends org.apache.commons.collections.SetUtils {
23
24 public static <E> HashSet<E> newHashSet() {
25 return new HashSet<E>();
26 }
27
28 @SafeVarargs
29 public static <E> HashSet<E> newHashSet(E... elements) {
30 HashSet<E> set = newHashSet(elements.length);
31 Collections.addAll(set, elements);
32 return set;
33 }
34
35 public static <E> HashSet<E> newHashSet(int initialCapacity) {
36 return new HashSet<E>(initialCapacity);
37 }
38
39 public static <E> HashSet<E> newHashSet(Iterable<? extends E> elements) {
40 return (elements instanceof Collection) ? new HashSet<E>(cast(elements)) : newHashSet(elements.iterator());
41 }
42
43 public static <E> HashSet<E> newHashSet(Iterator<? extends E> elements) {
44 HashSet<E> set = newHashSet();
45 addAll(set, elements);
46 return set;
47 }
48
49 public static <E> Set<E> newConcurrentHashSet() {
50 return Collections.newSetFromMap(new ConcurrentHashMap<E, Boolean>());
51 }
52
53 public static <E> Set<E> newConcurrentHashSet(Iterable<? extends E> elements) {
54 Set<E> set = newConcurrentHashSet();
55 addAll(set, elements);
56 return set;
57 }
58
59 public static <E> LinkedHashSet<E> newLinkedHashSet() {
60 return new LinkedHashSet<E>();
61 }
62
63 public static <E> LinkedHashSet<E> newLinkedHashSet(int initialCapacity) {
64 return new LinkedHashSet<E>(initialCapacity);
65 }
66
67 public static <E> LinkedHashSet<E> newLinkedHashSet(Iterable<? extends E> elements) {
68 if (elements instanceof Collection) {
69 return new LinkedHashSet<E>(cast(elements));
70 }
71 LinkedHashSet<E> set = newLinkedHashSet();
72 addAll(set, elements);
73 return set;
74 }
75
76 @SuppressWarnings("rawtypes")
77 public static <E extends Comparable> TreeSet<E> newTreeSet() {
78 return new TreeSet<E>();
79 }
80
81 @SuppressWarnings("rawtypes")
82 public static <E extends Comparable> TreeSet<E> newTreeSet(Iterable<? extends E> elements) {
83 TreeSet<E> set = newTreeSet();
84 addAll(set, elements);
85 return set;
86 }
87
88 public static <E> TreeSet<E> newTreeSet(Comparator<? super E> comparator) {
89 return new TreeSet<E>(comparator);
90 }
91
92 public static <E> Set<E> newIdentityHashSet() {
93 return Collections.newSetFromMap(MapUtils.<E, Boolean> newIdentityHashMap());
94 }
95
96 public static <E> CopyOnWriteArraySet<E> newCopyOnWriteArraySet() {
97 return new CopyOnWriteArraySet<E>();
98 }
99
100 public static <E> CopyOnWriteArraySet<E> newCopyOnWriteArraySet(Iterable<? extends E> elements) {
101 Collection<? extends E> elementsCollection = (elements instanceof Collection) ? cast(elements) : ListUtils.newArrayList(elements);
102 return new CopyOnWriteArraySet<E>(elementsCollection);
103 }
104
105 private static <T> Collection<T> cast(Iterable<T> iterable) {
106 return (Collection<T>) iterable;
107 }
108
109 private static <T> boolean addAll(Collection<T> addTo, Iterator<? extends T> iterator) {
110 boolean wasModified = false;
111 while (iterator.hasNext()) {
112 wasModified |= addTo.add(iterator.next());
113 }
114 return wasModified;
115 }
116
117 public static <T> boolean addAll(Collection<T> addTo, Iterable<? extends T> elementsToAdd) {
118 if (elementsToAdd instanceof Collection) {
119 Collection<? extends T> c = cast(elementsToAdd);
120 return addTo.addAll(c);
121 }
122 return addAll(addTo, elementsToAdd.iterator());
123 }
124 }
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.exec;
5
6 import java.io.BufferedReader;
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.io.InputStreamReader;
10 import java.io.Reader;
11
12 /**
13 * Command
14 * @author ThinkGem
15 * @version 2017年2月17日
16 */
17 public class CommandUtils {
18
19 public static String execute(String command) throws IOException {
20 return execute(command, "GBK");
21 }
22
23 public static String execute(String command, String charsetName) throws IOException {
24 Process process = Runtime.getRuntime().exec(command);
25 // 记录dos命令的返回信息
26 StringBuffer stringBuffer = new StringBuffer();
27 // 获取返回信息的流
28 InputStream in = process.getInputStream();
29 Reader reader = new InputStreamReader(in, charsetName);
30 BufferedReader bReader = new BufferedReader(reader);
31 String res = bReader.readLine();
32 while (res != null) {
33 stringBuffer.append(res);
34 stringBuffer.append("\n");
35 res = bReader.readLine();
36 }
37 bReader.close();
38 reader.close();
39 return stringBuffer.toString();
40 }
41
42 }
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.idgen;
5
6 import java.security.SecureRandom;
7 import java.util.UUID;
8
9 import com.jeesite.common.codec.EncodeUtils;
10 import com.jeesite.common.lang.ObjectUtils;
11 import com.jeesite.common.lang.StringUtils;
12
13 /**
14 * 封装各种生成唯一性ID算法的工具类.
15 * @author ThinkGem
16 * @version 2014-8-19
17 */
18 public class IdGenerate {
19
20 private static SecureRandom random = new SecureRandom();
21 private static IdWorker idWorker = new IdWorker(-1, -1);
22
23 /**
24 * 生成UUID, 中间无-分割.
25 */
26 public static String uuid() {
27 return UUID.randomUUID().toString().replaceAll("-", "");
28 }
29
30 /**
31 * 使用SecureRandom随机生成Long.
32 */
33 public static long randomLong() {
34 return Math.abs(random.nextLong());
35 }
36
37 /**
38 * 基于Base62编码的SecureRandom随机生成bytes.
39 */
40 public static String randomBase62(int length) {
41 byte[] randomBytes = new byte[length];
42 random.nextBytes(randomBytes);
43 return EncodeUtils.encodeBase62(randomBytes);
44 }
45
46 /**
47 * 获取新唯一编号(18为数值)
48 * 来自于twitter项目snowflake的id产生方案,全局唯一,时间有序。
49 * 64位ID (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加))
50 */
51 public static String nextId() {
52 return String.valueOf(idWorker.nextId());
53 }
54
55 /**
56 * 获取新代码编号
57 */
58 public static String nextCode(String code){
59 if (code != null){
60 String str = code.trim();
61 int len = str.length() - 1;
62 int lastNotNumIndex = 0;
63 for (int i = len; i >= 0; i--) {
64 if (!(str.charAt(i) >= '0' && str.charAt(i) <= '9')) {
65 lastNotNumIndex = i;
66 break;
67 }
68 }
69 // 如果最后一位是数字,并且last索引位置还在最后,则代表是纯数字,则最后一个不是数字的索引为-1
70 if ((str.charAt(len) >= '0' && str.charAt(len) <= '9') && (lastNotNumIndex == len)) {
71 lastNotNumIndex = -1;
72 }
73 String prefix = str.substring(0, lastNotNumIndex + 1);
74 String numStr = str.substring(lastNotNumIndex + 1, str.length());
75 long num = ObjectUtils.toLong(numStr);
76 // System.out.println("处理前:"+str);
77 str = prefix + StringUtils.leftPad(String.valueOf(num + 1), numStr.length(), "0");
78 // System.out.println("处理后:"+str);
79 return str;
80 }
81 return null;
82 }
83
84 // public static void main(String[] args) {
85 // System.out.println(uuid());
86 // System.out.println(nextId());
87 // System.out.println(nextCode("8"));
88 // System.out.println(nextCode("09"));
89 // System.out.println(nextCode("009"));
90 // System.out.println(nextCode("E09"));
91 // System.out.println(nextCode("EC09"));
92 // System.out.println(nextCode("EC0101"));
93 // System.out.println(nextCode("EC0109"));
94 // System.out.println(nextCode("EC02T03"));
95 // System.out.println(nextCode("EC02T099"));
96 // System.out.println(nextCode("EC02T100"));
97 // System.out.println(nextCode("EC02T10A"));
98 //// // 数值型ID重复验证测试
99 //// Set<String> set = SetUtils.newHashSet();
100 //// try{
101 //// for (int i=0; i<100; i++){
102 //// String id = String.valueOf(nextId());
103 //// if (set.contains(id)){
104 //// throw new Exception(id + " exists");
105 //// }
106 //// set.add(id);
107 //// System.out.println(id);
108 //// Thread.sleep(100);
109 //// }
110 //// }catch (Exception e) {
111 //// e.printStackTrace();
112 //// }
113 // }
114
115 }
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.idgen;
5
6 import java.util.Random;
7
8 /**
9 * 来自于twitter项目snowflake的id产生方案,全局唯一,时间有序。
10 * 64位ID (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加))
11 * https://github.com/twitter/snowflake/blob/scala_28/src/main/
12 * scala/com/twitter/service/snowflake/IdWorker.scala
13 */
14 public class IdWorker {
15
16 private final static long twepoch = 1288834974657L;
17 // 机器标识位数
18 private final static long workerIdBits = 5L;
19 // 数据中心标识位数
20 private final static long datacenterIdBits = 5L;
21 // 机器ID最大值
22 private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);
23 // 数据中心ID最大值
24 private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
25 // 毫秒内自增位
26 private final static long sequenceBits = 12L;
27 // 机器ID偏左移12位
28 private final static long workerIdShift = sequenceBits;
29 // 数据中心ID左移17位
30 private final static long datacenterIdShift = sequenceBits + workerIdBits;
31 // 时间毫秒左移22位
32 private final static long timestampLeftShift = sequenceBits + workerIdBits
33 + datacenterIdBits;
34
35 private final static long sequenceMask = -1L ^ (-1L << sequenceBits);
36
37 private static long lastTimestamp = -1L;
38
39 private long sequence = 0L;
40 private final long workerId;
41 private final long datacenterId;
42
43 public IdWorker(long workerId, long datacenterId) {
44 if (workerId > maxWorkerId || workerId < 0) {
45 if (workerId == -1){
46 this.workerId = new Random().nextInt((int)maxWorkerId);
47 }else{
48 throw new IllegalArgumentException(
49 "worker Id can't be greater than %d or less than 0");
50 }
51 }else{
52 this.workerId = workerId;
53 }
54 if (datacenterId > maxDatacenterId || datacenterId < 0) {
55 if (datacenterId == -1){
56 this.datacenterId = new Random().nextInt((int)maxDatacenterId);
57 }else{
58 throw new IllegalArgumentException(
59 "datacenter Id can't be greater than %d or less than 0");
60 }
61 }else{
62 this.datacenterId = datacenterId;
63 }
64 }
65
66 public synchronized long nextId() {
67 long timestamp = timeGen();
68 if (timestamp < lastTimestamp) {
69 try {
70 throw new Exception(
71 "Clock moved backwards. Refusing to generate id for "
72 + (lastTimestamp - timestamp) + " milliseconds");
73 } catch (Exception e) {
74 e.printStackTrace();
75 }
76 }
77
78 if (lastTimestamp == timestamp) {
79 // 当前毫秒内,则+1
80 sequence = (sequence + 1) & sequenceMask;
81 if (sequence == 0) {
82 // 当前毫秒内计数满了,则等待下一秒
83 timestamp = tilNextMillis(lastTimestamp);
84 }
85 } else {
86 sequence = 0;
87 }
88 lastTimestamp = timestamp;
89 // ID偏移组合生成最终的ID,并返回ID
90 long nextId = ((timestamp - twepoch) << timestampLeftShift)
91 | (datacenterId << datacenterIdShift)
92 | (workerId << workerIdShift) | sequence;
93
94 return nextId;
95 }
96
97 private long tilNextMillis(final long lastTimestamp) {
98 long timestamp = this.timeGen();
99 while (timestamp <= lastTimestamp) {
100 timestamp = this.timeGen();
101 }
102 return timestamp;
103 }
104
105 private long timeGen() {
106 return System.currentTimeMillis();
107 }
108
109 // //////////// test ////////////
110 //
111 // public static void main(String[] args) throws Exception {
112 // final Set<Long> set = SetUtils.newHashSet();
113 //
114 // final IdWorker w1 = new IdWorker(-1, -1);
115 // final IdWorker w2 = new IdWorker(-1, -1);
116 // final CyclicBarrier cdl = new CyclicBarrier(100);
117 //
118 // for (int i = 0; i < 1000; i++) {
119 // new Thread(new Runnable() {
120 // @Override
121 // public void run() {
122 // try {
123 // cdl.await();
124 // } catch (InterruptedException e) {
125 // e.printStackTrace();
126 // } catch (BrokenBarrierException e) {
127 // e.printStackTrace();
128 // }
129 //
130 // // id
131 // Long id = w1.nextId();
132 // if (set.contains(id)){
133 // System.out.println(id + " exists");
134 // }
135 // set.add(id);
136 // System.out.println(id);
137 //
138 // // id2
139 // Long id2 = w2.nextId();
140 // if (set.contains(id2)){
141 // System.out.println(id2 + " exists");
142 // }
143 // set.add(id2);
144 // System.out.println(id2);
145 // }
146 // }).start();
147 // }
148 // try {
149 // TimeUnit.SECONDS.sleep(5);
150 // } catch (InterruptedException e) {
151 // e.printStackTrace();
152 // }
153 // }
154
155 }
...\ No newline at end of file ...\ No newline at end of file
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.image;
5
6 import java.awt.Color;
7 import java.awt.Graphics;
8 import java.awt.image.BufferedImage;
9 import java.io.IOException;
10 import java.io.OutputStream;
11 import java.util.Random;
12
13 import org.patchca.background.BackgroundFactory;
14 import org.patchca.color.ColorFactory;
15 import org.patchca.filter.predefined.CurvesRippleFilterFactory;
16 import org.patchca.filter.predefined.DiffuseRippleFilterFactory;
17 import org.patchca.filter.predefined.DoubleRippleFilterFactory;
18 import org.patchca.filter.predefined.MarbleRippleFilterFactory;
19 import org.patchca.filter.predefined.WobbleRippleFilterFactory;
20 import org.patchca.font.RandomFontFactory;
21 import org.patchca.service.ConfigurableCaptchaService;
22 import org.patchca.text.renderer.BestFitTextRenderer;
23 import org.patchca.utils.encoder.EncoderHelper;
24 import org.patchca.word.RandomWordFactory;
25
26 /**
27 * 验证码工具
28 * @author ThinkGem
29 * @version 2017年12月23日
30 */
31 public class CaptchaUtils {
32
33 private static Random random = new Random();
34 private static ConfigurableCaptchaService ccs;
35 private static WobbleRippleFilterFactory wrff; // 摆波纹
36 private static DoubleRippleFilterFactory doff; // 双波纹
37 private static CurvesRippleFilterFactory crff; // 曲线波纹
38 private static DiffuseRippleFilterFactory drff; // 漫纹波
39 private static MarbleRippleFilterFactory mrff; // 大理石
40
41 private static void initialize(){
42 if (ccs == null){
43 synchronized (CaptchaUtils.class) {
44 if (ccs == null){
45 // 配置初始化
46 ccs = new ConfigurableCaptchaService();
47
48 // 设置图片大小
49 ccs.setWidth(100);
50 ccs.setHeight(28);
51
52 // 设置文字数量
53 RandomWordFactory wf = new RandomWordFactory();
54 wf.setCharacters("ABDEFGHKMNRSWX2345689");
55 wf.setMinLength(4);
56 wf.setMaxLength(4);
57 ccs.setWordFactory(wf);
58
59 // 设置字体大小
60 RandomFontFactory ff = new RandomFontFactory();
61 ff.setMinSize(28);
62 ff.setMaxSize(28);
63 ccs.setFontFactory(ff);
64
65 // 设置文字渲染边距
66 BestFitTextRenderer tr = new BestFitTextRenderer();
67 tr.setTopMargin(3);
68 tr.setRightMargin(3);
69 tr.setBottomMargin(3);
70 tr.setLeftMargin(3);
71 ccs.setTextRenderer(tr);
72
73 // 设置字体颜色
74 ccs.setColorFactory(new ColorFactory() {
75 @Override
76 public Color getColor(int x) {
77 int r = random.nextInt(90);
78 int g = random.nextInt(90);
79 int b = random.nextInt(90);
80 return new Color(r, g, b);
81 }
82 });
83
84 // 设置背景
85 ccs.setBackgroundFactory(new BackgroundFactory() {
86 @Override
87 public void fillBackground(BufferedImage image) {
88 Graphics graphics = image.getGraphics();
89 // 验证码图片的宽高
90 int imgWidth = image.getWidth();
91 int imgHeight = image.getHeight();
92 // 填充为白色背景
93 graphics.setColor(Color.WHITE);
94 graphics.fillRect(0, 0, imgWidth, imgHeight);
95 // 画 50 个噪点(颜色及位置随机)
96 for (int i = 0; i < 50; i++) {
97 // 随机颜色
98 int rInt = random.nextInt(100)+50;
99 int gInt = random.nextInt(100)+50;
100 int bInt = random.nextInt(100)+50;
101 graphics.setColor(new Color(rInt, gInt, bInt));
102 // 随机位置
103 int xInt = random.nextInt(imgWidth - 3);
104 int yInt = random.nextInt(imgHeight - 2);
105 // 随机旋转角度
106 int sAngleInt = random.nextInt(360);
107 int eAngleInt = random.nextInt(360);
108 // 随机大小
109 int wInt = random.nextInt(6);
110 int hInt = random.nextInt(6);
111 // 填充背景
112 graphics.fillArc(xInt, yInt, wInt, hInt, sAngleInt, eAngleInt);
113 // 画5条干扰线
114 if (i % 10 == 0) {
115 int xInt2 = random.nextInt(imgWidth);
116 int yInt2 = random.nextInt(imgHeight);
117 graphics.drawLine(xInt, yInt, xInt2, yInt2);
118 }
119 }
120 }
121 });
122
123 // 效果初始化
124 wrff = new WobbleRippleFilterFactory(); // 摆波纹
125 doff = new DoubleRippleFilterFactory(); // 双波纹
126 crff = new CurvesRippleFilterFactory(ccs.getColorFactory()); // 曲线波纹
127 drff = new DiffuseRippleFilterFactory(); // 漫纹波
128 mrff = new MarbleRippleFilterFactory(); // 大理石
129
130 }
131 }
132 }
133 }
134
135 /**
136 * 生成验证码
137 * @param request
138 * @param response
139 * @throws IOException
140 * @return 验证码字符
141 */
142 public static String generateCaptcha(OutputStream outputStream) throws IOException{
143
144 // 初始化设置
145 initialize();
146
147 // 随机选择一个样式
148 switch (random.nextInt(3)) {
149 case 0:
150 ccs.setFilterFactory(wrff); // 摆波纹
151 break;
152 case 1:
153 ccs.setFilterFactory(doff); // 双波纹
154 break;
155 case 2:
156 ccs.setFilterFactory(crff); // 曲线波纹
157 break;
158 case 3:
159 ccs.setFilterFactory(drff); // 漫纹波
160 break;
161 case 4:
162 ccs.setFilterFactory(mrff); // 大理石
163 break;
164 }
165
166 // 生成验证码
167 String s = EncoderHelper.getChallangeAndWriteImage(ccs, "png", outputStream);
168 // System.out.println(s);
169
170 return s;
171 }
172
173 // public static void main(String[] args) throws IOException {
174 //
175 // FileOutputStream fos = new FileOutputStream("x:\\captcha.png");
176 // String s = generateCaptcha(fos);
177 // System.out.println(s);
178 // fos.close();
179 //
180 // }
181 }
1 ///**
2 // * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 // */
4 //package com.jeesite.common.image;
5 //
6 //import java.io.File;
7 //
8 //import com.drew.imaging.jpeg.JpegMetadataReader;
9 //import com.drew.lang.Rational;
10 //import com.drew.metadata.Metadata;
11 //import com.drew.metadata.exif.GpsDirectory;
12 //
13 ///**
14 // * 图片地理信息获取
15 // * @author ThinkGem
16 // */
17 //public class ImageGeo {
18 //
19 // public double lat = 0.0;
20 // public double lon = 0.0;
21 // public double alt = 0.0;
22 // public boolean error = false;
23 //
24 // public ImageGeo(String filename) {
25 // try {
26 // error = false;
27 // File jpegFile = new File(filename);
28 // Metadata metadata = JpegMetadataReader.readMetadata(jpegFile);
29 //
30 // GpsDirectory gpsdir = (GpsDirectory) metadata.getDirectoriesOfType(GpsDirectory.class);
31 // Rational latpart[] = gpsdir.getRationalArray(GpsDirectory.TAG_LATITUDE);
32 // Rational lonpart[] = gpsdir.getRationalArray(GpsDirectory.TAG_LONGITUDE);
33 // String northing = gpsdir.getString(GpsDirectory.TAG_LATITUDE_REF);
34 // String easting = gpsdir.getString(GpsDirectory.TAG_LONGITUDE_REF);
35 //
36 // try {
37 // alt = gpsdir.getDouble(GpsDirectory.TAG_ALTITUDE);
38 // } catch (Exception ex) {}
39 //
40 // double latsign = 1.0d;
41 // if (northing.equalsIgnoreCase("S")) {
42 // latsign = -1.0d;
43 // }
44 // double lonsign = 1.0d;
45 // if (easting.equalsIgnoreCase("W")) {
46 // lonsign = -1.0d;
47 // }
48 //
49 // lat = (Math.abs(latpart[0].doubleValue()) + latpart[1].doubleValue() / 60.0d + latpart[2].doubleValue() / 3600.0d) * latsign;
50 // lon = (Math.abs(lonpart[0].doubleValue()) + lonpart[1].doubleValue() / 60.0d + lonpart[2].doubleValue() / 3600.0d) * lonsign;
51 //
52 // if (Double.isNaN(lat) || Double.isNaN(lon)) {
53 // error = true;
54 // }
55 // } catch (Exception ex) {
56 // error = true;
57 // }
58 // System.out.println(filename + ": (" + lat + ", " + lon + ")");
59 // }
60 //
61 //// public static void main(String[] args) {
62 //// ImageGeo imageGeo = new ImageGeo(ImageGeo.class.getResource("IMAG0068.jpg").getFile());
63 //// System.out.println(imageGeo.lon + "," + imageGeo.lat);
64 //// }
65 //
66 //}
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.image;
5
6 import java.awt.image.BufferedImage;
7 import java.io.File;
8 import java.io.IOException;
9
10 import javax.imageio.ImageIO;
11
12 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory;
14
15 import com.jeesite.common.io.FileUtils;
16 import com.jeesite.common.lang.StringUtils;
17
18 import net.coobird.thumbnailator.Thumbnails;
19 import net.coobird.thumbnailator.Thumbnails.Builder;
20
21 /**
22 * 图片处理工具类
23 * @author ThinkGem
24 * @version 2018年12月31日
25 */
26 public class ImageUtils {
27
28 private static Logger logger = LoggerFactory.getLogger(ImageUtils.class);
29
30 /**
31 * 缩略图生成,处理一些较大的图片,防止占用太多的网络资源
32 */
33 public static void thumbnails(File imageFile, int maxWidth, int maxHeight, String outputFormat){
34 if (imageFile == null || !imageFile.exists() || (maxWidth <= 0 && maxHeight <= 0)){
35 return;
36 }
37 // 只处理可以压缩的图片,如gif图片压缩后会出现黑色背景的情况
38 String extension = FileUtils.getFileExtension(imageFile.getName());
39 if (!StringUtils.inString(extension, "png", "jpg", "jpeg", "bmp", "ico")){
40 return;
41 }
42 try{
43 BufferedImage bufferedImage = ImageIO.read(imageFile);
44 Builder<BufferedImage> bilder = Thumbnails.of(bufferedImage);
45 if (bufferedImage != null){
46 if (maxWidth > 0){
47 if (bufferedImage.getWidth() <= maxWidth){
48 bilder.width(bufferedImage.getWidth());
49 }else{
50 bilder.width(maxWidth);
51 }
52 }
53 if (maxHeight > 0){
54 if (bufferedImage.getHeight() <= maxHeight){
55 bilder.height(bufferedImage.getHeight());
56 }else{
57 bilder.height(maxHeight);
58 }
59 }
60 if (StringUtils.isNotBlank(outputFormat)){
61 bilder.outputFormat(outputFormat);
62 }
63 bilder.toFile(imageFile);
64 }
65 }catch(IOException e){
66 logger.error("图片压缩失败:" + imageFile.getAbsoluteFile(), e);
67 }
68 }
69
70 }
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.image;
5
6 import java.awt.image.BufferedImage;
7 import java.io.File;
8 import java.util.Hashtable;
9
10 import javax.imageio.ImageIO;
11
12 import com.google.zxing.BarcodeFormat;
13 import com.google.zxing.BinaryBitmap;
14 import com.google.zxing.DecodeHintType;
15 import com.google.zxing.EncodeHintType;
16 import com.google.zxing.LuminanceSource;
17 import com.google.zxing.MultiFormatReader;
18 import com.google.zxing.MultiFormatWriter;
19 import com.google.zxing.Result;
20 import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
21 import com.google.zxing.client.j2se.MatrixToImageWriter;
22 import com.google.zxing.common.BitMatrix;
23 import com.google.zxing.common.HybridBinarizer;
24 import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
25
26 /**
27 * 条形码和二维码编码解码
28 * @author ThinkGem
29 * @version 2014-02-28
30 */
31 public class ZxingUtils {
32
33 /**
34 * 条形码编码
35 *
36 * @param contents
37 * @param width
38 * @param height
39 * @param imgPath
40 */
41 public static void encode(String contents, int width, int height, String imgPath) {
42 int codeWidth = 3 + // start guard
43 (7 * 6) + // left bars
44 5 + // middle guard
45 (7 * 6) + // right bars
46 3; // end guard
47 codeWidth = Math.max(codeWidth, width);
48 try {
49 BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.EAN_13, codeWidth, height, null);
50 MatrixToImageWriter.writeToPath(bitMatrix, "png", new File(imgPath).toPath());
51 } catch (Exception e) {
52 e.printStackTrace();
53 }
54 }
55
56 /**
57 * 条形码解码
58 *
59 * @param imgPath
60 * @return String
61 */
62 public static String decode(String imgPath) {
63 BufferedImage image = null;
64 Result result = null;
65 try {
66 image = ImageIO.read(new File(imgPath));
67 if (image == null) {
68 System.out.println("the decode image may be not exit.");
69 }
70 LuminanceSource source = new BufferedImageLuminanceSource(image);
71 BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
72 result = new MultiFormatReader().decode(bitmap, null);
73 return result.getText();
74 } catch (Exception e) {
75 e.printStackTrace();
76 }
77 return null;
78 }
79
80 /**
81 * 二维码编码
82 *
83 * @param contents
84 * @param width
85 * @param height
86 * @param imgPath
87 */
88 public static void encode2(String contents, int width, int height, String imgPath) {
89 Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
90 // 指定纠错等级
91 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
92 // 指定编码格式
93 hints.put(EncodeHintType.CHARACTER_SET, "GBK");
94 try {
95 BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints);
96 MatrixToImageWriter.writeToPath(bitMatrix, "png", new File(imgPath).toPath());
97 } catch (Exception e) {
98 e.printStackTrace();
99 }
100 }
101
102 /**
103 * 二维码解码
104 *
105 * @param imgPath
106 * @return String
107 */
108 public static String decode2(String imgPath) {
109 BufferedImage image = null;
110 Result result = null;
111 try {
112 image = ImageIO.read(new File(imgPath));
113 if (image == null) {
114 System.out.println("the decode image may be not exit.");
115 }
116 LuminanceSource source = new BufferedImageLuminanceSource(image);
117 BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
118 Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
119 hints.put(DecodeHintType.CHARACTER_SET, "GBK");
120 result = new MultiFormatReader().decode(bitmap, hints);
121 return result.getText();
122 } catch (Exception e) {
123 e.printStackTrace();
124 }
125 return null;
126 }
127
128 // public static void main(String[] args) {
129 //
130 // // 条形码
131 // String imgPath = "target\\zxing_EAN13.png";
132 // String contents = "6923450657713";
133 // int width = 105, height = 50;
134 //
135 // ZxingUtils.encode(contents, width, height, imgPath);
136 // System.out.println("finished zxing EAN-13 encode.");
137 //
138 // String decodeContent = ZxingUtils.decode(imgPath);
139 // System.out.println("解码内容如下:" + decodeContent);
140 // System.out.println("finished zxing EAN-13 decode.");
141 //
142 // // 二维码
143 // String imgPath2 = "target\\zxing.png";
144 // String contents2 = "Hello Gem, welcome to Zxing!" + "\nBlog [ http://thinkgem.iteye.com ]" + "\nEMail [ thinkgem@163.com ]";
145 // int width2 = 300, height2 = 300;
146 //
147 // ZxingUtils.encode2(contents2, width2, height2, imgPath2);
148 // System.out.println("finished zxing encode.");
149 //
150 // String decodeContent2 = ZxingUtils.decode2(imgPath2);
151 // System.out.println("解码内容如下:" + decodeContent2);
152 // System.out.println("finished zxing decode.");
153 //
154 // }
155
156 }
...\ No newline at end of file ...\ No newline at end of file
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.io;
5
6 import java.io.Closeable;
7 import java.io.File;
8 import java.io.FileInputStream;
9 import java.io.FileNotFoundException;
10 import java.io.FileOutputStream;
11 import java.io.IOException;
12 import java.io.InputStream;
13
14 /**
15 * 数据流工具类
16 * @author ThinkGem
17 */
18 public class IOUtils extends org.apache.commons.io.IOUtils {
19
20 /**
21 * 根据文件路径创建文件输入流处理 以字节为单位(非 unicode )
22 * @param path
23 * @return
24 */
25 public static FileInputStream getFileInputStream(String filepath) {
26 FileInputStream fileInputStream = null;
27 try {
28 fileInputStream = new FileInputStream(filepath);
29 } catch (FileNotFoundException e) {
30 System.out.println("错误信息:文件不存在");
31 e.printStackTrace();
32 }
33 return fileInputStream;
34 }
35
36 /**
37 * 根据文件对象创建文件输入流处理 以字节为单位(非 unicode )
38 * @param path
39 * @return
40 */
41 public static FileInputStream getFileInputStream(File file) {
42 FileInputStream fileInputStream = null;
43 try {
44 fileInputStream = new FileInputStream(file);
45 } catch (FileNotFoundException e) {
46 System.out.println("错误信息:文件不存在");
47 e.printStackTrace();
48 }
49 return fileInputStream;
50 }
51
52 /**
53 * 根据文件对象创建文件输出流处理 以字节为单位(非 unicode )
54 * @param file
55 * @param append true:文件以追加方式打开,false:则覆盖原文件的内容
56 * @return
57 */
58 public static FileOutputStream getFileOutputStream(File file, boolean append) {
59 FileOutputStream fileOutputStream = null;
60 try {
61 fileOutputStream = new FileOutputStream(file, append);
62 } catch (FileNotFoundException e) {
63 System.out.println("错误信息:文件不存在");
64 e.printStackTrace();
65 }
66 return fileOutputStream;
67 }
68
69 /**
70 * 根据文件路径创建文件输出流处理 以字节为单位(非 unicode )
71 * @param path
72 * @param append true:文件以追加方式打开,false:则覆盖原文件的内容
73 * @return
74 */
75 public static FileOutputStream getFileOutputStream(String filepath, boolean append) {
76 FileOutputStream fileOutputStream = null;
77 try {
78 fileOutputStream = new FileOutputStream(filepath, append);
79 } catch (FileNotFoundException e) {
80 System.out.println("错误信息:文件不存在");
81 e.printStackTrace();
82 }
83 return fileOutputStream;
84 }
85
86 /**
87 * Closes a <code>Closeable</code> unconditionally.
88 */
89 public static void closeQuietly(final InputStream input) {
90 closeQuietly((Closeable) input);
91 }
92
93 /**
94 * Closes a <code>Closeable</code> unconditionally.
95 */
96 public static void closeQuietly(final Closeable closeable) {
97 try {
98 if (closeable != null) {
99 closeable.close();
100 }
101 } catch (final IOException ioe) {
102 // ignore
103 }
104 }
105
106 }
...\ No newline at end of file ...\ No newline at end of file
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.io;
5
6 import java.io.File;
7 import java.io.IOException;
8 import java.io.InputStreamReader;
9 import java.util.Map;
10 import java.util.Properties;
11 import java.util.Set;
12 import java.util.regex.Matcher;
13 import java.util.regex.Pattern;
14
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
17 import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
18 import org.springframework.core.env.Environment;
19 import org.springframework.core.io.Resource;
20
21 import com.jeesite.common.collect.SetUtils;
22 import com.jeesite.common.lang.ObjectUtils;
23 import com.jeesite.common.lang.StringUtils;
24
25 /**
26 * Properties工具类, 可载入多个properties、yml文件,
27 * 相同的属性在最后载入的文件中的值将会覆盖之前的值,
28 * 取不到从System.getProperty()获取。
29 * @author ThinkGem
30 * @version 2017-12-30
31 */
32 public class PropertiesUtils {
33
34 // 默认加载的文件,可通过继承覆盖(若有相同Key,优先加载后面的)
35 public static final String[] DEFAULT_CONFIG_FILE = new String[]{
36 "classpath:config/bootstrap.yml", "classpath:bootstrap.yml",
37 "classpath:config/application.yml", "classpath:application.yml"};
38
39 private static Logger logger = PropertiesUtils.initLogger();
40 private final Set<String> configSet = SetUtils.newLinkedHashSet();
41 private final Properties properties = new Properties();
42 private static Environment environment;
43
44 /**
45 * 当前类的实例持有者(静态内部类,延迟加载,懒汉式,线程安全的单例模式)
46 */
47 private static final class PropertiesLoaderHolder {
48 private static PropertiesUtils INSTANCE;
49 static {
50 releadInstance();
51 }
52 public static void releadInstance(){
53 // 获取平台及模块相关的配置文件
54 Set<String> configSet = SetUtils.newLinkedHashSet();
55 Resource[] resources = ResourceUtils.getResources("classpath*:/config/jeesite-*.*");
56 for(Resource resource : resources){
57 configSet.add("classpath:config/"+resource.getFilename());
58 }
59 //configSet.add("classpath:config/jeesite.yml");
60 // 获取全局设置默认的配置文件(以下是支持环境配置的属性文件)
61 Set<String> set = SetUtils.newLinkedHashSet();
62 for (String configFile : DEFAULT_CONFIG_FILE){
63 set.add(configFile);
64 }
65 // 获取 spring.config.location 外部自定义的配置文件
66 String customConfigs = System.getProperty("spring.config.location");
67 if (StringUtils.isNotBlank(customConfigs)){
68 for (String customConfig : StringUtils.split(customConfigs, ",")){
69 if (!customConfig.contains("$")){
70 customConfig = org.springframework.util.StringUtils.cleanPath(customConfig);
71 if (!ResourceUtils.isUrl(customConfig)){
72 customConfig = ResourceUtils.FILE_URL_PREFIX + customConfig;
73 }
74 }
75 set.add(customConfig);
76 }
77 }
78 // 获取 spring.profiles.active 活动环境名称的配置文件
79 String[] configFiles = set.toArray(new String[set.size()]);
80 String profiles = System.getProperty("spring.profiles.active");
81 if (StringUtils.isBlank(profiles)){
82 PropertiesUtils propsTemp = new PropertiesUtils(configFiles);
83 profiles = propsTemp.getProperty("spring.profiles.active");
84 }
85 for (String location : configFiles){
86 configSet.add(location);
87 if (StringUtils.isNotBlank(profiles)){
88 if (location.endsWith(".properties")){
89 configSet.add(StringUtils.substringBeforeLast(location, ".properties")
90 + "-" + profiles + ".properties");
91 }else if (location.endsWith(".yml")){
92 configSet.add(StringUtils.substringBeforeLast(location, ".yml")
93 + "-" + profiles + ".yml");
94 }
95 }
96 }
97 configFiles = configSet.toArray(new String[configSet.size()]);
98 logger.debug("Loading jeesite config: {}", (Object)configFiles);
99 INSTANCE = new PropertiesUtils(configFiles);
100 }
101 }
102
103 /**
104 * 载入多个文件,路径使用Spring Resource格式,相同的属性在最后载入的文件中的值将会覆盖之前的值。
105 */
106 public PropertiesUtils(String... configFiles) {
107 for (String location : configFiles) {
108 try {
109 Resource resource = ResourceUtils.getResource(location);
110 if (resource.exists()){
111 if (location.endsWith(".properties")){
112 try (InputStreamReader is = new InputStreamReader(resource.getInputStream(), "UTF-8")){
113 properties.load(is);
114 configSet.add(location);
115 } catch (IOException ex) {
116 logger.error("Load " + location + " failure. ", ex);
117 }
118 }
119 else if (location.endsWith(".yml")){
120 YamlPropertiesFactoryBean bean = new YamlPropertiesFactoryBean();
121 bean.setResources(resource);
122 for (Map.Entry<Object,Object> entry : bean.getObject().entrySet()){
123 properties.put(ObjectUtils.toString(entry.getKey()),
124 ObjectUtils.toString(entry.getValue()));
125 }
126 configSet.add(location);
127 }
128 }
129 } catch (Exception e) {
130 logger.error("Load " + location + " failure. ", e);
131 }
132 }
133 }
134
135 /**
136 * 获取当前加载的属性文件
137 */
138 public Set<String> getConfigSet() {
139 return configSet;
140 }
141
142 /**
143 * 获取当前加载的属性数据
144 */
145 public Properties getProperties() {
146 return properties;
147 }
148
149 /**
150 * 当前类实例
151 */
152 public static PropertiesUtils getInstance(){
153 return PropertiesLoaderHolder.INSTANCE;
154 }
155
156 /**
157 * 重新加载实例(重新实例化,以重新加载属性文件数据)
158 */
159 public static void releadInstance(){
160 PropertiesLoaderHolder.releadInstance();
161 }
162
163 // 正则表达式预编译
164 private static Pattern p1 = Pattern.compile("\\$\\{.*?\\}");
165
166 /**
167 * 获取属性值,取不到从System.getProperty()获取,都取不到返回null
168 */
169 public String getProperty(String key) {
170 if (environment != null){
171 String value = environment.getProperty(key);
172 if (value != null){
173 return value;
174 }
175 }
176 String value = properties.getProperty(key);
177 if (value != null){
178 Matcher m = p1.matcher(value);
179 while(m.find()) {
180 String g = m.group();
181 String childKey = g.replaceAll("\\$\\{|\\}", "");
182 value = StringUtils.replace(value, g, getProperty(childKey));
183 }
184 return value;
185 }else{
186 String systemProperty = System.getProperty(key);
187 if (systemProperty != null) {
188 return systemProperty;
189 }
190 }
191 return null;
192 }
193
194 /**
195 * 取出String类型的Property,但以System的Property优先,如果都为null则返回defaultValue值
196 */
197 public String getProperty(String key, String defaultValue) {
198 String value = getProperty(key);
199 return value != null ? value : defaultValue;
200 }
201
202 /**
203 * 设置环境属性
204 * @param environment
205 */
206 public static void setEnvironment(Environment environment) {
207 PropertiesUtils.environment = environment;
208 }
209
210 /**
211 * 初始化日志路径
212 */
213 private static Logger initLogger(){
214 String logPath = null;
215 try {
216 // 获取当前classes目录
217 logPath = ResourceUtils.getResource("/").getFile().getPath();
218 } catch (Exception e) {
219 // 取不到,取当前工作路径
220 logPath = System.getProperty("user.dir");
221 }
222 // 取当前日志路径下有classes目录,则使用classes目录
223 String classesLogPath = FileUtils.path(logPath + "/WEB-INF/classes");
224 if (new File(classesLogPath).exists()){
225 logPath = classesLogPath;
226 }
227 if (StringUtils.isBlank(System.getProperty("logPath"))){
228 System.setProperty("logPath", FileUtils.path(logPath));
229 }
230 return LoggerFactory.getLogger(PropertiesUtils.class);
231 }
232
233 }
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.io;
5
6 import java.io.IOException;
7 import java.util.Collections;
8 import java.util.List;
9 import java.util.Properties;
10
11 import org.springframework.boot.env.OriginTrackedMapPropertySource;
12 import org.springframework.core.env.PropertySource;
13 import org.springframework.core.io.Resource;
14
15 /**
16 * 配置文件加载(Boot)
17 * @author ThinkGem
18 * @version 2018-10-16
19 */
20 public class PropertyLoader implements org.springframework.boot.env.PropertySourceLoader{
21
22 private static boolean isLoadPropertySource = false;
23
24 @Override
25 public String[] getFileExtensions() {
26 return new String[] { "properties", "yml" };
27 }
28
29 @Override
30 public List<PropertySource<?>> load(String name, Resource resource) throws IOException {
31 if (!isLoadPropertySource){
32 isLoadPropertySource = true;
33 Properties properties = PropertiesUtils.getInstance().getProperties();
34 return Collections.singletonList(new OriginTrackedMapPropertySource("jeesite", properties));
35 }
36 return Collections.emptyList();
37 }
38
39 }
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.io;
5
6 import java.io.IOException;
7 import java.io.InputStream;
8
9 import org.springframework.core.io.DefaultResourceLoader;
10 import org.springframework.core.io.Resource;
11 import org.springframework.core.io.ResourceLoader;
12 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
13 import org.springframework.core.io.support.ResourcePatternResolver;
14
15 import com.jeesite.common.lang.ExceptionUtils;
16
17 /**
18 * 资源供给类
19 * @author ThinkGem
20 * @version 2016-9-16
21 */
22 public class ResourceUtils extends org.springframework.util.ResourceUtils {
23
24 private static ResourceLoader resourceLoader;
25 private static ResourcePatternResolver resourceResolver;
26 static{
27 resourceLoader = new DefaultResourceLoader();
28 resourceResolver = new PathMatchingResourcePatternResolver(resourceLoader);
29 }
30
31 /**
32 * 获取资源加载器(可读取jar内的文件)
33 * @author ThinkGem
34 */
35 public static ResourceLoader getResourceLoader() {
36 return resourceLoader;
37 }
38
39 /**
40 * 获取ClassLoader
41 */
42 public static ClassLoader getClassLoader() {
43 return resourceLoader.getClassLoader();
44 }
45
46 /**
47 * 获取资源加载器(可读取jar内的文件)
48 */
49 public static Resource getResource(String location) {
50 return resourceLoader.getResource(location);
51 }
52
53 /**
54 * 获取资源文件流(用后记得关闭)
55 * @param location
56 * @author ThinkGem
57 * @throws IOException
58 */
59 public static InputStream getResourceFileStream(String location) throws IOException{
60 Resource resource = resourceLoader.getResource(location);
61 return resource.getInputStream();
62 }
63
64 /**
65 * 获取资源文件内容
66 * @param location
67 * @author ThinkGem
68 */
69 public static String getResourceFileContent(String location){
70 try(InputStream is = ResourceUtils.getResourceFileStream(location)){
71 return IOUtils.toString(is, "UTF-8");
72 }catch (IOException e) {
73 throw ExceptionUtils.unchecked(e);
74 }
75 }
76
77 /**
78 * Spring 搜索资源文件
79 * @param locationPattern
80 * @author ThinkGem
81 */
82 public static Resource[] getResources(String locationPattern){
83 try {
84 Resource[] resources = resourceResolver.getResources(locationPattern);
85 return resources;
86 } catch (IOException e) {
87 throw ExceptionUtils.unchecked(e);
88 }
89 }
90
91 }
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.lang;
5
6 /**
7 * 字节转换工具
8 * @author ThinkGem
9 * @version 2015-6-20
10 */
11 public class ByteUtils {
12
13 private static final int UNIT = 1024;
14
15 /**
16 * @param byteSize 字节
17 * @return
18 */
19 public static String formatByteSize(long byteSize) {
20
21 if (byteSize <= -1){
22 return String.valueOf(byteSize);
23 }
24
25 double size = 1.0 * byteSize;
26
27 String type = "B";
28 if((int)Math.floor(size / UNIT) <= 0) { //不足1KB
29 type = "B";
30 return format(size, type);
31 }
32
33 size = size / UNIT;
34 if((int)Math.floor(size / UNIT) <= 0) { //不足1MB
35 type = "KB";
36 return format(size, type);
37 }
38
39 size = size / UNIT;
40 if((int)Math.floor(size / UNIT) <= 0) { //不足1GB
41 type = "MB";
42 return format(size, type);
43 }
44
45 size = size / UNIT;
46 if((int)Math.floor(size / UNIT) <= 0) { //不足1TB
47 type = "GB";
48 return format(size, type);
49 }
50
51 size = size / UNIT;
52 if((int)Math.floor(size / UNIT) <= 0) { //不足1PB
53 type = "TB";
54 return format(size, type);
55 }
56
57 size = size / UNIT;
58 if((int)Math.floor(size / UNIT) <= 0) {
59 type = "PB";
60 return format(size, type);
61 }
62 return ">PB";
63 }
64
65 private static String format(double size, String type) {
66 int precision = 0;
67
68 if(size * 1000 % 10 > 0) {
69 precision = 3;
70 } else if(size * 100 % 10 > 0) {
71 precision = 2;
72 } else if(size * 10 % 10 > 0) {
73 precision = 1;
74 } else {
75 precision = 0;
76 }
77
78 String formatStr = "%." + precision + "f";
79
80 if("KB".equals(type)) {
81 return String.format(formatStr, (size)) + "KB";
82 } else if("MB".equals(type)) {
83 return String.format(formatStr, (size)) + "MB";
84 } else if("GB".equals(type)) {
85 return String.format(formatStr, (size)) + "GB";
86 } else if("TB".equals(type)) {
87 return String.format(formatStr, (size)) + "TB";
88 } else if("PB".equals(type)) {
89 return String.format(formatStr, (size)) + "PB";
90 }
91 return String.format(formatStr, (size)) + "B";
92 }
93
94 // public static void main(String[] args) {
95 // System.out.println(ByteUtils.formatByteSize(1023));
96 // System.out.println(ByteUtils.formatByteSize(1L * UNIT));
97 // System.out.println(ByteUtils.formatByteSize(1L * UNIT * UNIT));
98 // System.out.println(ByteUtils.formatByteSize(1L * UNIT * 1023));
99 // System.out.println(ByteUtils.formatByteSize(1L * 1023 * 1023 * 1023));
100 // System.out.println(ByteUtils.formatByteSize(1L * UNIT * UNIT * UNIT));
101 // System.out.println(ByteUtils.formatByteSize(1L * UNIT * UNIT * UNIT * UNIT));
102 // System.out.println(ByteUtils.formatByteSize(1L * UNIT * UNIT * UNIT * UNIT * UNIT));
103 // System.out.println(ByteUtils.formatByteSize(1L * UNIT * UNIT * UNIT * UNIT * UNIT * UNIT));
104 // }
105
106 }
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.lang;
5
6 import java.lang.management.ManagementFactory;
7 import java.text.ParseException;
8 import java.util.Calendar;
9 import java.util.Date;
10
11 import org.apache.commons.lang3.StringUtils;
12 import org.apache.commons.lang3.time.FastDateFormat;
13
14 /**
15 * 日期工具类, 继承org.apache.commons.lang.time.DateUtils类
16 * @author ThinkGem
17 * @version 2017-1-4
18 */
19 public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
20
21 private static String[] parsePatterns = {
22 "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM-dd HH", "yyyy-MM",
23 "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM/dd HH", "yyyy/MM",
24 "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM.dd HH", "yyyy.MM",
25 "yyyy年MM月dd日", "yyyy年MM月dd日 HH时mm分ss秒", "yyyy年MM月dd日 HH时mm分", "yyyy年MM月dd日 HH时", "yyyy年MM月",
26 "yyyy"};
27
28 /**
29 * 得到日期字符串 ,转换格式(yyyy-MM-dd)
30 */
31 public static String formatDate(Date date) {
32 return formatDate(date, "yyyy-MM-dd");
33 }
34
35 /**
36 * 得到日期字符串 默认格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E"
37 */
38 public static String formatDate(long dateTime, String pattern) {
39 return formatDate(new Date(dateTime), pattern);
40 }
41
42 /**
43 * 得到日期字符串 默认格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E"
44 */
45 public static String formatDate(Date date, String pattern) {
46 String formatDate = null;
47 if (date != null){
48 // if (StringUtils.isNotBlank(pattern)) {
49 // formatDate = DateFormatUtils.format(date, pattern);
50 // } else {
51 // formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
52 // }
53 if (StringUtils.isBlank(pattern)) {
54 pattern = "yyyy-MM-dd";
55 }
56 formatDate = FastDateFormat.getInstance(pattern).format(date);
57 }
58 return formatDate;
59 }
60
61 /**
62 * 得到日期时间字符串,转换格式(yyyy-MM-dd HH:mm:ss)
63 */
64 public static String formatDateTime(Date date) {
65 return formatDate(date, "yyyy-MM-dd HH:mm:ss");
66 }
67
68 /**
69 * 得到当前日期字符串 格式(yyyy-MM-dd)
70 */
71 public static String getDate() {
72 return getDate("yyyy-MM-dd");
73 }
74
75 /**
76 * 得到当前日期字符串 格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E"
77 */
78 public static String getDate(String pattern) {
79 // return DateFormatUtils.format(new Date(), pattern);
80 return FastDateFormat.getInstance(pattern).format(new Date());
81 }
82
83 /**
84 * 得到当前日期前后多少天,月,年的日期字符串
85 * @param pattern 格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E"
86 * @param amont 数量,前为负数,后为正数
87 * @param type 类型,可参考Calendar的常量(如:Calendar.HOUR、Calendar.MINUTE、Calendar.SECOND)
88 * @return
89 */
90 public static String getDate(String pattern, int amont, int type) {
91 Calendar calendar = Calendar.getInstance();
92 calendar.setTime(new Date());
93 calendar.add(type, amont);
94 // return DateFormatUtils.format(calendar.getTime(), pattern);
95 return FastDateFormat.getInstance(pattern).format(calendar.getTime());
96 }
97
98 /**
99 * 得到当前时间字符串 格式(HH:mm:ss)
100 */
101 public static String getTime() {
102 return formatDate(new Date(), "HH:mm:ss");
103 }
104
105 /**
106 * 得到当前日期和时间字符串 格式(yyyy-MM-dd HH:mm:ss)
107 */
108 public static String getDateTime() {
109 return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
110 }
111
112 /**
113 * 得到当前年份字符串 格式(yyyy)
114 */
115 public static String getYear() {
116 return formatDate(new Date(), "yyyy");
117 }
118
119 /**
120 * 得到当前月份字符串 格式(MM)
121 */
122 public static String getMonth() {
123 return formatDate(new Date(), "MM");
124 }
125
126 /**
127 * 得到当天字符串 格式(dd)
128 */
129 public static String getDay() {
130 return formatDate(new Date(), "dd");
131 }
132
133 /**
134 * 得到当前星期字符串 格式(E)星期几
135 */
136 public static String getWeek() {
137 return formatDate(new Date(), "E");
138 }
139
140 /**
141 * 日期型字符串转化为日期 格式 see to DateUtils#parsePatterns
142 */
143 public static Date parseDate(Object str) {
144 if (str == null){
145 return null;
146 }
147 try {
148 return parseDate(str.toString(), parsePatterns);
149 } catch (ParseException e) {
150 return null;
151 }
152 }
153
154 /**
155 * 获取过去的天数
156 * @param date
157 * @return
158 */
159 public static long pastDays(Date date) {
160 long t = System.currentTimeMillis()-date.getTime();
161 return t/(24*60*60*1000);
162 }
163
164 /**
165 * 获取过去的小时
166 * @param date
167 * @return
168 */
169 public static long pastHour(Date date) {
170 long t = System.currentTimeMillis()-date.getTime();
171 return t/(60*60*1000);
172 }
173
174 /**
175 * 获取过去的分钟
176 * @param date
177 * @return
178 */
179 public static long pastMinutes(Date date) {
180 long t = System.currentTimeMillis()-date.getTime();
181 return t/(60*1000);
182 }
183
184 /**
185 * 获取两个日期之间的天数
186 *
187 * @param before
188 * @param after
189 * @return
190 */
191 public static double getDistanceOfTwoDate(Date before, Date after) {
192 long beforeTime = before.getTime();
193 long afterTime = after.getTime();
194 return (afterTime - beforeTime) / (1000 * 60 * 60 * 24);
195 }
196
197 /**
198 * 获取某月有几天
199 * @param date 日期
200 * @return 天数
201 */
202 public static int getMonthHasDays(Date date){
203 // String yyyyMM = new SimpleDateFormat("yyyyMM").format(date);
204 String yyyyMM = FastDateFormat.getInstance("yyyyMM").format(date);
205 String year = yyyyMM.substring(0, 4);
206 String month = yyyyMM.substring(4, 6);
207 String day31 = ",01,03,05,07,08,10,12,";
208 String day30 = "04,06,09,11";
209 int day = 0;
210 if (day31.contains(month)) {
211 day = 31;
212 } else if (day30.contains(month)) {
213 day = 30;
214 } else {
215 int y = Integer.parseInt(year);
216 if ((y % 4 == 0 && (y % 100 != 0)) || y % 400 == 0) {
217 day = 29;
218 } else {
219 day = 28;
220 }
221 }
222 return day;
223 }
224
225 /**
226 * 获取日期是当年的第几周
227 * @param date
228 * @return
229 */
230 public static int getWeekOfYear(Date date){
231 Calendar cal = Calendar.getInstance();
232 cal.setTime(date);
233 return cal.get(Calendar.WEEK_OF_YEAR);
234 }
235
236 /**
237 * 获取一天的开始时间(如:2015-11-3 00:00:00.000)
238 * @param date 日期
239 * @return
240 */
241 public static Date getOfDayFirst(Date date) {
242 if (date == null){
243 return null;
244 }
245 Calendar calendar = Calendar.getInstance();
246 calendar.setTime(date);
247 calendar.set(Calendar.HOUR_OF_DAY, 0);
248 calendar.set(Calendar.MINUTE, 0);
249 calendar.set(Calendar.SECOND, 0);
250 calendar.set(Calendar.MILLISECOND, 0);
251 return calendar.getTime();
252 }
253
254 /**
255 * 获取一天的最后时间(如:2015-11-3 23:59:59.999)
256 * @param date 日期
257 * @return
258 */
259 public static Date getOfDayLast(Date date) {
260 if (date == null){
261 return null;
262 }
263 Calendar calendar = Calendar.getInstance();
264 calendar.setTime(date);
265 calendar.set(Calendar.HOUR_OF_DAY, 23);
266 calendar.set(Calendar.MINUTE, 59);
267 calendar.set(Calendar.SECOND, 59);
268 calendar.set(Calendar.MILLISECOND, 999);
269 return calendar.getTime();
270 }
271
272 /**
273 * 获取服务器启动时间
274 * @param date
275 * @return
276 */
277 public static Date getServerStartDate(){
278 long time = ManagementFactory.getRuntimeMXBean().getStartTime();
279 return new Date(time);
280 }
281
282 /**
283 * 格式化为日期范围字符串
284 * @param beginDate 2018-01-01
285 * @param endDate 2018-01-31
286 * @return 2018-01-01 ~ 2018-01-31
287 * @author ThinkGem
288 */
289 public static String formatDateBetweenString(Date beginDate, Date endDate){
290 String begin = DateUtils.formatDate(beginDate);
291 String end = DateUtils.formatDate(endDate);
292 if (StringUtils.isNoneBlank(begin, end)){
293 return begin + " ~ " + end;
294 }
295 return null;
296 }
297
298 /**
299 * 解析日期范围字符串为日期对象
300 * @param dateString 2018-01-01 ~ 2018-01-31
301 * @return new Date[]{2018-01-01, 2018-01-31}
302 * @author ThinkGem
303 */
304 public static Date[] parseDateBetweenString(String dateString){
305 Date beginDate = null; Date endDate = null;
306 if (StringUtils.isNotBlank(dateString)){
307 String[] ss = StringUtils.split(dateString, "~");
308 if (ss != null && ss.length == 2){
309 String begin = StringUtils.trim(ss[0]);
310 String end = StringUtils.trim(ss[1]);
311 if (StringUtils.isNoneBlank(begin, end)){
312 beginDate = DateUtils.parseDate(begin);
313 endDate = DateUtils.parseDate(end);
314 }
315 }
316 }
317 return new Date[]{beginDate, endDate};
318 }
319
320 // public static void main(String[] args) throws ParseException {
321 // System.out.println(formatDate(parseDate("2010/3/6")));
322 // System.out.println(getDate("yyyy年MM月dd日 E"));
323 // long time = new Date().getTime()-parseDate("2012-11-19").getTime();
324 // System.out.println(time/(24*60*60*1000));
325 // System.out.println(getWeekOfYear(new Date()));
326 // System.out.println(formatDate(getOfDayFirst(parseDate("2015/3/6")),"yyyy-MM-dd HH:mm:ss.sss"));
327 // System.out.println(formatDate(getOfDayLast(parseDate("2015/6/6")),"yyyy-MM-dd HH:mm:ss.sss"));
328 // }
329
330 }
1 /**
2 * Copyright (c) 2005-2012 springside.org.cn
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 */
6 package com.jeesite.common.lang;
7
8 import java.io.PrintWriter;
9 import java.io.StringWriter;
10
11 import javax.servlet.http.HttpServletRequest;
12
13 /**
14 * 关于异常的工具类.
15 * @author calvin
16 * @version 2014-8-19
17 */
18 public class ExceptionUtils {
19
20 /**
21 * 在request中获取异常类
22 * @param request
23 * @return
24 */
25 public static Throwable getThrowable(HttpServletRequest request){
26 Throwable ex = null;
27 if (request.getAttribute("exception") != null) {
28 ex = (Throwable) request.getAttribute("exception");
29 } else if (request.getAttribute("javax.servlet.error.exception") != null) {
30 ex = (Throwable) request.getAttribute("javax.servlet.error.exception");
31 }
32 return ex;
33 }
34
35 /**
36 * 将ErrorStack转化为String.
37 */
38 public static String getStackTraceAsString(Throwable e) {
39 if (e == null){
40 return "";
41 }
42 StringWriter stringWriter = new StringWriter();
43 e.printStackTrace(new PrintWriter(stringWriter));
44 return stringWriter.toString();
45 }
46
47 /**
48 * 判断异常是否由某些底层的异常引起.
49 */
50 @SuppressWarnings("unchecked")
51 public static boolean isCausedBy(Exception ex, Class<? extends Exception>... causeExceptionClasses) {
52 Throwable cause = ex.getCause();
53 while (cause != null) {
54 for (Class<? extends Exception> causeClass : causeExceptionClasses) {
55 if (causeClass.isInstance(cause)) {
56 return true;
57 }
58 }
59 cause = cause.getCause();
60 }
61 return false;
62 }
63
64 /**
65 * 将CheckedException转换为UncheckedException.
66 */
67 public static RuntimeException unchecked(Exception e) {
68 if (e instanceof RuntimeException) {
69 return (RuntimeException) e;
70 } else {
71 return new RuntimeException(e);
72 }
73 }
74
75 }
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.lang;
5
6 import java.math.BigDecimal;
7 import java.text.DecimalFormat;
8
9 /**
10 * BigDecimal工具类
11 * @author ThinkGem
12 * @version 2016年6月11日
13 */
14 public class NumberUtils extends org.apache.commons.lang3.math.NumberUtils {
15
16 /**
17 * 提供精确的减法运算。
18 * @param v1 被减数
19 * @param v2 减数
20 * @return 两个参数的差
21 */
22 public static double sub(double v1, double v2) {
23 BigDecimal b1 = new BigDecimal(Double.toString(v1));
24 BigDecimal b2 = new BigDecimal(Double.toString(v2));
25 return b1.subtract(b2).doubleValue();
26 }
27
28 /**
29 * 提供精确的加法运算。
30 * @param v1 被加数
31 * @param v2 加数
32 * @return 两个参数的和
33 */
34 public static double add(double v1, double v2) {
35 BigDecimal b1 = new BigDecimal(Double.toString(v1));
36 BigDecimal b2 = new BigDecimal(Double.toString(v2));
37 return b1.add(b2).doubleValue();
38 }
39
40 /**
41 * 提供精确的乘法运算。
42 * @param v1 被乘数
43 * @param v2 乘数
44 * @return 两个参数的积
45 */
46 public static double mul(double v1, double v2) {
47 BigDecimal b1 = new BigDecimal(Double.toString(v1));
48 BigDecimal b2 = new BigDecimal(Double.toString(v2));
49 return b1.multiply(b2).doubleValue();
50 }
51
52 /**
53 * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。
54 * @param v1 被除数
55 * @param v2 除数
56 * @return 两个参数的商
57 */
58 public static double div(double v1, double v2) {
59 return div(v1, v2, 10);
60 }
61
62 /**
63 * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。
64 * @param v1 被除数
65 * @param v2 除数
66 * @param scale 表示表示需要精确到小数点以后几位。
67 * @return 两个参数的商
68 */
69 public static double div(double v1, double v2, int scale) {
70 if (scale < 0) {
71 throw new IllegalArgumentException("The scale must be a positive integer or zero");
72 }
73 BigDecimal b1 = new BigDecimal(Double.toString(v1));
74 BigDecimal b2 = new BigDecimal(Double.toString(v2));
75 return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
76 }
77
78 /**
79 * 格式化双精度,保留两个小数
80 * @return
81 */
82 public static String formatDouble(Double b) {
83 BigDecimal bg = new BigDecimal(b);
84 return bg.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
85 }
86
87 /**
88 * 百分比计算
89 * @return
90 */
91 public static String formatScale(double one, long total) {
92 BigDecimal bg = new BigDecimal(one * 100 / total);
93 return bg.setScale(0, BigDecimal.ROUND_HALF_UP).toString();
94 }
95
96 /**
97 * 格式化数值类型
98 * @param data
99 * @param pattern
100 */
101 public static String formatNumber(Object data, String pattern) {
102 DecimalFormat df = null;
103 if (pattern == null) {
104 df = new DecimalFormat();
105 } else {
106 df = new DecimalFormat(pattern);
107 }
108 return df.format(data);
109 }
110
111 }
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.lang;
5
6 import java.io.ByteArrayInputStream;
7 import java.io.ByteArrayOutputStream;
8 import java.io.ObjectInputStream;
9 import java.io.ObjectOutputStream;
10 import java.lang.reflect.Method;
11
12 import org.apache.commons.lang3.BooleanUtils;
13 import org.apache.commons.lang3.StringUtils;
14 import org.apache.commons.lang3.math.NumberUtils;
15 import org.nustaq.serialization.FSTConfiguration;
16 import org.springframework.beans.BeanUtils;
17 import org.springframework.core.NamedThreadLocal;
18
19 /**
20 * 对象操作工具类, 继承org.apache.commons.lang3.ObjectUtils类
21 * @author ThinkGem
22 * @version 2018-08-11
23 */
24 public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils {
25
26 /**
27 * 转换为Double类型
28 */
29 public static Double toDouble(final Object val) {
30 if (val == null) {
31 return 0D;
32 }
33 try {
34 return NumberUtils.toDouble(StringUtils.trim(val.toString()));
35 } catch (Exception e) {
36 return 0D;
37 }
38 }
39
40 /**
41 * 转换为Float类型
42 */
43 public static Float toFloat(final Object val) {
44 return toDouble(val).floatValue();
45 }
46
47 /**
48 * 转换为Long类型
49 */
50 public static Long toLong(final Object val) {
51 return toDouble(val).longValue();
52 }
53
54 /**
55 * 转换为Integer类型
56 */
57 public static Integer toInteger(final Object val) {
58 return toLong(val).intValue();
59 }
60
61 /**
62 * 转换为Boolean类型 'true', 'on', 'y', 't', 'yes' or '1' (case insensitive) will return true. Otherwise, false is returned.
63 */
64 public static Boolean toBoolean(final Object val) {
65 if (val == null) {
66 return false;
67 }
68 return BooleanUtils.toBoolean(val.toString()) || "1".equals(val.toString());
69 }
70
71 /**
72 * 转换为字符串
73 * @param obj
74 * @return
75 */
76 public static String toString(final Object obj) {
77 return toString(obj, StringUtils.EMPTY);
78 }
79
80 /**
81 * 如果对象为空,则使用defaultVal值
82 * @param obj
83 * @param defaultVal
84 * @return
85 */
86 public static String toString(final Object obj, final String defaultVal) {
87 return obj == null ? defaultVal : obj.toString();
88 }
89
90 /**
91 * 空转空字符串("" to "" ; null to "" ; "null" to "" ; "NULL" to "" ; "Null" to "")
92 * @param val 需转换的值
93 * @return 返回转换后的值
94 */
95 public static String toStringIgnoreNull(final Object val) {
96 return ObjectUtils.toStringIgnoreNull(val, StringUtils.EMPTY);
97 }
98
99 /**
100 * 空对象转空字符串 ("" to defaultVal ; null to defaultVal ; "null" to defaultVal ; "NULL" to defaultVal ; "Null" to defaultVal)
101 * @param val 需转换的值
102 * @param defaultVal 默认值
103 * @return 返回转换后的值
104 */
105 public static String toStringIgnoreNull(final Object val, String defaultVal) {
106 String str = ObjectUtils.toString(val);
107 return !"".equals(str) && !"null".equals(str.trim().toLowerCase()) ? str : defaultVal;
108 }
109
110 /**
111 * 拷贝一个对象(但是子对象无法拷贝)
112 * @param source
113 * @param ignoreProperties
114 */
115 public static Object copyBean(Object source, String... ignoreProperties){
116 if (source == null){
117 return null;
118 }
119 try {
120 Object target = source.getClass().newInstance();
121 BeanUtils.copyProperties(source, target, ignoreProperties);
122 return target;
123 } catch (InstantiationException | IllegalAccessException e) {
124 throw ExceptionUtils.unchecked(e);
125 }
126 }
127
128 /**
129 * 注解到对象复制,只复制能匹配上的方法。 硕正组件用。
130 * @param annotation
131 * @param object
132 */
133 public static void annotationToObject(Object annotation, Object object) {
134 if (annotation != null && object != null) {
135 Class<?> annotationClass = annotation.getClass();
136 Class<?> objectClass = object.getClass();
137 for (Method m : objectClass.getMethods()) {
138 if (StringUtils.startsWith(m.getName(), "set")) {
139 try {
140 String s = StringUtils.uncapitalize(StringUtils.substring(m.getName(), 3));
141 Object obj = annotationClass.getMethod(s).invoke(annotation);
142 if (obj != null && !"".equals(obj.toString())) {
143 // if (object == null){
144 // object = objectClass.newInstance();
145 // }
146 m.invoke(object, obj);
147 }
148 } catch (Exception e) {
149 // 忽略所有设置失败方法
150 }
151 }
152 }
153 }
154 }
155
156 /**
157 * 序列化对象
158 * @param object
159 * @return
160 */
161 public static byte[] serialize(Object object) {
162 if (object == null){
163 return null;
164 }
165 long beginTime = System.currentTimeMillis();
166 byte[] bytes = null;
167 try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
168 ObjectOutputStream oos = new ObjectOutputStream(baos);) {
169 oos.writeObject(object);
170 bytes = baos.toByteArray();
171 } catch (Exception e) {
172 e.printStackTrace();
173 }
174 long totalTime = System.currentTimeMillis() - beginTime;
175 if (totalTime > 3000){
176 System.out.println("Serialize time: " + TimeUtils.formatDateAgo(totalTime));
177 }
178 return bytes;
179 }
180
181 /**
182 * 反序列化对象
183 * @param bytes
184 * @return
185 */
186 public static Object unserialize(byte[] bytes) {
187 if (bytes == null){
188 return null;
189 }
190 long beginTime = System.currentTimeMillis();
191 Object object = null;
192 if (bytes.length > 0) {
193 try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
194 ObjectInputStream ois = new ObjectInputStream(bais);) {
195 object = ois.readObject();
196 } catch (Exception e) {
197 e.printStackTrace();
198 }
199 }
200 long totalTime = System.currentTimeMillis() - beginTime;
201 if (totalTime > 3000){
202 System.out.println("Unserialize time: " + TimeUtils.formatDateAgo(totalTime));
203 }
204 return object;
205 }
206
207 // FST序列化配置对象
208 private static ThreadLocal<FSTConfiguration> fst = new NamedThreadLocal<FSTConfiguration>("FSTConfiguration") {
209 public FSTConfiguration initialValue() {
210 return FSTConfiguration.createDefaultConfiguration();
211 }
212 };
213
214 /**
215 * FST 序列化对象
216 * @param object
217 * @return
218 */
219 public static byte[] serializeFst(Object object) {
220 if (object == null){
221 return null;
222 }
223 long beginTime = System.currentTimeMillis();
224 byte[] bytes = fst.get().asByteArray(object);
225 long totalTime = System.currentTimeMillis() - beginTime;
226 if (totalTime > 3000){
227 System.out.println("Fst serialize time: " + TimeUtils.formatDateAgo(totalTime));
228 }
229 return bytes;
230 }
231
232 /**
233 * FST 反序列化对象
234 * @param bytes
235 * @return
236 */
237 public static Object unserializeFst(byte[] bytes) {
238 if (bytes == null){
239 return null;
240 }
241 long beginTime = System.currentTimeMillis();
242 Object object = fst.get().asObject(bytes);
243 long totalTime = System.currentTimeMillis() - beginTime;
244 if (totalTime > 3000){
245 System.out.println("Fst unserialize time: " + TimeUtils.formatDateAgo(totalTime));
246 }
247 return object;
248 }
249
250 /**
251 * 克隆一个对象(完全拷贝)
252 * @param source
253 */
254 public static Object cloneBean(Object source){
255 if (source == null){
256 return null;
257 }
258 byte[] bytes = ObjectUtils.serializeFst(source);
259 Object target = ObjectUtils.unserializeFst(bytes);
260 return target;
261 }
262
263 }
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.lang;
5
6 import java.util.Date;
7
8 /**
9 * 时间计算工具类
10 * @author ThinkGem
11 * @version 2015-6-20
12 */
13 public class TimeUtils {
14
15 /**
16 * 将毫秒数转换为:xx天,xx时,xx分,xx秒
17 */
18 public static String formatDateAgo(long millisecond) {
19 long ms = millisecond;
20 int ss = 1000;
21 int mi = ss * 60;
22 int hh = mi * 60;
23 int dd = hh * 24;
24 long day = ms / dd;
25 long hour = (ms - day * dd) / hh;
26 long minute = (ms - day * dd - hour * hh) / mi;
27 long second = (ms - day * dd - hour * hh - minute * mi) / ss;
28 StringBuilder sb = new StringBuilder();
29 if (ms < 1000) {
30 sb.append(ms).append("毫秒");
31 } else {
32 if (day > 0) {
33 sb.append(day).append("天");
34 }
35 if (hour > 0) {
36 sb.append(hour).append("时");
37 }
38 if (minute > 0) {
39 sb.append(minute).append("分");
40 }
41 if (second > 0) {
42 sb.append(second).append("秒");
43 }
44 }
45 return sb.toString();
46 }
47
48 /**
49 * 将过去的时间转为为,刚刚,xx秒,xx分钟,xx小时前、xx天前,大于3天的显示日期
50 */
51 public static String formatTimeAgo(String dateTime) {
52 return formatTimeAgo(DateUtils.parseDate(dateTime));
53 }
54
55 /**
56 * 将过去的时间转为为,刚刚,xx秒,xx分钟,xx小时前、xx天前,大于3天的显示日期
57 */
58 public static String formatTimeAgo(Date dateTime) {
59 String interval = null;
60 // 得出的时间间隔是毫秒
61 long time = System.currentTimeMillis() - dateTime.getTime();
62 // 如果时间间隔小于10秒则显示“刚刚”time/10得出的时间间隔的单位是秒
63 if (time / 1000 < 10 && time / 1000 >= 0) {
64 interval = "刚刚";
65 }
66 // 如果时间间隔大于24小时则显示多少天前
67 else if (time / 3600000 < 24 * 4 && time / 3600000 >= 24) {
68 int d = (int) (time / (3600000 * 24));// 得出的时间间隔的单位是天
69 interval = d + "天前";
70 }
71 // 如果时间间隔小于24小时则显示多少小时前
72 else if (time / 3600000 < 24 && time / 3600000 >= 1) {
73 int h = (int) (time / 3600000);// 得出的时间间隔的单位是小时
74 interval = h + "小时前";
75 }
76 // 如果时间间隔小于60分钟则显示多少分钟前
77 else if (time / 60000 < 60 && time / 60000 >= 1) {
78 int m = (int) ((time % 3600000) / 60000);// 得出的时间间隔的单位是分钟
79 interval = m + "分钟前";
80 }
81 // 如果时间间隔小于60秒则显示多少秒前
82 else if (time / 1000 < 60 && time / 1000 >= 10) {
83 int se = (int) ((time % 60000) / 1000);
84 interval = se + "秒前";
85 }
86 // 大于3天的,则显示正常的时间,但是不显示秒
87 else {
88 interval = DateUtils.formatDate(dateTime, "yyyy-MM-dd");
89 }
90 return interval;
91 }
92
93 }
...\ No newline at end of file ...\ No newline at end of file
1 package com.jeesite.common.lang;
2
3 import java.util.Calendar;
4
5 /**
6 * 工作日计算工具类
7 * @author ThinkGem
8 */
9 public class WorkDayUtils {
10
11 /**
12 * 获取日期之间的天数
13 * @param d1
14 * @param d2
15 * @return
16 */
17 public int getDaysBetween(java.util.Calendar d1, java.util.Calendar d2) {
18 if (d1.after(d2)) { // swap dates so that d1 is start and d2 is end
19 java.util.Calendar swap = d1;
20 d1 = d2;
21 d2 = swap;
22 }
23 int days = d2.get(java.util.Calendar.DAY_OF_YEAR)
24 - d1.get(java.util.Calendar.DAY_OF_YEAR);
25 int y2 = d2.get(java.util.Calendar.YEAR);
26 if (d1.get(java.util.Calendar.YEAR) != y2) {
27 d1 = (java.util.Calendar) d1.clone();
28 do {
29 days += d1.getActualMaximum(java.util.Calendar.DAY_OF_YEAR);
30 d1.add(java.util.Calendar.YEAR, 1);
31 } while (d1.get(java.util.Calendar.YEAR) != y2);
32 }
33 return days;
34 }
35
36 /**
37 * 获取工作日
38 * @param d1
39 * @param d2
40 * @return
41 */
42 public int getWorkingDay(java.util.Calendar d1, java.util.Calendar d2) {
43 int result = -1;
44 if (d1.after(d2)) { // swap dates so that d1 is start and d2 is end
45 java.util.Calendar swap = d1;
46 d1 = d2;
47 d2 = swap;
48 }
49 // int betweendays = getDaysBetween(d1, d2);
50 // int charge_date = 0;
51 int charge_start_date = 0;// 开始日期的日期偏移量
52 int charge_end_date = 0;// 结束日期的日期偏移量
53 // 日期不在同一个日期内
54 int stmp;
55 int etmp;
56 stmp = 7 - d1.get(Calendar.DAY_OF_WEEK);
57 etmp = 7 - d2.get(Calendar.DAY_OF_WEEK);
58 if (stmp != 0 && stmp != 6) {// 开始日期为星期六和星期日时偏移量为0
59 charge_start_date = stmp - 1;
60 }
61 if (etmp != 0 && etmp != 6) {// 结束日期为星期六和星期日时偏移量为0
62 charge_end_date = etmp - 1;
63 }
64 // }
65 result = (getDaysBetween(this.getNextMonday(d1), this.getNextMonday(d2)) / 7)
66 * 5 + charge_start_date - charge_end_date;
67 // System.out.println("charge_start_date>" + charge_start_date);
68 // System.out.println("charge_end_date>" + charge_end_date);
69 // System.out.println("between day is-->" + betweendays);
70 return result;
71 }
72
73 /**
74 * 获取中文日期
75 * @param date
76 * @return
77 */
78 public String getChineseWeek(Calendar date) {
79 final String dayNames[] = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
80 int dayOfWeek = date.get(Calendar.DAY_OF_WEEK);
81 // System.out.println(dayNames[dayOfWeek - 1]);
82 return dayNames[dayOfWeek - 1];
83 }
84
85 /**
86 * 获得日期的下一个星期一的日期
87 * @param date
88 * @return
89 */
90 public Calendar getNextMonday(Calendar date) {
91 Calendar result = null;
92 result = date;
93 do {
94 result = (Calendar) result.clone();
95 result.add(Calendar.DATE, 1);
96 } while (result.get(Calendar.DAY_OF_WEEK) != 2);
97 return result;
98 }
99
100 /**
101 * 获取休息日
102 * @param d1
103 * @param d2
104 * @return
105 */
106 public int getHolidays(Calendar d1, Calendar d2) {
107 return this.getDaysBetween(d1, d2) - this.getWorkingDay(d1, d2);
108 }
109
110 // public static void main(String[] args) {
111 // try {
112 // String strDateStart = "2013-08-01";
113 // String strDateEnd = "2014-08-31";
114 //
115 // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
116 // Date date_start = sdf.parse(strDateStart);
117 // Date date_end = sdf.parse(strDateEnd);
118 // WorkDayUtils app = new WorkDayUtils();
119 // Calendar cal_start = Calendar.getInstance();
120 // Calendar cal_end = Calendar.getInstance();
121 // cal_start.setTime(date_start);
122 // cal_end.setTime(date_end);
123 // System.out.println("开始日:" + cal_start.get(Calendar.YEAR) + "-" + (cal_start.get(Calendar.MONTH) + 1)
124 // + "-" + cal_start.get(Calendar.DAY_OF_MONTH) + " " + app.getChineseWeek(cal_start));
125 // System.out.println("结束日:" + cal_end.get(Calendar.YEAR) + "-" + (cal_end.get(Calendar.MONTH) + 1)
126 // + "-" + cal_end.get(Calendar.DAY_OF_MONTH) + " " + app.getChineseWeek(cal_end));
127 // System.out.println("工作日:" + app.getWorkingDay(cal_start, cal_end));
128 // System.out.println("休息日:" + app.getHolidays(cal_start, cal_end));
129 // } catch (Exception e) {
130 // e.printStackTrace();
131 // }
132 // }
133
134 }
1 /**
2 * Copyright (c) 2005-2012 springside.org.cn
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 */
6 package com.jeesite.common.mapper;
7
8 import java.io.StringReader;
9 import java.io.StringWriter;
10 import java.util.Collection;
11 import java.util.concurrent.ConcurrentHashMap;
12 import java.util.concurrent.ConcurrentMap;
13
14 import javax.xml.bind.JAXBContext;
15 import javax.xml.bind.JAXBElement;
16 import javax.xml.bind.JAXBException;
17 import javax.xml.bind.Marshaller;
18 import javax.xml.bind.Unmarshaller;
19 import javax.xml.bind.annotation.XmlAnyElement;
20 import javax.xml.namespace.QName;
21
22 import com.jeesite.common.lang.ExceptionUtils;
23 import com.jeesite.common.lang.StringUtils;
24 import com.jeesite.common.reflect.ReflectUtils;
25
26 /**
27 * 使用Jaxb2.0实现XML<->Java Object的Mapper.
28 *
29 * 在创建时需要设定所有需要序列化的Root对象的Class.
30 * 特别支持Root对象是Collection的情形.
31 *
32 * @author calvin
33 * @version 2013-01-15
34 */
35 @SuppressWarnings("rawtypes")
36 public class JaxbMapper {
37
38 private static ConcurrentMap<Class, JAXBContext> jaxbContexts = new ConcurrentHashMap<Class, JAXBContext>();
39
40 /**
41 * Java Object->Xml without encoding.
42 */
43 public static String toXml(Object root) {
44 Class clazz = ReflectUtils.getUserClass(root);
45 return toXml(root, clazz, null);
46 }
47
48 /**
49 * Java Object->Xml with encoding.
50 */
51 public static String toXml(Object root, String encoding) {
52 Class clazz = ReflectUtils.getUserClass(root);
53 return toXml(root, clazz, encoding);
54 }
55
56 /**
57 * Java Object->Xml with encoding.
58 */
59 public static String toXml(Object root, Class clazz, String encoding) {
60 try {
61 StringWriter writer = new StringWriter();
62 createMarshaller(clazz, encoding).marshal(root, writer);
63 return writer.toString();
64 } catch (JAXBException e) {
65 throw ExceptionUtils.unchecked(e);
66 }
67 }
68
69 /**
70 * Java Collection->Xml without encoding, 特别支持Root Element是Collection的情形.
71 */
72 public static String toXml(Collection<?> root, String rootName, Class clazz) {
73 return toXml(root, rootName, clazz, null);
74 }
75
76 /**
77 * Java Collection->Xml with encoding, 特别支持Root Element是Collection的情形.
78 */
79 public static String toXml(Collection<?> root, String rootName, Class clazz, String encoding) {
80 try {
81 CollectionWrapper wrapper = new CollectionWrapper();
82 wrapper.collection = root;
83
84 JAXBElement<CollectionWrapper> wrapperElement = new JAXBElement<CollectionWrapper>(new QName(rootName),
85 CollectionWrapper.class, wrapper);
86
87 StringWriter writer = new StringWriter();
88 createMarshaller(clazz, encoding).marshal(wrapperElement, writer);
89
90 return writer.toString();
91 } catch (JAXBException e) {
92 throw ExceptionUtils.unchecked(e);
93 }
94 }
95
96 /**
97 * Xml->Java Object.
98 */
99 @SuppressWarnings("unchecked")
100 public static <T> T fromXml(String xml, Class<T> clazz) {
101 try {
102 StringReader reader = new StringReader(xml);
103 return (T) createUnmarshaller(clazz).unmarshal(reader);
104 } catch (JAXBException e) {
105 throw ExceptionUtils.unchecked(e);
106 }
107 }
108
109 /**
110 * 创建Marshaller并设定encoding(可为null).
111 * 线程不安全,需要每次创建或pooling。
112 */
113 public static Marshaller createMarshaller(Class clazz, String encoding) {
114 try {
115 JAXBContext jaxbContext = getJaxbContext(clazz);
116
117 Marshaller marshaller = jaxbContext.createMarshaller();
118
119 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
120
121 if (StringUtils.isNotBlank(encoding)) {
122 marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
123 }
124
125 return marshaller;
126 } catch (JAXBException e) {
127 throw ExceptionUtils.unchecked(e);
128 }
129 }
130
131 /**
132 * 创建UnMarshaller.
133 * 线程不安全,需要每次创建或pooling。
134 */
135 public static Unmarshaller createUnmarshaller(Class clazz) {
136 try {
137 JAXBContext jaxbContext = getJaxbContext(clazz);
138 return jaxbContext.createUnmarshaller();
139 } catch (JAXBException e) {
140 throw ExceptionUtils.unchecked(e);
141 }
142 }
143
144 protected static JAXBContext getJaxbContext(Class clazz) {
145 if (clazz == null){
146 throw new RuntimeException("'clazz' must not be null");
147 }
148 JAXBContext jaxbContext = jaxbContexts.get(clazz);
149 if (jaxbContext == null) {
150 try {
151 jaxbContext = JAXBContext.newInstance(clazz, CollectionWrapper.class);
152 jaxbContexts.putIfAbsent(clazz, jaxbContext);
153 } catch (JAXBException ex) {
154 // throw new HttpMessageConversionException("Could not instantiate JAXBContext for class [" + clazz
155 // + "]: " + ex.getMessage(), ex);
156 throw new RuntimeException("Could not instantiate JAXBContext for class [" + clazz
157 + "]: " + ex.getMessage(), ex);
158 }
159 }
160 return jaxbContext;
161 }
162
163 /**
164 * 封装Root Element 是 Collection的情况.
165 */
166 public static class CollectionWrapper {
167
168 @XmlAnyElement
169 protected Collection<?> collection;
170 }
171
172 }
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.mapper;
5
6 import java.io.IOException;
7 import java.util.List;
8 import java.util.Map;
9 import java.util.TimeZone;
10
11 import org.apache.commons.lang3.StringUtils;
12 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory;
14 import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
15
16 import com.fasterxml.jackson.annotation.JsonInclude.Include;
17 import com.fasterxml.jackson.core.JsonGenerator;
18 import com.fasterxml.jackson.core.JsonParser.Feature;
19 import com.fasterxml.jackson.core.JsonProcessingException;
20 import com.fasterxml.jackson.databind.DeserializationFeature;
21 import com.fasterxml.jackson.databind.JavaType;
22 import com.fasterxml.jackson.databind.JsonSerializer;
23 import com.fasterxml.jackson.databind.ObjectMapper;
24 import com.fasterxml.jackson.databind.SerializationFeature;
25 import com.fasterxml.jackson.databind.SerializerProvider;
26 import com.fasterxml.jackson.databind.util.JSONPObject;
27 import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
28 import com.jeesite.common.collect.ListUtils;
29 import com.jeesite.common.io.PropertiesUtils;
30
31 /**
32 * 简单封装Jackson,实现JSON String<->Java Object的Mapper.
33 * 封装不同的输出风格, 使用不同的builder函数创建实例.
34 * @author ThinkGem
35 * @version 2016-3-2
36 */
37 public class JsonMapper extends ObjectMapper {
38
39 private static final long serialVersionUID = 1L;
40
41 private static Logger logger = LoggerFactory.getLogger(JsonMapper.class);
42
43 /**
44 * 当前类的实例持有者(静态内部类,延迟加载,懒汉式,线程安全的单例模式)
45 */
46 private static final class JsonMapperHolder {
47 private static final JsonMapper INSTANCE = new JsonMapper();
48 }
49
50 public JsonMapper() {
51 // Spring ObjectMapper 初始化配置,支持 @JsonView
52 new Jackson2ObjectMapperBuilder().configure(this);
53 // 为Null时不序列化
54 this.setSerializationInclusion(Include.NON_NULL);
55 // 允许单引号
56 this.configure(Feature.ALLOW_SINGLE_QUOTES, true);
57 // 允许不带引号的字段名称
58 this.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
59 // 设置默认时区
60 this.setTimeZone(TimeZone.getTimeZone(PropertiesUtils.getInstance()
61 .getProperty("lang.defaultTimeZone", "GMT+08:00")));
62 // 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性
63 this.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
64 // 遇到空值处理为空串
65 this.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>(){
66 @Override
67 public void serialize(Object value, JsonGenerator jgen,
68 SerializerProvider provider) throws IOException, JsonProcessingException {
69 jgen.writeString(StringUtils.EMPTY);
70 }
71 });
72 // // 统一默认Date类型转换格式。如果设置,Bean中的@JsonFormat将失效
73 // final String dataFormat = Global.getProperty("json.mapper.dataFormat");
74 // if (StringUtils.isNotBlank(dataFormat)){
75 // this.registerModule(new SimpleModule().addSerializer(Date.class, new JsonSerializer<Date>(){
76 // @Override
77 // public void serialize(Date value, JsonGenerator jgen,
78 // SerializerProvider provider) throws IOException, JsonProcessingException {
79 // if (value != null){
80 // jgen.writeString(DateUtils.formatDate(value, dataFormat));
81 // }
82 // }
83 // }));
84 // }
85 // // 进行HTML解码(先注释掉,否则会造成XSS攻击,比如菜单名称里输入<script>alert(123)</script>转josn后就会还原这个编码 ,并在浏览器中运行)。
86 // this.registerModule(new SimpleModule().addSerializer(String.class, new JsonSerializer<String>(){
87 // @Override
88 // public void serialize(String value, JsonGenerator jgen,
89 // SerializerProvider provider) throws IOException,
90 // JsonProcessingException {
91 // if (value != null){
92 // jgen.writeString(StringEscapeUtils.unescapeHtml4(value));
93 // }
94 // }
95 // }));
96 }
97
98 /**
99 * Object可以是POJO,也可以是Collection或数组。
100 * 如果对象为Null, 返回"null".
101 * 如果集合为空集合, 返回"[]".
102 */
103 public String toJsonString(Object object) {
104 try {
105 return this.writeValueAsString(object);
106 } catch (IOException e) {
107 logger.warn("write to json string error:" + object, e);
108 return null;
109 }
110 }
111
112 /**
113 * 输出JSONP格式数据.
114 */
115 public String toJsonpString(String functionName, Object object) {
116 return toJsonString(new JSONPObject(functionName, object));
117 }
118
119 /**
120 * 反序列化POJO或简单Collection如List<String>.
121 * 如果JSON字符串为Null或"null"字符串, 返回Null.
122 * 如果JSON字符串为"[]", 返回空集合.
123 * 如需反序列化复杂Collection如List<MyBean>, 请使用fromJson(String,JavaType)
124 * @see #fromJson(String, JavaType)
125 */
126 public <T> T fromJsonString(String jsonString, Class<T> clazz) {
127 if (StringUtils.isEmpty(jsonString) || "<CLOB>".equals(jsonString)) {
128 return null;
129 }
130 try {
131 return this.readValue(jsonString, clazz);
132 } catch (IOException e) {
133 logger.warn("parse json string error:" + jsonString, e);
134 return null;
135 }
136 }
137
138 /**
139 * 反序列化复杂Collection如List<Bean>, 先使用函数createCollectionType构造类型,然后调用本函数.
140 * @see #createCollectionType(Class, Class...)
141 */
142 @SuppressWarnings("unchecked")
143 public <T> T fromJsonString(String jsonString, JavaType javaType) {
144 if (StringUtils.isEmpty(jsonString) || "<CLOB>".equals(jsonString)) {
145 return null;
146 }
147 try {
148 return (T) this.readValue(jsonString, javaType);
149 } catch (IOException e) {
150 logger.warn("parse json string error:" + jsonString, e);
151 return null;
152 }
153 }
154
155 /**
156 * 构造泛型的Collection Type如:
157 * ArrayList<MyBean>, 则调用constructCollectionType(ArrayList.class,MyBean.class)
158 * HashMap<String,MyBean>, 则调用(HashMap.class,String.class, MyBean.class)
159 */
160 public JavaType createCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
161 return this.getTypeFactory().constructParametricType(collectionClass, elementClasses);
162 }
163
164 /**
165 * 当JSON里只含有Bean的部分属性時,更新一个已存在Bean,只覆盖该部分的属性.
166 */
167 @SuppressWarnings("unchecked")
168 public <T> T update(String jsonString, T object) {
169 try {
170 return (T) this.readerForUpdating(object).readValue(jsonString);
171 } catch (JsonProcessingException e) {
172 logger.warn("update json string:" + jsonString + " to object:" + object + " error.", e);
173 } catch (IOException e) {
174 logger.warn("update json string:" + jsonString + " to object:" + object + " error.", e);
175 }
176 return null;
177 }
178
179 /**
180 * 设定是否使用Enum的toString函数来读写Enum,
181 * 为False实时使用Enum的name()函数来读写Enum, 默认为False.
182 * 注意本函数一定要在Mapper创建后, 所有的读写动作之前调用.
183 */
184 public JsonMapper enableEnumUseToString() {
185 this.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
186 this.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
187 return this;
188 }
189
190 /**
191 * 支持使用Jaxb的Annotation,使得POJO上的annotation不用与Jackson耦合。
192 * 默认会先查找jaxb的annotation,如果找不到再找jackson的。
193 */
194 public JsonMapper enableJaxbAnnotation() {
195 JaxbAnnotationModule module = new JaxbAnnotationModule();
196 this.registerModule(module);
197 return this;
198 }
199
200 /**
201 * 取出Mapper做进一步的设置或使用其他序列化API.
202 */
203 public ObjectMapper getMapper() {
204 return this;
205 }
206
207 /**
208 * 获取当前实例
209 */
210 public static JsonMapper getInstance() {
211 return JsonMapperHolder.INSTANCE;
212 }
213
214 /**
215 * 对象转换为JSON字符串
216 */
217 public static String toJson(Object object){
218 return JsonMapper.getInstance().toJsonString(object);
219 }
220
221 /**
222 * 对象转换为JSONP字符串
223 */
224 public static String toJsonp(String functionName, Object object){
225 return JsonMapper.getInstance().toJsonpString(functionName, object);
226 }
227
228 /**
229 * JSON字符串转换为对象
230 */
231 @SuppressWarnings("unchecked")
232 public static <T> T fromJson(String jsonString, Class<?> clazz){
233 return (T) JsonMapper.getInstance().fromJsonString(jsonString, clazz);
234 }
235
236 /**
237 * JSON字符串转换为 List<Map<String, Object>>
238 */
239 public static List<Map<String, Object>> fromJsonForMapList(String jsonString){
240 List<Map<String, Object>> result = ListUtils.newArrayList();
241 if (StringUtils.startsWith(jsonString, "{")){
242 Map<String, Object> map = fromJson(jsonString, Map.class);
243 if (map != null){
244 result.add(map);
245 }
246 }else if (StringUtils.startsWith(jsonString, "[")){
247 List<Map<String, Object>> list = fromJson(jsonString, List.class);
248 if (list != null){
249 result = list;
250 }
251 }
252 return result;
253 }
254
255 // public static void main(String[] args) {
256 // List<Map<String, Object>> list = ListUtils.newArrayList();
257 // Map<String, Object> map = MapUtils.newHashMap();
258 // map.put("id", 1);
259 // map.put("pId", -1);
260 // map.put("name", "根节点");
261 // list.add(map);
262 // map = MapUtils.newHashMap();
263 // map.put("id", 2);
264 // map.put("pId", 1);
265 // map.put("name", "你好");
266 // map.put("open", true);
267 // list.add(map);
268 // String json = JsonMapper.toJson(list);
269 // System.out.println(json);
270 // List<Map<String, Object>> map2 = JsonMapper.fromJson(json, List.class);
271 // System.out.println(map2);
272 // Map<String, Object> map3 = JsonMapper.fromJson("{extendS1:{title:'站牌号',"
273 // + "sort:1,type:'text',maxlength:0,maxlength:30},extendS2:{title:'规模分类',"
274 // + "sort:2,type:'dict',dictType:'scope_category'}}", Map.class);
275 // System.out.println(map3);
276 // List<String> list2 = fromJson("[1,2]", List.class);
277 // System.out.println(list2);
278 // }
279
280 }
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.mapper;
5
6 import java.io.IOException;
7 import java.util.ArrayList;
8 import java.util.HashMap;
9 import java.util.LinkedHashMap;
10 import java.util.List;
11 import java.util.Map;
12 import java.util.Set;
13 import java.util.TimeZone;
14
15 import org.apache.commons.lang3.StringUtils;
16 import org.dom4j.Attribute;
17 import org.dom4j.Document;
18 import org.dom4j.DocumentException;
19 import org.dom4j.DocumentHelper;
20 import org.dom4j.Element;
21 import org.dom4j.Namespace;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24 import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
25
26 import com.fasterxml.jackson.databind.JavaType;
27 import com.jeesite.common.io.PropertiesUtils;
28
29 /**
30 * XML <-> Map、Object
31 * @author ThinkGem
32 * @version 2016-9-2
33 */
34 public class XmlMapper extends com.fasterxml.jackson.dataformat.xml.XmlMapper{
35
36 private static final long serialVersionUID = 1L;
37
38 private static Logger logger = LoggerFactory.getLogger(XmlMapper.class);
39
40 /**
41 * 当前类的实例持有者(静态内部类,延迟加载,懒汉式,线程安全的单例模式)
42 */
43 private static final class XmlMapperHolder {
44 private static final XmlMapper INSTANCE = new XmlMapper();
45 }
46
47 /**
48 * 构造方法
49 */
50 public XmlMapper() {
51 // Spring ObjectMapper 初始化配置,支持 @JsonView
52 new Jackson2ObjectMapperBuilder().configure(this);
53 // 设置默认时区
54 this.setTimeZone(TimeZone.getTimeZone(PropertiesUtils.getInstance()
55 .getProperty("lang.defaultTimeZone", "GMT+08:00")));
56 }
57
58 /**
59 * Object可以是POJO,也可以是Collection或数组。
60 */
61 public String toXmlString(Object object) {
62 try {
63 return this.writeValueAsString(object);
64 } catch (IOException e) {
65 logger.warn("write to xml string error:" + object, e);
66 return null;
67 }
68 }
69
70 /**
71 * 反序列化POJO或简单Collection如List<String>.
72 * @see #fromJson(String, JavaType)
73 */
74 public <T> T fromXmlString(String xmlString, Class<T> clazz) {
75 if (StringUtils.isEmpty(xmlString) || "<CLOB>".equals(xmlString)) {
76 return null;
77 }
78 try {
79 return this.readValue(xmlString, clazz);
80 } catch (IOException e) {
81 logger.warn("parse xml string error:" + xmlString, e);
82 return null;
83 }
84 }
85
86 /**
87 * 获取当前实例
88 */
89 public static XmlMapper getInstance() {
90 return XmlMapperHolder.INSTANCE;
91 }
92
93 /**
94 * 对象转换为XML字符串
95 */
96 public static String toXml(Object object){
97 return XmlMapper.getInstance().toXmlString(object);
98 }
99
100 /**
101 * XML字符串转换为对象
102 */
103 @SuppressWarnings("unchecked")
104 public static <T> T fromXml(String jsonString, Class<?> clazz){
105 return (T) XmlMapper.getInstance().fromXmlString(jsonString, clazz);
106 }
107
108 /**
109 * xml转map 不带属性
110 * @param xmlStr
111 * @param needRootKey 是否需要在返回的map里加根节点键
112 * @throws DocumentException
113 */
114 @SuppressWarnings("unchecked")
115 public static Map<String, Object> xmlToMap(String xmlStr, boolean needRootKey) {
116 try {
117 Document doc = DocumentHelper.parseText(xmlStr);
118 Element root = doc.getRootElement();
119 Map<String, Object> map = (Map<String, Object>) xmlToMap(root);
120 if (root.elements().size() == 0 && root.attributes().size() == 0) {
121 return map;
122 }
123 if (needRootKey) {
124 //在返回的map里加根节点键(如果需要)
125 Map<String, Object> rootMap = new HashMap<String, Object>();
126 rootMap.put(root.getName(), map);
127 return rootMap;
128 }
129 return map;
130 } catch (DocumentException e) {
131 e.printStackTrace();
132 }
133 return null;
134 }
135
136 /**
137 * xml转map 带属性
138 * @param xmlStr
139 * @param needRootKey 是否需要在返回的map里加根节点键
140 * @return
141 * @throws DocumentException
142 */
143 @SuppressWarnings("unchecked")
144 public static Map<String, Object> xmlToMapWithAttr(String xmlStr, boolean needRootKey) {
145 try {
146 Document doc = DocumentHelper.parseText(xmlStr);
147 Element root = doc.getRootElement();
148 Map<String, Object> map = (Map<String, Object>) xmlToMapWithAttr(root);
149 if (root.elements().size() == 0 && root.attributes().size() == 0) {
150 return map; //根节点只有一个文本内容
151 }
152 if (needRootKey) {
153 //在返回的map里加根节点键(如果需要)
154 Map<String, Object> rootMap = new HashMap<String, Object>();
155 rootMap.put(root.getName(), map);
156 return rootMap;
157 }
158 return map;
159 } catch (DocumentException e) {
160 e.printStackTrace();
161 }
162 return null;
163 }
164
165 /**
166 * xml转map 不带属性
167 * @param element
168 * @return
169 */
170 @SuppressWarnings("unchecked")
171 private static Object xmlToMap(Element element) {
172 // System.out.println(element.getName());
173 Map<String, Object> map = new LinkedHashMap<String, Object>();
174 List<Element> elements = element.elements();
175 if (elements.size() == 0) {
176 map.put(element.getName(), element.getText());
177 if (!element.isRootElement()) {
178 return element.getText();
179 }
180 } else if (elements.size() == 1) {
181 map.put(elements.get(0).getName(), xmlToMap(elements.get(0)));
182 } else if (elements.size() > 1) {
183 // 多个子节点的话就得考虑list的情况了,比如多个子节点有节点名称相同的
184 // 构造一个map用来去重
185 Map<String, Element> tempMap = new LinkedHashMap<String, Element>();
186 for (Element ele : elements) {
187 tempMap.put(ele.getName(), ele);
188 }
189 Set<String> keySet = tempMap.keySet();
190 for (String string : keySet) {
191 Namespace namespace = tempMap.get(string).getNamespace();
192 List<Element> elements2 = element.elements(new org.dom4j.QName(string, namespace));
193 // 如果同名的数目大于1则表示要构建list
194 if (elements2.size() > 1) {
195 List<Object> list = new ArrayList<Object>();
196 for (Element ele : elements2) {
197 list.add(xmlToMap(ele));
198 }
199 map.put(string, list);
200 } else {
201 // 同名的数量不大于1则直接递归去
202 map.put(string, xmlToMap(elements2.get(0)));
203 }
204 }
205 }
206
207 return map;
208 }
209
210 /**
211 * xml转map 带属性
212 * @param element
213 * @return
214 */
215 @SuppressWarnings("unchecked")
216 private static Object xmlToMapWithAttr(Element element) {
217 // System.out.println(element.getName());
218 Map<String, Object> map = new LinkedHashMap<String, Object>();
219 List<Element> elements = element.elements();
220
221 List<Attribute> listAttr = element.attributes(); // 当前节点的所有属性的list
222 boolean hasAttributes = false;
223 for (Attribute attr : listAttr) {
224 hasAttributes = true;
225 map.put("@" + attr.getName(), attr.getValue());
226 }
227
228 if (elements.size() == 0) {
229 // map.put(element.getName(), element.getText());
230 if (hasAttributes) {
231 map.put("#text", element.getText());
232 } else {
233 map.put(element.getName(), element.getText());
234 }
235
236 if (!element.isRootElement()) {
237 // return element.getText();
238 if (!hasAttributes) {
239 return element.getText();
240 }
241 }
242 } else if (elements.size() == 1) {
243 map.put(elements.get(0).getName(), xmlToMapWithAttr(elements.get(0)));
244 } else if (elements.size() > 1) {
245 // 多个子节点的话就得考虑list的情况了,比如多个子节点有节点名称相同的
246 // 构造一个map用来去重
247 Map<String, Element> tempMap = new LinkedHashMap<String, Element>();
248 for (Element ele : elements) {
249 tempMap.put(ele.getName(), ele);
250 }
251 Set<String> keySet = tempMap.keySet();
252 for (String string : keySet) {
253 Namespace namespace = tempMap.get(string).getNamespace();
254 List<Element> elements2 = element.elements(new org.dom4j.QName(string, namespace));
255 // 如果同名的数目大于1则表示要构建list
256 if (elements2.size() > 1) {
257 List<Object> list = new ArrayList<Object>();
258 for (Element ele : elements2) {
259 list.add(xmlToMapWithAttr(ele));
260 }
261 map.put(string, list);
262 } else {
263 // 同名的数量不大于1则直接递归去
264 map.put(string, xmlToMapWithAttr(elements2.get(0)));
265 }
266 }
267 }
268
269 return map;
270 }
271
272 // public static void main(String[] args) throws Exception {
273 //
274 // File file = new File(FileUtils.getProjectPath()
275 // + "/../modules/core/src/main/resources/spring/spring-context-core.xml");
276 // String xml = FileUtils.readFileToString(file, Charset.defaultCharset());
277 //
278 // System.out.println(xmlToMap(xml, true));
279 // System.out.println(xmlToMapWithAttr(xml, true));
280 //
281 // XmlMapper m = XmlMapper.getInstance();
282 // System.out.println(m.readValue(xml, List.class));
283 // System.out.println(m.readValue(xml, Map.class));
284 //
285 // List<Map<String, Object>> list = ListUtils.newArrayList();
286 // Map<String, Object> map = MapUtils.newHashMap();
287 // map.put("id", 1);
288 // map.put("pId", -1);
289 // map.put("name", "根节点");
290 // list.add(map);
291 // map = MapUtils.newHashMap();
292 // map.put("id", 2);
293 // map.put("pId", 1);
294 // map.put("name", "你好");
295 // map.put("open", true);
296 // list.add(map);
297 //
298 // String s = XmlMapper.getInstance().writeValueAsString(list);
299 // System.out.println(s);
300 //
301 // list = XmlMapper.getInstance().readValue(s, List.class);
302 // System.out.println(list);
303 //
304 // }
305
306 }
1 /**
2 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
3 */
4 package com.jeesite.common.msg;
5
6 import org.apache.commons.mail.HtmlEmail;
7 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory;
9
10 import com.jeesite.common.io.PropertiesUtils;
11
12 /**
13 * 发送电子邮件
14 */
15 public class EmailUtils {
16
17 private final static Logger logger = LoggerFactory.getLogger(EmailUtils.class);
18
19 /**
20 * 发送邮件
21 * @param toAddress 接收地址
22 * @param subject 标题
23 * @param content 内容
24 * @return
25 */
26 public static boolean send(String toAddress, String subject, String content) {
27 PropertiesUtils props = PropertiesUtils.getInstance();
28 String fromAddress = props.getProperty("msg.email.fromAddress");
29 String fromPassword = props.getProperty("msg.email.fromPassword");
30 String fromHostName = props.getProperty("msg.email.fromHostName");
31 String sslOnConnect = props.getProperty("msg.email.sslOnConnect", "false");
32 String sslSmtpPort = props.getProperty("msg.email.sslSmtpPort");
33 return send(fromAddress, fromPassword, fromHostName, sslOnConnect, sslSmtpPort, toAddress, subject, content);
34 }
35
36 /**
37 * 发送邮件
38 * @param toAddress 接收地址
39 * @param subject 标题
40 * @param content 内容
41 * @return
42 */
43 public static boolean send(String fromAddress, String fromPassword, String fromHostName,
44 String sslOnConnect, String sslSmtpPort, String toAddress, String subject, String content) {
45 try {
46 HtmlEmail htmlEmail = new HtmlEmail();
47 // 发送地址
48 htmlEmail.setFrom(fromAddress);
49 // 密码校验
50 htmlEmail.setAuthentication(fromAddress, fromPassword);
51 // 发送服务器协议
52 htmlEmail.setHostName(fromHostName);
53
54 // SSL
55 if ("true".equals(sslOnConnect)) {
56 htmlEmail.setSSLOnConnect(true);
57 htmlEmail.setSslSmtpPort(sslSmtpPort);
58 }
59
60 // 接收地址
61 htmlEmail.addTo(toAddress);
62
63 // 标题
64 htmlEmail.setSubject(subject);
65 // 内容
66 htmlEmail.setMsg(content);
67
68 // 其他信息
69 htmlEmail.setCharset("utf-8");
70
71 // 发送
72 htmlEmail.send();
73 return true;
74 } catch (Exception ex) {
75 logger.error(ex.getMessage(), ex);
76 }
77 return false;
78 }
79
80 }
...\ No newline at end of file ...\ No newline at end of file
1 package com.jeesite.common.msg;
2
3 import org.slf4j.Logger;
4 import org.slf4j.LoggerFactory;
5
6 /**
7 * 发送短信(请实现send方法)
8 */
9 public class SmsUtils {
10
11 private final static Logger logger = LoggerFactory.getLogger(SmsUtils.class);
12
13 /**
14 * 发送短信
15 * @param content 短信内容
16 * @param mobile 接受手机号码
17 */
18 public static String send(String content, String mobile) {
19 // PropertiesUtils props = PropertiesUtils.getInstance();
20 // String url = props.getProperty("msg.sms.url");
21 // String data = props.getProperty("msg.sms.data");
22 // String prefix = props.getProperty("msg.sms.prefix", "");
23 // String suffix = props.getProperty("msg.sms.suffix", "");
24 // Connection conn = Jsoup.connect(url);
25 // conn.postDataCharset("UTF-8");
26 // conn.method(Method.POST);
27 // for (String param : StringUtils.split(data, "&")){
28 // String[] ss = StringUtils.split(param, "=");
29 // if (ss.length == 1){
30 // conn.data(ss[0], "");
31 // }else if (ss.length == 2){
32 // conn.data(ss[0], ss[1]);
33 // }
34 // }
35 // // 手机号码
36 // conn.data("mobile", mobile);
37 // // 短信内容
38 // conn.data("content", prefix + content + suffix);
39 logger.warn("模拟发送短信成功!请实现 "+SmsUtils.class+" 的 send 方法。");
40 return "{result:0,message:\"模拟发送短信成功!\"}";
41 }
42
43 }
1 package com.jeesite.common.network;
2
3 import javax.servlet.http.HttpServletRequest;
4
5 import com.jeesite.common.codec.EncodeUtils;
6 import com.jeesite.common.io.PropertiesUtils;
7 import com.jeesite.common.lang.StringUtils;
8
9 public class IpUtils {
10
11 /**
12 * 获取客户端IP地址
13 * @param request
14 * @return
15 */
16 public static String getRemoteAddr(HttpServletRequest request) {
17 if (request == null) {
18 return "unknown";
19 }
20 String ip = null;
21 String xffName = PropertiesUtils.getInstance()
22 .getProperty("shiro.remoteAddrHeaderName");
23 if (StringUtils.isNotBlank(xffName)){
24 ip = request.getHeader(xffName);
25 }
26 if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
27 ip = request.getRemoteAddr();
28 }
29 if (StringUtils.isNotBlank(ip)){
30 ip = EncodeUtils.xssFilter(ip);
31 ip = StringUtils.split(ip, ",")[0];
32 }
33 if (StringUtils.isBlank(ip)){
34 ip = "unknown";
35 }
36 return ip;
37 }
38
39 /**
40 * 是否是本地地址
41 * @param ip
42 * @return
43 */
44 public static boolean isLocalAddr(String ip){
45 return StringUtils.inString(ip, "127.0.0.1", "0:0:0:0:0:0:0:1");
46 }
47
48 /**
49 * 判断IP地址为内网IP还是公网IP
50 *
51 * tcp/ip协议中,专门保留了三个IP地址区域作为私有地址,其地址范围如下:
52 * 10.0.0.0/8:10.0.0.0~10.255.255.255
53 * 172.16.0.0/12:172.16.0.0~172.31.255.255
54 * 192.168.0.0/16:192.168.0.0~192.168.255.255
55 *
56 * @param ip
57 * @return
58 */
59 public static boolean isInternalAddr(String ip) {
60
61 if (isLocalAddr(ip)){
62 return true;
63 }
64
65 byte[] addr = textToNumericFormatV4(ip);
66
67 final byte b0 = addr[0];
68 final byte b1 = addr[1];
69 //10.x.x.x/8
70 final byte SECTION_1 = 0x0A;
71 //172.16.x.x/12
72 final byte SECTION_2 = (byte) 0xAC;
73 final byte SECTION_3 = (byte) 0x10;
74 final byte SECTION_4 = (byte) 0x1F;
75 //192.168.x.x/16
76 final byte SECTION_5 = (byte) 0xC0;
77 final byte SECTION_6 = (byte) 0xA8;
78 switch (b0) {
79 case SECTION_1:
80 return true;
81 case SECTION_2:
82 if (b1 >= SECTION_3 && b1 <= SECTION_4) {
83 return true;
84 }
85 case SECTION_5:
86 switch (b1) {
87 case SECTION_6:
88 return true;
89 }
90 default:
91 return false;
92 }
93 }
94
95 public static byte[] textToNumericFormatV4(String paramString) {
96 if (paramString.length() == 0) {
97 return null;
98 }
99 byte[] arrayOfByte = new byte[4];
100 String[] arrayOfString = paramString.split("\\.", -1);
101 try {
102 long l;
103 int i;
104 switch (arrayOfString.length) {
105 case 1:
106 l = Long.parseLong(arrayOfString[0]);
107 if ((l < 0L) || (l > 4294967295L)) {
108 return null;
109 }
110 arrayOfByte[0] = ((byte) (int) (l >> 24 & 0xFF));
111 arrayOfByte[1] = ((byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF));
112 arrayOfByte[2] = ((byte) (int) ((l & 0xFFFF) >> 8 & 0xFF));
113 arrayOfByte[3] = ((byte) (int) (l & 0xFF));
114 break;
115 case 2:
116 l = Integer.parseInt(arrayOfString[0]);
117 if ((l < 0L) || (l > 255L)) {
118 return null;
119 }
120 arrayOfByte[0] = ((byte) (int) (l & 0xFF));
121 l = Integer.parseInt(arrayOfString[1]);
122 if ((l < 0L) || (l > 16777215L)) {
123 return null;
124 }
125 arrayOfByte[1] = ((byte) (int) (l >> 16 & 0xFF));
126 arrayOfByte[2] = ((byte) (int) ((l & 0xFFFF) >> 8 & 0xFF));
127 arrayOfByte[3] = ((byte) (int) (l & 0xFF));
128 break;
129 case 3:
130 for (i = 0; i < 2; i++) {
131 l = Integer.parseInt(arrayOfString[i]);
132 if ((l < 0L) || (l > 255L)) {
133 return null;
134 }
135 arrayOfByte[i] = ((byte) (int) (l & 0xFF));
136 }
137 l = Integer.parseInt(arrayOfString[2]);
138 if ((l < 0L) || (l > 65535L)) {
139 return null;
140 }
141 arrayOfByte[2] = ((byte) (int) (l >> 8 & 0xFF));
142 arrayOfByte[3] = ((byte) (int) (l & 0xFF));
143 break;
144 case 4:
145 for (i = 0; i < 4; i++) {
146 l = Integer.parseInt(arrayOfString[i]);
147 if ((l < 0L) || (l > 255L)) {
148 return null;
149 }
150 arrayOfByte[i] = ((byte) (int) (l & 0xFF));
151 }
152 break;
153 default:
154 return null;
155 }
156 } catch (NumberFormatException localNumberFormatException) {
157 return null;
158 }
159 return arrayOfByte;
160 }
161
162 public static byte[] textToNumericFormatV6(String paramString) {
163 if (paramString.length() < 2) {
164 return null;
165 }
166 char[] arrayOfChar = paramString.toCharArray();
167 byte[] arrayOfByte1 = new byte[16];
168
169 int m = arrayOfChar.length;
170 int n = paramString.indexOf("%");
171 if (n == m - 1) {
172 return null;
173 }
174 if (n != -1) {
175 m = n;
176 }
177 int i = -1;
178 int i1 = 0;
179 int i2 = 0;
180 if ((arrayOfChar[i1] == ':') && (arrayOfChar[(++i1)] != ':')) {
181 return null;
182 }
183 int i3 = i1;
184 int j = 0;
185 int k = 0;
186 int i4;
187 while (i1 < m) {
188 char c = arrayOfChar[(i1++)];
189 i4 = Character.digit(c, 16);
190 if (i4 != -1) {
191 k <<= 4;
192 k |= i4;
193 if (k > 65535) {
194 return null;
195 }
196 j = 1;
197 } else if (c == ':') {
198 i3 = i1;
199 if (j == 0) {
200 if (i != -1) {
201 return null;
202 }
203 i = i2;
204 } else {
205 if (i1 == m) {
206 return null;
207 }
208 if (i2 + 2 > 16) {
209 return null;
210 }
211 arrayOfByte1[(i2++)] = ((byte) (k >> 8 & 0xFF));
212 arrayOfByte1[(i2++)] = ((byte) (k & 0xFF));
213 j = 0;
214 k = 0;
215 }
216 } else if ((c == '.') && (i2 + 4 <= 16)) {
217 String str = paramString.substring(i3, m);
218
219 int i5 = 0;
220 int i6 = 0;
221 while ((i6 = str.indexOf('.', i6)) != -1) {
222 i5++;
223 i6++;
224 }
225 if (i5 != 3) {
226 return null;
227 }
228 byte[] arrayOfByte3 = textToNumericFormatV4(str);
229 if (arrayOfByte3 == null) {
230 return null;
231 }
232 for (int i7 = 0; i7 < 4; i7++) {
233 arrayOfByte1[(i2++)] = arrayOfByte3[i7];
234 }
235 j = 0;
236 } else {
237 return null;
238 }
239 }
240 if (j != 0) {
241 if (i2 + 2 > 16) {
242 return null;
243 }
244 arrayOfByte1[(i2++)] = ((byte) (k >> 8 & 0xFF));
245 arrayOfByte1[(i2++)] = ((byte) (k & 0xFF));
246 }
247 if (i != -1) {
248 i4 = i2 - i;
249 if (i2 == 16) {
250 return null;
251 }
252 for (i1 = 1; i1 <= i4; i1++) {
253 arrayOfByte1[(16 - i1)] = arrayOfByte1[(i + i4 - i1)];
254 arrayOfByte1[(i + i4 - i1)] = 0;
255 }
256 i2 = 16;
257 }
258 if (i2 != 16) {
259 return null;
260 }
261 byte[] arrayOfByte2 = convertFromIPv4MappedAddress(arrayOfByte1);
262 if (arrayOfByte2 != null) {
263 return arrayOfByte2;
264 }
265 return arrayOfByte1;
266 }
267
268 public static boolean isIPv4LiteralAddress(String paramString) {
269 return textToNumericFormatV4(paramString) != null;
270 }
271
272 public static boolean isIPv6LiteralAddress(String paramString) {
273 return textToNumericFormatV6(paramString) != null;
274 }
275
276 public static byte[] convertFromIPv4MappedAddress(byte[] paramArrayOfByte) {
277 if (isIPv4MappedAddress(paramArrayOfByte)) {
278 byte[] arrayOfByte = new byte[4];
279 System.arraycopy(paramArrayOfByte, 12, arrayOfByte, 0, 4);
280 return arrayOfByte;
281 }
282 return null;
283 }
284
285 private static boolean isIPv4MappedAddress(byte[] paramArrayOfByte) {
286 if (paramArrayOfByte.length < 16) {
287 return false;
288 }
289 if ((paramArrayOfByte[0] == 0) && (paramArrayOfByte[1] == 0) && (paramArrayOfByte[2] == 0) && (paramArrayOfByte[3] == 0)
290 && (paramArrayOfByte[4] == 0) && (paramArrayOfByte[5] == 0) && (paramArrayOfByte[6] == 0) && (paramArrayOfByte[7] == 0)
291 && (paramArrayOfByte[8] == 0) && (paramArrayOfByte[9] == 0) && (paramArrayOfByte[10] == -1) && (paramArrayOfByte[11] == -1)) {
292 return true;
293 }
294 return false;
295 }
296
297 }
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!