ソースを参照

将SVN的核心代码移交到Git

liukx@elab 6 年 前
コミット
e9e9d08e5d
100 ファイル変更11184 行追加0 行削除
  1. 30 0
      elab-alert/pom.xml
  2. 69 0
      elab-alert/src/main/java/com/elab/alert/model/dingding/LinkModel.java
  3. 80 0
      elab-alert/src/main/java/com/elab/alert/model/dingding/TextModel.java
  4. 29 0
      elab-alert/src/main/java/com/elab/alert/model/mail/MailAuthenticator.java
  5. 73 0
      elab-alert/src/main/java/com/elab/alert/model/mail/MailRequestModel.java
  6. 137 0
      elab-alert/src/main/java/com/elab/alert/model/mail/MailSenderInfo.java
  7. 86 0
      elab-alert/src/main/java/com/elab/alert/utils/DingDingUtils.java
  8. 110 0
      elab-alert/src/main/java/com/elab/alert/utils/EmailUtils.java
  9. 38 0
      elab-annotation/pom.xml
  10. 22 0
      elab-annotation/src/main/java/com/elab/annotation/db/Column.java
  11. 23 0
      elab-annotation/src/main/java/com/elab/annotation/db/datasource/DataSource.java
  12. 203 0
      elab-cache/pom.xml
  13. 205 0
      elab-cache/pom.xml.versionsBackup
  14. 297 0
      elab-cache/src/main/java/com/elab/cache/ICacheClient.java
  15. 60 0
      elab-cache/src/main/java/com/elab/cache/error/CacheErrorProcess.java
  16. 43 0
      elab-cache/src/main/java/com/elab/cache/error/impl/SimpleCacheErrorProcess.java
  17. 49 0
      elab-cache/src/main/java/com/elab/cache/redis/BaseRedis.java
  18. 719 0
      elab-cache/src/main/java/com/elab/cache/redis/BaseRedisOperation.java
  19. 608 0
      elab-cache/src/main/java/com/elab/cache/redis/RedisClusterClient.java
  20. 55 0
      elab-cache/src/main/java/com/elab/cache/redis/RedisSentinelClient.java
  21. 38 0
      elab-cache/src/main/java/com/elab/cache/redis/RedisStandaloneClient.java
  22. 45 0
      elab-cache/src/main/java/com/elab/cache/spring/generator/DefaultCacheKeyGenerator.java
  23. 46 0
      elab-cache/src/main/java/com/elab/cache/spring/handle/ErrorCacheHandle.java
  24. 205 0
      elab-cache/src/main/java/com/elab/cache/spring/manage/SystemCacheManage.java
  25. 38 0
      elab-cache/src/main/java/com/elab/cache/spring/wrapper/CacheValueWrapper.java
  26. 206 0
      elab-cache/src/main/resources/ELAB-CACHE.md
  27. 285 0
      elab-cache/src/test/java/RedisTest.java
  28. 61 0
      elab-cache/src/test/java/model/RedisModel.java
  29. 25 0
      elab-cache/src/test/java/service/IService.java
  30. 81 0
      elab-cache/src/test/java/service/impl/ServiceImpl.java
  31. 41 0
      elab-cache/src/test/java/utils/SerializeUtil.java
  32. 116 0
      elab-cache/src/test/resources/cacheCloud/applicationContext-redis.xml
  33. 8 0
      elab-cache/src/test/resources/cacheCloud/cacheCloudClient.properties
  34. 98 0
      elab-cache/src/test/resources/log4j.properties
  35. 201 0
      elab-core/pom.xml
  36. 335 0
      elab-core/pom.xml.versionsBackup
  37. BIN
      elab-core/readme.docx
  38. 31 0
      elab-core/src/main/java/com/elab/core/CoreConstant.java
  39. 37 0
      elab-core/src/main/java/com/elab/core/aop/annotations/ExceptionHandle.java
  40. 69 0
      elab-core/src/main/java/com/elab/core/bean/BaseInfo.java
  41. 65 0
      elab-core/src/main/java/com/elab/core/bean/Info.java
  42. 25 0
      elab-core/src/main/java/com/elab/core/bean/PageInfo.java
  43. 124 0
      elab-core/src/main/java/com/elab/core/bean/PageModel.java
  44. 45 0
      elab-core/src/main/java/com/elab/core/collections/MapAdapter.java
  45. 22 0
      elab-core/src/main/java/com/elab/core/collections/MapElements.java
  46. 280 0
      elab-core/src/main/java/com/elab/core/collections/NameValueCollection.java
  47. 82 0
      elab-core/src/main/java/com/elab/core/configuration/ConfigEnumeration.java
  48. 42 0
      elab-core/src/main/java/com/elab/core/configuration/ConfigManager.java
  49. 53 0
      elab-core/src/main/java/com/elab/core/configuration/entity/EnumerationMode.java
  50. 31 0
      elab-core/src/main/java/com/elab/core/configuration/entity/EnumerationModes.java
  51. 53 0
      elab-core/src/main/java/com/elab/core/configuration/entity/GlobalConfig.java
  52. 106 0
      elab-core/src/main/java/com/elab/core/configuration/entity/LogConfig.java
  53. 85 0
      elab-core/src/main/java/com/elab/core/configuration/entity/LogManager.java
  54. 41 0
      elab-core/src/main/java/com/elab/core/configuration/entity/SettingConfig.java
  55. 37 0
      elab-core/src/main/java/com/elab/core/configuration/entity/SettingsManager.java
  56. 40 0
      elab-core/src/main/java/com/elab/core/configuration/entity/ValueMode.java
  57. 47 0
      elab-core/src/main/java/com/elab/core/exception/BusinessException.java
  58. 47 0
      elab-core/src/main/java/com/elab/core/exception/CoreException.java
  59. 10 0
      elab-core/src/main/java/com/elab/core/log/ILogAdapter.java
  60. 148 0
      elab-core/src/main/java/com/elab/core/log/LogEntry.java
  61. 12 0
      elab-core/src/main/java/com/elab/core/log/LogLevel.java
  62. 53 0
      elab-core/src/main/java/com/elab/core/log/LogProvider.java
  63. 77 0
      elab-core/src/main/java/com/elab/core/log/adapter/Log4jFileAdapter.java
  64. 17 0
      elab-core/src/main/java/com/elab/core/log/adapter/Log4jMQAdapter.java
  65. 24 0
      elab-core/src/main/java/com/elab/core/log/adapter/Log4jMockAdapter.java
  66. 74 0
      elab-core/src/main/java/com/elab/core/log/adapter/Log4jMongoDBAdapter.java
  67. 65 0
      elab-core/src/main/java/com/elab/core/log/adapter/MongoDbPatternLayout.java
  68. 82 0
      elab-core/src/main/java/com/elab/core/log/adapter/Slf4jAdapter.java
  69. 16 0
      elab-core/src/main/java/com/elab/core/serialization/ISerializer.java
  70. 43 0
      elab-core/src/main/java/com/elab/core/serialization/SerializeBase.java
  71. 40 0
      elab-core/src/main/java/com/elab/core/serialization/SerializeFactory.java
  72. 19 0
      elab-core/src/main/java/com/elab/core/serialization/SerializeType.java
  73. 36 0
      elab-core/src/main/java/com/elab/core/serialization/impl/JsonSerializer.java
  74. 52 0
      elab-core/src/main/java/com/elab/core/serialization/impl/XmlSerializer.java
  75. 162 0
      elab-core/src/main/java/com/elab/core/utils/AESForNodejs.java
  76. 176 0
      elab-core/src/main/java/com/elab/core/utils/AESUtils.java
  77. 116 0
      elab-core/src/main/java/com/elab/core/utils/DESUtils.java
  78. 174 0
      elab-core/src/main/java/com/elab/core/utils/DateCalculate.java
  79. 592 0
      elab-core/src/main/java/com/elab/core/utils/DateUtils.java
  80. 213 0
      elab-core/src/main/java/com/elab/core/utils/DoubleUtils.java
  81. 37 0
      elab-core/src/main/java/com/elab/core/utils/ExceptionUtils.java
  82. 195 0
      elab-core/src/main/java/com/elab/core/utils/FavFTPUtil.java
  83. 179 0
      elab-core/src/main/java/com/elab/core/utils/FileUtils.java
  84. 41 0
      elab-core/src/main/java/com/elab/core/utils/FreeMarkerUtils.java
  85. 60 0
      elab-core/src/main/java/com/elab/core/utils/Ftp.java
  86. 231 0
      elab-core/src/main/java/com/elab/core/utils/FtpUtil.java
  87. 258 0
      elab-core/src/main/java/com/elab/core/utils/LogUtils.java
  88. 302 0
      elab-core/src/main/java/com/elab/core/utils/MD5Utils.java
  89. 147 0
      elab-core/src/main/java/com/elab/core/utils/MapUtils.java
  90. 145 0
      elab-core/src/main/java/com/elab/core/utils/MoneyUtils.java
  91. 319 0
      elab-core/src/main/java/com/elab/core/utils/ObjectUtils.java
  92. 97 0
      elab-core/src/main/java/com/elab/core/utils/RandomUtils.java
  93. 623 0
      elab-core/src/main/java/com/elab/core/utils/StringUtils.java
  94. 82 0
      elab-core/src/main/java/com/elab/core/utils/UnderlineFormatCamel.java
  95. 29 0
      elab-core/src/test/java/com/elab/test/model/User.java
  96. 44 0
      elab-core/src/test/java/com/elab/test/utils/ObjectUtilsCase.java
  97. 1 0
      elab-core/src/test/resources/META-INF/app.properties
  98. 7 0
      elab-core/src/test/resources/META-INF/cat/client.xml
  99. 59 0
      elab-core/src/test/resources/META-INF/cat/config.xsd
  100. 0 0
      elab-core/src/test/resources/dictionary/enumeration.xml

+ 30 - 0
elab-alert/pom.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>elab-parent</artifactId>
+        <groupId>com.elab.core</groupId>
+        <version>2.0.4.10-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>elab-alert</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.elab.core</groupId>
+            <artifactId>elab-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.mail</groupId>
+            <artifactId>mail</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-http</artifactId>
+            <version>4.1.21</version>
+        </dependency>
+    </dependencies>
+
+</project>

+ 69 - 0
elab-alert/src/main/java/com/elab/alert/model/dingding/LinkModel.java

@@ -0,0 +1,69 @@
+package com.elab.alert.model.dingding;
+
+/**
+ * 钉钉链接消息发送对象
+ *
+ * @author : liukx
+ * @create : 2018/11/16 16:50
+ * @email : liukx@elab-plus.com
+ */
+public class LinkModel {
+
+    private String msgtype = "link";
+    private LinkBean link;
+
+    public String getMsgtype() {
+        return msgtype;
+    }
+
+    public void setMsgtype(String msgtype) {
+        this.msgtype = msgtype;
+    }
+
+    public LinkBean getLink() {
+        return link;
+    }
+
+    public void setLink(LinkBean link) {
+        this.link = link;
+    }
+
+    public static class LinkBean {
+        private String text;
+        private String title;
+        private String picUrl;
+        private String messageUrl;
+
+        public String getText() {
+            return text;
+        }
+
+        public void setText(String text) {
+            this.text = text;
+        }
+
+        public String getTitle() {
+            return title;
+        }
+
+        public void setTitle(String title) {
+            this.title = title;
+        }
+
+        public String getPicUrl() {
+            return picUrl;
+        }
+
+        public void setPicUrl(String picUrl) {
+            this.picUrl = picUrl;
+        }
+
+        public String getMessageUrl() {
+            return messageUrl;
+        }
+
+        public void setMessageUrl(String messageUrl) {
+            this.messageUrl = messageUrl;
+        }
+    }
+}

+ 80 - 0
elab-alert/src/main/java/com/elab/alert/model/dingding/TextModel.java

@@ -0,0 +1,80 @@
+package com.elab.alert.model.dingding;
+
+import java.util.List;
+
+/**
+ * 钉钉普通消息发送对象
+ *
+ * @author : liukx
+ * @create : 2018/11/16 16:18
+ * @email : liukx@elab-plus.com
+ */
+public class TextModel {
+
+    private String msgtype = "text";
+    private TextBean text;
+    private AtBean at;
+
+
+    public String getMsgtype() {
+        return msgtype;
+    }
+
+    public void setMsgtype(String msgtype) {
+        this.msgtype = msgtype;
+    }
+
+    public TextBean getText() {
+        return text;
+    }
+
+    public void setText(TextBean text) {
+        this.text = text;
+    }
+
+    public AtBean getAt() {
+        return at;
+    }
+
+    public void setAt(AtBean at) {
+        this.at = at;
+    }
+
+    public static class TextBean {
+        /**
+         * content : 我就是我,  @1825718XXXX 是不一样的烟火
+         */
+
+        private String content;
+
+        public String getContent() {
+            return content;
+        }
+
+        public void setContent(String content) {
+            this.content = content;
+        }
+    }
+
+    public static class AtBean {
+
+        private boolean isAtAll = true;
+        private List<String> atMobiles;
+
+        public boolean isIsAtAll() {
+            return isAtAll;
+        }
+
+        public void setIsAtAll(boolean isAtAll) {
+            this.isAtAll = isAtAll;
+        }
+
+        public List<String> getAtMobiles() {
+            return atMobiles;
+        }
+
+        public void setAtMobiles(List<String> atMobiles) {
+            this.atMobiles = atMobiles;
+        }
+    }
+}

+ 29 - 0
elab-alert/src/main/java/com/elab/alert/model/mail/MailAuthenticator.java

@@ -0,0 +1,29 @@
+package com.elab.alert.model.mail;
+
+
+import javax.mail.PasswordAuthentication;
+
+/**
+ * 邮件的帐号密码存储对象
+ *
+ * @author : liukx
+ * @create : 2018/11/19 10:02
+ * @email : liukx@elab-plus.com
+ */
+public class MailAuthenticator extends javax.mail.Authenticator {
+    String userName = null;
+    String password = null;
+
+    public MailAuthenticator() {
+    }
+
+    public MailAuthenticator(String username, String password) {
+        this.userName = username;
+        this.password = password;
+    }
+
+    @Override
+    protected PasswordAuthentication getPasswordAuthentication() {
+        return new PasswordAuthentication(userName, password);
+    }
+}

+ 73 - 0
elab-alert/src/main/java/com/elab/alert/model/mail/MailRequestModel.java

@@ -0,0 +1,73 @@
+package com.elab.alert.model.mail;
+
+/**
+ * 邮件发送内容
+ *
+ * @author : liukx
+ * @create : 2018/11/16 10:35
+ * @email : liukx@elab-plus.com
+ */
+public class MailRequestModel {
+
+    /**
+     * 邮件类型
+     */
+    private String mailType;
+    /**
+     * 邮件发送人
+     */
+    private String mailAddressee;
+    /**
+     * 邮件发送标题
+     */
+    private String mailTitle;
+    /**
+     * 邮件发送内容
+     */
+    private String mailContent;
+    /**
+     * 附件名称
+     */
+    private String mailEnclosureName;
+
+
+    public String getMailType() {
+        return mailType;
+    }
+
+    public void setMailType(String mailType) {
+        this.mailType = mailType;
+    }
+
+    public String getMailAddressee() {
+        return mailAddressee;
+    }
+
+    public void setMailAddressee(String mailAddressee) {
+        this.mailAddressee = mailAddressee;
+    }
+
+    public String getMailTitle() {
+        return mailTitle;
+    }
+
+    public void setMailTitle(String mailTitle) {
+        this.mailTitle = mailTitle;
+    }
+
+    public String getMailContent() {
+        return mailContent;
+    }
+
+    public void setMailContent(String mailContent) {
+        this.mailContent = mailContent;
+    }
+
+    public String getMailEnclosureName() {
+        return mailEnclosureName;
+    }
+
+    public void setMailEnclosureName(String mailEnclosureName) {
+        this.mailEnclosureName = mailEnclosureName;
+    }
+}

+ 137 - 0
elab-alert/src/main/java/com/elab/alert/model/mail/MailSenderInfo.java

@@ -0,0 +1,137 @@
+package com.elab.alert.model.mail;
+
+import java.util.Properties;
+
+/**
+ * 发送邮件参数承装对象
+ *
+ * @author : liukx
+ * @create : 2018/11/19 10:00
+ * @email : liukx@elab-plus.com
+ */
+public class MailSenderInfo {
+
+    private String host;     //邮件域名  默认从配置文件里面获取
+    private String port;   //默认邮件端口  默认从配置文件里面获取
+    private String socketFactoryClass = "javax.net.ssl.SSLSocketFactory";
+    private String username;     //发件人邮件帐号  默认从配置文件里面获取
+    private String password;     //发件人邮件密码  默认从配置文件里面获取
+    private String type;    //邮件内容类型   默认从配置文件里面获取text/html
+    private String fromAddress;   //邮件发送人  默认从配置文件里面获取
+
+    private String toAddress;    //邮件接收人
+    private boolean validate = false;
+
+    private String subject;     //邮件主题/标题
+
+    private String content;     //邮件内容
+
+    private String enclosureName;   //邮件附件名称
+
+
+    /**
+     * 获得邮件会话属性
+     *
+     * @return
+     */
+    public Properties getProperties() {
+        Properties p = new Properties();
+        p.put("mail.smtp.localhost", "127.0.0.1");
+        p.put("mail.smtp.host", this.host);
+        p.put("mail.smtp.port", this.port);
+        p.put("mail.smtp.socketFactory.class", this.socketFactoryClass);
+        p.put("mail.smtp.socketFactory.port", this.port);
+        p.put("mail.smtp.auth", validate ? "true" : "false");
+        return p;
+    }
+
+
+    public String getHost() {
+        return host;
+    }
+
+    public void setHost(String host) {
+        this.host = host;
+    }
+
+    public String getPort() {
+        return port;
+    }
+
+    public void setPort(String port) {
+        this.port = port;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getFromAddress() {
+        return fromAddress;
+    }
+
+    public void setFromAddress(String fromAddress) {
+        this.fromAddress = fromAddress;
+    }
+
+    public String getToAddress() {
+        return toAddress;
+    }
+
+    public void setToAddress(String toAddress) {
+        this.toAddress = toAddress;
+    }
+
+    public boolean isValidate() {
+        return validate;
+    }
+
+    public void setValidate(boolean validate) {
+        this.validate = validate;
+    }
+
+    public String getSubject() {
+        return subject;
+    }
+
+    public void setSubject(String subject) {
+        this.subject = subject;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public String getEnclosureName() {
+        return enclosureName;
+    }
+
+    public void setEnclosureName(String enclosureName) {
+        this.enclosureName = enclosureName;
+    }
+
+}

+ 86 - 0
elab-alert/src/main/java/com/elab/alert/utils/DingDingUtils.java

@@ -0,0 +1,86 @@
+package com.elab.alert.utils;
+
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.elab.alert.model.dingding.LinkModel;
+import com.elab.alert.model.dingding.TextModel;
+import com.elab.core.utils.ObjectUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 钉钉消息发送工具类
+ * 参考 : https://www.cnblogs.com/bbling/p/9060308.html
+ *
+ * @author : liukx
+ * @create : 2018/11/16 16:03
+ * @email : liukx@elab-plus.com
+ */
+public class DingDingUtils {
+
+    private static Logger logger = LoggerFactory.getLogger(DingDingUtils.class);
+    private final static String dd = "https://oapi.dingtalk.com/robot/send?access_token=0009e049c04411ff18487db2bb7e5907f719e8c0d9aa35fa722b93bae2d8a931";
+
+    /**
+     * 发送消息到钉钉上
+     *
+     * @param url   钉钉机器人的URL
+     * @param model 消息模型
+     * @return
+     */
+    public static boolean send(String url, TextModel model) {
+        return sendDingDing(url, ObjectUtils.objectParseJsonStr(model));
+    }
+
+    /**
+     * 发送带连接的消息
+     *
+     * @param url   钉钉机器人的URL
+     * @param model 连接消息实体
+     * @return
+     */
+    public static boolean send(String url, LinkModel model) {
+        return sendDingDing(url, ObjectUtils.objectParseJsonStr(model));
+    }
+
+    private static boolean sendDingDing(String url, String data) {
+        String post = HttpUtil.post(url, data, 5000);
+        JSONObject jsonObject = JSON.parseObject(post);
+        String errmsg = jsonObject.getString("errmsg");
+        if ("ok".equals(errmsg)) {
+            return true;
+        } else {
+            System.out.println(" 钉钉调用返回结果 : " + jsonObject.toJSONString());
+            logger.info(" 钉钉调用返回结果 : " + jsonObject.toJSONString());
+        }
+        return false;
+    }
+
+    public static void main(String[] args) {
+        String json = "{\n" +
+                "     \"msgtype\": \"text\",\n" +
+                "     \"text\": {\n" +
+                "         \"content\": \"我就是我,  @1825718XXXX 是不一样的烟火\"\n" +
+                "     },\n" +
+                "     \"at\": {\n" +
+                "         \"atMobiles\": [\n" +
+                "             \"1825718XXXX\"\n" +
+                "         ], \n" +
+                "         \"isAtAll\": false\n" +
+                "     }\n" +
+                " }";
+
+//        String json = "{\"link\":{\"messageUrl\":\"http://106.14.4.198:2281/cat/r/p?domain=elab-marketing-sms\",\"title\":\"[CAT异常告警] [项目: elab-marketing-sms]\",\"text\":\"aaaa\"},\"msgtype\":\"link\"}";
+
+        TextModel textModel = JSON.parseObject(json, TextModel.class);
+//        TextModel textModel = JSON.parseObject(json, TextModel.class);
+//        textModel.getAt().setIsAtAll(true);
+        boolean send = send(dd, textModel);
+        System.out.println(send);
+        if (send) {
+            System.out.println("发送成功 ...");
+        }
+    }
+
+}

+ 110 - 0
elab-alert/src/main/java/com/elab/alert/utils/EmailUtils.java

@@ -0,0 +1,110 @@
+package com.elab.alert.utils;
+
+import com.elab.alert.model.mail.MailAuthenticator;
+import com.elab.alert.model.mail.MailSenderInfo;
+
+import javax.mail.*;
+import javax.mail.internet.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * 发送邮件
+ *
+ * @author : liukx
+ * @create : 2018/11/19 10:41
+ * @email : liukx@elab-plus.com
+ */
+public class EmailUtils {
+
+    /**
+     * 发送邮件
+     *
+     * @param mailInfo
+     * @return
+     */
+    public static boolean send(MailSenderInfo mailInfo) {
+        return send(mailInfo, null);
+    }
+
+
+    /**
+     * 发送邮件
+     *
+     * @param mailInfo 待发送的邮件信息
+     */
+    public static boolean send(MailSenderInfo mailInfo, List<InputStream> fileList) {
+        MailAuthenticator mailAuthenticator = null;
+        Properties pro = mailInfo.getProperties();
+        if (mailInfo.isValidate()) {
+            mailAuthenticator = new MailAuthenticator(mailInfo.getUsername(), mailInfo.getPassword());
+        }
+        Session sendMailSession = Session.getInstance(pro, mailAuthenticator);
+        try {
+            Message mailMessage = new MimeMessage(sendMailSession);
+            Address from = new InternetAddress(mailInfo.getFromAddress());
+            mailMessage.setFrom(from);
+            String to[] = {mailInfo.getToAddress()};
+            String toList = getMailList(to);
+            InternetAddress[] iaToList = InternetAddress.parse(toList);
+            mailMessage.addRecipients(Message.RecipientType.TO, iaToList);
+            mailMessage.setSubject(MimeUtility.encodeText(mailInfo.getSubject(), "UTF-8", "B"));
+            mailMessage.setSentDate(new Date());
+            Multipart mainPart = new MimeMultipart();
+            //添加邮件内容
+            BodyPart html = new MimeBodyPart();
+            html.setContent(mailInfo.getContent(), mailInfo.getType() + "; charset=utf-8");
+            mainPart.addBodyPart(html);
+            mailMessage.setContent(mainPart);
+            //添加附件
+//            if (ObjectUtils.isNotEmpty(fileList)) {
+//                BodyPart enclosurePart = new MimeBodyPart();
+//                ByteArrayDataSource fileDataSource = new ByteArrayDataSource(emailFile);
+//                enclosurePart.setDataHandler(new DataHandler(fileDataSource));
+//                enclosurePart.setFileName(MimeUtility.encodeText(fileDataSource.getName(), "UTF-8", "B"));
+//                mainPart.addBodyPart(enclosurePart);
+//            }
+            Transport.send(mailMessage);
+            return true;
+        } catch (MessagingException ex) {
+            ex.printStackTrace();
+            return false;
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+            return false;
+        } catch (IOException e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 处理发送多人邮件
+     *
+     * @param mailArray
+     * @return
+     */
+    private static String getMailList(String[] mailArray) {
+        StringBuffer toList = new StringBuffer();
+        int length = mailArray.length;
+        if (mailArray != null && length < 2) {
+            toList.append(mailArray[0]);
+        } else {
+            for (int i = 0; i < length; i++) {
+                toList.append(mailArray[i]);
+                if (i != (length - 1)) {
+                    toList.append(",");
+                }
+
+            }
+        }
+        return toList.toString();
+    }
+
+
+}
+

+ 38 - 0
elab-annotation/pom.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>elab-parent</artifactId>
+        <groupId>com.elab.core</groupId>
+        <version>2.0.4.10-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>elab-annotation</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.persistence</groupId>
+            <artifactId>persistence-api</artifactId>
+        </dependency>
+    </dependencies>
+
+    <distributionManagement>
+        <repository>
+            <id>releases</id>
+            <name>Nexus Release Repository</name>
+            <url>http://192.168.0.11:8081/nexus/content/repositories/elab/</url>
+        </repository>
+        <snapshotRepository>
+            <id>snapshots</id>
+            <name>User Project SNAPSHOTS</name>
+            <url>http://192.168.0.11:8081/nexus/content/repositories/snapshots/</url>
+        </snapshotRepository>
+    </distributionManagement>
+
+</project>

+ 22 - 0
elab-annotation/src/main/java/com/elab/annotation/db/Column.java

@@ -0,0 +1,22 @@
+package com.elab.annotation.db;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @Description:数据库对应字段实体注解类
+ * @Author: Liukx on 2017/4/5 - 17:24
+ */
+@Deprecated
+@Target({ElementType.METHOD, ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Column {
+    /**
+     * 数据库对应字段
+     *
+     * @return
+     */
+    String name() default "";
+}

+ 23 - 0
elab-annotation/src/main/java/com/elab/annotation/db/datasource/DataSource.java

@@ -0,0 +1,23 @@
+package com.elab.annotation.db.datasource;
+
+import java.lang.annotation.*;
+
+/**
+ * @author liuhx on 2016/12/8 10:37
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface DataSource {
+    String name() default DataSource.mvp;
+
+    public static String mvp = "default";
+
+    public static String system = "system";
+
+    public static String test = "test";
+
+    public static String onlyRead = "onlyRead";
+}

+ 203 - 0
elab-cache/pom.xml

@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.elab.core</groupId>
+        <artifactId>elab-parent</artifactId>
+        <version>2.0.4.10-SNAPSHOT</version>
+    </parent>
+    <groupId>com.elab.cache</groupId>
+    <artifactId>elab-cache</artifactId>
+
+    <properties>
+        <java-version>1.8</java-version>
+        <profiles.active>skyforest</profiles.active>
+        <elasticsearch>5.3.2</elasticsearch>
+        <cachecloud-open-client-basic>1.0-SNAPSHOT</cachecloud-open-client-basic>
+        <cachecloud-jedis>1.0-SNAPSHOT</cachecloud-jedis>
+        <cachecloud-open-common.version>1.0-SNAPSHOT</cachecloud-open-common.version>
+        <maven.compiler.plugin>3.1</maven.compiler.plugin>
+        <maven.compiler.target>1.7</maven.compiler.target>
+        <maven.war.plugin>2.4</maven.war.plugin>
+        <maven.surefire.plugin>2.16</maven.surefire.plugin>
+        <maven.clean.plugin>2.5</maven.clean.plugin>
+        <maven.deloy.plugin>2.8.1</maven.deloy.plugin>
+        <maven-source-plugin>2.2.1</maven-source-plugin>
+        <maven-resources-plugin>2.6</maven-resources-plugin>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.elab.core</groupId>
+            <artifactId>elab-core</artifactId>
+            <version>${project.version}</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>javax.servlet-api</artifactId>
+                    <groupId>javax.servlet</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <!-- sohu redis -->
+        <dependency>
+            <groupId>com.sohu.tv</groupId>
+            <artifactId>cachecloud-jedis</artifactId>
+            <version>${cachecloud-jedis}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.sohu.tv</groupId>
+            <artifactId>cachecloud-open-client-redis</artifactId>
+            <version>${cachecloud-open-client-basic}</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>jedis</artifactId>
+                    <groupId>redis.clients</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <!--<dependency>-->
+            <!--<groupId>org.apache.logging.log4j</groupId>-->
+            <!--<artifactId>log4j-core</artifactId>-->
+            <!--<version>2.8.2</version>-->
+        <!--</dependency>-->
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+        </dependency>
+        <!--<dependency>-->
+            <!--<groupId>org.springframework.data</groupId>-->
+            <!--<artifactId>spring-data-redis</artifactId>-->
+            <!--<version>2.0.0.RELEASE</version>-->
+        <!--</dependency>-->
+        <!-- 工具 -->
+        <!--<dependency>-->
+            <!--<groupId>com.alibaba</groupId>-->
+            <!--<artifactId>fastjson</artifactId>-->
+        <!--</dependency>-->
+
+        <!--<dependency>-->
+            <!--<groupId>org.apache.commons</groupId>-->
+            <!--<artifactId>commons-lang3</artifactId>-->
+            <!--<version>3.4</version>-->
+        <!--</dependency>-->
+        <!--<dependency>-->
+            <!--<groupId>commons-beanutils</groupId>-->
+            <!--<artifactId>commons-beanutils</artifactId>-->
+            <!--<version>1.9.3</version>-->
+        <!--</dependency>-->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-test</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <version>${maven.compiler.plugin}</version>
+                    <configuration>
+                        <source>${maven.compiler.target}</source>
+                        <target>${maven.compiler.target}</target>
+                    </configuration>
+                </plugin>
+
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-surefire-plugin</artifactId>
+                    <version>${maven.surefire.plugin}</version>
+                    <configuration>
+                        <skipTests>true</skipTests>
+                    </configuration>
+                </plugin>
+
+                <!--<plugin>-->
+                    <!--<artifactId>maven-clean-plugin</artifactId>-->
+                    <!--<version>${maven.clean.plugin}</version>-->
+                    <!--<configuration>-->
+                        <!--<filesets>-->
+                            <!--<fileset>-->
+                                <!--<directory>${basedir}/src/main/webapp/WEB-INF/classes</directory>-->
+                            <!--</fileset>-->
+                            <!--<fileset>-->
+                                <!--<directory>${basedir}/src/main/webapp/WEB-INF/lib</directory>-->
+                            <!--</fileset>-->
+                        <!--</filesets>-->
+                    <!--</configuration>-->
+                <!--</plugin>-->
+
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-deploy-plugin</artifactId>
+                    <version>${maven.deloy.plugin}</version>
+                </plugin>
+
+
+                <!-- 打包javadoc插件 -->
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-javadoc-plugin</artifactId>
+                    <executions>
+                        <execution>
+                            <id>attach-javadocs</id>
+                            <goals>
+                                <goal>jar</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-source-plugin</artifactId>
+                    <version>${maven-source-plugin}</version>
+                    <configuration>
+                        <attach>true</attach>
+                    </configuration>
+                    <executions>
+                        <execution>
+                            <phase>compile</phase>
+                            <goals>
+                                <goal>jar</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                </plugin>
+
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-resources-plugin</artifactId>
+                    <version>${maven-resources-plugin}</version>
+                    <configuration>
+                        <encoding>UTF-8</encoding>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+
+    <distributionManagement>
+        <repository>
+            <id>releases</id>
+            <name>Nexus Release Repository</name>
+            <url>http://192.168.0.11:8081/nexus/content/repositories/elab/</url>
+        </repository>
+    </distributionManagement>
+</project>

+ 205 - 0
elab-cache/pom.xml.versionsBackup

@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.elab.core</groupId>
+        <artifactId>elab-parent</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+    <groupId>com.elab.cache</groupId>
+    <artifactId>elab-cache</artifactId>
+    <version>1.4</version>
+
+    <properties>
+        <java-version>1.8</java-version>
+        <profiles.active>skyforest</profiles.active>
+        <springframework.version>4.3.7.RELEASE</springframework.version>
+        <elasticsearch>5.3.2</elasticsearch>
+        <cachecloud-open-client-basic>1.0</cachecloud-open-client-basic>
+        <cachecloud-jedis>1.0</cachecloud-jedis>
+        <cachecloud-open-common.version>1.0</cachecloud-open-common.version>
+        <maven.compiler.plugin>3.1</maven.compiler.plugin>
+        <maven.compiler.target>1.7</maven.compiler.target>
+        <maven.war.plugin>2.4</maven.war.plugin>
+        <maven.surefire.plugin>2.16</maven.surefire.plugin>
+        <maven.clean.plugin>2.5</maven.clean.plugin>
+        <maven.deloy.plugin>2.8.1</maven.deloy.plugin>
+        <maven-source-plugin>2.2.1</maven-source-plugin>
+        <maven-resources-plugin>2.6</maven-resources-plugin>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.elab.core</groupId>
+            <artifactId>elab-core</artifactId>
+            <version>1.1.0</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>javax.servlet-api</artifactId>
+                    <groupId>javax.servlet</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <!-- sohu redis -->
+        <dependency>
+            <groupId>com.sohu.tv</groupId>
+            <artifactId>cachecloud-jedis</artifactId>
+            <version>${cachecloud-jedis}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.sohu.tv</groupId>
+            <artifactId>cachecloud-open-client-redis</artifactId>
+            <version>${cachecloud-open-client-basic}</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>jedis</artifactId>
+                    <groupId>redis.clients</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-core</artifactId>
+            <version>2.8.2</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-core</artifactId>
+            <version>${springframework.version}</version>
+        </dependency>
+        <!--<dependency>-->
+            <!--<groupId>org.springframework.data</groupId>-->
+            <!--<artifactId>spring-data-redis</artifactId>-->
+            <!--<version>2.0.0.RELEASE</version>-->
+        <!--</dependency>-->
+        <!-- 工具 -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.16</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>3.4</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-beanutils</groupId>
+            <artifactId>commons-beanutils</artifactId>
+            <version>1.9.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-test</artifactId>
+            <version>${springframework.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <version>${maven.compiler.plugin}</version>
+                    <configuration>
+                        <source>${maven.compiler.target}</source>
+                        <target>${maven.compiler.target}</target>
+                    </configuration>
+                </plugin>
+
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-surefire-plugin</artifactId>
+                    <version>${maven.surefire.plugin}</version>
+                    <configuration>
+                        <skipTests>true</skipTests>
+                    </configuration>
+                </plugin>
+
+                <!--<plugin>-->
+                    <!--<artifactId>maven-clean-plugin</artifactId>-->
+                    <!--<version>${maven.clean.plugin}</version>-->
+                    <!--<configuration>-->
+                        <!--<filesets>-->
+                            <!--<fileset>-->
+                                <!--<directory>${basedir}/src/main/webapp/WEB-INF/classes</directory>-->
+                            <!--</fileset>-->
+                            <!--<fileset>-->
+                                <!--<directory>${basedir}/src/main/webapp/WEB-INF/lib</directory>-->
+                            <!--</fileset>-->
+                        <!--</filesets>-->
+                    <!--</configuration>-->
+                <!--</plugin>-->
+
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-deploy-plugin</artifactId>
+                    <version>${maven.deloy.plugin}</version>
+                </plugin>
+
+
+                <!-- 打包javadoc插件 -->
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-javadoc-plugin</artifactId>
+                    <executions>
+                        <execution>
+                            <id>attach-javadocs</id>
+                            <goals>
+                                <goal>jar</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-source-plugin</artifactId>
+                    <version>${maven-source-plugin}</version>
+                    <configuration>
+                        <attach>true</attach>
+                    </configuration>
+                    <executions>
+                        <execution>
+                            <phase>compile</phase>
+                            <goals>
+                                <goal>jar</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                </plugin>
+
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-resources-plugin</artifactId>
+                    <version>${maven-resources-plugin}</version>
+                    <configuration>
+                        <encoding>UTF-8</encoding>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+
+    <distributionManagement>
+        <repository>
+            <id>releases</id>
+            <name>Nexus Release Repository</name>
+            <url>http://192.168.0.11:8081/nexus/content/repositories/elab/</url>
+        </repository>
+    </distributionManagement>
+</project>

+ 297 - 0
elab-cache/src/main/java/com/elab/cache/ICacheClient.java

@@ -0,0 +1,297 @@
+package com.elab.cache;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 缓存接口定义
+ *
+ * @author Liukx
+ * @create 2017-05-17 15:40
+ * @email liukx@elab-plus.com
+ **/
+public interface ICacheClient {
+
+    /**
+     * 将一个数组key进行原子性相减
+     *
+     * @param key 键
+     * @param num 减去的值
+     * @return
+     */
+    Long decrby(String key, long num);
+
+    /**
+     * 将一个原子性的数值即你想那个累加
+     *
+     * @param key 键
+     * @param num 累加的值
+     * @return
+     */
+    Long incrby(String key, long num);
+
+    /**
+     * 判断key是否存在
+     *
+     * @param key
+     * @return
+     */
+    boolean exsit(String key);
+
+    /**
+     * 设置一个键的有效时长
+     *
+     * @param key     键
+     * @param seconds 有效时长 单位:秒
+     */
+    boolean expire(String key, int seconds);
+
+    /**
+     * 获取一个key的有效时长
+     *
+     * @param key
+     * @return
+     */
+    Long ttl(String key);
+
+    /**
+     * 添加一个普通值
+     *
+     * @param key   键
+     * @param value 值
+     */
+    <T> void set(String key, T value);
+
+    /**
+     * 添加一个list的值
+     *
+     * @param key  键
+     * @param list 值
+     */
+    <T> void setList(String key, List<T> list);
+
+    /**
+     * 添加一个map的值
+     *
+     * @param key
+     * @param map
+     * @param <T>
+     */
+    <T> void setMap(String key, Map<String, T> map);
+
+    /**
+     * 添加一个值,并为它设置一个有效时间
+     *
+     * @param key       键
+     * @param value     值
+     * @param validTime 有效时间  1秒=1000   -1 永久有效
+     */
+    void set(String key, Object value, int validTime);
+
+    /**
+     * 根据键获取值
+     *
+     * @param key 键 - 标识
+     * @return
+     */
+    <T> T get(String key, Class t);
+
+    /**
+     * 获取list结果集
+     *
+     * @param key
+     * @param <T>
+     * @return
+     */
+    <T> List<T> getList(String key, Class clazz);
+
+    /**
+     * 获取map结果集
+     *
+     * @param key
+     * @param <T>
+     * @return
+     */
+    <T> Map<String, T> getMap(String key, Class clazz);
+
+    /**
+     * 设置一个值到集合中,如果存在则返回key存在 则返回false
+     *
+     * @param key   键
+     * @param value 值
+     * @return
+     */
+    boolean setNX(String key, Object value);
+
+    /**
+     * 根据键删除一个值
+     *
+     * @param key 键
+     */
+    void delete(String key);
+
+    /**
+     * 带锁的数据操作,例如当设置一个setnx发现键已经存在,则超时时间的范围内阻塞尝试,直到锁被释放,如果过了超时时间则表示失败
+     *
+     * @param key     key
+     * @param value   值
+     * @param timeout 超时时间 单位秒
+     * @return
+     */
+    boolean tryLock(String key, Object value, int timeout);
+
+    /**
+     * 删除带锁的数据
+     *
+     * @param key 带锁的key
+     */
+    void unLock(String key);
+
+    /**
+     * <p>通过key 和offset 从指定的位置开始将原先value替换</p>
+     * <p>下标从0开始,offset表示从offset下标开始替换</p>
+     * <p>如果替换的字符串长度过小则会这样</p>
+     * <p>example:</p>
+     * <p>value : bigsea@zto.cn</p>
+     * <p>str : abc </p>
+     * <P>从下标7开始替换  则结果为</p>
+     * <p>RES : bigsea.abc.cn</p>
+     *
+     * @param key
+     * @param value
+     * @param offset 下标位置
+     * @return 返回替换后  value 的长度
+     */
+    Long setRange(String key, String value, int offset);
+
+    /**
+     * <p>通过下标 和key 获取指定下标位置的 value</p>
+     *
+     * @param key
+     * @param startOffset 开始位置 从0 开始 负数表示从右边开始截取
+     * @param endOffset
+     * @return 如果没有返回null
+     */
+    String getRange(String key, int startOffset, int endOffset);
+
+    /**
+     * <p>通过批量的key获取批量的value</p>
+     *
+     * @param keys string数组 也可以是一个key
+     * @return 成功返回value的集合, 失败返回null的集合 ,异常返回空
+     */
+    List<String> mget(String... keys);
+
+    /**
+     * <p>批量的设置key:value,可以一个</p>
+     * <p>example:</p>
+     * <p>  obj.mset(new String[]{"key2","value1","key2","value2"})</p>
+     *
+     * @param keysvalues
+     * @return 成功返回OK 失败 异常 返回 null
+     */
+    String mset(String... keysvalues);
+
+
+    /**
+     * <p>批量的设置key:value,可以一个,如果key已经存在则会失败,操作会回滚</p>
+     * <p>example:</p>
+     * <p>  obj.msetnx(new String[]{"key2","value1","key2","value2"})</p>
+     *
+     * @param keysvalues
+     * @return 成功返回1 失败返回0
+     */
+    Long msetnx(String... keysvalues);
+
+    /**
+     * <p>通过key给Hash Field设置指定的值,如果key不存在,则先创建</p>
+     *
+     * @param key
+     * @param field 字段
+     * @param value
+     * @return 如果存在返回0 异常返回null
+     */
+    Long hset(String key, String field, String value);
+
+    /**
+     * <p>Sets field in the hash stored at key to value
+     * 通过key给field设置指定的值,如果key不存在则先创建,如果field已经存在,返回0</p>
+     *
+     * @param key
+     * @param field
+     * @param value
+     * @return
+     */
+    public Long hsetnx(String key, String field, String value);
+
+    /**
+     * <p>通过key同时设置 hash的多个field</p>
+     *
+     * @param key
+     * @param hash
+     * @return 返回OK 异常返回null
+     */
+    public String hmset(String key, Map<String, String> hash);
+
+    /**
+     * <p>通过key 和 field 获取指定的 value</p>
+     *
+     * @param key
+     * @param field
+     * @return 没有返回null
+     */
+    public String hget(String key, String field);
+
+    /**
+     * <p>通过key 和 fields 获取指定的value 如果没有对应的value则返回null</p>
+     *
+     * @param key
+     * @param fields 可以是 一个String 也可以是 String数组
+     * @return
+     */
+    public List<String> hmget(String key, String... fields);
+
+    /**
+     * <p>通过key向list头部添加字符串</p>
+     *
+     * @param key
+     * @param strs 可以是一个string 也可以是string数组
+     * @return 返回list的value个数
+     */
+    Long lpush(String key, String... strs);
+
+    /**
+     * 获取指定list
+     *
+     * @param key        键
+     * @param startIndex 开始下标
+     * @param endIndex   结束下标  -1 代表获取所有
+     * @return
+     */
+    List<String> lrange(String key, int startIndex, int endIndex);
+
+    /**
+     * 获取所有list
+     *
+     * @param key 键
+     * @return
+     */
+    List<String> lrange(String key);
+
+    /**
+     * 根据key获取缓存中的数据
+     *
+     * @param key 缓存的key
+     * @return
+     */
+    String get(String key);
+
+    /**
+     * 根据key的前缀获取
+     *
+     * @param prefixKey
+     * @return
+     */
+    Set<String> keys(String prefixKey);
+}

+ 60 - 0
elab-cache/src/main/java/com/elab/cache/error/CacheErrorProcess.java

@@ -0,0 +1,60 @@
+package com.elab.cache.error;
+
+
+import com.elab.cache.ICacheClient;
+
+
+/**
+ * @Description: 当缓存发生故障时, 需要处理的类
+ * @Author: Liukx on 2017/11/9 - 16:14
+ */
+public interface CacheErrorProcess {
+
+    /**
+     * 当调用获取缓存数据的操作发送故障时
+     *
+     * @param exception 异常信息
+     * @param cache     缓存信息
+     * @param key       key
+     */
+    void handleCacheGetError(RuntimeException exception, ICacheClient cache, Object key);
+
+    /**
+     * 当调用更新缓存发生异常的处理方法
+     *
+     * @param exception 异常信息
+     * @param cache     缓存信息
+     * @param key       指定的key
+     * @param value     具体的值
+     */
+    void handleCachePutError(RuntimeException exception, ICacheClient cache, Object key, Object value);
+
+    /**
+     * 当调用更新缓存发生异常的处理方法
+     *
+     * @param exception 异常信息
+     * @param cache     缓存信息
+     * @param key       指定的key
+     * @param filed     指定的字段
+     * @param value     指定的值
+     */
+    void handleCachePutError(RuntimeException exception, ICacheClient cache, Object key, Object filed, Object value);
+
+    /**
+     * 当删除缓存异常时,处理方法
+     *
+     * @param exception 异常信息
+     * @param cache     缓存对象信息
+     * @param key       指定的key
+     */
+    void handleCacheEvictError(RuntimeException exception, ICacheClient cache, Object key);
+
+    /**
+     * 当清空缓存出现异常时,处理方法
+     *
+     * @param exception 异常信息
+     * @param cache     缓存信息
+     */
+    void handleCacheClearError(RuntimeException exception, ICacheClient cache);
+
+}

+ 43 - 0
elab-cache/src/main/java/com/elab/cache/error/impl/SimpleCacheErrorProcess.java

@@ -0,0 +1,43 @@
+package com.elab.cache.error.impl;
+
+import com.elab.cache.ICacheClient;
+import com.elab.cache.error.CacheErrorProcess;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 简单的日志记录异常缓存处理结果
+ *
+ * @author Liukx
+ * @create 2017-11-09 17:18
+ * @email liukx@elab-plus.com
+ **/
+public class SimpleCacheErrorProcess implements CacheErrorProcess {
+
+    Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Override
+    public void handleCacheGetError(RuntimeException exception, ICacheClient cache, Object key) {
+        logger.error("==============handleCacheGetError==================== [key]" + key, exception);
+    }
+
+    @Override
+    public void handleCachePutError(RuntimeException exception, ICacheClient cache, Object key, Object value) {
+        logger.error("==============handleCachePutError==================== [key]" + key + "=======[value]" + value, exception);
+    }
+
+    @Override
+    public void handleCachePutError(RuntimeException exception, ICacheClient cache, Object key, Object filed, Object value) {
+        logger.error("==============handleCachePutError==================== [key]" + key + "=======[value]" + value + "========[filed]========" + filed, exception);
+    }
+
+    @Override
+    public void handleCacheEvictError(RuntimeException exception, ICacheClient cache, Object key) {
+        logger.error("==============handleCacheEvictError====================", exception);
+    }
+
+    @Override
+    public void handleCacheClearError(RuntimeException exception, ICacheClient cache) {
+        logger.error("==============handleCacheClearError====================", exception);
+    }
+}

+ 49 - 0
elab-cache/src/main/java/com/elab/cache/redis/BaseRedis.java

@@ -0,0 +1,49 @@
+package com.elab.cache.redis;
+
+import com.elab.cache.error.CacheErrorProcess;
+import com.elab.cache.error.impl.SimpleCacheErrorProcess;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 通用redis属性
+ *
+ * @author Liukx
+ * @create 2018-03-06 10:04
+ * @email liukx@elab-plus.com
+ **/
+public class BaseRedis {
+
+    protected Logger logger = LoggerFactory.getLogger(getClass());
+
+    // 缓存异常处理类
+    private CacheErrorProcess cacheErrorProcess;
+    /**
+     * 密码填写,没有则不填
+     */
+    protected String password;
+
+    /**
+     * 数据库索引下标
+     */
+    protected int dbIndex = 0;
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public void setDbIndex(int dbIndex) {
+        this.dbIndex = dbIndex;
+    }
+
+    public CacheErrorProcess getCacheErrorProcess() {
+        if (cacheErrorProcess == null) {
+            cacheErrorProcess = new SimpleCacheErrorProcess();
+        }
+        return cacheErrorProcess;
+    }
+
+    public void setCacheErrorProcess(CacheErrorProcess cacheErrorProcess) {
+        this.cacheErrorProcess = cacheErrorProcess;
+    }
+}

+ 719 - 0
elab-cache/src/main/java/com/elab/cache/redis/BaseRedisOperation.java

@@ -0,0 +1,719 @@
+package com.elab.cache.redis;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.TypeReference;
+import com.elab.cache.ICacheClient;
+import com.elab.core.utils.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import redis.clients.jedis.Jedis;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * redis基础服务定义
+ *
+ * @author Liukx
+ * @create 2018-03-05 19:00
+ * @email liukx@elab-plus.com
+ **/
+public abstract class BaseRedisOperation extends BaseRedis {
+
+    public Jedis getJedis() {
+        Jedis jedis = getResource();
+        if (ObjectUtils.isNotEmpty(this.password)) {
+            jedis.auth(this.password);
+        }
+        jedis.select(dbIndex);
+        logger.debug(" 获取redis连接 db  [" + dbIndex + "]");
+        return jedis;
+    }
+
+    /**
+     * 获取当前redis的连接资源
+     *
+     * @return
+     */
+    public abstract Jedis getResource();
+
+    public void close(Jedis jedis) {
+        try {
+            jedis.close();
+        } catch (RuntimeException e) {
+            logger.error("关闭redis异常", e);
+        }
+        logger.debug(" 关闭 redis连接 db  [" + dbIndex + "]");
+    }
+
+    public abstract ICacheClient getCacheClient();
+
+    /**
+     * 将指定的key进行递减
+     *
+     * @param key 键
+     * @param num 减去的值
+     * @return
+     */
+    public Long decrby(String key, long num) {
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            return jedis.decrBy(key, num);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, getCacheClient(), key, num + "");
+        } finally {
+            close(jedis);
+        }
+        return 0L;
+    }
+
+    /**
+     * 将指定的key进行自增
+     *
+     * @param key 键
+     * @param num 累加的值
+     * @return
+     */
+    public Long incrby(String key, long num) {
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            return jedis.incrBy(key, num);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, getCacheClient(), key, num + "");
+        } finally {
+            close(jedis);
+        }
+        return 0L;
+    }
+
+    /**
+     * 根据指定的key获取对象
+     *
+     * @param key   键 - 标识
+     * @param clazz
+     * @param <T>
+     * @return
+     */
+    public <T> T get(String key, Class clazz) {
+        String value = null;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            value = jedis.get(key);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, getCacheClient(), key);
+        } finally {
+            close(jedis);
+        }
+        if (StringUtils.isEmpty(value)) {
+            return null;
+        }
+        T t = (T) JSON.parseObject(value, clazz);
+        return t;
+    }
+
+    /**
+     * 根据缓存的key获取一个集合
+     *
+     * @param key
+     * @param clazz
+     * @param <T>
+     * @return
+     */
+    public <T> List<T> getList(String key, Class clazz) {
+        String value = null;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            value = jedis.get(key);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, getCacheClient(), key);
+        } finally {
+            close(jedis);
+        }
+
+        if (StringUtils.isEmpty(value)) {
+            return null;
+        }
+
+        List<T> tempList = JSON.parseObject(value, new TypeReference<List<T>>() {
+        });
+        List<T> list = JSONArray.parseArray(tempList.toString(), clazz);
+        return list;
+    }
+
+    /**
+     * 根据key获取Map对象
+     *
+     * @param key   缓存的key
+     * @param clazz 需要转换的对象
+     * @param <T>
+     * @return
+     */
+    public <T> Map<String, T> getMap(String key, Class clazz) {
+        String value = null;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            value = jedis.get(key);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, getCacheClient(), key);
+        } finally {
+            close(jedis);
+        }
+        if (StringUtils.isEmpty(value)) {
+            return null;
+        }
+        Map<String, T> map = JSON.parseObject(value, new TypeReference<Map<String, T>>() {
+        });
+        return map;
+    }
+
+    /**
+     * 为指定的key设定有效时长
+     *
+     * @param key     键
+     * @param seconds 有效时长 单位:秒
+     * @return
+     */
+    public boolean expire(String key, int seconds) {
+        Long expire = 0L;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            expire = jedis.expire(key, seconds);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, getCacheClient(), key, seconds);
+        } finally {
+            close(jedis);
+        }
+        if (expire > 0) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 查看当前key 还有多少有效时间
+     *
+     * @param key
+     * @return
+     */
+    public Long ttl(String key) {
+        Long ttl = 0L;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            ttl = jedis.ttl(key);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, getCacheClient(), key);
+        } finally {
+            close(jedis);
+        }
+        return ttl;
+    }
+
+    /**
+     * 如果不存在则添加,存在则返回false
+     *
+     * @param key   键
+     * @param value 值
+     * @return
+     */
+    public boolean setNX(String key, Object value) {
+        Long setex = 0L;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            setex = jedis.setnx(key, value.toString());
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, getCacheClient(), key);
+        } finally {
+            close(jedis);
+        }
+        // 0 表示未设置 1表示已经设置了
+        if (setex > 0) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 删除缓存中的数据
+     *
+     * @param key 键
+     */
+    public void delete(String key) {
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            jedis.del(key);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, getCacheClient(), key);
+        } finally {
+            close(jedis);
+        }
+    }
+
+    /**
+     * 为缓存中的数据加锁,通常用于分布式锁
+     *
+     * @param key     key
+     * @param value   值
+     * @param timeout 超时时间 单位秒
+     * @return
+     */
+    public boolean tryLock(String key, Object value, int timeout) {
+        String lockKey = "locked#" + key;
+        long startTime = System.currentTimeMillis();
+        int sleepTimes = 0;
+
+        while (!setNX(lockKey, value)) {
+            try {
+                Thread.sleep(1);
+                sleepTimes++;
+                if (sleepTimes % 100 == 0) {
+                    //超时判断
+                    if (System.currentTimeMillis() - startTime > timeout * 1000) {
+                        return false;
+                    }
+                }
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public void unLock(String key) {
+        String lockKey = "locked#" + key;
+        delete(lockKey);
+    }
+
+    /**
+     * <p>通过key 和offset 从指定的位置开始将原先value替换</p>
+     * <p>下标从0开始,offset表示从offset下标开始替换</p>
+     * <p>如果替换的字符串长度过小则会这样</p>
+     * <p>example:</p>
+     * <p>value : bigsea@zto.cn</p>
+     * <p>str : abc </p>
+     * <P>从下标7开始替换  则结果为</p>
+     * <p>RES : bigsea.abc.cn</p>
+     *
+     * @param key
+     * @param value
+     * @param offset 下标位置
+     * @return 返回替换后  value 的长度
+     */
+    public Long setRange(String key, String value, int offset) {
+        Long count = 0L;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            count = jedis.setrange(key, offset, value);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, getCacheClient(), key, value);
+        } finally {
+            close(jedis);
+        }
+        return count;
+    }
+
+    /**
+     * <p>通过下标 和key 获取指定下标位置的 value</p>
+     *
+     * @param key
+     * @param startOffset 开始位置 从0 开始 负数表示从右边开始截取
+     * @param endOffset
+     * @return 如果没有返回null
+     */
+    public String getRange(String key, int startOffset, int endOffset) {
+        String data = null;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            data = jedis.getrange(key, startOffset, endOffset);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, getCacheClient(), key);
+        } finally {
+            close(jedis);
+        }
+        return data;
+    }
+
+    /**
+     * <p>通过批量的key获取批量的value</p>
+     *
+     * @param keys string数组 也可以是一个key
+     * @return 成功返回value的集合, 失败返回null的集合 ,异常返回空
+     */
+    public List<String> mget(String... keys) {
+        List<String> list = null;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            list = jedis.mget(keys);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, getCacheClient(), keys);
+        } finally {
+            close(jedis);
+        }
+        return list;
+    }
+
+    /**
+     * <p>批量的设置key:value,可以一个</p>
+     * <p>example:</p>
+     * <p>  obj.mset(new String[]{"key2","value1","key2","value2"})</p>
+     *
+     * @param keysvalues
+     * @return 成功返回OK 失败 异常 返回 null
+     */
+    public String mset(String... keysvalues) {
+        String data = null;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            data = jedis.mset(keysvalues);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, getCacheClient(), keysvalues, keysvalues);
+        } finally {
+            close(jedis);
+        }
+        return data;
+    }
+
+    /**
+     * <p>批量的设置key:value,可以一个,如果key已经存在则会失败,操作会回滚</p>
+     * <p>example:</p>
+     * <p>  obj.msetnx(new String[]{"key2","value1","key2","value2"})</p>
+     *
+     * @param keysvalues
+     * @return 成功返回1 失败返回0
+     */
+    public Long msetnx(String... keysvalues) {
+        Long result = 0L;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            result = jedis.msetnx(keysvalues);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, getCacheClient(), keysvalues, keysvalues);
+        } finally {
+            close(jedis);
+        }
+        return result;
+    }
+
+    /**
+     * <p>通过key给Hash Field设置指定的值,如果key不存在,则先创建</p>
+     *
+     * @param key
+     * @param field 字段
+     * @param value
+     * @return 如果存在返回0 异常返回null
+     */
+    public Long hset(String key, String field, String value) {
+        Long count = null;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            count = jedis.hset(key, field, value);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, getCacheClient(), key, field, value);
+        } finally {
+            close(jedis);
+        }
+        return count;
+    }
+
+    /**
+     * <p>Sets field in the hash stored at key to value
+     * 通过key给field设置指定的值,如果key不存在则先创建,如果field已经存在,返回0</p>
+     *
+     * @param key
+     * @param field
+     * @param value
+     * @return
+     */
+    public Long hsetnx(String key, String field, String value) {
+        Long count = 0L;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            count = jedis.hsetnx(key, field, value);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, getCacheClient(), key, field, value);
+        } finally {
+            close(jedis);
+        }
+        return count;
+    }
+
+    /**
+     * <p>通过key同时设置 hash的多个field</p>
+     *
+     * @param key
+     * @param hash
+     * @return 返回OK 异常返回null
+     */
+    public String hmset(String key, Map<String, String> hash) {
+        String result = null;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            result = jedis.hmset(key, hash);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, getCacheClient(), key, hash);
+        } finally {
+            close(jedis);
+        }
+        return result;
+    }
+
+    /**
+     * <p>通过key 和 field 获取指定的 value</p>
+     *
+     * @param key
+     * @param field
+     * @return 没有返回null
+     */
+    public String hget(String key, String field) {
+        String result = null;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            result = jedis.hget(key, field);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, getCacheClient(), key, field);
+        } finally {
+            close(jedis);
+        }
+        return result;
+    }
+
+    /**
+     * <p>通过key 和 fields 获取指定的value 如果没有对应的value则返回null</p>
+     *
+     * @param key
+     * @param fields 可以使 一个String 也可以是 String数组
+     * @return
+     */
+    public List<String> hmget(String key, String... fields) {
+        List<String> result = null;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            result = jedis.hmget(key, fields);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, getCacheClient(), key, fields);
+        } finally {
+            close(jedis);
+        }
+        return result;
+    }
+
+
+    /**
+     * <p>通过key向list头部添加字符串</p>
+     *
+     * @param key
+     * @param strs 可以是一个string 也可以是string数组
+     * @return 返回list的value个数
+     */
+    public Long lpush(String key, String... strs) {
+        Long result = 0L;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            result = jedis.lpush(key, strs);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, getCacheClient(), key, strs);
+        } finally {
+            close(jedis);
+        }
+        return result;
+    }
+
+    /**
+     * 获取指定list
+     *
+     * @param key        键
+     * @param startIndex 开始下标
+     * @param endIndex   结束下标  -1 代表获取所有
+     * @return
+     */
+    public List<String> lrange(String key, int startIndex, int endIndex) {
+        List<String> list = null;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            list = jedis.lrange(key, startIndex, endIndex);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, getCacheClient(), key, startIndex, endIndex);
+        } finally {
+            close(jedis);
+        }
+        return list;
+    }
+
+
+    /**
+     * 获取所有list
+     *
+     * @param key 键
+     * @return
+     */
+    public List<String> lrange(String key) {
+        List<String> list = null;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            list = jedis.lrange(key, 0, -1);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, getCacheClient(), key);
+        } finally {
+            close(jedis);
+        }
+        return list;
+    }
+
+    /**
+     * 设定数据到缓存中
+     *
+     * @param key  键
+     * @param data
+     * @param <T>
+     */
+    public <T> void set(String key, T data) {
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            jedis.set(key, JSON.toJSONString(data));
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, getCacheClient(), key);
+        } finally {
+            close(jedis);
+        }
+    }
+
+    public <T> void setList(String key, List<T> list) {
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            jedis.set(key, JSON.toJSONString(list));
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, getCacheClient(), key, list);
+        } finally {
+            close(jedis);
+        }
+    }
+
+    /**
+     * 添加一个map的值
+     *
+     * @param key 键
+     * @param map Map集合
+     * @param <T> 泛型任意类型
+     */
+    public <T> void setMap(String key, Map<String, T> map) {
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            jedis.set(key, JSON.toJSONString(map));
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, getCacheClient(), key, map);
+        } finally {
+            close(jedis);
+        }
+    }
+
+    /**
+     * 判断指定的key是否存在
+     *
+     * @param key
+     * @return
+     */
+    public boolean exsit(String key) {
+        boolean flag = false;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            flag = jedis.exists(key);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, getCacheClient(), key);
+        } finally {
+            close(jedis);
+        }
+        return flag;
+    }
+
+    /**
+     * 添加数据到缓存中
+     *
+     * @param key       键
+     * @param value     值
+     * @param validTime 有效时间  1秒=1000   -1 永久有效
+     */
+    public void set(String key, Object value, int validTime) {
+        String data = null;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            data = JSON.toJSONString(value);
+        } catch (Exception e) {
+            data = value.toString();
+        }
+        try {
+            jedis.set(key, data);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, getCacheClient(), key, value);
+        } finally {
+            close(jedis);
+        }
+        expire(key, validTime);
+    }
+
+    /**
+     * 获取缓存中的数据
+     *
+     * @param key 缓存的key
+     * @return
+     */
+    public String get(String key) {
+        String result = null;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            result = jedis.get(key);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, getCacheClient(), key);
+        } finally {
+            close(jedis);
+        }
+        return result;
+    }
+
+    /**
+     * 根据前缀获取缓存的key集合
+     *
+     * @param prefixKey
+     * @return
+     */
+    public Set<String> keys(String prefixKey) {
+        Set<String> keyList = null;
+        Jedis jedis = null;
+        try {
+            jedis = getJedis();
+            keyList = jedis.keys(prefixKey);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, getCacheClient(), prefixKey);
+        } finally {
+            close(jedis);
+        }
+        return keyList;
+    }
+}

+ 608 - 0
elab-cache/src/main/java/com/elab/cache/redis/RedisClusterClient.java

@@ -0,0 +1,608 @@
+package com.elab.cache.redis;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.TypeReference;
+import com.elab.cache.ICacheClient;
+import com.sohu.tv.builder.RedisClusterBuilder;
+import org.apache.commons.lang3.StringUtils;
+import redis.clients.jedis.JedisCluster;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 操作redis集群
+ *
+ * @author Liukx
+ * @create 2017-05-17 14:06
+ * @email liukx@elab-plus.com
+ **/
+public class RedisClusterClient extends BaseRedis implements ICacheClient {
+
+    public RedisClusterBuilder redisBuilder;
+
+    public RedisClusterBuilder getRedisBuilder() {
+        return redisBuilder;
+    }
+
+    public void setRedisBuilder(RedisClusterBuilder redisBuilder) {
+        this.redisBuilder = redisBuilder;
+    }
+
+    public JedisCluster jedisCluster;
+
+    public void init() {
+        jedisCluster = redisBuilder.build();
+    }
+
+
+    public void close(JedisCluster jedis) {
+        try {
+            jedis.close();
+        } catch (RuntimeException e) {
+            logger.error("关闭redis异常", e);
+        }
+        logger.debug(" 关闭 redis连接 db  [" + dbIndex + "]");
+    }
+
+    /**
+     * 将指定的key进行递减
+     *
+     * @param key 键
+     * @param num 减去的值
+     * @return
+     */
+    public Long decrby(String key, long num) {
+        try {
+            return jedisCluster.decrBy(key, num);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, this, key, num + "");
+        }
+        return 0L;
+    }
+
+    /**
+     * 将指定的key进行自增
+     *
+     * @param key 键
+     * @param num 累加的值
+     * @return
+     */
+    public Long incrby(String key, long num) {
+        try {
+            return jedisCluster.incrBy(key, num);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, this, key, num + "");
+        }
+        return 0L;
+    }
+
+    /**
+     * 根据指定的key获取对象
+     *
+     * @param key   键 - 标识
+     * @param clazz
+     * @param <T>
+     * @return
+     */
+    public <T> T get(String key, Class clazz) {
+        String value = null;
+        try {
+            value = jedisCluster.get(key);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, this, key);
+        }
+        if (StringUtils.isEmpty(value)) {
+            return null;
+        }
+        T t = (T) JSON.parseObject(value, clazz);
+        return t;
+    }
+
+    /**
+     * 根据缓存的key获取一个集合
+     *
+     * @param key
+     * @param clazz
+     * @param <T>
+     * @return
+     */
+    public <T> List<T> getList(String key, Class clazz) {
+        String value = null;
+        try {
+            value = jedisCluster.get(key);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, this, key);
+        }
+        if (StringUtils.isEmpty(value)) {
+            return null;
+        }
+
+        List<T> tempList = JSON.parseObject(value, new TypeReference<List<T>>() {
+        });
+        List<T> list = JSONArray.parseArray(tempList.toString(), clazz);
+        return list;
+    }
+
+    /**
+     * 根据key获取Map对象
+     *
+     * @param key   缓存的key
+     * @param clazz 需要转换的对象
+     * @param <T>
+     * @return
+     */
+    public <T> Map<String, T> getMap(String key, Class clazz) {
+        String value = null;
+        try {
+            value = jedisCluster.get(key);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, this, key);
+        }
+        if (StringUtils.isEmpty(value)) {
+            return null;
+        }
+        Map<String, T> map = JSON.parseObject(value, new TypeReference<Map<String, T>>() {
+        });
+        return map;
+    }
+
+    /**
+     * 为指定的key设定有效时长
+     *
+     * @param key     键
+     * @param seconds 有效时长 单位:秒
+     * @return
+     */
+    public boolean expire(String key, int seconds) {
+        Long expire = 0L;
+        try {
+            expire = jedisCluster.expire(key, seconds);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, this, key, seconds);
+        }
+        if (expire > 0) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 查看当前key 还有多少有效时间
+     *
+     * @param key
+     * @return
+     */
+    public Long ttl(String key) {
+        Long ttl = 0L;
+        try {
+            ttl = jedisCluster.ttl(key);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, this, key);
+        }
+        return ttl;
+    }
+
+    /**
+     * 如果不存在则添加,存在则返回false
+     *
+     * @param key   键
+     * @param value 值
+     * @return
+     */
+    public boolean setNX(String key, Object value) {
+        Long setex = 0L;
+        try {
+            setex = jedisCluster.setnx(key, value.toString());
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, this, key);
+        }
+        // 0 表示未设置 1表示已经设置了
+        if (setex > 0) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 删除缓存中的数据
+     *
+     * @param key 键
+     */
+    public void delete(String key) {
+        try {
+            jedisCluster.del(key);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, this, key);
+        }
+    }
+
+    /**
+     * 为缓存中的数据加锁,通常用于分布式锁
+     *
+     * @param key     key
+     * @param value   值
+     * @param timeout 超时时间 单位秒
+     * @return
+     */
+    public boolean tryLock(String key, Object value, int timeout) {
+        String lockKey = "locked#" + key;
+        long startTime = System.currentTimeMillis();
+        int sleepTimes = 0;
+
+        while (!setNX(lockKey, value)) {
+            try {
+                Thread.sleep(1);
+                sleepTimes++;
+                if (sleepTimes % 100 == 0) {
+                    //超时判断
+                    if (System.currentTimeMillis() - startTime > timeout * 1000) {
+                        return false;
+                    }
+                }
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public void unLock(String key) {
+        String lockKey = "locked#" + key;
+        delete(lockKey);
+    }
+
+    /**
+     * <p>通过key 和offset 从指定的位置开始将原先value替换</p>
+     * <p>下标从0开始,offset表示从offset下标开始替换</p>
+     * <p>如果替换的字符串长度过小则会这样</p>
+     * <p>example:</p>
+     * <p>value : bigsea@zto.cn</p>
+     * <p>str : abc </p>
+     * <P>从下标7开始替换  则结果为</p>
+     * <p>RES : bigsea.abc.cn</p>
+     *
+     * @param key
+     * @param value
+     * @param offset 下标位置
+     * @return 返回替换后  value 的长度
+     */
+    @Override
+    public Long setRange(String key, String value, int offset) {
+        Long count = 0L;
+        try {
+            count = jedisCluster.setrange(key, offset, value);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, this, key, value);
+        }
+        return count;
+    }
+
+    /**
+     * <p>通过下标 和key 获取指定下标位置的 value</p>
+     *
+     * @param key
+     * @param startOffset 开始位置 从0 开始 负数表示从右边开始截取
+     * @param endOffset
+     * @return 如果没有返回null
+     */
+    @Override
+    public String getRange(String key, int startOffset, int endOffset) {
+        String data = null;
+        try {
+            data = jedisCluster.getrange(key, startOffset, endOffset);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, this, key);
+        }
+        return data;
+    }
+
+    /**
+     * <p>通过批量的key获取批量的value</p>
+     *
+     * @param keys string数组 也可以是一个key
+     * @return 成功返回value的集合, 失败返回null的集合 ,异常返回空
+     */
+    public List<String> mget(String... keys) {
+        List<String> list = null;
+        try {
+            list = jedisCluster.mget(keys);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, this, keys);
+        }
+        return list;
+    }
+
+    /**
+     * <p>批量的设置key:value,可以一个</p>
+     * <p>example:</p>
+     * <p>  obj.mset(new String[]{"key2","value1","key2","value2"})</p>
+     *
+     * @param keysvalues
+     * @return 成功返回OK 失败 异常 返回 null
+     */
+    public String mset(String... keysvalues) {
+        String data = null;
+        try {
+            data = jedisCluster.mset(keysvalues);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, this, keysvalues, keysvalues);
+        }
+        return data;
+    }
+
+    /**
+     * <p>批量的设置key:value,可以一个,如果key已经存在则会失败,操作会回滚</p>
+     * <p>example:</p>
+     * <p>  obj.msetnx(new String[]{"key2","value1","key2","value2"})</p>
+     *
+     * @param keysvalues
+     * @return 成功返回1 失败返回0
+     */
+    public Long msetnx(String... keysvalues) {
+        Long result = 0L;
+        try {
+            result = jedisCluster.msetnx(keysvalues);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, this, keysvalues, keysvalues);
+        }
+        return result;
+    }
+
+    /**
+     * <p>通过key给Hash Field设置指定的值,如果key不存在,则先创建</p>
+     *
+     * @param key
+     * @param field 字段
+     * @param value
+     * @return 如果存在返回0 异常返回null
+     */
+    public Long hset(String key, String field, String value) {
+        Long count = null;
+        try {
+            count = jedisCluster.hset(key, field, value);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, this, key, field, value);
+        }
+        return count;
+    }
+
+    /**
+     * <p>Sets field in the hash stored at key to value
+     * 通过key给field设置指定的值,如果key不存在则先创建,如果field已经存在,返回0</p>
+     *
+     * @param key
+     * @param field
+     * @param value
+     * @return
+     */
+    public Long hsetnx(String key, String field, String value) {
+        Long count = 0L;
+        try {
+            count = jedisCluster.hsetnx(key, field, value);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, this, key, field, value);
+        }
+        return count;
+    }
+
+    /**
+     * <p>通过key同时设置 hash的多个field</p>
+     *
+     * @param key
+     * @param hash
+     * @return 返回OK 异常返回null
+     */
+    public String hmset(String key, Map<String, String> hash) {
+        String result = null;
+        try {
+            result = jedisCluster.hmset(key, hash);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, this, key, hash);
+        }
+        return result;
+    }
+
+    /**
+     * <p>通过key 和 field 获取指定的 value</p>
+     *
+     * @param key
+     * @param field
+     * @return 没有返回null
+     */
+    public String hget(String key, String field) {
+        String result = null;
+        try {
+            result = jedisCluster.hget(key, field);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, this, key, field);
+        }
+        return result;
+    }
+
+    /**
+     * <p>通过key 和 fields 获取指定的value 如果没有对应的value则返回null</p>
+     *
+     * @param key
+     * @param fields 可以使 一个String 也可以是 String数组
+     * @return
+     */
+    public List<String> hmget(String key, String... fields) {
+        List<String> result = null;
+        try {
+            result = jedisCluster.hmget(key, fields);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, this, key, fields);
+        }
+        return result;
+    }
+
+
+    /**
+     * <p>通过key向list头部添加字符串</p>
+     *
+     * @param key
+     * @param strs 可以是一个string 也可以是string数组
+     * @return 返回list的value个数
+     */
+    public Long lpush(String key, String... strs) {
+        Long result = 0L;
+        try {
+            result = jedisCluster.lpush(key, strs);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, this, key, strs);
+        }
+        return result;
+    }
+
+    /**
+     * 获取指定list
+     *
+     * @param key        键
+     * @param startIndex 开始下标
+     * @param endIndex   结束下标  -1 代表获取所有
+     * @return
+     */
+    public List<String> lrange(String key, int startIndex, int endIndex) {
+        List<String> list = null;
+        try {
+            list = jedisCluster.lrange(key, startIndex, endIndex);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, this, key, startIndex, endIndex);
+        }
+        return list;
+    }
+
+
+    /**
+     * 获取所有list
+     *
+     * @param key 键
+     * @return
+     */
+    public List<String> lrange(String key) {
+        List<String> list = null;
+        try {
+            list = jedisCluster.lrange(key, 0, -1);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, this, key);
+        }
+        return list;
+    }
+
+    /**
+     * 设定数据到缓存中
+     *
+     * @param key  键
+     * @param data
+     * @param <T>
+     */
+    public <T> void set(String key, T data) {
+        try {
+            jedisCluster.set(key, JSON.toJSONString(data));
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, this, key);
+        }
+    }
+
+    public <T> void setList(String key, List<T> list) {
+        try {
+            jedisCluster.set(key, JSON.toJSONString(list));
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, this, key, list);
+        }
+    }
+
+    /**
+     * 添加一个map的值
+     *
+     * @param key 键
+     * @param map Map集合
+     * @param <T> 泛型任意类型
+     */
+    public <T> void setMap(String key, Map<String, T> map) {
+        try {
+            jedisCluster.set(key, JSON.toJSONString(map));
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, this, key, map);
+        }
+    }
+
+    /**
+     * 判断指定的key是否存在
+     *
+     * @param key
+     * @return
+     */
+    public boolean exsit(String key) {
+        boolean flag = false;
+        try {
+            flag = jedisCluster.exists(key);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, this, key);
+        }
+        return flag;
+    }
+
+    /**
+     * 添加数据到缓存中
+     *
+     * @param key       键
+     * @param value     值
+     * @param validTime 有效时间  1秒=1000   -1 永久有效
+     */
+    public void set(String key, Object value, int validTime) {
+        String data = null;
+        try {
+            data = JSON.toJSONString(value);
+        } catch (Exception e) {
+            data = value.toString();
+        }
+        try {
+            jedisCluster.set(key, data);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCachePutError(e, this, key, value);
+        }
+        expire(key, validTime);
+    }
+
+    /**
+     * 获取缓存中的数据
+     *
+     * @param key 缓存的key
+     * @return
+     */
+    public String get(String key) {
+        String result = null;
+        try {
+            result = jedisCluster.get(key);
+        } catch (RuntimeException e) {
+            getCacheErrorProcess().handleCacheGetError(e, this, key);
+        }
+        return result;
+    }
+
+//    @Override
+//    public Set<String> keys(String prefixKey) {
+//        String result = null;
+//        try {
+//            result = jedisCluster.eval(key);
+//        } catch (RuntimeException e) {
+//            getCacheErrorProcess().handleCacheGetError(e, this, key);
+//        }
+//        return result;
+//    }
+
+    /**
+     * 集群的方法不适合提供这个keys
+     *
+     * @param prefixKey
+     * @return
+     */
+    @Override
+    public Set<String> keys(String prefixKey) {
+        return null;
+    }
+}

+ 55 - 0
elab-cache/src/main/java/com/elab/cache/redis/RedisSentinelClient.java

@@ -0,0 +1,55 @@
+package com.elab.cache.redis;
+
+import com.elab.cache.ICacheClient;
+import com.sohu.tv.builder.RedisSentinelBuilder;
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.JedisSentinelPool;
+
+/**
+ * 操作主备类型的redis
+ *
+ * @author Liukx
+ * @create 2017-05-17 14:06
+ * @email liukx@elab-plus.com
+ **/
+public class RedisSentinelClient extends BaseRedisOperation implements ICacheClient {
+
+    public RedisSentinelBuilder redisBuilder;
+
+    public JedisSentinelPool jedisSentinelPool;
+
+    private Jedis jedisCluster;
+
+    public void init() {
+        this.jedisSentinelPool = redisBuilder.build();
+    }
+
+    public RedisSentinelBuilder getRedisBuilder() {
+        return redisBuilder;
+    }
+
+    public void setRedisBuilder(RedisSentinelBuilder redisBuilder) {
+        this.redisBuilder = redisBuilder;
+    }
+
+    public Jedis getJedisCluster() {
+        return jedisCluster;
+    }
+
+    public void setJedisCluster(Jedis jedisCluster) {
+        this.jedisCluster = jedisCluster;
+    }
+
+    @Override
+    public Jedis getResource() {
+//        HostAndPort currentHostMaster = jedisSentinelPool.getCurrentHostMaster();
+//        logger.debug("当前选举的IP : " + currentHostMaster);
+        return this.jedisSentinelPool.getResource();
+    }
+
+
+    @Override
+    public ICacheClient getCacheClient() {
+        return this;
+    }
+}

+ 38 - 0
elab-cache/src/main/java/com/elab/cache/redis/RedisStandaloneClient.java

@@ -0,0 +1,38 @@
+package com.elab.cache.redis;
+
+import com.elab.cache.ICacheClient;
+import com.sohu.tv.builder.RedisStandaloneBuilder;
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.JedisPool;
+
+/**
+ * 操作redis单机
+ *
+ * @author Liukx
+ * @create 2017-05-17 14:06
+ * @email liukx@elab-plus.com
+ **/
+public class RedisStandaloneClient extends BaseRedisOperation implements ICacheClient {
+
+    private RedisStandaloneBuilder redisBuilder;
+
+    private JedisPool jedisPool;
+
+    public void setRedisBuilder(RedisStandaloneBuilder redisBuilder) {
+        this.redisBuilder = redisBuilder;
+    }
+
+    public void init() {
+        jedisPool = redisBuilder.build();
+    }
+
+    @Override
+    public ICacheClient getCacheClient() {
+        return this;
+    }
+
+    @Override
+    public Jedis getResource() {
+        return jedisPool.getResource();
+    }
+}

+ 45 - 0
elab-cache/src/main/java/com/elab/cache/spring/generator/DefaultCacheKeyGenerator.java

@@ -0,0 +1,45 @@
+package com.elab.cache.spring.generator;
+
+import com.alibaba.fastjson.JSON;
+import org.springframework.cache.interceptor.KeyGenerator;
+
+import java.lang.reflect.Method;
+
+/**
+ * 默认的缓存key生成策略
+ *
+ * @author Liukx
+ * @create 2017-11-06 13:38
+ * @email liukx@elab-plus.com
+ **/
+public class DefaultCacheKeyGenerator implements KeyGenerator {
+    // 标识前缀
+    private String prefix;
+    // 分隔符
+    private String separator = "_";
+
+    @Override
+    public Object generate(Object target, Method method, Object... params) {
+        String className = target.getClass().getSimpleName();
+        String name = method.getName();
+        String jsonParams = JSON.toJSONString(params);
+        String cachekey = prefix + separator + className + separator + name + separator + jsonParams;
+        return cachekey;
+    }
+
+    public String getSeparator() {
+        return separator;
+    }
+
+    public void setSeparator(String separator) {
+        this.separator = separator;
+    }
+
+    public String getPrefix() {
+        return prefix;
+    }
+
+    public void setPrefix(String prefix) {
+        this.prefix = prefix;
+    }
+}

+ 46 - 0
elab-cache/src/main/java/com/elab/cache/spring/handle/ErrorCacheHandle.java

@@ -0,0 +1,46 @@
+package com.elab.cache.spring.handle;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cache.Cache;
+import org.springframework.cache.interceptor.CacheErrorHandler;
+
+/**
+ * 缓存异常处理
+ *
+ * @author Liukx
+ * @create 2017-11-06 17:58
+ * @email liukx@elab-plus.com
+ **/
+public class ErrorCacheHandle implements CacheErrorHandler {
+
+    Logger logger = LoggerFactory.getLogger(ErrorCacheHandle.class);
+
+    public void handleCacheGetError(RuntimeException exception, Cache cache, Object key) {
+        logger.error("‖‖‖‖‖‖‖‖‖缓存异常[handleCacheGetError]‖‖‖‖‖‖‖‖‖‖ cache : " + cache.getName() + " \t key : " + key.toString() + " 异常原因 : " + exception.getMessage(), exception);
+//        if (logger.isDebugEnabled()) {
+//            exception.printStackTrace();
+//        }
+    }
+
+    public void handleCachePutError(RuntimeException exception, Cache cache, Object key, Object value) {
+        logger.error("‖‖‖‖‖‖‖‖‖缓存异常[handleCachePutError]‖‖‖‖‖‖‖‖‖‖ cache : " + cache.getName() + " \t key : " + key.toString() + "\t value : " + value + " 异常原因 : " + exception.getMessage(), exception);
+//        if (logger.isDebugEnabled()) {
+//            exception.printStackTrace();
+//        }
+    }
+
+    public void handleCacheEvictError(RuntimeException exception, Cache cache, Object key) {
+        logger.error("‖‖‖‖‖‖‖‖‖缓存异常[handleCacheEvictError]‖‖‖‖‖‖‖‖‖‖ cache : " + cache.getName() + " \t key : " + key.toString() + " 异常原因 : " + exception.getMessage(), exception);
+//        if (logger.isDebugEnabled()) {
+//            exception.printStackTrace();
+//        }
+    }
+
+    public void handleCacheClearError(RuntimeException exception, Cache cache) {
+        logger.error("‖‖‖‖‖‖‖‖‖缓存异常[handleCacheClearError]‖‖‖‖‖‖‖‖‖‖ cache : " + cache.getName() + " 异常原因 : " + exception.getMessage(), exception);
+//        if (logger.isDebugEnabled()) {
+//            exception.printStackTrace();
+//        }
+    }
+}

+ 205 - 0
elab-cache/src/main/java/com/elab/cache/spring/manage/SystemCacheManage.java

@@ -0,0 +1,205 @@
+package com.elab.cache.spring.manage;
+
+import com.alibaba.fastjson.JSON;
+import com.elab.cache.ICacheClient;
+import com.elab.cache.spring.wrapper.CacheValueWrapper;
+import com.elab.core.utils.ObjectUtils;
+import org.springframework.cache.Cache;
+import org.springframework.cache.support.SimpleValueWrapper;
+
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+public class SystemCacheManage implements Cache {
+
+
+    @Override
+    public ValueWrapper putIfAbsent(Object key, Object value) {
+        return null;
+    }
+
+    /**
+     * Redis
+     */
+    private ICacheClient cacheClient;
+
+    /**
+     * 缓存名称
+     */
+    private String name;
+
+    /**
+     * 超时时间
+     */
+    private int timeout;
+
+    /**
+     * 暂无实现
+     *
+     * @param o
+     * @param callable
+     * @param <T>
+     * @return
+     */
+    @Override
+    public <T> T get(Object o, Callable<T> callable) {
+        return null;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.springframework.cache.Cache#getName()
+     */
+    @Override
+    public String getName() {
+        return this.name;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.springframework.cache.Cache#getNativeCache()
+     */
+    @Override
+    public Object getNativeCache() {
+        return this.cacheClient;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.springframework.cache.Cache#get(java.lang.Object)
+     */
+    @Override
+    public ValueWrapper get(Object key) {
+        if (ObjectUtils.isEmpty(key)) {
+            return null;
+        } else {
+            final String finalKey;
+            if (key instanceof String) {
+                finalKey = (String) key;
+            } else {
+                finalKey = key.toString();
+            }
+            CacheValueWrapper wrapperObject = cacheClient.get(finalKey, CacheValueWrapper.class);
+            if (wrapperObject == null) {
+                return null;
+            }
+
+            Object object = null;
+            if (wrapperObject.getJson() != null && wrapperObject.getClazz() != null) {
+                object = JSON.parseObject(wrapperObject.getJson(), wrapperObject.getClazz());
+            }
+            return (object != null ? new SimpleValueWrapper(object) : null);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.springframework.cache.Cache#get(java.lang.Object, java.lang.Class)
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T> T get(Object key, Class<T> type) {
+        if (ObjectUtils.isEmpty(key) || null == type) {
+            return null;
+        } else {
+            final String finalKey;
+            final Class<T> finalType = type;
+            if (key instanceof String) {
+                finalKey = (String) key;
+            } else {
+                finalKey = key.toString();
+            }
+            final Object object = cacheClient.get(finalKey, type);
+            if (finalType != null && finalType.isInstance(object) && null != object) {
+                return (T) object;
+            } else {
+                return null;
+            }
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.springframework.cache.Cache#put(java.lang.Object, java.lang.Object)
+     */
+    @Override
+    public void put(final Object key, final Object value) {
+        if (ObjectUtils.isEmpty(key) || ObjectUtils.isEmpty(value)) {
+            return;
+        } else {
+            final String finalKey;
+            if (key instanceof String) {
+                finalKey = (String) key;
+            } else {
+                finalKey = key.toString();
+            }
+            if (!ObjectUtils.isEmpty(finalKey)) {
+                String valueJson = JSON.toJSONString(value);
+                CacheValueWrapper wrapper = new CacheValueWrapper(valueJson, value.getClass());
+                cacheClient.set(finalKey, wrapper, timeout);
+            }
+        }
+    }
+
+    /*
+     * 根据Key 删除缓存
+     *
+     * 1. 这里考虑到一些集合存在的情况,
+     * 所以尽可能的情况是根据前缀去匹配key,
+     * 然后将匹配到的key进行清除.
+     * 所以这里还是要求在key设计的时候,有一定的规则性
+     *
+     */
+    @Override
+    public void evict(Object key) {
+        if (null != key) {
+            String finalKey;
+            if (key instanceof String) {
+                finalKey = (String) key;
+            } else {
+                finalKey = key.toString();
+            }
+            if (!com.elab.core.utils.ObjectUtils.isEmpty(finalKey)) {
+                Set<String> keys = cacheClient.keys(finalKey + "*");
+                for (String k : keys) {
+                    cacheClient.delete(k);
+                }
+            }
+        }
+    }
+
+    /*
+     * 清除系统缓存
+     */
+    @Override
+    public void clear() {
+        System.out.println("====================");
+        // TODO Auto-generated method stub
+        // redisTemplate.execute(new RedisCallback<String>() {
+        // public String doInRedis(RedisConnection connection) throws DataAccessException {
+        // connection.flushDb();
+        // return "ok";
+        // }
+        // });
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public int getTimeout() {
+        return timeout;
+    }
+
+    public void setTimeout(int timeout) {
+        this.timeout = timeout;
+    }
+
+    public ICacheClient getCacheClient() {
+        return cacheClient;
+    }
+
+    public void setCacheClient(ICacheClient cacheClient) {
+        this.cacheClient = cacheClient;
+    }
+}

+ 38 - 0
elab-cache/src/main/java/com/elab/cache/spring/wrapper/CacheValueWrapper.java

@@ -0,0 +1,38 @@
+package com.elab.cache.spring.wrapper;
+
+/**
+ * 缓存的值进行包装
+ *
+ * @author Liukx
+ * @create 2018-02-28 11:12
+ * @email liukx@elab-plus.com
+ **/
+public class CacheValueWrapper {
+
+    public String json;
+    private Class<?> clazz;
+
+    public CacheValueWrapper() {
+    }
+
+    public CacheValueWrapper(String json, Class<?> clazz) {
+        this.json = json;
+        this.clazz = clazz;
+    }
+
+    public String getJson() {
+        return json;
+    }
+
+    public void setJson(String json) {
+        this.json = json;
+    }
+
+    public Class<?> getClazz() {
+        return clazz;
+    }
+
+    public void setClazz(Class<?> clazz) {
+        this.clazz = clazz;
+    }
+}

+ 206 - 0
elab-cache/src/main/resources/ELAB-CACHE.md

@@ -0,0 +1,206 @@
+## elab-cache 使用注意事项
+
+#### 使用步骤:
+1. 引入maven的依赖
+```
+<dependency>
+    <groupId>com.elab.cache</groupId>
+    <artifactId>elab-cache</artifactId>
+    <version>1.4</version>
+</dependency>
+```
+
+2. 在配置文件中配置使用的对象
+```
+     <!-- 默认生成的缓存key的实现策略 -->
+    <bean id="defaultCacheKeyGenerator" class="com.elab.cache.spring.generator.DefaultCacheKeyGenerator">
+        <property name="prefix" value="demo"/>
+        <property name="separator" value="_"/>
+    </bean>
+        
+    <!-- 开启cache注解扫描 -->
+    <cache:annotation-driven cache-manager="cacheManager" key-generator="defaultCacheKeyGenerator"/>
+
+    <!-- redis 集群操作类 -->
+    <bean id="redisClusterClient" class="com.elab.cache.redis.RedisClusterClient" init-method="init" lazy-init="true">
+        <property name="redisBuilder" ref="redisClusterBuilder"></property>
+    </bean>
+
+    <!-- redis 主备操作类 -->
+    <bean id="redisSentineClient" class="com.elab.cache.redis.RedisSentinelClient" init-method="init" lazy-init="true">
+        <property name="redisBuilder" ref="redisSentinelBuilder"/>
+         <property name="password" value="elab@123"/>
+        <property name="dbIndex" value="2"/>
+    </bean>
+
+    <!-- redis 单机操作类 -->
+    <bean id="redisStandaloneClient" class="com.elab.cache.redis.RedisStandaloneClient" init-method="init"
+          lazy-init="true">
+        <property name="redisBuilder" ref="redisStandaloneBuilder"/>
+        <property name="password" value="elab@123"/>
+        <property name="dbIndex" value="2"/>
+    </bean>
+
+    <!-- 集群连接池配置 -->
+    <bean id="redisPoolConfig" class="org.apache.commons.pool2.impl.GenericObjectPoolConfig">
+        <property name="maxTotal" value="160"/>
+        <property name="maxIdle" value="160"/>
+        <property name="minIdle" value="80"/>
+        <property name="maxWaitMillis" value="1000"/>
+        <property name="jmxNamePrefix" value="jedis-pool"/>
+        <property name="jmxEnabled" value="true"/>
+    </bean>
+
+    <!-- 集群版redis操作 -->
+    <bean id="redisClusterBuilder" class="com.sohu.tv.builder.RedisClusterBuilder" lazy-init="true">
+        <constructor-arg value="10021"/>
+        <property name="jedisPoolConfig" ref="redisPoolConfig"/>
+        <property name="connectionTimeout" value="2000"/>
+        <property name="soTimeout" value="1000"/>
+    </bean>
+
+    <!-- 单机版redis 操作 -->
+    <bean id="redisStandaloneBuilder" class="com.sohu.tv.builder.RedisStandaloneBuilder" lazy-init="true">
+        <constructor-arg value="10002"/>
+        <property name="timeout" value="2000"/>
+        <property name="poolConfig" ref="redisPoolConfig"/>
+    </bean>
+
+    <!-- redisSentine操作 -->
+    <bean id="redisSentinelBuilder" class="com.sohu.tv.builder.RedisSentinelBuilder" lazy-init="true">
+        <constructor-arg value="10020"/>
+        <property name="poolConfig" ref="redisPoolConfig"/>
+        <property name="connectionTimeout" value="2000"/>
+        <property name="soTimeout" value="1000"/>
+    </bean>
+
+    <!-- 将默认的实现集成到spring-cache中 -->
+    <bean id="systemCacheManage" class="com.elab.cache.spring.manage.SystemCacheManage">
+        <property name="cacheClient" ref="redisStandaloneClient"/>
+        <property name="timeout" value="30000"/>
+        <property name="name" value="redisClient"/>
+    </bean>
+
+    <!-- 简单的缓存管理器 -->
+    <bean id="simpleCacheManager" class="org.springframework.cache.support.SimpleCacheManager">
+        <property name="caches" ref="systemCacheManage"/>
+    </bean>
+
+    <!-- 统一的缓存管理器 -->
+    <bean id="cacheManager"
+          class="org.springframework.cache.support.CompositeCacheManager">
+        <property name="cacheManagers">
+            <list>
+                <ref bean="simpleCacheManager"/>
+            </list>
+        </property>
+        <property name="fallbackToNoOpCache" value="true"/>
+    </bean>
+```
+3. 代码层面如何使用,具体需要
+```
+
+// 这里需要注意的是定义了CacheConfig相当于对这个类定义了全局的缓存配置
+// 下面的value可以不用定义了 -> @Cacheable(value = "redisClient")
+@CacheConfig(cacheNames = "redisClient")
+public class ServiceImpl implements IService {
+    // 需要注意的是
+    // 第一个参数与配置文件中的systemCacheManage.name 参数要保持一致,这个注解是为了标识你要使用那个缓存
+    // 第二个参数是key生成的策略,不填默认[类_方法名_JSON参数],下面的生成最后lkx_test_2,表示自己指定的
+    // 第三个参数表示条件,表示redisModel的id不能为空才会进行缓存
+    @Cacheable(value = "redisClient", key = "'lkx_test_'+#redisModel.id" ,condition = "#redisModel.id != null")
+    public String test(RedisModel redisModel) {
+        System.out.println("执行完毕");
+        return "你好啊~~";
+    }
+
+/**
+     * 每次都执行更新操作的注解
+     * @param redisModel
+     * @return
+     */
+    @CachePut(value = "redisClient", key = "'lkx_test_'+#redisModel.id")
+    public String updateCache(RedisModel redisModel) {
+        System.out.println("执行修改完毕..");
+        return "OK";
+    }
+
+    /**
+     * allEntries : 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存
+     * beforeInvocation : 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存
+     *
+     * @param redisModel
+     * @return
+     */
+    @CacheEvict(value = "redisClient", key = "'lkx_test_'+#redisModel.id", allEntries = false, beforeInvocation = false)
+    public String CacheEvict(RedisModel redisModel) {
+        System.out.println("执行del完毕..");
+        return "OK~";
+    }
+    }
+```
+**注意**
+1. 集合如何更新  
+    自定义的key的话最好有规律可循,例如再缓存了多个集合的情况出现数据更新就比较麻烦了,
+    所以推荐key的定义方式[project_class_list_method],这种的话,在更新缓存的时候,方便通过[project_class_list]为前缀的key全部删除掉,重新加载
+2. CachePut在没有集合出现的情况比较适合,但是如果缓存的集合比较多,要做更新的话就会比较麻烦
+
+5. 参考案例
+RedisTest.testCache
+
+6. 异常处理
+> 当redis遇到异常导致停止时,不能导致应用无法使用
+
+参考类: SimpleCacheErrorProcess , 里面是你具体的业务实现
+```
+public class SimpleCacheErrorProcess implements CacheErrorProcess {
+
+    Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Override
+    public void handleCacheGetError(RuntimeException exception, ICacheClient cache, Object key) {
+        logger.error("==============handleCacheGetError==================== [key]" + key, exception);
+    }
+
+    @Override
+    public void handleCachePutError(RuntimeException exception, ICacheClient cache, Object key, Object value) {
+        logger.error("==============handleCachePutError==================== [key]" + key + "=======[value]" + value, exception);
+    }
+
+    @Override
+    public void handleCachePutError(RuntimeException exception, ICacheClient cache, Object key, Object filed, Object value) {
+        logger.error("==============handleCachePutError==================== [key]" + key + "=======[value]" + value + "========[filed]========" + filed, exception);
+    }
+
+    @Override
+    public void handleCacheEvictError(RuntimeException exception, ICacheClient cache, Object key) {
+        logger.error("==============handleCacheEvictError====================", exception);
+    }
+
+    @Override
+    public void handleCacheClearError(RuntimeException exception, ICacheClient cache) {
+        logger.error("==============handleCacheClearError====================", exception);
+    }
+}
+
+```
+
+然后在spring中进行配置将这个SimpleCacheErrorProcess注入到每个redis的cacheErrorProcess属性中就行了
+```
+<bean id="redisStandaloneClient" class="com.elab.cache.redis.RedisStandaloneClient" init-method="init"
+          lazy-init="true">
+        <property name="redisBuilder" ref="redisStandaloneBuilder"/>
+        <property name="cacheErrorProcess" ref="你的实现类"/>
+</bean>
+```
+
+## 升级日志
+- 1.1 添加了日志容错功能,在redis报错的同时,不影响其他程序运行
+- 1.2 升级spring-cache注解版功能
+    - 可以将注解添加到任意Spring扫描的包下
+- 1.3 解决redis单机操作实现类在多线程下报错的原因。
+    - 将redis错误日志的exception也放入到了error日志中
+- 1.4 解决问题:
+    - 解决reids连接未释放的问题
+    - redis配置添加密码配置
+    - redis配置选择数据库的问题

+ 285 - 0
elab-cache/src/test/java/RedisTest.java

@@ -0,0 +1,285 @@
+import com.elab.cache.ICacheClient;
+import model.RedisModel;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import service.IService;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * redis操作测试
+ *
+ * @author Liukx
+ * @create 2017-05-17 10:36
+ * @email liukx@elab-plus.com
+ **/
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = "classpath*:cacheCloud/applicationContext-redis.xml")
+public class RedisTest {
+
+    private final String text = "redisSentinelBuilder";
+
+
+    // redisStandaloneClient - 单机
+    // redisSentineClient 主备
+    // redisClusterClient 集群
+    @Qualifier("redisSentineClient")
+    @Autowired
+    private ICacheClient redisClient;
+
+
+    /**
+     * jedis中处理list的方式,但是只能处理list泛型为String的方式,不太能满足具体业务
+     */
+    @Test
+    public void redisListByString() {
+        //http://192.168.0.24:9999/cache/client/redis/standalone/10024.json?clientVersion=1.0-SNAPSHOT
+        //http://192.168.0.24:9999/cache/client/redis/sentinel/10026.json?clientVersion=1.0-SNAPSHOT
+//        List<String> list = new ArrayList<String>();
+//        list.add("aaa123");
+//        list.add("bbb456");
+//        list.add("ccc789");
+//        String[] strings = new String[list.size()];
+//        strings = list.toArray(strings);
+//        redisClient.delete("redisListByString");
+//        redisClient.lpush("redisListByString", strings);
+//        List<String> resultList = redisClient.lrange("redisListByString");
+//        System.out.println("redisListByString:" + resultList);
+
+//        RedisModel redisModel = new RedisModel();
+//        redisModel.setId(1);
+//        redisModel.setName("某某某");
+//        redisModel.setText("洗香香");
+//        redisModel.setAge(15);
+//
+//        redisClient.set("test", redisModel);
+//        RedisModel test = redisClient.get("test", RedisModel.class);
+//        System.out.println("======================" + JSON.toJSONString(test));
+
+        redisClient.set("test", 0);
+        Long lkx1 = redisClient.incrby("test", 10);
+        System.out.println("-------------2----------" + lkx1);
+        Long lkx2 = redisClient.decrby("test", 5);
+        System.out.println("-------------3----------" + lkx2);
+        Long lkx3 = redisClient.ttl("lkx");
+        System.out.println("-------------4----------" + lkx3);
+        boolean lkx4 = redisClient.exsit("lkx");
+        System.out.println("-------------5----------" + lkx4);
+        boolean lkx5 = redisClient.setNX("lkx", "555");
+        System.out.println("-------------6----------" + lkx5);
+        String lkx = redisClient.get("lkx");
+        System.out.println("--------------->>>" + lkx);
+//        try {
+//            TimeUnit.MILLISECONDS.sleep(70000);
+//        } catch (InterruptedException e) {
+//            e.printStackTrace();
+//        }
+    }
+
+
+    /**
+     * 自己封装的redis中存放List任意泛型的方式,存储用的是json,不是序列化
+     */
+    @Test
+    public void redisListByObj() {
+        List<RedisModel> list = new ArrayList();
+        RedisModel model1 = new RedisModel();
+        model1.setAge(11);
+        model1.setName("name11");
+        model1.setText("text11");
+        list.add(model1);
+        RedisModel model2 = new RedisModel();
+        model2.setAge(12);
+        model2.setName("name12");
+        model2.setText("text12");
+        list.add(model2);
+        redisClient.delete("redisListByObj");
+        redisClient.setList("redisListByObj", list);
+        List<RedisModel> models = redisClient.getList("redisListByObj", RedisModel.class);
+        System.out.println("redisListByObj:" + models.toString());
+    }
+
+    /**
+     * 自己封装的redis中存放map任意泛型的方式,存储用的是json,不是序列化
+     */
+    @Test
+    public void redisMapByString() {
+        Map<String, String> map = new LinkedHashMap();
+        map.put("haixiao1", "海啸小哥");
+        map.put("haixiao2", "海啸大哥");
+        redisClient.delete("redisMapByString");
+        redisClient.set("redisMapByString", map);
+        Map<String, String> strMap = redisClient.getMap("redisMapByString", String.class);
+        System.out.println("redisMapByString:" + strMap);
+    }
+
+    /**
+     * 自己封装的redis中存放map任意泛型的方式,存储用的是json,不是序列化
+     */
+    @Test
+    public void redisMapByObj() {
+        Map<String, RedisModel> map = new LinkedHashMap();
+        RedisModel r1 = new RedisModel();
+        r1.setAge(22);
+        r1.setName("姓名22");
+        r1.setText("text22");
+        map.put("r1", r1);
+        RedisModel r2 = new RedisModel();
+        r2.setAge(23);
+        r2.setName("姓名23");
+        r2.setText("text23");
+        map.put("r2", r2);
+        redisClient.delete("redisMapByObj");
+        redisClient.set("redisMapByObj", map);
+        Map<String, RedisModel> mapResult = redisClient.getMap("redisMapByObj", RedisModel.class);
+        System.out.println("mapRequest:" + mapResult);
+
+    }
+
+    /**
+     * 自己封装的redis中存放任意泛型的方式,存储用的是json,不是序列化
+     */
+    @Test
+    public void storageJavaBean() {
+//        RedisModel model = new RedisModel();
+//        model.setAge(28);
+//        model.setName("海啸");
+//        model.setText("你好,大世界");
+//        model.setId(98);
+//        redisClient.delete("storageJavaBean");
+//        ////////////////////存储自定义对象方式///////////////
+//        redisClient.set("storageJavaBean", model);
+//        RedisModel redisModel = redisClient.get("storageJavaBean", RedisModel.class);
+//        System.out.println(redisModel);
+//        ////////////////////存储包装类对象方式-String///////////////
+//        redisClient.set("haixiaoString", "沈杜公路沃尔");
+//        String haixiaoString = redisClient.get("haixiaoString", String.class);
+//        System.out.println("haixiaoString:"+haixiaoString);
+//        ////////////////////存储包装类对象方式-Integer///////////////
+//        redisClient.set("haixiaoInteger", 78909);
+//        Integer haixiaoInteger = redisClient.get("haixiaoInteger", Integer.class);
+//        System.out.println("haixiaoInteger:"+haixiaoInteger);
+//        ////////////////////存储包装类对象方式-Double///////////////
+//        redisClient.set("haixiaoDouble", 888.49);
+//        Double haixiaoDouble = redisClient.get("haixiaoDouble", Double.class);
+//        System.out.println("haixiaoDouble:"+haixiaoDouble);
+//        ////////////////////存储包装类对象方式-Long///////////////
+//        redisClient.set("haixiaoLong", 999);
+//        Long haixiaoLong = redisClient.get("haixiaoLong", Long.class);
+//        System.out.println("haixiaoLong:"+haixiaoLong);
+//        ////////////////////存储包装类对象方式-Float///////////////
+//        redisClient.set("haixiaoFloat", 525.52f);
+//        Float haixiaoFloat = redisClient.get("haixiaoFloat", Float.class);
+//        System.out.println("haixiaoFloat:"+haixiaoFloat);
+//
+//
+//        Map<String, String> map = new LinkedHashMap();
+//        map.put("haixiao1", "海啸小哥");
+//        map.put("haixiao2", "海啸大哥");
+//        redisClient.set("haixiaoMap", map);
+//        Map haixiaoMap = redisClient.get("haixiaoMap", Map.class);
+//
+        Map<String, String> map1 = new LinkedHashMap();
+        map1.put("haixiao1", "海啸小哥");
+        map1.put("haixiao2", "海啸大哥");
+//        for (int i = 0; i < 10; i++) {
+//            System.out.println(redisClient.toString());
+        redisClient.set("jjj", map1);
+//        }
+
+        Map aaaa = redisClient.get("jjj", Map.class);
+        System.out.println("-->" + aaaa.toString());
+    }
+
+    @Test
+    public void testRedisError() throws InterruptedException {
+        for (int i = 0; i < 20; i++) {
+            redisClient.set("aaa", "asdasd");
+            System.out.println("添加成功~~~");
+            String aaa = redisClient.get("aaa");
+            System.out.println("aaaaa==" + aaa);
+            Thread.sleep(5000);
+        }
+
+    }
+
+    @Autowired
+    private IService service;
+
+    /**
+     * 缓存注解测试
+     */
+    @Test
+    public void testCache() {
+        RedisModel model = new RedisModel();
+        model.setAge(5655);
+        model.setId(2);
+        model.setText("aaaaa");
+//        Info test2 = service.test(model);
+//        Info test = service.test(model);
+//        System.out.println("111---->" + JSON.toJSONString(test));
+//        RedisModel redisModel = service.testParams(model);
+//        RedisModel redisModel1 = service.testParams(model);
+        List<String> strings = service.testList();
+        List<String> strings1 = service.testList();
+
+//        System.out.println("222---->" + JSON.toJSONString(redisModel1));
+//        System.out.println("----->" + JSON.toJSONString(redisModel1));
+//        service.updateCache(model);
+//        service.updateCache(model);
+
+//        service.CacheEvict()
+//        service.CacheEvict(model);
+//        service.CacheEvict(model);
+
+    }
+
+    /**
+     * 连接关闭测试
+     *
+     * @throws InterruptedException
+     */
+    @Test
+    public void connectClose() throws InterruptedException {
+        for (int i = 0; i < 100; i++) {
+            Thread.sleep(1000);
+            String lkx = redisClient.get("lkx");
+            System.out.println("==========" + lkx);
+        }
+    }
+
+
+    /**
+     * 并发测试
+     *
+     * @throws InterruptedException
+     */
+    @Test
+    public void testThread() throws Exception {
+        final AtomicInteger count = new AtomicInteger();
+        for (int i = 0; i < 300; i++) {
+            Thread thread = new Thread(new Runnable() {
+                @Override
+                public void run() {
+//                    redisListByString();
+                    int andIncrement = count.getAndIncrement();
+                    System.out.println("=============>" + andIncrement);
+                    redisClient.set("lkx", "tttttt");
+                    System.out.println("设置完成" + andIncrement);
+                }
+            });
+            thread.start();
+        }
+        System.out.println("初始化线程OK");
+        System.in.read();
+    }
+
+}

+ 61 - 0
elab-cache/src/test/java/model/RedisModel.java

@@ -0,0 +1,61 @@
+package model;
+
+import java.io.Serializable;
+
+/**
+ * @author Liukx
+ * @create 2017-05-17 15:05
+ * @email liukx@elab-plus.com
+ **/
+public class RedisModel implements Serializable{
+
+    private int id;
+
+    private String name;
+
+    private int age;
+
+    private String text;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public int getAge() {
+        return age;
+    }
+
+    public void setAge(int age) {
+        this.age = age;
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    @Override
+    public String toString() {
+        return "RedisModel{" +
+                "id=" + id +
+                ", name='" + name + '\'' +
+                ", age=" + age +
+                ", text='" + text + '\'' +
+                '}';
+    }
+}

+ 25 - 0
elab-cache/src/test/java/service/IService.java

@@ -0,0 +1,25 @@
+package service;
+
+import com.elab.core.bean.Info;
+import model.RedisModel;
+
+import java.util.List;
+
+/**
+ * @author Liukx
+ * @create 2017-11-06 11:24
+ * @email liukx@elab-plus.com
+ **/
+public interface IService {
+
+    public Info test(RedisModel redisModel);
+
+    public RedisModel testParams(RedisModel redisModel);
+
+    public List<String> testList();
+
+    public Info updateCache(RedisModel redisModel);
+
+    public Info CacheEvict(RedisModel redisModel);
+
+}

+ 81 - 0
elab-cache/src/test/java/service/impl/ServiceImpl.java

@@ -0,0 +1,81 @@
+package service.impl;
+
+import com.elab.core.bean.Info;
+import model.RedisModel;
+import org.springframework.cache.annotation.CacheConfig;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.CachePut;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+import service.IService;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Liukx
+ * @create 2017-11-06 11:24
+ * @email liukx@elab-plus.com
+ **/
+@Service
+@CacheConfig(cacheNames = "redisClient")
+public class ServiceImpl implements IService {
+
+//    @Autowired
+//    ICacheClient cacheClient;
+
+
+    @Cacheable(key = "'lkx_test_'+#redisModel.id", condition = "#redisModel.id != null")
+    public Info test(RedisModel redisModel) {
+        System.out.println("执行完毕");
+        Info info = new Info();
+        info.setSingle("OK");
+        return info;
+    }
+
+    @Override
+    @Cacheable
+    public RedisModel testParams(RedisModel redisModel) {
+        System.out.println("===========执行了===========");
+        return redisModel;
+    }
+
+    @Cacheable
+    public List<String> testList() {
+        List<String> list= new ArrayList<>();
+        list.add("aaaa");
+        list.add("aaaa1");
+        list.add("aaaa2");
+        System.out.println("进入 OK--------");
+        return list;
+    }
+
+    /**
+     * 每次都执行更新操作的注解
+     *
+     * @param redisModel
+     * @return
+     */
+    @CachePut(key = "'lkx_test_'+#redisModel.id")
+    public Info updateCache(RedisModel redisModel) {
+        System.out.println("执行修改完毕..");
+        Info info = new Info();
+        info.setSingle("OK");
+        return info;
+    }
+
+    /**
+     * allEntries : 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存
+     * beforeInvocation : 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存
+     *
+     * @param redisModel
+     * @return
+     */
+    @CacheEvict(key = "'lkx'", allEntries = false, beforeInvocation = false)
+    public Info CacheEvict(RedisModel redisModel) {
+        System.out.println("执行del完毕..");
+        Info info = new Info();
+        info.setSingle("OK");
+        return info;
+    }
+}

+ 41 - 0
elab-cache/src/test/java/utils/SerializeUtil.java

@@ -0,0 +1,41 @@
+package utils;
+
+import java.io.*;
+
+/**
+ * @Description: 对象序列化工具类
+ * @Author: Liukx on 2017/5/22 - 9:38
+ */
+public class SerializeUtil {
+
+    //序列化
+    public static byte[] serialize(Object obj) {
+        ObjectOutputStream obi = null;
+        ByteArrayOutputStream bai = null;
+        try {
+            bai = new ByteArrayOutputStream();
+            obi = new ObjectOutputStream(bai);
+            obi.writeObject(obj);
+            byte[] byt = bai.toByteArray();
+            return byt;
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    //反序列化
+    public static Object unserizlize(byte[] byt) {
+        ObjectInputStream oii = null;
+        ByteArrayInputStream bis = null;
+        bis = new ByteArrayInputStream(byt);
+        try {
+            oii = new ObjectInputStream(bis);
+            Object obj = oii.readObject();
+            return obj;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}

+ 116 - 0
elab-cache/src/test/resources/cacheCloud/applicationContext-redis.xml

@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns:cache="http://www.springframework.org/schema/cache"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+    http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
+    http://www.springframework.org/schema/context
+    http://www.springframework.org/schema/context/spring-context.xsd
+     http://www.springframework.org/schema/cache
+     http://www.springframework.org/schema/cache/spring-cache.xsd
+    ">
+    <!--<context:property-placeholder location="classpath:cacheCloudClient.properties"/>-->
+    <context:component-scan base-package="service">
+        <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
+        <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
+        <context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/>
+        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
+    </context:component-scan>
+    <!-- 默认生成的缓存key的实现策略 -->
+    <bean id="defaultCacheKeyGenerator" class="com.elab.cache.spring.generator.DefaultCacheKeyGenerator">
+        <property name="prefix" value="demo"/>
+        <property name="separator" value="_"/>
+    </bean>
+
+    <!--<bean id="namedCacheResolver" class="org.springframework.cache.interceptor.NamedCacheResolver">-->
+    <!--<property name="cacheNames">-->
+    <!--<list>-->
+    <!--<value>redisClient</value>-->
+    <!--</list>-->
+    <!--</property>-->
+    <!--<property name="cacheManager" ref="cacheManager" />-->
+    <!--</bean>-->
+
+    <!-- 异常处理类 -->
+    <bean id="errorCacheHandle" class="com.elab.cache.spring.handle.ErrorCacheHandle"/>
+
+    <!-- 开启缓存扫描注解包 -->
+    <cache:annotation-driven error-handler="errorCacheHandle" key-generator="defaultCacheKeyGenerator"/>
+
+    <!-- 客户端操作类 -->
+    <!--<bean id="redisClusterClient" class="com.elab.cache.redis.RedisClusterClient" init-method="init" lazy-init="true">-->
+    <!--<property name="redisBuilder" ref="redisClusterBuilder"></property>-->
+    <!--</bean>-->
+
+    <!-- 主备 -->
+    <bean id="redisSentineClient" class="com.elab.cache.redis.RedisSentinelClient" init-method="init" lazy-init="true">
+        <property name="redisBuilder" ref="redisSentinelBuilder"/>
+        <property name="password" value="elab@123"/>
+    </bean>
+
+    <!-- 单机 -->
+    <bean id="redisStandaloneClient" class="com.elab.cache.redis.RedisStandaloneClient" init-method="init"
+          lazy-init="true">
+        <property name="redisBuilder" ref="redisStandaloneBuilder"/>
+        <property name="password" value="elab@123"/>
+        <property name="dbIndex" value="2"/>
+    </bean>
+
+    <!-- 集群连接池配置 -->
+    <bean id="redisPoolConfig" class="org.apache.commons.pool2.impl.GenericObjectPoolConfig">
+        <property name="maxTotal" value="160"/>
+        <property name="maxIdle" value="160"/>
+        <property name="minIdle" value="80"/>
+        <!-- 获取连接最大等待值 -->
+        <property name="maxWaitMillis" value="5000"/>
+        <property name="jmxNamePrefix" value="jedis-pool"/>
+        <property name="jmxEnabled" value="true"/>
+    </bean>
+
+    <!-- 集群版redis操作 -->
+    <!--<bean id="redisClusterBuilder" class="com.sohu.tv.builder.RedisClusterBuilder" lazy-init="true">-->
+    <!--<constructor-arg value="10024"/>-->
+    <!--<property name="jedisPoolConfig" ref="redisPoolConfig"/>-->
+    <!--<property name="connectionTimeout" value="2000"/>-->
+    <!--<property name="soTimeout" value="1000"/>-->
+    <!--</bean>-->
+
+    <!-- 单机版redis 操作 -->
+    <bean id="redisStandaloneBuilder" class="com.sohu.tv.builder.RedisStandaloneBuilder" lazy-init="true">
+        <constructor-arg value="10024"/>
+        <property name="timeout" value="2000"/>
+        <property name="poolConfig" ref="redisPoolConfig"/>
+    </bean>
+
+    <!-- redisSentine操作 -->
+    <bean id="redisSentinelBuilder" class="com.sohu.tv.builder.RedisSentinelBuilder" lazy-init="true">
+        <constructor-arg value="10034"/>
+        <property name="poolConfig" ref="redisPoolConfig"/>
+        <property name="connectionTimeout" value="2000"/>
+        <property name="soTimeout" value="1000"/>
+    </bean>
+
+    <bean id="systemCacheManage" class="com.elab.cache.spring.manage.SystemCacheManage">
+        <property name="cacheClient" ref="redisStandaloneClient"/>
+        <property name="timeout" value="300"/>
+        <property name="name" value="redisClient"/>
+    </bean>
+
+    <bean id="simpleCacheManager" class="org.springframework.cache.support.SimpleCacheManager">
+        <property name="caches" ref="systemCacheManage"/>
+    </bean>
+
+
+    <bean id="cacheManager"
+          class="org.springframework.cache.support.CompositeCacheManager">
+        <property name="cacheManagers">
+            <list>
+                <ref bean="simpleCacheManager"/>
+            </list>
+        </property>
+        <property name="fallbackToNoOpCache" value="true"/>
+    </bean>
+
+
+</beans>

+ 8 - 0
elab-cache/src/test/resources/cacheCloud/cacheCloudClient.properties

@@ -0,0 +1,8 @@
+http_conn_timeout = 3000
+http_socket_timeout = 5000
+client_version = 1.0-SNAPSHOT
+domain_url =http://192.168.0.24:9999
+redis_cluster_suffix = /cache/client/redis/cluster/%s.json?clientVersion=
+redis_sentinel_suffix = /cache/client/redis/sentinel/%s.json?clientVersion=
+redis_standalone_suffix = /cache/client/redis/standalone/%s.json?clientVersion=
+cachecloud_report_url = /cachecloud/client/reportData.json

+ 98 - 0
elab-cache/src/test/resources/log4j.properties

@@ -0,0 +1,98 @@
+log4j.rootLogger=DEBUG,systemOut
+  
+log4j.appender.systemOut = org.apache.log4j.ConsoleAppender
+log4j.appender.systemOut.layout = org.apache.log4j.PatternLayout
+log4j.appender.systemOut.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}] [%l] %n [ **************** %m ****************** ] %n%n
+log4j.appender.systemOut.Threshold = DEBUG
+log4j.appender.systemOut.ImmediateFlush = TRUE
+log4j.appender.systemOut.Target = System.out
+
+# 输出错误日志 ###
+#log4j.appender.logFile=org.apache.log4j.ConsoleAppender
+log4j.appender.logFile=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.logFile.File = /var/logs/clgg-dtms/error/dtms-error.logs
+#log4j.appender.logFile.Target = System.out
+log4j.appender.logFile.Threshold = ERROR
+log4j.appender.logFile.layout=org.apache.log4j.PatternLayout
+log4j.appender.logFile.DatePattern = '.'yyyy-MM-dd-HH-mm'.log'
+log4j.appender.logFile.layout.ConversionPattern=%p: [%d{yy/MM/dd HH:mm:ss}][%C-%M] -%m%n
+
+log4j.logger.com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory
+#com.atomikos.icatch.console_file_name = /home/logs/tx/tx.out.log
+#com.atomikos.icatch.log_base_name = txlog
+log4j.logger.com.atomikos.icatch.tm_unique_name = com.atomikos.spring.jdbc.tm
+log4j.logger.com.atomikos.icatch=INFO
+#log4j.logger.com.mybatis=DEBUG
+#log4j.logger.com.mybatis.config.jdbc.SimpleDataSource=DEBUG
+#log4j.logger.com.mybatis.config.jdbc.ScriptRunner=DEBUG
+#log4j.logger.com.mybatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
+#log4j.logger.java.sql.Connection=DEBUG
+#log4j.logger.java.sql.Statement=DEBUG
+#log4j.logger.java.sql.PreparedStatement=DEBUG
+log4j.logger.java.sql.ResultSet=INFO
+log4j.logger.org.apache=INFO  
+log4j.logger.java.sql.Connection=DEBUG  
+log4j.logger.java.sql.Statement=DEBUG  
+log4j.logger.java.sql.PreparedStatement=DEBUG 
+
+
+#log4j.logger.com.lkx = info
+log4j.logger.org.springframework=INFO
+
+#OFF,systemOut,logFile,logDailyFile,logRollingFile,logMail,logDB,ALL 
+#log4j.rootLogger =DEBUG,systemOut,logFile,logDailyFile,logRollingFile
+
+#输出到控制台 
+#log4j.appender.systemOut = org.apache.log4j.ConsoleAppender 
+#log4j.appender.systemOut.layout = org.apache.log4j.PatternLayout 
+#log4j.appender.systemOut.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}][%l]%n%m%n 
+#log4j.appender.systemOut.Threshold = DEBUG 
+#log4j.appender.systemOut.ImmediateFlush = TRUE 
+#log4j.appender.systemOut.Target = System.out 
+
+#输出到文件 
+#log4j.appender.logFile = org.apache.log4j.FileAppender 
+#log4j.appender.logFile.layout = org.apache.log4j.PatternLayout 
+#log4j.appender.logFile.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}][%l]%n%m%n 
+#log4j.appender.logFile.Threshold = DEBUG 
+#log4j.appender.logFile.ImmediateFlush = TRUE 
+#log4j.appender.logFile.Append = TRUE 
+#log4j.appender.logFile.File = E:\\logs\\log4j_Struts.log 
+#log4j.appender.logFile.Encoding = UTF-8 
+
+#按DatePattern输出到文件 
+#log4j.appender.logDailyFile = org.apache.log4j.DailyRollingFileAppender 
+#log4j.appender.logDailyFile.layout = org.apache.log4j.PatternLayout 
+#log4j.appender.logDailyFile.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}][%l]%n%m%n 
+#log4j.appender.logDailyFile.Threshold = ERROR 
+#log4j.appender.logDailyFile.ImmediateFlush = TRUE 
+#log4j.appender.logDailyFile.Append = TRUE 
+#log4j.appender.logDailyFile.File = E:\\logs\\error.log
+#log4j.appender.logDailyFile.DatePattern = '.'yyyy-MM-dd-HH-mm'.log' 
+#log4j.appender.logDailyFile.Encoding = UTF-8 
+
+#设定文件大小输出到文件 
+#log4j.appender.logRollingFile = org.apache.log4j.RollingFileAppender 
+#log4j.appender.logRollingFile.layout = org.apache.log4j.PatternLayout 
+#log4j.appender.logRollingFile.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}][%l]%n%m%n 
+#log4j.appender.logRollingFile.Threshold = ERROR 
+#log4j.appender.logRollingFile.ImmediateFlush = TRUE 
+#log4j.appender.logRollingFile.Append = TRUE 
+#log4j.appender.logRollingFile.File = E:\\logs\\logFile.log
+#log4j.appender.logRollingFile.MaxFileSize = 1MB 
+#log4j.appender.logRollingFile.MaxBackupIndex = 10 
+#log4j.appender.logRollingFile.Encoding = UTF-8 
+
+###显示SQL语句部分
+#log4j.logger.com.mybatis=DEBUG
+#log4j.logger.com.mybatis.config.jdbc.SimpleDataSource=DEBUG
+#log4j.logger.com.mybatis.config.jdbc.ScriptRunner=DEBUG
+#log4j.logger.com.mybatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
+#log4j.logger.java.sql.Connection=DEBUG
+#log4j.logger.java.sql.Statement=DEBUG
+#log4j.logger.java.sql.PreparedStatement=DEBUG
+
+#log4j.logger.org.springframework=WARN
+
+#log4j.logger.org.springframework=INFO
+#log4j.logger.org.springframework.web.servlet.view=INFO

+ 201 - 0
elab-core/pom.xml

@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>com.elab.core</groupId>
+        <artifactId>elab-parent</artifactId>
+        <version>2.0.4.10-SNAPSHOT</version>
+    </parent>
+
+    <groupId>com.elab.core</groupId>
+    <artifactId>elab-core</artifactId>
+    <packaging>jar</packaging>
+
+    <properties>
+        <java-version>1.8</java-version>
+        <profiles.active>test</profiles.active>
+    </properties>
+    <!-- jetty插件 -->
+    <build>
+
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>${java-version}</source>
+                    <target>${java-version}</target>
+                </configuration>
+            </plugin>
+
+            <!-- 打包源码插件 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>attach-sources</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <!-- 打包javadoc插件 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <!--<version>2.9</version>-->
+                <executions>
+                    <execution>
+                        <id>attach-javadocs</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                        <configuration>
+                            <additionalOptions>-Xdoclint:none</additionalOptions>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+
+    <distributionManagement>
+        <repository>
+            <id>releases</id>
+            <name>Nexus Release Repository</name>
+            <url>http://192.168.0.11:8081/nexus/content/repositories/elab/</url>
+        </repository>
+    </distributionManagement>
+
+    <dependencies>
+        <!--<dependency>-->
+        <!--<groupId>mysql</groupId>-->
+        <!--<artifactId>mysql-connector-java</artifactId>-->
+        <!--</dependency>-->
+
+        <!-- 数据源 -->
+        <!--<dependency>-->
+        <!--<groupId>com.alibaba</groupId>-->
+        <!--<artifactId>druid</artifactId>-->
+        <!--</dependency>-->
+
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+
+        <!-- 工具 -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+        </dependency>
+
+        <!-- https://mvnrepository.com/artifact/commons-net/commons-net -->
+        <dependency>
+            <groupId>commons-net</groupId>
+            <artifactId>commons-net</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjweaver</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+
+        <!-- xml解析 -->
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+
+        <!-- 中文转pinyin -->
+        <dependency>
+            <groupId>com.belerweb</groupId>
+            <artifactId>pinyin4j</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-utils</artifactId>
+        </dependency>
+
+
+
+        <!-- log4j 日志 本地存储 -->
+        <!--<dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.16</version>
+        </dependency>
+-->
+        <!-- log4 日志 mongodb数据库存储 -->
+        <!--<dependency>-->
+        <!--<groupId>org.log4mongo</groupId>-->
+        <!--<artifactId>log4mongo-java</artifactId>-->
+        <!--</dependency>-->
+
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+
+        <!--发送邮件  -->
+        <!--<dependency>-->
+            <!--<groupId>javax.mail</groupId>-->
+            <!--<artifactId>mail</artifactId>-->
+        <!--</dependency>-->
+
+        <!-- 模板 -->
+        <dependency>
+            <groupId>org.freemarker</groupId>
+            <artifactId>freemarker</artifactId>
+        </dependency>
+
+        <!-- servlet -->
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+        </dependency>
+
+        <!-- 文件上传 -->
+        <dependency>
+            <groupId>commons-fileupload</groupId>
+            <artifactId>commons-fileupload</artifactId>
+        </dependency>
+
+        <!-- encoding -->
+        <dependency>
+            <groupId>org.apache.axis</groupId>
+            <artifactId>axis</artifactId>
+        </dependency>
+
+        <!--<dependency>-->
+        <!--<groupId>com.dianping.cat</groupId>-->
+        <!--<artifactId>cat-core</artifactId>-->
+        <!--<version>2.0.0</version>-->
+        <!--</dependency>-->
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-beanutils</groupId>
+            <artifactId>commons-beanutils</artifactId>
+        </dependency>
+    </dependencies>
+
+
+</project>

+ 335 - 0
elab-core/pom.xml.versionsBackup

@@ -0,0 +1,335 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>com.elab.core</groupId>
+        <artifactId>elab-parent</artifactId>
+        <version>2.0.0</version>
+    </parent>
+
+    <groupId>com.elab.core</groupId>
+    <artifactId>elab-core</artifactId>
+    <version>2.0.0</version>
+    <packaging>jar</packaging>
+
+    <properties>
+        <java-version>1.8</java-version>
+        <profiles.active>test</profiles.active>
+        <springframework.version>4.1.6.RELEASE</springframework.version>
+    </properties>
+    <!-- jetty插件 -->
+    <build>
+
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>${java-version}</source>
+                    <target>${java-version}</target>
+                </configuration>
+            </plugin>
+
+
+            <plugin>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-maven-plugin</artifactId>
+                <version>9.4.5.v20170502</version>
+                <configuration>
+                    <stopPort>9981</stopPort>
+                    <stopKey>foo</stopKey>
+                    <scanIntervalSeconds>10</scanIntervalSeconds>
+
+                    <httpConnector>
+                        <port>8080</port>
+                    </httpConnector>
+                    <webAppConfig>
+                        <contextPath>/elab</contextPath>
+                    </webAppConfig>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-war-plugin</artifactId>
+                <version>2.1.1</version>
+                <configuration>
+                    <packagingExcludes>WEB-INF/web.xml</packagingExcludes>
+                    <warName>${profiles.active}</warName>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>com/elab/core/controller/HelloController.class</exclude>
+                        <exclude>com/elab/core/service/**</exclude>   <!--排除一些不需要打包的class文件,此处是排除aboutjar包下的所有class文件-->
+                        <exclude>com/elab/core/dao/IHelloDao.class</exclude>
+                        <exclude>com/elab/core/dao/impl/**</exclude>
+                        <exclude>com/elab/core/models/**</exclude>
+                        <exclude>applicationContext-datasource.xml</exclude>
+                        <exclude>global-config.xml</exclude>
+                        <exclude>META-INF/app.properties</exclude>
+                        <exclude>spring-mvc.xml</exclude>
+                        <exclude>database.properties</exclude>
+                        <exclude>dictionary/**</exclude>
+                        <exclude>sql/**</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+
+
+
+            <!-- 打包源码插件 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>attach-sources</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <!-- 打包javadoc插件 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <!--<version>2.9</version>-->
+                <executions>
+                    <execution>
+                        <id>attach-javadocs</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                        <configuration>
+                            <additionalparam>-Xdoclint:none</additionalparam>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+
+    <distributionManagement>
+        <repository>
+            <id>releases</id>
+            <name>Nexus Release Repository</name>
+            <url>http://192.168.0.11:8081/nexus/content/repositories/elab/</url>
+        </repository>
+    </distributionManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>5.1.18</version>
+        </dependency>
+
+        <!-- Spring Core -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-core</artifactId>
+            <version>${springframework.version}</version>
+        </dependency>
+
+        <!-- context -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+            <version>${springframework.version}</version>
+        </dependency>
+
+        <!-- context -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context-support</artifactId>
+            <version>${springframework.version}</version>
+        </dependency>
+
+        <!-- jdbc -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-jdbc</artifactId>
+            <version>${springframework.version}</version>
+        </dependency>
+
+        <!-- tx -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-tx</artifactId>  <!--spring transaction-->
+            <version>${springframework.version}</version>
+        </dependency>
+
+        <!-- beans -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-beans</artifactId>
+            <version>${springframework.version}</version>
+        </dependency>
+
+        <!-- aop -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-aop</artifactId>
+            <version>${springframework.version}</version>
+        </dependency>
+
+        <!-- webmvc -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+            <version>${springframework.version}</version>
+        </dependency>
+
+        <!-- web -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+            <version>${springframework.version}</version>
+        </dependency>
+
+        <!-- 数据源 -->
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid</artifactId>
+            <version>1.1.6</version>
+        </dependency>
+
+        <!-- 工具 -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.16</version>
+        </dependency>
+
+        <!-- https://mvnrepository.com/artifact/commons-net/commons-net -->
+        <dependency>
+            <groupId>commons-net</groupId>
+            <artifactId>commons-net</artifactId>
+            <version>3.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjweaver</artifactId>
+            <version>1.8.4</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>18.0</version>
+        </dependency>
+
+        <!-- xml解析 -->
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>2.2.2</version>
+        </dependency>
+
+        <!-- 中文转pinyin -->
+        <dependency>
+            <groupId>com.belerweb</groupId>
+            <artifactId>pinyin4j</artifactId>
+            <version>2.5.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-utils</artifactId>
+            <version>3.0.8</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.21</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.7.21</version>
+        </dependency>
+
+        <!-- log4j 日志 本地存储 -->
+        <!--<dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.16</version>
+        </dependency>
+-->
+        <!-- log4 日志 mongodb数据库存储 -->
+        <dependency>
+            <groupId>org.log4mongo</groupId>
+            <artifactId>log4mongo-java</artifactId>
+            <version>0.7.4</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>3.4</version>
+        </dependency>
+
+        <!--发送邮件  -->
+        <dependency>
+            <groupId>javax.mail</groupId>
+            <artifactId>mail</artifactId>
+            <version>1.4.1</version>
+        </dependency>
+
+        <!-- 模板 -->
+        <dependency>
+            <groupId>org.freemarker</groupId>
+            <artifactId>freemarker</artifactId>
+            <version>2.3.16</version>
+        </dependency>
+
+        <!-- servlet -->
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <version>3.1.0</version>
+        </dependency>
+
+        <!-- 文件上传 -->
+        <dependency>
+            <groupId>commons-fileupload</groupId>
+            <artifactId>commons-fileupload</artifactId>
+            <version>1.3.1</version>
+        </dependency>
+
+        <!-- encoding -->
+        <dependency>
+            <groupId>org.apache.axis</groupId>
+            <artifactId>axis</artifactId>
+            <version>1.4</version>
+        </dependency>
+
+        <!--<dependency>-->
+            <!--<groupId>com.dianping.cat</groupId>-->
+            <!--<artifactId>cat-core</artifactId>-->
+            <!--<version>2.0.0</version>-->
+        <!--</dependency>-->
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+
+</project>

BIN
elab-core/readme.docx


+ 31 - 0
elab-core/src/main/java/com/elab/core/CoreConstant.java

@@ -0,0 +1,31 @@
+package com.elab.core;
+
+/**
+ * @author liuhx on 2017/1/2 13:57
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class CoreConstant {
+    public static final String DELIMITER=",";
+    public static final String SIGN_TYPE = "sign_type";
+    public static final String SIGN_TYPE_RSA = "RSA";
+    public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
+    public static final String FORMAT = "format";
+    public static final String METHOD = "method";
+    public static final String TIMESTAMP = "timestamp";
+    public static final String VERSION = "version";
+    public static final String SIGN = "sign";
+    //token 密钥
+    public static final String AUTH_TOKEN_KEY = "MIGfMA0GCSqGSIb3DQEBAQUA";
+    public static final String ACCESS_TOKEN = "auth_token";
+    public static final String HEAD = "head";
+    public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
+    public static final String DATE_TIMEZONE = "GMT+8";
+    public static final String CHARSET = "charset";
+    public static final String CHARSET_UTF8 = "UTF-8";
+    public static final String CHARSET_GBK = "GBK";
+    public static final String FORMAT_JSON = "json";
+    public static final String FORMAT_XML = "xml";
+
+
+}

+ 37 - 0
elab-core/src/main/java/com/elab/core/aop/annotations/ExceptionHandle.java

@@ -0,0 +1,37 @@
+package com.elab.core.aop.annotations;
+
+import java.lang.annotation.*;
+
+/**
+ * 处理异常的AOP注解
+ *
+ * @author liuhx on 2017/1/5 20:07
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+@Inherited
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ExceptionHandle {
+
+    /**
+     * 负责人名称
+     *
+     * @return
+     */
+    String username() default "";
+
+    /**
+     * 定义异常来源于哪个类
+     *
+     * @return
+     */
+    Class ModuleName();
+
+    /**
+     * 异常是否需要往外部调用方抛
+     *
+     * @return
+     */
+    boolean Throwable() default false;
+}

+ 69 - 0
elab-core/src/main/java/com/elab/core/bean/BaseInfo.java

@@ -0,0 +1,69 @@
+package com.elab.core.bean;
+
+import com.elab.core.utils.DateUtils;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ *
+ * @author liuhx on 2016/12/11 15:12
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class BaseInfo implements Serializable {
+    private Boolean success = Boolean.valueOf(true);
+    private String errorCode;
+    private String message;
+    private String timestamp = DateUtils.getCurrentTime();                       //服务器的时间戳
+    private Map<String, Object> extension;          // 扩展字段
+
+    public BaseInfo() {
+    }
+
+    public BaseInfo(Boolean success, String errorCode, String message) {
+        this.success = success;
+        this.errorCode = errorCode;
+        this.message = message;
+    }
+
+    public boolean isSuccess() {
+        return this.success.booleanValue();
+    }
+
+    public void setSuccess(boolean success) {
+        this.success = Boolean.valueOf(success);
+    }
+
+    public String getErrorCode() {
+        return this.errorCode;
+    }
+
+    public void setErrorCode(String errorCode) {
+        this.errorCode = errorCode;
+    }
+
+    public String getMessage() {
+        return this.message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public String getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(String timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public Map<String, Object> getExtension() {
+        return extension;
+    }
+
+    public void setExtension(Map<String, Object> extension) {
+        this.extension = extension;
+    }
+}

+ 65 - 0
elab-core/src/main/java/com/elab/core/bean/Info.java

@@ -0,0 +1,65 @@
+package com.elab.core.bean;
+
+import java.util.List;
+
+/**
+ * 单个对象或者是集合,使用这个返回类
+ *
+ * @author liuhx on 2016/12/11 15:11
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class Info<T> extends BaseInfo {
+    private T single;
+    private List<T> list;
+    private int id;
+    private PageModel<T> pageModel;
+
+    public Info() {
+
+    }
+
+    public static Info NO(String errorCode, String message) {
+        Info info = new Info();
+        info.setSuccess(false);
+        info.setErrorCode(errorCode);
+        info.setMessage(message);
+        return info;
+    }
+
+    public Info(Boolean success, String errorCode, String message) {
+        super(success, errorCode, message);
+    }
+
+    public T getSingle() {
+        return single;
+    }
+
+    public void setSingle(T single) {
+        this.single = single;
+    }
+
+    public List<T> getList() {
+        return list;
+    }
+
+    public void setList(List<T> list) {
+        this.list = list;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public PageModel<T> getPageModel() {
+        return pageModel;
+    }
+
+    public void setPageModel(PageModel<T> pageModel) {
+        this.pageModel = pageModel;
+    }
+}

+ 25 - 0
elab-core/src/main/java/com/elab/core/bean/PageInfo.java

@@ -0,0 +1,25 @@
+package com.elab.core.bean;
+
+/**
+ * @author liuhx on 2016/12/19 10:50
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class PageInfo extends BaseInfo {
+    private PageModel pageModel;
+
+    public PageInfo() {
+    }
+
+    public PageInfo(boolean success, String errorCode, String message) {
+        super(success, errorCode, message);
+    }
+
+    public PageModel getPageModel() {
+        return this.pageModel;
+    }
+
+    public void setPageModel(PageModel pageModel) {
+        this.pageModel = pageModel;
+    }
+}

+ 124 - 0
elab-core/src/main/java/com/elab/core/bean/PageModel.java

@@ -0,0 +1,124 @@
+package com.elab.core.bean;
+
+import java.util.List;
+
+/**
+ * @author liuhx on 2016/12/19 10:50
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class PageModel<T> {
+
+    private int rowTotal;
+    private int pageSize = 3;
+    private int count = 1;
+    private int total;
+    private int beginIndex;
+    private int endIndex;
+    private List<T> resultSet;
+    private String orderby = "";
+
+    public PageModel(int totalRow, int count) {
+        this.rowTotal = totalRow;
+        this.count = count;
+    }
+
+    public PageModel(int totalRow, int count, int pageSize) {
+        this.rowTotal = totalRow;
+        this.count = count;
+        this.pageSize = pageSize;
+    }
+
+    public List<T> getResultSet() {
+        return this.resultSet;
+    }
+
+    public void setResultSet(List<T> resultSet) {
+        this.resultSet = resultSet;
+    }
+
+    public int getRowTotal() {
+        return this.rowTotal;
+    }
+
+    public void setRowTotal(int rowTotal) {
+        this.rowTotal = rowTotal;
+        this.calculate();
+    }
+
+    private void calculate() {
+        if(this.rowTotal != 0) {
+            this.total = this.rowTotal / this.pageSize + (this.rowTotal % this.pageSize > 0?1:0);
+            if(this.count >= this.total) {
+                this.count = this.total;
+            } else if(this.count < 1) {
+                this.count = 1;
+            }
+
+            this.beginIndex = (this.count - 1) * this.pageSize;
+            if(this.beginIndex > this.rowTotal) {
+                this.beginIndex = this.rowTotal - 1;
+            }
+
+            this.endIndex = this.beginIndex + this.pageSize - 1;
+            if(this.endIndex > this.rowTotal) {
+                this.endIndex = this.rowTotal;
+            }
+
+        }
+    }
+
+    public int getCount() {
+        return this.count;
+    }
+
+    public void setCount(int count) {
+        this.count = count;
+        this.calculate();
+    }
+
+    public int getTotal() {
+        return this.total;
+    }
+
+    public void setTotal(int total) {
+        this.total = total;
+    }
+
+    public int getTotalRow() {
+        return this.rowTotal;
+    }
+
+    public int getPageSize() {
+        return this.pageSize;
+    }
+
+    public void setPageSize(int pageSize) {
+        this.pageSize = pageSize;
+        this.calculate();
+    }
+
+    public int getBeginIndex() {
+        return this.beginIndex;
+    }
+
+    public void setBeginIndex(int beginIndex) {
+        this.beginIndex = beginIndex;
+    }
+
+    public int getEndIndex() {
+        return this.endIndex;
+    }
+
+    public void setEndIndex(int endIndex) {
+        this.endIndex = endIndex;
+    }
+
+    public String getOrderby() {
+        return this.orderby;
+    }
+
+    public void setOrderby(String orderby) {
+        this.orderby = orderby;
+    }
+}

+ 45 - 0
elab-core/src/main/java/com/elab/core/collections/MapAdapter.java

@@ -0,0 +1,45 @@
+package com.elab.core.collections;
+
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author liuhx on 2017/1/2 13:51
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class MapAdapter extends XmlAdapter<MapElements[],HashMap<String,String>> {
+
+    /**
+     * Convert a value type to a bound type.
+     *
+     * @param v The value to be converted. Can be null.
+     * @throws Exception if there's an error during the conversion. The caller is responsible for
+     *                   reporting the error to the user through {@link javax.xml.bind.ValidationEventHandler}.
+     */
+    @Override
+    public HashMap<String, String> unmarshal(MapElements[] v) throws Exception {
+        HashMap<String, String> r = new HashMap<String, String>();
+        for (MapElements mapelement : v)
+            r.put(mapelement.key, mapelement.value);
+        return r;
+    }
+
+    /**
+     * Convert a bound type to a value type.
+     *
+     * @param v The value to be convereted. Can be null.
+     * @throws Exception if there's an error during the conversion. The caller is responsible for
+     *                   reporting the error to the user through {@link javax.xml.bind.ValidationEventHandler}.
+     */
+    @Override
+    public MapElements[] marshal(HashMap<String, String> v) throws Exception {
+        MapElements[] mapElements = new MapElements[v.size()];
+        int i = 0;
+        for (Map.Entry<String, String> entry : v.entrySet())
+            mapElements[i++] = new MapElements(entry.getKey(), entry.getValue());
+        return mapElements;
+    }
+}
+

+ 22 - 0
elab-core/src/main/java/com/elab/core/collections/MapElements.java

@@ -0,0 +1,22 @@
+package com.elab.core.collections;
+
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * @author liuhx on 2017/1/2 13:51
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class MapElements {
+    @XmlElement
+    public String key;
+    @XmlElement
+    public String value;
+    @SuppressWarnings("unused")
+    private MapElements() {
+    }
+    public MapElements(String key, String value) {
+        this.key = key;
+        this.value = value;
+    }
+}

+ 280 - 0
elab-core/src/main/java/com/elab/core/collections/NameValueCollection.java

@@ -0,0 +1,280 @@
+package com.elab.core.collections;
+
+import java.util.*;
+
+/**
+ * @author liuhx on 2017/1/2 14:21
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class NameValueCollection extends HashMap
+{
+    private static final long serialVersionUID = -6855645147487103017L;
+    private transient Collection values=null;
+
+    /**
+     * Constructor.
+     */
+    public NameValueCollection()
+    {
+        super();
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param initialCapacity  the initial capacity
+     */
+    public NameValueCollection(int initialCapacity)
+    {
+        super(initialCapacity);
+    }
+
+    /**
+     * Constructor.
+     * @param initialCapacity initial capacity
+     * @param loadFactor      load factor for the Map.
+     */
+    public NameValueCollection(int initialCapacity, float loadFactor)
+    {
+        super(initialCapacity, loadFactor);
+    }
+
+    /**
+     * Constructor.
+     * @param map  The initial Map.
+     */
+    public NameValueCollection(NameValueCollection map)
+    {
+        super();
+        if( map != null )
+        {
+            Iterator it = map.entrySet().iterator();
+            while( it.hasNext() )
+            {
+                Entry entry = (Entry) it.next();
+                super.put(entry.getKey(), new ArrayList((List)entry.getValue()));
+            }
+        }
+    }
+
+    /**
+     * Check if the map contains the passed value.
+     *
+     * @param value  the value to search for
+     * @return true if the list contains the value
+     */
+    @Override
+    public boolean containsValue(Object value)
+    {
+        Set pairs = super.entrySet();
+
+        if (pairs == null)
+        {
+            return false;
+        }
+        Iterator pairsIterator = pairs.iterator();
+        while (pairsIterator.hasNext())
+        {
+            Entry keyValuePair = (Entry) pairsIterator.next();
+            Collection coll = (Collection) keyValuePair.getValue();
+            if (coll.contains(value))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Add a key, and its value, to the map.
+     *
+     * @param key   the key to set
+     * @param value the value to set the key to
+     * @return the value added when successful, or null if an error
+     */
+    @Override
+    public Object put(Object key,Object value)
+    {
+        Collection c=(Collection)super.get(key);
+        if (c == null)
+        {
+            c = createCollection(null);
+            super.put(key, c);
+        }
+        boolean results = c.add(value);
+
+        return (results ? value : null);
+    }
+
+    /**
+     * Removes a specific value from map.
+     * The item is removed from the collection mapped to the specified key.
+     *
+     * @param key  the key to remove from
+     * @param item  the value to remove
+     * @return the value removed (which was passed in)
+     */
+    public boolean remove(Object key, Object item)
+    {
+        Collection valuesForKey=(Collection)super.get(key);
+        if (valuesForKey == null)
+        {
+            return false;
+        }
+        valuesForKey.remove(item);
+
+        // remove the list if it is now empty
+        // (saves space, and allows equals to work)
+        if (valuesForKey.isEmpty())
+        {
+            remove(key);
+        }
+        return true;
+    }
+
+    /**
+     * Clear the map.
+     */
+    public void clear()
+    {
+        // Clear the mappings
+        Set pairs=super.entrySet();
+        Iterator pairsIterator = pairs.iterator();
+        while (pairsIterator.hasNext())
+        {
+            Entry keyValuePair=(Entry) pairsIterator.next();
+            Collection coll=(Collection)keyValuePair.getValue();
+            coll.clear();
+        }
+        super.clear();
+    }
+
+    /**
+     * Accessor for the values in the Map.
+     * @return all of the values in the map
+     */
+    public Collection values()
+    {
+        Collection vs = values;
+        return (vs != null ? vs : (values = new ValueElement()));
+    }
+
+    /**
+     * Method to clone the Map. Performs a shallow copy of the entry set.
+     * @return the cloned map
+     */
+    public Object clone()
+    {
+        NameValueCollection obj = (NameValueCollection) super.clone();
+
+        // Clone the entry set.
+        for (Iterator it = entrySet().iterator(); it.hasNext();)
+        {
+            Entry entry = (Entry) it.next();
+            Collection coll = (Collection) entry.getValue();
+            Collection newColl = createCollection(coll);
+            entry.setValue(newColl);
+        }
+        return obj;
+    }
+
+    /**
+     * Creates a new instance of the map value Collection container.
+     *
+     * @param c  the collection to copy
+     * @return   new collection
+     */
+    protected Collection createCollection(Collection c)
+    {
+        if (c == null)
+        {
+            return new ArrayList();
+        }
+        else
+        {
+            return new ArrayList(c);
+        }
+    }
+
+    /**
+     * Representation of the values.
+     */
+    private class ValueElement extends AbstractCollection
+    {
+        public Iterator iterator()
+        {
+            return new ValueElementIter();
+        }
+
+        public int size()
+        {
+            int i=0;
+            Iterator iter = iterator();
+            while (iter.hasNext())
+            {
+                iter.next();
+                i++;
+            }
+            return i;
+        }
+
+        public void clear()
+        {
+            NameValueCollection.this.clear();
+        }
+    }
+
+    /**
+     * Iterator for the values.
+     */
+    private class ValueElementIter implements Iterator
+    {
+        private Iterator backing;
+        private Iterator temp;
+
+        private ValueElementIter()
+        {
+            backing = NameValueCollection.super.values().iterator();
+        }
+
+        private boolean searchNextIterator()
+        {
+            while (temp == null ||
+                    temp.hasNext() == false)
+            {
+                if (backing.hasNext() == false)
+                {
+                    return false;
+                }
+                temp = ((Collection) backing.next()).iterator();
+            }
+            return true;
+        }
+
+        @Override
+        public boolean hasNext()
+        {
+            return searchNextIterator();
+        }
+
+        public Object next()
+        {
+            if (searchNextIterator() == false)
+            {
+                throw new NoSuchElementException();
+            }
+            return temp.next();
+        }
+
+        public void remove()
+        {
+            if (temp == null)
+            {
+                throw new IllegalStateException();
+            }
+            temp.remove();
+        }
+
+    }
+}

+ 82 - 0
elab-core/src/main/java/com/elab/core/configuration/ConfigEnumeration.java

@@ -0,0 +1,82 @@
+package com.elab.core.configuration;
+
+import com.elab.core.CoreConstant;
+import com.elab.core.configuration.entity.EnumerationMode;
+import com.elab.core.configuration.entity.EnumerationModes;
+import com.elab.core.configuration.entity.ValueMode;
+import com.elab.core.serialization.SerializeFactory;
+import com.elab.core.utils.StringUtils;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 字典数据配置,一个key对应集合,用于和后台管理系统的字典枚举类型相呼应
+ * 枚举配置化,主要用于文字写死之类的
+ * @author liuhx on 2017/3/22 16:53
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class ConfigEnumeration {
+    public static final String ENUMERATION_CONFIG = CoreConstant.class.getClassLoader().getResource("dictionary/enumeration.xml").getPath();
+
+    public static Map<String,List<ValueMode>> enumerationMap;
+    public static Map<String,ValueMode> valueModeMap;
+
+    static{
+        //枚举
+        enumerationMap = new HashMap();
+        valueModeMap = new HashMap();
+
+        EnumerationModes modes = SerializeFactory.getXmlSerializer().FromFile(ENUMERATION_CONFIG, EnumerationModes.class);
+        List<EnumerationMode> list =  modes.getEnumeration();
+        if(list != null){
+            for(EnumerationMode mode : list){
+                String type = mode.getType();
+                List<ValueMode> values = mode.getValues();
+                enumerationMap.put(type,values);
+                for(ValueMode vm : values){
+                    valueModeMap.put(type+vm.getVal(),vm);
+                }
+            }
+        }
+    }
+
+    public static String getName(String type,String code){
+        ValueMode vm = valueModeMap.get(type + code);
+        if(vm != null) {
+            return vm.getName();
+        }
+        return "";
+    }
+
+    public static boolean isOutOfRange(String type, String value){
+        if(!StringUtils.areNotEmpty(type,value)){
+            return true;
+        }
+
+        List<ValueMode> vm  = ConfigEnumeration.enumerationMap.get(type);
+
+        if(null == vm || vm.isEmpty()){
+            return true;
+        }
+
+        for(ValueMode item: vm){
+            if(item.getVal().equals(value)){
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static void main(String[] args){
+        List<ValueMode> valueModeList = enumerationMap.get("10001");
+        for(ValueMode vm : valueModeList){
+            System.out.println(vm.getName()+":"+vm.getVal());
+        }
+
+        String name = getName("10001", "1");
+        System.out.println(name);
+    }
+}

+ 42 - 0
elab-core/src/main/java/com/elab/core/configuration/ConfigManager.java

@@ -0,0 +1,42 @@
+package com.elab.core.configuration;
+
+import com.elab.core.CoreConstant;
+import com.elab.core.configuration.entity.GlobalConfig;
+import com.elab.core.configuration.entity.LogManager;
+import com.elab.core.configuration.entity.SettingConfig;
+import com.elab.core.serialization.SerializeFactory;
+import com.elab.core.utils.StringUtils;
+
+/**
+ * @author liuhx on 2017/1/2 13:43
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class ConfigManager {
+    public static final String GLOABLE_CONFIG = CoreConstant.class.getClassLoader().getResource("global-config.xml").getPath();
+
+    static{
+        try {
+            globalConfig = SerializeFactory.getXmlSerializer().FromFile(GLOABLE_CONFIG, GlobalConfig.class);
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            globalConfig = new GlobalConfig();
+        }
+    }
+
+    private static GlobalConfig globalConfig;
+
+    public static LogManager getLogManager() {  return globalConfig.getLogManager();  }
+
+    public static String getProperty(String name) {
+        if(StringUtils.isEmpty(name)) {
+            return "";
+        }
+        SettingConfig config = globalConfig.getSettings().getPropertyByName(name);
+        if(null == config) {
+            return "";
+        }
+        return config.getValue();
+    }
+}

+ 53 - 0
elab-core/src/main/java/com/elab/core/configuration/entity/EnumerationMode.java

@@ -0,0 +1,53 @@
+package com.elab.core.configuration.entity;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import java.util.List;
+
+/**
+ * 第二层节点
+ * <enumerations>
+ *     <enumeration type="" remark=""></enumeration>
+ * </enumerations>
+ * @author liuhx on 2017/3/22 13:48
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+public class EnumerationMode {
+
+    @XmlAttribute(name = "type")
+    private String type;
+
+    @XmlAttribute(name = "remark")
+    private String remark;
+
+    @XmlElement(name = "value")
+    private List<ValueMode> values;
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public List<ValueMode> getValues() {
+        return values;
+    }
+
+    public void setValues(List<ValueMode> values) {
+        this.values = values;
+    }
+}

+ 31 - 0
elab-core/src/main/java/com/elab/core/configuration/entity/EnumerationModes.java

@@ -0,0 +1,31 @@
+package com.elab.core.configuration.entity;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.List;
+
+/**
+ * 最外层xml标签,根节点
+ * <enumerations></enumerations>
+ * @author liuhx on 2017/3/22 13:56
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+@SuppressWarnings("serial")
+@XmlRootElement(name = "enumerations")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class EnumerationModes {
+
+   @XmlElement(name = "enumeration")
+   private List<EnumerationMode> enumeration;
+
+    public List<EnumerationMode> getEnumeration() {
+        return enumeration;
+    }
+
+    public void setEnumeration(List<EnumerationMode> enumeration) {
+        this.enumeration = enumeration;
+    }
+}

+ 53 - 0
elab-core/src/main/java/com/elab/core/configuration/entity/GlobalConfig.java

@@ -0,0 +1,53 @@
+package com.elab.core.configuration.entity;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * @author liuhx on 2017/1/2 13:43
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+@XmlRootElement(name = "global")
+public class GlobalConfig {
+    /**
+     * 日志相关配置
+     */
+    @XmlElement(name = "logManager")
+    public LogManager lm;
+
+    /**
+     * 参数相关配置
+     */
+    @XmlElement(name = "settings")
+    public SettingsManager st;
+
+    /**
+     * 系统版本号
+     */
+    @XmlAttribute(name = "version")
+    public String versionNo;
+
+    public LogManager getLogManager() { return lm; }
+
+    public void setLogManager(LogManager logManager) {
+        this.lm = logManager;
+    }
+
+    public String getVersion() {
+        return versionNo;
+    }
+
+    public void setVersion(String version) {
+        this.versionNo = version;
+    }
+
+    public SettingsManager getSettings() {
+        return st;
+    }
+
+    public void setSettings(SettingsManager st) {
+        this.st = st;
+    }
+}

+ 106 - 0
elab-core/src/main/java/com/elab/core/configuration/entity/LogConfig.java

@@ -0,0 +1,106 @@
+package com.elab.core.configuration.entity;
+
+import com.elab.core.collections.MapAdapter;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import java.util.HashMap;
+
+/**
+ * @author liuhx on 2017/1/2 13:53
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+public class LogConfig {
+    /**
+     * 日志名称
+     */
+    @XmlAttribute(name="name")
+    public String logName;
+
+    /**
+     * 日志类型
+     */
+    @XmlAttribute(name="type")
+    public String objType;
+
+
+    /**
+     * 是否记录debug日志
+     */
+    @XmlAttribute(name="logDebug")
+    public Boolean logDebug;
+
+
+    /**
+     * 是否记录Info日志
+     */
+    @XmlAttribute(name="logInfo")
+    public Boolean logInfo;
+
+
+    /**
+     * 日志配置参数
+     */
+    @XmlJavaTypeAdapter(MapAdapter.class)
+    public HashMap<String,String> properties;
+
+    public HashMap<String,String> getProperties() {
+        return properties;
+    }
+
+    public void setProperties(HashMap<String,String> properties) {
+        this.properties = properties;
+    }
+
+    public String getName() {
+        return logName;
+    }
+
+    public void setName(String name) {
+        this.logName = name;
+    }
+
+    public String getType() {
+        return objType;
+    }
+
+    public void setType(String type) {
+        this.objType = type;
+    }
+
+    public String getLogName() {
+        return logName;
+    }
+
+    public void setLogName(String logName) {
+        this.logName = logName;
+    }
+
+    public String getObjType() {
+        return objType;
+    }
+
+    public void setObjType(String objType) {
+        this.objType = objType;
+    }
+
+    public Boolean getLogDebug() {
+        return logDebug;
+    }
+
+    public void setLogDebug(Boolean logDebug) {
+        this.logDebug = logDebug;
+    }
+
+    public Boolean getLogInfo() {
+        return logInfo;
+    }
+
+    public void setLogInfo(Boolean logInfo) {
+        this.logInfo = logInfo;
+    }
+}

+ 85 - 0
elab-core/src/main/java/com/elab/core/configuration/entity/LogManager.java

@@ -0,0 +1,85 @@
+package com.elab.core.configuration.entity;
+
+import com.elab.core.utils.StringUtils;
+
+import javax.xml.bind.annotation.*;
+import java.util.List;
+
+/**
+ * @author liuhx on 2017/1/2 13:53
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+public class LogManager {
+    /**
+     * 日志记录所属系统名称ͳ
+     */
+    @XmlAttribute(name="system")
+    public String systemName;
+
+    /**
+     * 是否开始日志debug模式
+     */
+    @XmlAttribute(name="isDebugEnabled")
+    public Boolean isSystemDebugEnabled;
+
+    /**
+     * 日志包含的实现类型
+     */
+    @XmlElements(@XmlElement(name = "log", type = LogConfig.class))
+    public List<LogConfig> emitters;
+
+    public LogConfig getEmitterByName(String name) {
+        LogConfig emitter = null;
+        if(!StringUtils.isEmpty(name) && null != emitters && emitters.size() > 0) {
+            for (int i = 0; i < emitters.size(); i++) {
+                if(name.equals(emitters.get(i).getName())) {
+                    emitter = emitters.get(i);
+                    break;
+                }
+            }
+        }
+        return emitter;
+    }
+
+    /**
+     * 默认调用的日志实现类
+     */
+    @XmlAttribute(name="defaultEmitter")
+    public String defaultEmitterType;
+
+
+    public String getDefaultEmitter() { return defaultEmitterType; }
+
+    public void setDefaultEmitter(String defaultEmitter) {
+        this.defaultEmitterType = defaultEmitter;
+    }
+
+
+    public List<LogConfig> getEmitters() { return emitters; }
+
+    public void setEmitters(List<LogConfig> emitters) {
+        this.emitters = emitters;
+    }
+
+
+    public Boolean getIsDebugEnabled() {
+        return isSystemDebugEnabled;
+    }
+
+    public void setIsDebugEnabled(Boolean isDebugEnabled) {
+        this.isSystemDebugEnabled = isDebugEnabled;
+    }
+
+
+    public String getSystem() {
+        return systemName;
+    }
+
+    public void setSystem(String systemName) {
+        this.systemName = systemName;
+    }
+
+
+}

+ 41 - 0
elab-core/src/main/java/com/elab/core/configuration/entity/SettingConfig.java

@@ -0,0 +1,41 @@
+package com.elab.core.configuration.entity;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+
+/**
+ * 解析XML中的<settings>字段,它对应的属性是name和value
+ * @author liuhx on 2017/1/2 13:46
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+public class SettingConfig {
+    /**
+     * 属性名称
+     */
+    @XmlAttribute(name="name")
+    private String name;
+    /**
+     * 属性值
+     */
+    @XmlAttribute(name="value")
+    private String value;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+}

+ 37 - 0
elab-core/src/main/java/com/elab/core/configuration/entity/SettingsManager.java

@@ -0,0 +1,37 @@
+package com.elab.core.configuration.entity;
+
+import com.elab.core.utils.StringUtils;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElements;
+import java.util.List;
+
+/**
+ * @author liuhx on 2017/1/2 13:46
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+public class SettingsManager {
+    /**
+     * 参数列表
+     */
+    @XmlElements(@XmlElement(name = "property", type = SettingConfig.class))
+    public List<SettingConfig> properties;
+
+    public SettingConfig getPropertyByName(String name) {
+        SettingConfig property = null;
+        if(!StringUtils.isEmpty(name) && null != properties && properties.size() > 0) {
+            for (int i = 0; i < properties.size(); i++) {
+                if(name.equals(properties.get(i).getName())) {
+                    property = properties.get(i);
+                    break;
+                }
+            }
+        }
+        return property;
+    }
+}
+

+ 40 - 0
elab-core/src/main/java/com/elab/core/configuration/entity/ValueMode.java

@@ -0,0 +1,40 @@
+package com.elab.core.configuration.entity;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+
+/**
+ * 第二层节点的子节点
+ * <enumerations>
+ *     <enumeration type="" remark="">
+ *         <value name="" val=""></value>
+ *     </enumeration>
+ * </enumerations>
+ * @author liuhx on 2017/3/22 14:11
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ValueMode {
+    @XmlAttribute(name = "name")
+    private String name;
+    @XmlAttribute(name = "val")
+    private String val;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getVal() {
+        return val;
+    }
+
+    public void setVal(String val) {
+        this.val = val;
+    }
+}

+ 47 - 0
elab-core/src/main/java/com/elab/core/exception/BusinessException.java

@@ -0,0 +1,47 @@
+package com.elab.core.exception;
+
+/**
+ * 业务异常标识
+ *
+ * @author liuhx on 2016/12/8 15:57
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class BusinessException extends RuntimeException {
+
+    private String errorCode;
+
+    public BusinessException() {
+        super();
+    }
+
+    public BusinessException(String message) {
+        super(message);
+    }
+
+    public BusinessException(String errorCode, String message) {
+        super(message);
+        this.errorCode = errorCode;
+    }
+
+    public BusinessException(Throwable cause) {
+        super(cause);
+    }
+
+    public BusinessException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    @Override
+    public String getMessage() {
+        return super.getMessage();
+    }
+
+    public String getErrorCode() {
+        return errorCode;
+    }
+
+    public void setErrorCode(String errorCode) {
+        this.errorCode = errorCode;
+    }
+}

+ 47 - 0
elab-core/src/main/java/com/elab/core/exception/CoreException.java

@@ -0,0 +1,47 @@
+package com.elab.core.exception;
+
+/**
+ * 框架异常
+ *
+ * @author liuhx on 2016/12/8 15:57
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class CoreException extends RuntimeException {
+
+    private String errorCode;
+
+    public CoreException() {
+        super();
+    }
+
+    public CoreException(String message) {
+        super(message);
+    }
+
+    public CoreException(String errorCode, String message) {
+        super(message);
+        this.errorCode = errorCode;
+    }
+
+    public CoreException(Throwable cause) {
+        super(cause);
+    }
+
+    public CoreException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    @Override
+    public String getMessage() {
+        return super.getMessage();
+    }
+
+    public String getErrorCode() {
+        return errorCode;
+    }
+
+    public void setErrorCode(String errorCode) {
+        this.errorCode = errorCode;
+    }
+}

+ 10 - 0
elab-core/src/main/java/com/elab/core/log/ILogAdapter.java

@@ -0,0 +1,10 @@
+package com.elab.core.log;
+
+/**
+ * @author liuhx on 2017/1/2 14:41
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public interface ILogAdapter {
+    void log(LogEntry logEntry) throws Exception;
+}

+ 148 - 0
elab-core/src/main/java/com/elab/core/log/LogEntry.java

@@ -0,0 +1,148 @@
+package com.elab.core.log;
+
+import com.elab.core.collections.NameValueCollection;
+import com.elab.core.configuration.ConfigManager;
+import com.elab.core.utils.DateUtils;
+import com.elab.core.utils.StringUtils;
+
+import java.util.UUID;
+
+/**
+ * @author liuhx on 2017/1/2 14:20
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class LogEntry {
+
+    private String logID;
+
+    private String systemName;
+
+    public String moduleName;
+
+    public String content;
+
+    public String logServerIP;
+
+    public LogLevel logLevel;
+
+    public String logDate;
+
+    public String processTime;
+
+    public String[] contents;
+
+    public String format;
+
+    public LogEntry(String moduleName){
+        this(moduleName, "", LogLevel.Info);
+    }
+
+    public LogEntry(String moduleName, String content){
+        this(moduleName, content, LogLevel.Info);
+    }
+
+    public LogEntry(String moduleName, String content, LogLevel logLevel){
+        this.logID = UUID.randomUUID().toString();
+        this.systemName = ConfigManager.getLogManager().systemName;
+        this.moduleName = moduleName;
+        this.content = content;
+        this.logLevel = logLevel;
+        this.logDate = DateUtils.getCurrentTime();
+    }
+
+    public LogEntry(String moduleName, String format, String... contents){
+        this.logID = UUID.randomUUID().toString();
+        this.systemName = ConfigManager.getLogManager().systemName;
+        this.moduleName = moduleName;
+        this.format = format;
+        this.contents = contents;
+        this.logLevel = LogLevel.Info;
+        this.logDate = DateUtils.getCurrentTime();
+    }
+
+    public String getLogID() {
+        return logID;
+    }
+
+    public NameValueCollection getProperties() {
+        return properties;
+    }
+
+    public void setProperties(NameValueCollection properties) {
+        this.properties = properties;
+    }
+
+    public NameValueCollection properties;
+
+    public String getSystemName() {
+        return systemName;
+    }
+
+    public void setSystemName(String systemName) {
+        this.systemName = systemName;
+    }
+
+    public String getLogServerIP() {
+        if(null == logServerIP || logServerIP.length() < 0) {
+            logServerIP = StringUtils.getLocalNetWorkIp();
+        }
+        return logServerIP;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public String getModuleName() {
+        return moduleName;
+    }
+
+    public void setModuleName(String moduleName) {
+        this.moduleName = moduleName;
+    }
+
+    public LogLevel getLogLevel() {
+        return logLevel;
+    }
+
+    public void setLogLevel(LogLevel logLevel) {
+        this.logLevel = logLevel;
+    }
+
+    public String getLogDate() {
+        return logDate;
+    }
+
+    public void setLogDate(String logDate) {
+        this.logDate = logDate;
+    }
+
+    public String getProcessTime() {
+        return processTime;
+    }
+
+    public void setProcessTime(String processTime) {
+        this.processTime = processTime;
+    }
+
+    public String[] getContents() {
+        return contents;
+    }
+
+    public void setContents(String[] contents) {
+        this.contents = contents;
+    }
+
+    public String getFormat() {
+        return format;
+    }
+
+    public void setFormat(String format) {
+        this.format = format;
+    }
+}

+ 12 - 0
elab-core/src/main/java/com/elab/core/log/LogLevel.java

@@ -0,0 +1,12 @@
+package com.elab.core.log;
+
+/**
+ * @author liuhx on 2017/1/2 14:20
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public enum LogLevel {
+    Error,
+    Info,
+    Debug
+}

+ 53 - 0
elab-core/src/main/java/com/elab/core/log/LogProvider.java

@@ -0,0 +1,53 @@
+package com.elab.core.log;
+
+import com.elab.core.configuration.ConfigManager;
+import com.elab.core.exception.CoreException;
+import com.elab.core.utils.StringUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * @author liuhx on 2017/1/2 14:41
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class LogProvider {
+    public final static Map<String,ILogAdapter> emitters = new HashMap<String, ILogAdapter>();
+    private static final ReentrantLock LOG_EMITTER_LOCK = new ReentrantLock();
+
+    public static ILogAdapter createDefault() throws Exception {
+        if(null == ConfigManager.getLogManager() || StringUtils.isEmpty(ConfigManager.getLogManager().getDefaultEmitter())){
+            throw new CoreException("logger setting is not exist");
+        }
+        return create(ConfigManager.getLogManager().getDefaultEmitter());
+    }
+
+    public static ILogAdapter create(String logType) throws Exception {
+        if (StringUtils.isEmpty(logType)) {
+            throw new CoreException("logType is not exist");
+        }
+
+        ILogAdapter emitter = emitters.get(logType);
+        if (null == emitter) {
+
+            try {
+                LOG_EMITTER_LOCK.lock();
+                if (null == ConfigManager.getLogManager()) {
+                    throw new CoreException("logger is not exist");
+                }
+                emitter = emitters.get(logType);
+                if (null == emitter) {
+                    emitter = (ILogAdapter) Class.forName(ConfigManager.getLogManager().getEmitterByName(logType).getType()).newInstance();
+                    emitters.put(logType, emitter);
+                }
+            } finally {
+                LOG_EMITTER_LOCK.unlock();
+            }
+        }
+
+        return emitter;
+    }
+
+}

+ 77 - 0
elab-core/src/main/java/com/elab/core/log/adapter/Log4jFileAdapter.java

@@ -0,0 +1,77 @@
+//package com.elab.core.log.adapter;
+//
+//import com.elab.core.configuration.ConfigManager;
+//import com.elab.core.configuration.entity.LogConfig;
+//import com.elab.core.log.ILogAdapter;
+//import com.elab.core.log.LogEntry;
+//import com.elab.core.log.LogLevel;
+//import com.elab.core.serialization.SerializeFactory;
+//import org.apache.log4j.BasicConfigurator;
+//import org.apache.log4j.Logger;
+//import org.apache.log4j.PropertyConfigurator;
+//
+//import java.util.HashMap;
+//import java.util.Iterator;
+//import java.util.Map;
+//import java.util.Properties;
+//
+///** 记录于文件形式的日志
+// * @author liuhx on 2017/1/2 14:46
+// * @version V1.0
+// * @email liuhx@elab-plus.com
+// */
+//public class Log4jFileAdapter implements ILogAdapter {
+//    private static Logger instance = null;
+//    private static Boolean isLogDebug = false;
+//    private static Boolean isLogInfo = false;
+//
+//    public static Logger getLogger(){
+//        if(null == instance){
+//            synchronized(Log4jFileAdapter.class){
+//                LogConfig config = ConfigManager.getLogManager().getEmitterByName("log4jFileAdapter");
+//                if(null == instance){
+//                    instance = Logger.getLogger("elab");
+//                    isLogDebug = config.logDebug;
+//                    isLogInfo = config.logInfo;
+//                    if(null == config){
+//                        BasicConfigurator.configure();
+//                    }else{
+//                        HashMap<String,String> properties = config.getProperties();
+//                        if(null == properties || properties.isEmpty()){
+//                            BasicConfigurator.configure();
+//                        }else{
+//                            Properties prop = new Properties();
+//                            Iterator<Map.Entry<String,String>> iter = properties.entrySet().iterator();
+//                            while (iter.hasNext()) {
+//                                Map.Entry<String,String> entry = iter.next();
+//                                prop.setProperty(entry.getKey(), entry.getValue());
+//                            }
+//                            PropertyConfigurator.configure(prop);
+//                        }
+//                    }
+//                }
+//            }
+//        }
+//        return instance;
+//    }
+//
+//    public void log(LogEntry logEntry) throws Exception {
+//        String message = SerializeFactory.getJsonSerializer().ToSerializedString(logEntry);
+//        Logger logger = Log4jFileAdapter.getLogger();
+//
+//
+//        if (ConfigManager.getLogManager().getIsDebugEnabled() && isLogDebug && logEntry.logLevel == LogLevel.Debug) {
+////            logger.debug(message);
+//            logger.info(message);
+//        }
+//
+//        if (isLogInfo && logEntry.logLevel == LogLevel.Info) {
+//            logger.info(message);
+//        }
+//
+//        if(logEntry.logLevel == LogLevel.Error) {
+//            logger.error(message);
+//        }
+//    }
+//
+//}

+ 17 - 0
elab-core/src/main/java/com/elab/core/log/adapter/Log4jMQAdapter.java

@@ -0,0 +1,17 @@
+package com.elab.core.log.adapter;
+
+import com.elab.core.log.ILogAdapter;
+import com.elab.core.log.LogEntry;
+
+/**
+ * 消息队列形式的日志
+ * @author liuhx on 2017/1/2 14:56
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class Log4jMQAdapter implements ILogAdapter {
+
+    public void log(LogEntry logEntry) throws Exception {
+
+    }
+}

+ 24 - 0
elab-core/src/main/java/com/elab/core/log/adapter/Log4jMockAdapter.java

@@ -0,0 +1,24 @@
+package com.elab.core.log.adapter;
+
+import com.elab.core.log.ILogAdapter;
+import com.elab.core.log.LogEntry;
+import com.elab.core.serialization.SerializeFactory;
+import org.apache.commons.lang3.StringEscapeUtils;
+
+/**
+ * 直接打印控制台形式的日志
+ * @author liuhx on 2017/1/2 14:54
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class Log4jMockAdapter implements ILogAdapter {
+
+    public void log(LogEntry logEntry) throws Exception{
+        String message = SerializeFactory.getJsonSerializer().ToSerializedString(logEntry);
+        message = StringEscapeUtils.unescapeJava(message);
+        System.out.println(message);
+        /*Transaction t = Cat.getProducer().newTransaction("core", "params");
+        t.addData(message);
+        t.complete();*/
+    }
+}

+ 74 - 0
elab-core/src/main/java/com/elab/core/log/adapter/Log4jMongoDBAdapter.java

@@ -0,0 +1,74 @@
+//package com.elab.core.log.adapter;
+//
+//import com.elab.core.configuration.ConfigManager;
+//import com.elab.core.configuration.entity.LogConfig;
+//import com.elab.core.log.ILogAdapter;
+//import com.elab.core.log.LogEntry;
+//import com.elab.core.log.LogLevel;
+//import org.apache.log4j.BasicConfigurator;
+//import org.apache.log4j.Logger;
+//import org.apache.log4j.PropertyConfigurator;
+//
+//import java.util.HashMap;
+//import java.util.Iterator;
+//import java.util.Map;
+//import java.util.Properties;
+//
+///**
+// * 记录于数据库形式的日志
+// * @author liuhx on 2017/1/2 14:52
+// * @version V1.0
+// * @email liuhx@elab-plus.com
+// */
+//public class Log4jMongoDBAdapter implements ILogAdapter {
+//
+//    private static Logger instance = null;
+//    private static Boolean isLogDebug = false;
+//    private static Boolean isLogInfo = false;
+//
+//    public static Logger getLogger(){
+//        if(null == instance){
+//            synchronized(Log4jMongoDBAdapter.class){
+//                LogConfig config = ConfigManager.getLogManager().getEmitterByName("log4jMongoDBAdapter");
+//                if(null == instance){
+//                    instance = Logger.getLogger("SM");
+//                    isLogDebug = config.logDebug;
+//                    isLogInfo = config.logInfo;
+//                    if(null == config){
+//                        BasicConfigurator.configure();
+//                    }else{
+//                        HashMap<String,String> properties = config.getProperties();
+//                        if(null == properties || properties.isEmpty()){
+//                            BasicConfigurator.configure();
+//                        }else{
+//                            Properties prop = new Properties();
+//                            Iterator<Map.Entry<String,String>> iter = properties.entrySet().iterator();
+//                            while (iter.hasNext()) {
+//                                Map.Entry<String,String> entry = iter.next();
+//                                prop.setProperty(entry.getKey(), entry.getValue());
+//                            }
+//                            PropertyConfigurator.configure(prop);
+//                        }
+//                    }
+//                }
+//            }
+//        }
+//        return instance;
+//    }
+//
+//    public void log(LogEntry logEntry) throws Exception {
+//
+//        Logger logger = Log4jMongoDBAdapter.getLogger();
+//        if (ConfigManager.getLogManager().getIsDebugEnabled() && isLogDebug && logEntry.logLevel == LogLevel.Debug) {
+//            logger.debug(logEntry);
+//        }
+//
+//        if (isLogInfo && logEntry.logLevel == LogLevel.Info) {
+//            logger.info(logEntry);
+//        }
+//
+//        if(logEntry.logLevel == LogLevel.Error) {
+//            logger.error(logEntry);
+//        }
+//    }
+//}

+ 65 - 0
elab-core/src/main/java/com/elab/core/log/adapter/MongoDbPatternLayout.java

@@ -0,0 +1,65 @@
+//package com.elab.core.log.adapter;
+//
+//import com.elab.core.collections.NameValueCollection;
+//import com.elab.core.log.LogEntry;
+//import com.elab.core.serialization.SerializeFactory;
+//import com.elab.core.utils.StringUtils;
+//import com.mongodb.BasicDBObject;
+//import com.mongodb.DBObject;
+//import org.apache.log4j.PatternLayout;
+//import org.apache.log4j.spi.LoggingEvent;
+//
+///**
+// * @author liuhx on 2017/1/2 14:55
+// * @version V1.0
+// * @email liuhx@elab-plus.com
+// */
+//public class MongoDbPatternLayout extends PatternLayout {
+//    private static final String PROPERTY_PRE = "P";
+//
+//    @Override
+//    public String format(LoggingEvent loggingEvent) {
+//        Object logMessage = loggingEvent.getMessage();
+//        if(logMessage == null) {
+//            return "";
+//        }
+//        if(logMessage instanceof LogEntry) {
+//            LogEntry logEntry = (LogEntry)logMessage;
+//            DBObject doc = new BasicDBObject();
+//            if(logMessage != null) {
+//                if(StringUtils.isNotEmpty(logEntry.getContent())) {
+//                    doc.put("content", logEntry.getContent().replace("'","|").replace("\"","|").replace("{","").replace("}",""));//URLEncoder.encode(), "utf-8"));
+//                }
+//                if(StringUtils.isNotEmpty(logEntry.getLogID())) {
+//                    doc.put("logid", logEntry.getLogID());
+//                }
+//                if(StringUtils.isNotEmpty(logEntry.getLogServerIP())) {
+//                    doc.put("serverip", logEntry.getLogServerIP());
+//                }
+//                if(StringUtils.isNotEmpty(logEntry.getModuleName())) {
+//                    doc.put("modulename", logEntry.getModuleName());
+//                }
+//                if(StringUtils.isNotEmpty(logEntry.getSystemName())) {
+//                    doc.put("systemname", logEntry.getSystemName());
+//                }
+//                if(StringUtils.isNotEmpty(logEntry.getProcessTime())) {
+//                    doc.put("processtime", logEntry.getProcessTime());
+//                }
+//                doc.put("logLevel", logEntry.getLogLevel().toString());
+//                doc.put("logdate", logEntry.getLogDate());
+//
+//                if(logEntry.getProperties() != null) {
+//                    NameValueCollection collection = logEntry.getProperties();
+//                    int i = 0;
+//                    for (Object key : collection.keySet()) {
+//                        doc.put(PROPERTY_PRE + i , key.toString() + collection.get(key).toString());//+ URLEncoder.encode(collection.get(key).toString(), "utf-8") + "】").replace("{","").replace("}","").replace("[","").replace("]",""));
+//                        i++;
+//                    }
+//                }
+//            }
+//            return SerializeFactory.getJsonSerializer().ToSerializedString(doc);
+//        } else {
+//            return "";
+//        }
+//    }
+//}

+ 82 - 0
elab-core/src/main/java/com/elab/core/log/adapter/Slf4jAdapter.java

@@ -0,0 +1,82 @@
+//package com.elab.core.log.adapter;
+//
+//import com.elab.core.configuration.ConfigManager;
+//import com.elab.core.configuration.entity.LogConfig;
+//import com.elab.core.log.ILogAdapter;
+//import com.elab.core.log.LogEntry;
+//import com.elab.core.log.LogLevel;
+//import com.elab.core.serialization.SerializeFactory;
+//import com.elab.core.utils.ObjectUtils;
+//import org.apache.log4j.Level;
+//import org.apache.log4j.PropertyConfigurator;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//import org.slf4j.helpers.FormattingTuple;
+//import org.slf4j.helpers.MessageFormatter;
+//
+//import java.util.HashMap;
+//import java.util.Iterator;
+//import java.util.Map;
+//import java.util.Properties;
+//
+///**
+// * @author liuhx on 2017/3/23 18:38
+// * @version V1.0
+// * @email liuhx@elab-plus.com
+// */
+//public class Slf4jAdapter implements ILogAdapter {
+//
+//    private static Logger instance = null;
+//    private static Boolean isLogDebug = false;
+//    private static Boolean isLogInfo = false;
+//
+//    public static Logger getLogger() {
+//        if(null == instance){
+//            synchronized(Slf4jAdapter.class) {
+//                LogConfig config = ConfigManager.getLogManager().getEmitterByName("slf4jAdapter");
+//                if(null == instance) {
+//                    instance = LoggerFactory.getLogger("elab");
+//                    isLogDebug = config.logDebug;
+//                    isLogInfo = config.logInfo;
+//                    HashMap<String,String> properties = config.getProperties();
+//                    Properties prop = new Properties();
+//                    Iterator<Map.Entry<String,String>> iter = properties.entrySet().iterator();
+//                    while (iter.hasNext()) {
+//                        Map.Entry<String,String> entry = iter.next();
+//                        prop.setProperty(entry.getKey(), entry.getValue());
+//                    }
+//                    PropertyConfigurator.configure(prop);
+//                }
+//            }
+//        }
+//        return instance;
+//    }
+//
+//    @Override
+//    public void log(LogEntry logEntry) throws Exception {
+//        if (ObjectUtils.isNotEmpty(logEntry.getFormat()) || (ObjectUtils.isNotEmpty(logEntry.getContents()) && logEntry.getContents().length > 0)) {
+//            FormattingTuple ft = MessageFormatter.arrayFormat(logEntry.getFormat(), logEntry.getContents());
+//            logEntry.setContent(ft.getMessage());
+//            logEntry.contents = null;
+//            logEntry.format = null;
+//        }
+//        String message = SerializeFactory.getJsonSerializer().ToSerializedString(logEntry);
+//        message = message.replaceAll("\\\\t", "");
+//        message = message.replaceAll("\\\\n", "");
+//        message = message.replaceAll("\\\\", "");
+//        Logger logger = Slf4jAdapter.getLogger();
+//
+//
+//        if (ConfigManager.getLogManager().getIsDebugEnabled() && isLogDebug && logEntry.logLevel == LogLevel.Debug) {
+//            logger.debug(message);
+//        }
+//
+//        if (isLogInfo && logEntry.logLevel == LogLevel.Info) {
+//            logger.info(message);
+//        }
+//
+//        if(logEntry.logLevel == LogLevel.Error) {
+//            logger.error(message);
+//        }
+//    }
+//}

+ 16 - 0
elab-core/src/main/java/com/elab/core/serialization/ISerializer.java

@@ -0,0 +1,16 @@
+package com.elab.core.serialization;
+
+/**
+ * @author liuhx on 2016/12/30 23:09
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public interface ISerializer {
+    <T> Boolean ToFile(T obj, String fileName);
+
+    String ToSerializedString(Object obj);
+
+    <T> T FromSerializedString(String str,Class<T> objType);
+
+    <T> T FromFile(String filePath, Class<T> objType);
+}

+ 43 - 0
elab-core/src/main/java/com/elab/core/serialization/SerializeBase.java

@@ -0,0 +1,43 @@
+package com.elab.core.serialization;
+
+import com.elab.core.utils.FileUtils;
+import com.elab.core.utils.StringUtils;
+
+import java.io.IOException;
+
+/**
+ * @author liuhx on 2016/12/30 23:10
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public abstract class SerializeBase implements ISerializer {
+    public <T> Boolean ToFile(T obj, String fileName) {
+        if(StringUtils.isEmpty(fileName)){
+            return  false;
+        }
+        String str = ToSerializedString(obj);
+        try {
+            FileUtils.writeFile(str.getBytes(), fileName);
+            return  true;
+        } catch (IOException e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    public <T> T FromFile(String filePath, Class<T> classType) {
+        if(StringUtils.isEmpty(filePath)){
+            return  null;
+        }
+        try {
+            return FromSerializedString(new String(FileUtils.readFile(filePath), "UTF-8"), classType);
+        } catch (IOException e) {
+            e.printStackTrace();
+            return  null;
+        }
+    }
+
+    public abstract String ToSerializedString(Object obj);
+
+    public abstract <T> T FromSerializedString(String str, Class<T> classType);
+}

+ 40 - 0
elab-core/src/main/java/com/elab/core/serialization/SerializeFactory.java

@@ -0,0 +1,40 @@
+package com.elab.core.serialization;
+
+import com.elab.core.serialization.impl.JsonSerializer;
+import com.elab.core.serialization.impl.XmlSerializer;
+
+/**
+ * @author liuhx on 2016/12/30 23:13
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class SerializeFactory {
+
+    public static ISerializer getXmlSerializer()
+    {
+        return create(SerializeType.XML);
+    }
+
+    public static ISerializer getJsonSerializer()
+    {
+        return create(SerializeType.JSON);
+    }
+
+    private static ISerializer create(SerializeType type){
+        ISerializer serializer = null;
+        switch (type.getType())
+        {
+            case 1:
+                serializer = XmlSerializer.getInstance();
+                break;
+            case 2:
+                serializer = JsonSerializer.getInstance();
+                break;
+            default:
+                serializer = XmlSerializer.getInstance();
+                break;
+        }
+
+        return  serializer;
+    }
+}

+ 19 - 0
elab-core/src/main/java/com/elab/core/serialization/SerializeType.java

@@ -0,0 +1,19 @@
+package com.elab.core.serialization;
+
+/**
+ * @author liuhx on 2016/12/30 23:13
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public enum SerializeType {
+    XML(1),
+    JSON(2)
+    ;
+    private final int type;
+    SerializeType(int type){
+        this.type = type;
+    }
+    public int getType(){
+        return type;
+    }
+}

+ 36 - 0
elab-core/src/main/java/com/elab/core/serialization/impl/JsonSerializer.java

@@ -0,0 +1,36 @@
+package com.elab.core.serialization.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.elab.core.serialization.SerializeBase;
+
+/**
+ * @author liuhx on 2016/12/30 23:12
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class JsonSerializer extends SerializeBase {
+    @Override
+    public String ToSerializedString(Object obj) {
+        return JSON.toJSONString(obj);
+    }
+
+    @Override
+    public <T> T FromSerializedString(String str, Class<T> classType) {
+        T obj =  JSON.parseObject(str, classType);
+        try {
+            if(null != obj){
+                return obj;
+            }
+        } catch (ClassCastException ex) {
+            ex.printStackTrace();
+        }
+        return  null;
+    }
+
+
+    private static JsonSerializer instance = new JsonSerializer();
+
+    public static JsonSerializer getInstance(){
+        return  instance;
+    }
+}

+ 52 - 0
elab-core/src/main/java/com/elab/core/serialization/impl/XmlSerializer.java

@@ -0,0 +1,52 @@
+package com.elab.core.serialization.impl;
+
+import com.elab.core.serialization.SerializeBase;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+/**
+ * @author liuhx on 2016/12/30 23:11
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class XmlSerializer extends SerializeBase {
+    @Override
+    public String ToSerializedString(Object obj) {
+        try {
+            JAXBContext context = JAXBContext.newInstance(obj.getClass());
+
+            Marshaller marshaller = context.createMarshaller();
+            marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");// //编码格式
+            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);// 是否格式化生成的xml串
+            marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);// 是否省略xm头声明信息
+            StringWriter writer = new StringWriter();
+            marshaller.marshal(obj, writer);
+            return writer.toString();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return  "";
+    }
+
+    @Override
+    public <T> T FromSerializedString(String str, Class<T> classType) {
+        try {
+            JAXBContext context = JAXBContext.newInstance(classType);
+            Unmarshaller unmarshaller = context.createUnmarshaller();
+            return (T) unmarshaller.unmarshal(new StringReader(str));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    private static XmlSerializer instance = new XmlSerializer();
+
+    public static XmlSerializer getInstance(){
+        return  instance;
+    }
+}

+ 162 - 0
elab-core/src/main/java/com/elab/core/utils/AESForNodejs.java

@@ -0,0 +1,162 @@
+package com.elab.core.utils;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.MessageDigest;
+
+/**
+ * @author liuhx on 2017/1/2 14:38
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class AESForNodejs {
+    public static final String DEFAULT_CODING = "utf-8";
+    public static final String KEY = "ACE4F440D45CE1CCF7CB702F";
+
+    /**
+     * 解密
+     * @param encrypted
+     * @param key
+     * @return
+     * @throws Exception
+     */
+    public static String decrypt(String encrypted, String key) throws Exception {
+        byte[] keyb = key.getBytes(DEFAULT_CODING);
+        MessageDigest md = MessageDigest.getInstance("MD5");
+        byte[] thedigest = md.digest(keyb);
+        SecretKeySpec skey = new SecretKeySpec(thedigest, "AES");
+        Cipher dcipher = Cipher.getInstance("AES");
+        dcipher.init(Cipher.DECRYPT_MODE, skey);
+
+        byte[] clearbyte = dcipher.doFinal(toByte(encrypted));
+        return new String(clearbyte);
+    }
+
+    /**
+     * 解密
+     * @param encrypted
+     * @return
+     * @throws Exception
+     */
+    public static String decrypt(String encrypted) throws Exception {
+        return decrypt(encrypted, KEY);
+    }
+
+    /**
+     * 加密
+     * @param content
+     * @return
+     * @throws Exception
+     */
+    public static String encrypt(String content) throws Exception {
+        return encrypt(content, KEY);
+    }
+
+    /**
+     * 加密
+     * @param content
+     * @param key
+     * @return
+     * @throws Exception
+     */
+    public static String encrypt(String content, String key) throws Exception {
+        byte[] input = content.getBytes(DEFAULT_CODING);
+
+        MessageDigest md = MessageDigest.getInstance("MD5");
+        byte[] thedigest = md.digest(key.getBytes(DEFAULT_CODING));
+        SecretKeySpec skc = new SecretKeySpec(thedigest, "AES");
+        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
+        cipher.init(Cipher.ENCRYPT_MODE, skc);
+
+        byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
+        int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
+        ctLength += cipher.doFinal(cipherText, ctLength);
+
+        return parseByte2HexStr(cipherText);
+    }
+
+    /**
+     * 字符串转字节数组
+     * @param hexString
+     * @return
+     */
+    private static byte[] toByte(String hexString) {
+        int len = hexString.length() / 2;
+        byte[] result = new byte[len];
+        for (int i = 0; i < len; i++) {
+            result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue();
+        }
+        return result;
+    }
+
+    /**
+     * 字节转16进制数组
+     * @param buf
+     * @return
+     */
+    private static String parseByte2HexStr(byte buf[]) {
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < buf.length; i++) {
+            String hex = Integer.toHexString(buf[i] & 0xFF);
+            if (hex.length() == 1) {
+                hex = '0' + hex;
+            }
+            sb.append(hex);
+        }
+        return sb.toString();
+    }
+
+    public static void main(String[] args) throws Exception {
+        String key = "ACE4F440D45CE1CCF7CB702F";
+        String content = "YSD-YX-001";
+        String jiami = AESForNodejs.encrypt(content, key);
+        System.out.println(jiami);
+        content = "YSD-YX-001";
+        jiami = AESForNodejs.encrypt(content, key);
+        System.out.println(jiami);
+        content = "YSD-YX-002";
+        jiami = AESForNodejs.encrypt(content, key);
+        System.out.println(jiami);
+        content = "YSD-YX-003";
+        jiami = AESForNodejs.encrypt(content, key);
+        System.out.println(jiami);
+        content = "YSD-YX-004";
+        jiami = AESForNodejs.encrypt(content, key);
+        System.out.println(jiami);
+        content = "YSD-YX-005";
+        jiami = AESForNodejs.encrypt(content, key);
+        System.out.println(jiami);
+        content = "YSD-YX-006";
+        jiami = AESForNodejs.encrypt(content, key);
+        System.out.println(jiami);
+        content = "YSD-YX-007";
+        jiami = AESForNodejs.encrypt(content, key);
+        System.out.println(jiami);
+        content = "YSD-YX-008";
+        jiami = AESForNodejs.encrypt(content, key);
+        System.out.println(jiami);
+        content = "YSD-YX-009";
+        jiami = AESForNodejs.encrypt(content, key);
+        System.out.println(jiami);
+        content = "YSD-YX-010";
+        jiami = AESForNodejs.encrypt(content, key);
+        System.out.println(jiami);
+        content = "YSD-YX-011";
+        jiami = AESForNodejs.encrypt(content, key);
+        System.out.println(jiami);
+        content = "YSD-YX-012";
+        jiami = AESForNodejs.encrypt(content, key);
+        System.out.println(jiami);
+        content = "YSD-YX-013";
+        jiami = AESForNodejs.encrypt(content, key);
+        System.out.println(jiami);
+        content = "YSD-YX-014";
+        jiami = AESForNodejs.encrypt(content, key);
+        System.out.println(jiami);
+        content = "YSD-YX-015";
+        jiami = AESForNodejs.encrypt(content, key);
+        System.out.println(jiami);
+        String jiemi = AESForNodejs.decrypt(jiami, key);
+        System.out.println(jiemi);
+    }
+}

+ 176 - 0
elab-core/src/main/java/com/elab/core/utils/AESUtils.java

@@ -0,0 +1,176 @@
+package com.elab.core.utils;
+
+import org.apache.axis.encoding.Base64;
+
+import javax.crypto.*;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.UnsupportedEncodingException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+/**
+ * @author liuhx on 2017/2/7 19:05
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class AESUtils {
+    private static int length=128;
+    public static final String KEY = "ACE4F440D45CE1CCF7CB702F";
+    /**
+     * 加密
+     *
+     * @param content
+     *            需要加密的内容
+     * @param password
+     *            加密密码
+     * @return
+     * @throws NoSuchAlgorithmException
+     * @throws NoSuchPaddingException
+     * @throws UnsupportedEncodingException
+     * @throws InvalidKeyException
+     * @throws BadPaddingException
+     * @throws IllegalBlockSizeException
+     */
+    private static byte[] encrypt(String content, String password)
+            throws Exception {
+
+        KeyGenerator kgen = KeyGenerator.getInstance("AES");
+        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );
+        secureRandom.setSeed(password.getBytes());
+        kgen.init(length, secureRandom);
+        SecretKey secretKey = kgen.generateKey();
+        byte[] enCodeFormat = secretKey.getEncoded();
+        SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
+        Cipher cipher = Cipher.getInstance("AES");// 创建密码器
+        byte[] byteContent = content.getBytes("utf-8");
+        cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
+        byte[] result = cipher.doFinal(byteContent);
+        return result; // 加密
+
+    }
+
+    /**
+     * 解密
+     *
+     * @param content
+     *            待解密内容
+     * @param password
+     *            解密密钥
+     * @return
+     */
+    private static byte[] decrypt(byte[] content, String password)
+            throws Exception {
+
+        KeyGenerator kgen = KeyGenerator.getInstance("AES");
+        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );
+        secureRandom.setSeed(password.getBytes());
+        kgen.init(length, secureRandom);
+        SecretKey secretKey = kgen.generateKey();
+        byte[] enCodeFormat = secretKey.getEncoded();
+        SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
+        Cipher cipher = Cipher.getInstance("AES");// 创建密码器
+        cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
+        byte[] result = cipher.doFinal(content);
+        return result; // 加密
+
+
+
+    }
+
+    /**
+     * 加密
+     *
+     * @param content
+     *            需要加密的内容
+     * @param password
+     *            加密密码
+     * @return
+     */
+    private static byte[] encrypt2(String content, String password) {
+        try {
+            SecretKeySpec key = new SecretKeySpec(password.getBytes(), "AES");
+            Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
+            byte[] byteContent = content.getBytes("utf-8");
+            cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
+            byte[] result = cipher.doFinal(byteContent);
+            return result; // 加密
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        } catch (NoSuchPaddingException e) {
+            e.printStackTrace();
+        } catch (InvalidKeyException e) {
+            e.printStackTrace();
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        } catch (IllegalBlockSizeException e) {
+            e.printStackTrace();
+        } catch (BadPaddingException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 按照固定KEY加密字符串
+     * @param content 字符串
+     * @return AES加密后的字符串
+     * @throws Exception
+     */
+    public static String encrypt2Str(String content) throws Exception {
+        return encrypt2Str(content, KEY);
+    }
+
+    /**
+     * 按照指定KEY加密字符串
+     * @param content 字符串
+     * @param password 指定key
+     * @return AES加密后的字符串
+     * @throws Exception
+     */
+    public static String encrypt2Str(String content, String password) throws Exception {
+        byte[] encryptResult = encrypt(content, password);
+        return Base64.encode(encryptResult);
+    }
+
+    /**
+     * 按照固定KEY解密加密字符串
+     * @param content 加密字符串
+     * @return 解密后的字符串
+     * @throws Exception
+     */
+    public static String decrypt2Str(String content) throws Exception {
+        return decrypt2Str(content, KEY);
+    }
+
+    /**
+     * 按照指定KEY解密加密字符串
+     * @param content 加密字符串
+     * @param password 指定KEY
+     * @return 解密后的字符串
+     * @throws Exception
+     */
+    public static String decrypt2Str(String content, String password) throws Exception {
+
+        byte[] decryptResult = decrypt(Base64.decode(content), password);
+        return new String(decryptResult,"UTF-8");
+    }
+
+    public static void main(String[] args) throws Exception {
+        String content = "t太阳est地";
+        String password = "12345678";
+        // 加密
+        System.out.println("加密前:" + content);
+
+        String tt4 = encrypt2Str(content, password);
+        System.out.println(new String(tt4));
+
+        // 解密
+        String d = decrypt2Str(tt4, password);
+        System.out.println("解密后:" + d);
+
+//		加密前:t太阳est地
+//		Bpf0jyJDj/pVHaRf66+OMA==
+//		解密后:t太阳est地
+    }
+}

+ 116 - 0
elab-core/src/main/java/com/elab/core/utils/DESUtils.java

@@ -0,0 +1,116 @@
+package com.elab.core.utils;
+
+import com.elab.core.CoreConstant;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.DESKeySpec;
+import javax.crypto.spec.IvParameterSpec;
+import java.security.Key;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * Created by admin on 2015/11/4.
+ */
+public class DESUtils {
+    public static final String ALGORITHM_DES = "DES/CBC/PKCS5Padding";
+
+    /**
+     * DES算法,加密
+     *
+     * @param data 待加密字符串
+     * @param key  加密私钥,长度不能够小于8位
+     * @return 加密后的字节数组,一般结合Base64编码使用
+     * @throws
+     * @throws Exception
+     */
+    public static String encode(String key,String data) {
+        if(data == null)
+            return null;
+        try{
+            DESKeySpec dks = new DESKeySpec(key.getBytes());
+            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
+            //key的长度不能够小于8位字节
+            Key secretKey = keyFactory.generateSecret(dks);
+            Cipher cipher = Cipher.getInstance(ALGORITHM_DES);
+            IvParameterSpec iv = new IvParameterSpec("12345678".getBytes());
+            AlgorithmParameterSpec paramSpec = iv;
+            cipher.init(Cipher.ENCRYPT_MODE, secretKey,paramSpec);
+            byte[] bytes = cipher.doFinal(data.getBytes());
+            return byte2hex(bytes);
+        }catch(Exception e){
+            e.printStackTrace();
+            return data;
+        }
+    }
+
+    /**
+     * DES算法,解密
+     *
+     * @param data 待解密字符串
+     * @param key  解密私钥,长度不能够小于8位
+     * @return 解密后的字节数组
+     * @throws Exception 异常
+     */
+    public static String decode(String key,String data) {
+        if(data == null)
+            return null;
+        try {
+            DESKeySpec dks = new DESKeySpec(key.getBytes());
+            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
+            //key的长度不能够小于8位字节
+            Key secretKey = keyFactory.generateSecret(dks);
+            Cipher cipher = Cipher.getInstance(ALGORITHM_DES);
+            IvParameterSpec iv = new IvParameterSpec("12345678".getBytes());
+            AlgorithmParameterSpec paramSpec = iv;
+            cipher.init(Cipher.DECRYPT_MODE, secretKey, paramSpec);
+            return new String(cipher.doFinal(hex2byte(data.getBytes())));
+        } catch (Exception e){
+            return null;
+        }
+    }
+
+    /**
+     * 二行制转字符串
+     * @param b
+     * @return
+     */
+    private static String byte2hex(byte[] b) {
+        StringBuilder hs = new StringBuilder();
+        String stmp;
+        for (int n = 0; b!=null && n < b.length; n++) {
+            stmp = Integer.toHexString(b[n] & 0XFF);
+            if (stmp.length() == 1)
+                hs.append('0');
+            hs.append(stmp);
+        }
+        return hs.toString().toUpperCase();
+    }
+
+    private static byte[] hex2byte(byte[] b) {
+//        if((b.length%2)!=0)
+//            throw new IllegalArgumentException();
+        byte[] b2 = new byte[b.length/2];
+        for (int n = 0; n < b.length; n+=2) {
+            String item = new String(b,n,2);
+            b2[n/2] = (byte)Integer.parseInt(item,16);
+        }
+        return b2;
+    }
+
+    public static String generateToken(int customerid) {
+        String token = DESUtils.encode(CoreConstant.AUTH_TOKEN_KEY, String.format("%s|%s", RandomUtils.randomString(8), customerid));
+        return token;
+    }
+
+
+    public static void main(String[] args) throws Exception {
+        String data = "123 456";
+        String key = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDI6d306Q8fIfCOaTXyiUeJ";
+        String en = encode(key, data);
+        System.err.println(en);
+        System.err.println(decode(key, en));
+        String token = generateToken(4402);
+        System.out.println("token:"+token);
+    }
+}

+ 174 - 0
elab-core/src/main/java/com/elab/core/utils/DateCalculate.java

@@ -0,0 +1,174 @@
+package com.elab.core.utils;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+/**
+ * 日期比较差值不包括起始日期,包括最后日期
+ * @author liuhx on 2017/1/2 14:26
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class DateCalculate {
+    private long differenceOfMonths=0;//月份差值
+    private long differenceOfDays=0;//天数差值
+
+    static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
+
+    public static DateCalculate calculate(String startdate, String endDate){
+        try {
+            return calculate(dateFormat.parse(startdate),dateFormat.parse(endDate));
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 计算差值,注意 endDate > startDate
+     * @param startDate
+     * @param endDate
+     * @return
+     */
+    public static DateCalculate calculate(Date startDate, Date endDate){
+        DateCalculate dataCalculate = new DateCalculate();
+        if(startDate.after(endDate)) return dataCalculate;
+
+        Calendar firstDay = Calendar.getInstance();
+        Calendar lastDay = Calendar.getInstance();
+        firstDay.setTime(startDate);
+        firstDay.set(Calendar.MILLISECOND, 0);
+        lastDay.setTime(endDate);
+        lastDay.set(Calendar.MILLISECOND, 0);
+
+        //算出天数总差值
+        long allDays = ((lastDay.getTimeInMillis()) - (firstDay.getTimeInMillis()))/(1000*24*60*60);
+
+        Calendar loopEndDay = calculateLoopEndOfDate(firstDay,lastDay);
+        loopEndDay.set(Calendar.MILLISECOND, 0);
+
+        dataCalculate.setDifferenceOfDays(0);
+        dataCalculate.setDifferenceOfMonths(0);
+
+        int month = firstDay.get(Calendar.MONTH);
+        while(firstDay.compareTo(loopEndDay) < 0){
+            firstDay.add(Calendar.DAY_OF_MONTH, 1);
+            allDays--;
+            if(month != firstDay.get(Calendar.MONTH)){
+                month = firstDay.get(Calendar.MONTH);
+                dataCalculate.setDifferenceOfMonths(dataCalculate.getDifferenceOfMonths()+1);
+            }
+        }
+        dataCalculate.setDifferenceOfDays(allDays);
+        return dataCalculate;
+
+    }
+
+    /**
+     * 计算循环终止日期
+     * 例如:开始日:2011/03/17    结束日 2012/02/13 ,循环终止日期 2012/01/17;
+     * @param startDate
+     * @param endDate
+     * @return
+     */
+    private static Calendar calculateLoopEndOfDate(Calendar startDate, Calendar endDate) {
+        int year = endDate.get(Calendar.YEAR);
+        int month = endDate.get(Calendar.MONTH);
+        int day = startDate.get(Calendar.DAY_OF_MONTH);
+        int maxDaysInMonth = getMaxDaysOfMonth(new GregorianCalendar(year,month,1));
+
+        if(year > startDate.get(Calendar.YEAR)){
+            if(month == Calendar.JANUARY){
+                year -= 1;
+                month = Calendar.DECEMBER;
+            }else{
+                if(day > maxDaysInMonth){
+                    month -= 1;
+                    endDate.set(year, month, 1);
+                    day = getMaxDaysOfMonth(new GregorianCalendar(year,month,1));
+                }else{
+                    if(day > endDate.get(Calendar.DAY_OF_MONTH)){
+                        month -= 1;
+                        endDate.set(year, month, 1);
+                        maxDaysInMonth = getMaxDaysOfMonth(new GregorianCalendar(year,month,1));;
+                        if(day > maxDaysInMonth){
+                            day = maxDaysInMonth;
+                        }
+                    }
+                }
+            }
+        }else{
+            if(day > maxDaysInMonth){
+                month -= 1;
+                endDate.set(year, month, 1);
+                day = getMaxDaysOfMonth(new GregorianCalendar(year,month,1));
+            }else{
+                if(day > endDate.get(Calendar.DAY_OF_MONTH)){
+                    month -= 1;
+                    endDate.set(year, month, 1);
+                    maxDaysInMonth = getMaxDaysOfMonth(new GregorianCalendar(year,month,1));
+                    if(day > maxDaysInMonth){
+                        day = maxDaysInMonth;
+                    }
+                }
+            }
+        }
+
+        return new GregorianCalendar(year, month, day);
+    }
+
+    /**
+     * 获取一月最大天数,考虑年份是否为润年
+     * (对API中的 getMaximum(int field)不了解, date.getMaximum(Calendar.DAY_OF_MONTH)却不是月份的最大天数)
+     * @param date
+     * @return
+     */
+    private static int getMaxDaysOfMonth(GregorianCalendar date) {
+        int month = date.get(Calendar.MONTH);
+        int maxDays  = 0;
+        switch(month){
+            case Calendar.JANUARY:
+            case Calendar.MARCH:
+            case Calendar.MAY:
+            case Calendar.JULY:
+            case Calendar.AUGUST:
+            case Calendar.OCTOBER:
+            case Calendar.DECEMBER:
+                maxDays = 31;
+                break;
+            case Calendar.APRIL:
+            case Calendar.JUNE:
+            case Calendar.SEPTEMBER:
+            case Calendar.NOVEMBER:
+                maxDays = 30;
+                break;
+            case Calendar.FEBRUARY:
+                if(date.isLeapYear(date.get(Calendar.YEAR))){
+                    maxDays = 29;
+                }else{
+                    maxDays = 28;
+                }
+                break;
+        }
+        return maxDays;
+    }
+
+    public long getDifferenceOfMonths() {
+        return differenceOfMonths;
+    }
+
+    public void setDifferenceOfMonths(long differenceOfmonths) {
+        this.differenceOfMonths = differenceOfmonths;
+    }
+
+    public long getDifferenceOfDays() {
+        return differenceOfDays;
+    }
+
+    public void setDifferenceOfDays(long differenceOfDays) {
+        this.differenceOfDays = differenceOfDays;
+    }
+}

+ 592 - 0
elab-core/src/main/java/com/elab/core/utils/DateUtils.java

@@ -0,0 +1,592 @@
+package com.elab.core.utils;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+/** 日期操作类
+ * @author liuhx on 2017/1/2 14:23
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
+
+    public static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd",java.util.Locale.CHINA);
+    public static final DateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss",java.util.Locale.CHINA);
+    public static final DateFormat DATE_TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",java.util.Locale.CHINA);
+
+    /**
+     * 返回当前时间
+     *
+     * @return 返回当前时间
+     */
+    public static Date getCurrentDateTime() {
+        java.util.Calendar calNow = java.util.Calendar.getInstance();
+        java.util.Date dtNow = calNow.getTime();
+        return dtNow;
+    }
+
+    /**
+     * 返回当前时间的数字
+     *
+     * @return 返回当前时间的数字
+     */
+    public static String getCurrentTime() {
+        return DATE_TIME_FORMAT.format(new java.util.Date());
+    }
+
+    public static int getCurrentUnixTime() throws Exception {
+        long epoch = new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm:ss")
+                .parse("01/01/1970 00:00:00").getTime() / 1000;
+        return Integer.parseInt(Long.toString(System.currentTimeMillis() / 1000
+                - epoch));
+    }
+
+    /**
+     * @return 返回今天日期,时间部分为0。例如:2006-4-8 00:00:00
+     */
+    public static Date getToday() {
+        return truncate(new Date(), Calendar.DATE);
+    }
+
+    /**
+     * @return 返回今天日期,时间部分为23:59:59.999。例如:2006-4-19 23:59:59.999
+     */
+    public static Date getTodayEnd() {
+        return getDayEnd(new Date());
+    }
+
+    /**
+     * 将字符串转换为日期(不包括时间)
+     *
+     * @param dateString
+     *            "yyyy-MM-dd"格式的日期字符串
+     * @return 日期
+     */
+    public static Date convertToDate(String dateString) {
+        try {
+            return DATE_FORMAT.parse(dateString);
+        } catch (ParseException e) {
+            return null;
+        }
+    }
+
+    /**
+     * 检查字符串是否为日期格式yyyy-MM-dd
+     *
+     * @param dateString
+     * @return true=是;false=否
+     */
+    public static boolean checkDateString(String dateString) {
+        return (convertToDate(dateString) != null);
+    }
+
+    /**
+     * 将字符串转换为日期(包括时间)
+     *
+     * @param dateTimeString
+     *            "yyyy-MM-dd HH:mm:ss"格式的日期字符串
+     * @return 日期时间
+     */
+    public static Date convertToDateTime(String dateTimeString) {
+        try {
+            return DATE_TIME_FORMAT.parse(dateTimeString);
+        } catch (ParseException e) {
+            return null;
+        }
+    }
+
+    /**
+     * 将字符串转换为日期(包括时间)
+     *
+     * @param dateString
+     *            "dd/MM/yyyy HH:mm"格式的日期字符串
+     * @return 日期
+     */
+    public static Date convertSimpleToDateTime(String dateString) {
+        try {
+            return new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm")
+                    .parse(dateString);
+        } catch (ParseException e) {
+            return null;
+        }
+    }
+
+    /**
+     * 检查字符串是否为日期时间格式yyyy-MM-dd HH:mm:ss
+     *
+     * @param dateTimeString
+     * @return true=是;false=否
+     */
+    public static boolean checkDateTimeString(String dateTimeString) {
+        return (convertToDateTime(dateTimeString) != null);
+    }
+
+    /**
+     * 获取月底
+     *
+     * @param year
+     *            年 4位年度
+     * @param month
+     *            月 1~12
+     * @return 月底的Date对象。例如:2006-3-31 23:59:59.999
+     */
+    public static Date getMonthEnd(int year, int month) {
+        StringBuffer sb = new StringBuffer(10);
+        Date date;
+        if (month < 12) {
+            sb.append(Integer.toString(year));
+            sb.append("-");
+            sb.append(month + 1);
+            sb.append("-1");
+            date = convertToDate(sb.toString());
+        } else {
+            sb.append(Integer.toString(year + 1));
+            sb.append("-1-1");
+            date = convertToDate(sb.toString());
+        }
+        date.setTime(date.getTime() - 1);
+        return date;
+    }
+
+    /**
+     * 获取月底
+     *
+     * @param when
+     *            要计算月底的日期
+     * @return 月底的Date对象。例如:2006-3-31 23:59:59.999
+     */
+    public static Date getMonthEnd(Date when) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(when);
+        int year = calendar.get(Calendar.YEAR);
+        int month = calendar.get(Calendar.MONTH) + 1;
+        return getMonthEnd(year, month);
+    }
+
+    /**
+     * 日期格式转换为字符串
+     *
+     * @param date
+     * @return
+     */
+    public static String dateParseString(Date date) {
+        java.text.DateFormat df = new java.text.SimpleDateFormat(
+                "yyyy-MM-dd HH:mm:ss");
+        return df.format(date);
+    }
+
+    /**
+     * 日期格式转换为字符串
+     *
+     * @param date
+     * @return
+     */
+    public static String dateParseShortString(Date date) {
+        java.text.DateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd");
+        return df.format(date);
+    }
+
+    /**
+     * 获取给定日的最后一刻。
+     *
+     * @param when
+     *            给定日
+     * @return 最后一刻。例如:2006-4-19 23:59:59.999
+     */
+    public static Date getDayEnd(Date when) {
+        Date date = truncate(when, Calendar.DATE);
+        date = addDays(date, 1);
+        date.setTime(date.getTime() - 1);
+        return date;
+    }
+
+    /**
+     * 获取给定日的第一刻。
+     *
+     * @param when
+     *            给定日
+     * @return 最后一刻。例如:2006-4-19 23:59:59.999
+     */
+    public static Date getDay(Date when) {
+        Date date = truncate(when, Calendar.DATE);
+        date = addDays(date, -1);
+        date.setTime(date.getTime() + 1);
+        return date;
+    }
+
+    /**
+     * 日期加法
+     *
+     * @param when
+     *            被计算的日期
+     * @param field
+     *            the time field. 在Calendar中定义的常数,例如Calendar.DATE
+     * @param amount
+     *            加数
+     * @return 计算后的日期
+     */
+    public static Date add(Date when, int field, int amount) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(when);
+        calendar.add(field, amount);
+        return calendar.getTime();
+    }
+
+    /**
+     * 计算给定的日期加上给定的天数。
+     *
+     * @param when
+     *            给定的日期
+     * @param amount
+     *            给定的天数
+     * @return 计算后的日期
+     */
+    public static Date addDays(Date when, int amount) {
+
+        return add(when, Calendar.DAY_OF_YEAR, amount);
+    }
+    /**
+     * 计算给定的日期加上给定的分钟数。
+     *
+     * @param when
+     *            给定的日期
+     * @param amount
+     *            给定的分钟数
+     * @return 计算后的日期
+     */
+    public static Date addMinutes(Date when, int amount) {
+
+        return add(when, Calendar.MINUTE, amount);
+    }
+
+    /**
+     * 计算给定的日期加上给定的秒数。
+     *
+     * @param when
+     *            给定的日期
+     * @param amount
+     *            给定的秒数
+     * @return 计算后的日期
+     */
+    public static Date addSeconds(Date when, int amount) {
+
+        return add(when, Calendar.SECOND, amount);
+    }
+
+    /**
+     * 计算给定的日期加上给定的月数。
+     *
+     * @param when
+     *            给定的日期
+     * @param amount
+     *            给定的月数
+     * @return 计算后的日期
+     */
+    public static Date addMonths(Date when, int amount) {
+        return add(when, Calendar.MONTH, amount);
+    }
+
+    /**
+     * 获取当前时段:早上、上午、下午、晚上、凌晨
+     *
+     * @return 当前时段
+     */
+    @SuppressWarnings("deprecation")
+    public static String getTimePeriod() {
+        String period = "";
+        Date now = getCurrentDateTime();
+        int hour = now.getHours();
+        if (hour >= 0 && hour < 6) {
+            period = "凌晨";
+        } else if (hour >= 6 && hour < 8) {
+            period = "早上";
+        } else if (hour >= 8 && hour < 12) {
+            period = "上午";
+        } else if (hour >= 12 && hour < 18) {
+            period = "下午";
+        } else if (hour >= 18) {
+            period = "晚上";
+        }
+        return period;
+    }
+
+    /**
+     *
+     * @param date
+     * @param n
+     * @return
+     */
+    public static Date getTimePriTenDay(Date date, int n) {
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+        return convertToDateTime(df.format(new Date(date.getTime() + n * 24
+                * 60 * 60 * 1000)));
+    }
+
+    /**
+     * 将Date对象类型转化为日期(2006-09-17 5:20:5)的字符串
+     * @param date
+     * @return String
+     */
+    public static String dateToString(Date date) {
+
+        try {
+            if (date != null)
+                return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.gc();
+        }
+        return null;
+    }
+
+    /**
+     * 将String 类型的转化为日期格式(2006-09-17 5:20:5)
+     * @param dateStr
+     * @return Date
+     */
+    public static Date stringToDate(String dateStr) {
+
+        try {
+            if (dateStr != null)
+                return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
+                        .parse(dateStr);
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.gc();
+        }
+        return null;
+    }
+
+    /**
+     * 字符串转为时间类型
+     *
+     * @param dateStr
+     *            <String>
+     * @return Date
+     */
+    public static final Date parseDate(String dateStr) {
+
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+
+        try {
+            return df.parse(dateStr);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public static final Date parseDateByFormat(String dateStr,String format) {
+
+        SimpleDateFormat df = new SimpleDateFormat(format);
+
+        try {
+            return df.parse(dateStr);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 得到具体时间如:几天前;几小时前;几分钟前;几秒钟前
+     *
+     * @param time
+     *            传入一个Date类型的日期
+     * @return 根据当天当时当秒解析出距离当天当时当秒的字符串 String
+     */
+    public static String getTimeInterval(Date time) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+        try {
+            Long dateDiff = sdf.parse(sdf.format(new Date())).getTime()
+                    - sdf.parse(sdf.format(time)).getTime();
+
+            Long day = dateDiff / (24 * 60 * 60 * 1000);
+
+            if (day > 0) {
+                return day + "天前";
+            }
+
+            Long hour = dateDiff / (60 * 60 * 1000);
+
+            if (hour > 0) {
+                return hour + "小时前";
+            }
+
+            Long minute = dateDiff / (60 * 1000);
+
+            if (minute > 0) {
+                return minute + "分钟前";
+            }
+
+            Long second = dateDiff / 1000;
+
+            return second + "秒前";
+        } catch (Exception e) {
+            e.printStackTrace();
+            return "未知";
+        }
+    }
+
+    /**
+     * 由当前时间返回yyyy-mm-dd格式的日期字符串
+     *
+     * @return String
+     */
+    public static String getStringOfTodayDate() {
+
+        Date d = new Date();
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+        return df.format(d);
+    }
+
+
+    /**
+     * 比较两日期(字符)的大小,日期格式为yyMMdd.
+     *
+     * @param beginDate
+     * @param endDate
+     * @return boolean
+     */
+    public static final boolean compareDate(String beginDate, String endDate) {
+
+        long begin = Integer.parseInt(beginDate.substring(0, 4)
+                + beginDate.substring(5, 7) + beginDate.substring(8, 10));
+        long end = Integer.parseInt(endDate.substring(0, 4)
+                + endDate.substring(5, 7) + endDate.substring(8, 10));
+        if (begin > end) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * 将Date对象类型转化为指定的格式字符串
+     *
+     * @param date<Date>日期
+     * @param format<String>格式
+     * @return String
+     */
+    public static String dateToString(Date date, String format) {
+
+        try {
+            if(date!=null)
+                return new SimpleDateFormat(format).format(date);
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.gc();
+        }
+        return null;
+    }
+
+    /**
+     * 系统日期减去传入日期得到天数
+     * @param date1 传入日期
+     * @return 天数
+     * long
+     */
+    public static long sub(Date date1) {
+        Date d2 = convertToDate(dateParseShortString(new Date()));
+        Date d1 = convertToDate(dateParseShortString(date1));
+        long day = (d2.getTime() - d1.getTime())/(24*60*60*1000);
+        return day;
+    }
+
+    /**
+     * 日期相减得到年数
+     * @param date1 相减的日期
+     * @return
+     */
+    public static long subDateGetYear(Date date1) {
+        Date d2 = convertToDate(dateParseShortString(new Date()));
+        Date d1 = convertToDate(dateParseShortString(date1));
+        long day = (d2.getYear() - d1.getYear());
+        return day+1;
+    }
+
+    /**
+     * 计算两个日期间的月份
+     * @param date1 起始日期
+     * @param date2 结束日期
+     * @return
+     */
+    public static long subDateGetMonth(Date date1,Date date2) {
+        DateCalculate  culate=DateCalculate.calculate(date1, date2);
+        return culate.getDifferenceOfMonths();
+    }
+
+    /**
+     * 计算两个日期间的月份,不满一个月按一个月计算
+     * @param date1 起始日期
+     * @param date2 结束日期
+     * @return
+     */
+    public static long subDateGetFullMonth(Date date1,Date date2) {
+        DateCalculate  culate=DateCalculate.calculate(date1, date2);
+        long month=culate.getDifferenceOfMonths();
+        if(culate.getDifferenceOfDays() > 0)
+            month++;
+        return month;
+    }
+
+
+    /**
+     * 日期提前一天
+     *
+     * @param when 被计算的日期
+     * @param dateFormat 日期格式化
+     * @return 计算后的日期
+     */
+    public static String beforeOneDayByDate(Date when, DateFormat dateFormat) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(when);
+        calendar.add(Calendar.DATE, -1);//日期减一天
+        return dateFormat.format(calendar.getTime());
+    }
+
+    /**
+     * 当前日期提前一天
+     * @return
+     */
+    public static String beforeOneDayByCurDate() {
+        return beforeOneDayByDate(getCurrentDateTime(), DATE_FORMAT);
+    }
+
+    /**
+     * 日期提前一个月
+     * @param when 日期
+     * @param dateFormat 日期格式化
+     * @return
+     */
+    public static String beforeOneMonthByDate(Date when, DateFormat dateFormat) {
+        Calendar calendar = Calendar.getInstance();//日历对象
+        calendar.setTime(when);//设置日期
+        calendar.add(Calendar.MONTH, -1);//月份减一
+        return dateFormat.format(calendar.getTime());
+    }
+
+    /**
+     * 当前日期提前一个月
+     * @return
+     */
+    public static String beforeOneMonthByCurDate() {
+        return beforeOneMonthByDate(getCurrentDateTime(), DATE_FORMAT);
+    }
+
+    public static void main(String[] args) {
+        String yesterday = DateUtils.beforeOneDayByCurDate();
+        System.out.println(yesterday);
+        String monthBefore = DateUtils.beforeOneMonthByCurDate();
+        System.out.println(monthBefore);
+        Date date = DateUtils.parseDateByFormat(DateUtils.getCurrentTime(),"yyyy-MM-dd HH:mm:ss");
+        Date date2 = DateUtils.parseDate(DateUtils.getCurrentTime());
+        System.out.println(DateUtils.getCurrentTime());
+        System.out.println("date2:"+date2);
+
+    }
+}

+ 213 - 0
elab-core/src/main/java/com/elab/core/utils/DoubleUtils.java

@@ -0,0 +1,213 @@
+package com.elab.core.utils;
+
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+
+/**
+ * 加减乘除运算工具类
+ * @author liuhx on 2017/1/2 14:38
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class DoubleUtils {
+    private static final int DEF_DIV_SCALE = 10;
+
+    /**
+     * 6. * 提供精确的加法运算 7. * @param v1 被加数 8. * @param v2 加数 9. * @return 两个参数的和
+     * 10.
+     */
+
+    public static int compareWeight(double v1, double v2) {
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
+        b1 = b1.setScale(4, BigDecimal.ROUND_HALF_UP);
+        b2 = b2.setScale(4, BigDecimal.ROUND_HALF_UP);
+        return b1.compareTo(b2);
+
+    }
+
+    public static int compareMoney(double v1, double v2) {
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
+        b1 = b1.setScale(2, BigDecimal.ROUND_HALF_UP);
+        b2 = b2.setScale(2, BigDecimal.ROUND_HALF_UP);
+        return b1.compareTo(b2);
+
+    }
+
+    public static double add(double v1, double v2) {
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
+
+        return b1.add(b2).doubleValue();
+    }
+
+    /**
+     * 18. * 提供精确的减法运算 19. * @param v1 被减数 20. * @param v2 减数 21. * @return
+     * 两个参数的差 22.
+     */
+    public static double substract(double v1, double v2) {
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
+        return b1.subtract(b2).doubleValue();
+    }
+
+    /**
+     * 30. * 提供精确的乘法运算 31. * @param v1 被乘数 32. * @param v2 乘数 33. * @return
+     * 两个参数的积 34.
+     */
+    public static double multiply(double v1, double v2) {
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
+        return b1.multiply(b2).doubleValue();
+    }
+
+    /**
+     * 42. * 提供(相对)精确的除法运算,当发生除不尽的情况时, 43. * 精确到小数点以后10位,以后的数字四舍五入. 44. * @param
+     * v1 被除数 45. * @param v2 除数 46. * @return 两个参数的商 47.
+     */
+    public static double divide(double v1, double v2) {
+        return divide(v1, v2, DEF_DIV_SCALE);
+    }
+
+    /**
+     * 53. * 提供(相对)精确的除法运算. 54. * 当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入. 55. * 56.
+     * * @param v1 被除数 57. * @param v2 除数 58. * @param scale 表示需要精确到小数点以后几位 59.
+     * * @return 两个参数的商 60.
+     */
+    public static double divide(double v1, double v2, int scale) {
+        if (scale < 0) {
+            throw new IllegalArgumentException(
+                    "The scale must be a positive integer or zero");
+        }
+
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
+        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
+    }
+
+    /**
+     * 72. * 提供精确的小数位四舍五入处理 73. * @param v 需要四舍五入的数字 74. * @param scale 小数点后保留几位
+     * 75. * @return 四舍五入后的结果 76.
+     */
+    public static double round(double v, int scale) {
+        if (scale < 0) {
+            throw new IllegalArgumentException(
+                    "The scale must be a positive integer or zero");
+        }
+
+        BigDecimal b = new BigDecimal(Double.toString(v));
+        BigDecimal one = new BigDecimal("1");
+        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
+    }
+
+    public static double roundMoney(double v) {
+
+        BigDecimal b = new BigDecimal(Double.toString(v));
+        BigDecimal one = new BigDecimal("1");
+        return b.divide(one, 2, BigDecimal.ROUND_HALF_UP).doubleValue();
+    }
+
+    public static double roundWeight(double v) {
+        BigDecimal b = new BigDecimal(Double.toString(v));
+        BigDecimal one = new BigDecimal("1");
+        return b.divide(one, 4, BigDecimal.ROUND_HALF_UP).doubleValue();
+    }
+
+    public static String toMoney(double amount) {
+        DecimalFormat df = new DecimalFormat("0.00");
+        return df.format(amount);
+    }
+
+    /**
+     * 将以元为单位的金额转换成以分为单位的金额
+     *
+     * @param amount
+     * @return
+     */
+    public static String toMinuteMoney(double amount) {
+        if (compareMoney(amount, 0) == 0)
+            return "0";
+        DecimalFormat df = new DecimalFormat("0");
+        return df.format(multiply(roundMoney(amount), 100));
+    }
+
+    /**
+     * 将以元为单位的金额转换成以分为单位的金额
+     *
+     * @param amount
+     * @return
+     */
+    public static double toYuanMoney(double amount) {
+        if (compareMoney(amount, 0) == 0)
+            return amount;
+        return roundMoney(divide(amount, 100));
+    }
+
+    /**
+     * 将以元为单位的金额转换成以分为单位的金额
+     *
+     * @param amount
+     * @return
+     */
+    public static double toYuanMoney(String amount) {
+        if (StringUtils.isEmpty(amount))
+            return 0;
+        return roundMoney(divide(Double.parseDouble(amount), 100));
+    }
+
+    /**
+     * 将放大了10000倍后的利率还原成原形
+     *
+     * @param rate
+     * @return
+     */
+    public static double toRealRate(String rate) {
+        if (StringUtils.isEmpty(rate))
+            return 0;
+        return round(divide(Double.parseDouble(rate), 10000), 5);
+    }
+
+    /**
+     * 将放大了10000倍后的利率
+     *
+     * @param rate
+     * @return
+     */
+    public static String toMaxRate(double rate) {
+        if (compareMoney(rate, 0) == 0)
+            return "0";
+        DecimalFormat df = new DecimalFormat("0");
+        return df.format(multiply(roundMoney(rate), 10000));
+    }
+
+    public static void main(String[] args) {
+        double str = DoubleUtils.toYuanMoney("1100007");
+        System.out.println(str);
+
+    }
+
+    /***
+     * 是否为正整数
+     */
+    public static boolean isPositiveInteger(double value) {
+        long a = (long) value;
+        if (a != value || a < 0) {
+            return false;
+        }
+        return true;
+    }
+
+    /***
+     * 是否为正整数
+     */
+    public static boolean isPositiveInteger(String value) {
+        double d = Double.parseDouble(value);
+        long a = (long) d;
+        if (a != d || a < 0) {
+            return false;
+        }
+        return true;
+    }
+
+}

+ 37 - 0
elab-core/src/main/java/com/elab/core/utils/ExceptionUtils.java

@@ -0,0 +1,37 @@
+package com.elab.core.utils;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/**
+ * 把异常信息从堆栈中获取到字符串中
+ * @author liuhx on 2017/1/2 14:39
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class ExceptionUtils {
+    /**
+     * 把异常信息从堆栈中获取到字符串中
+     * @param e
+     * @return
+     */
+    public static String getExceptionInfo(Exception e) {
+        StringWriter sw = new StringWriter();
+        e.printStackTrace(new PrintWriter(sw, true));
+        String str = sw.toString();
+
+        try {
+            sw.close();
+        } catch (Exception var4) {
+            var4.printStackTrace();
+        }
+
+        return str;
+    }
+
+    public static void main(String[] args) {
+        Exception e = new Exception();
+        String info = getExceptionInfo(e);
+        System.out.println(info);
+    }
+}

+ 195 - 0
elab-core/src/main/java/com/elab/core/utils/FavFTPUtil.java

@@ -0,0 +1,195 @@
+package com.elab.core.utils;
+
+import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPFile;
+import org.apache.commons.net.ftp.FTPReply;
+
+import java.io.*;
+
+public class FavFTPUtil {
+    public static boolean uploadFile(String hostname, int port, String username, String password, String pathname, String fileName, InputStream inputStream) {
+        boolean flag = false;
+        FTPClient ftpClient = new FTPClient();
+        ftpClient.setControlEncoding("UTF-8");
+        try {
+            //连接FTP服务器
+            ftpClient.connect(hostname, port);
+            //登录FTP服务器
+            boolean flag1 = ftpClient.login(username, password);
+            System.out.println("flag1连接是否成功:"+flag1);
+            //是否成功登录FTP服务器
+            int replyCode = ftpClient.getReplyCode();
+            if (!FTPReply.isPositiveCompletion(replyCode)) {
+                return flag;
+            }
+            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
+            ftpClient.makeDirectory(pathname);
+            ftpClient.changeWorkingDirectory(pathname);
+            ftpClient.storeFile(fileName, inputStream);
+            inputStream.close();
+            ftpClient.logout();
+            flag = true;
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (ftpClient.isConnected()) {
+                try {
+                    ftpClient.disconnect();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return flag;
+    }
+
+    /**
+     * 上传文件(可对文件进行重命名)
+     * @param hostname FTP服务器地址
+     * @param port FTP服务器端口号
+     * @param username FTP登录帐号
+     * @param password FTP登录密码
+     * @param pathname FTP服务器保存目录
+     * @param filename 上传到FTP服务器后的文件名称
+     * @param originfilename 待上传文件的名称(绝对地址)
+     * @return
+     */
+    public static boolean uploadFileFromProduction(String hostname, int port, String username, String password, String pathname, String filename, String originfilename){
+        boolean flag = false;
+        try {
+            InputStream inputStream = new FileInputStream(new File(originfilename));
+            flag = uploadFile(hostname, port, username, password, pathname, filename, inputStream);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return flag;
+    }
+
+    /**
+     * 上传文件(不可以进行文件的重命名操作)
+     * @param hostname FTP服务器地址
+     * @param port FTP服务器端口号
+     * @param username FTP登录帐号
+     * @param password FTP登录密码
+     * @param pathname FTP服务器保存目录
+     * @param originfilename 待上传文件的名称(绝对地址)
+     * @return
+     */
+    public static boolean uploadFileFromProduction(String hostname, int port, String username, String password, String pathname, String originfilename){
+        boolean flag = false;
+        try {
+            String fileName = new File(originfilename).getName();
+            InputStream inputStream = new FileInputStream(new File(originfilename));
+            flag = uploadFile(hostname, port, username, password, pathname, fileName, inputStream);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return flag;
+    }
+
+    /**
+     * 删除文件
+     * @param hostname FTP服务器地址
+     * @param port FTP服务器端口号
+     * @param username FTP登录帐号
+     * @param password FTP登录密码
+     * @param pathname FTP服务器保存目录
+     * @param filename 要删除的文件名称
+     * @return
+     */
+    public static boolean deleteFile(String hostname, int port, String username, String password, String pathname, String filename){
+        boolean flag = false;
+        FTPClient ftpClient = new FTPClient();
+        try {
+            //连接FTP服务器
+            ftpClient.connect(hostname, port);
+            //登录FTP服务器
+            ftpClient.login(username, password);
+            //验证FTP服务器是否登录成功
+            int replyCode = ftpClient.getReplyCode();
+            if(!FTPReply.isPositiveCompletion(replyCode)){
+                return flag;
+            }
+            //切换FTP目录
+            ftpClient.changeWorkingDirectory(pathname);
+            ftpClient.dele(filename);
+            ftpClient.logout();
+            flag = true;
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally{
+            if(ftpClient.isConnected()){
+                try {
+                    ftpClient.logout();
+                } catch (IOException e) {
+
+                }
+            }
+        }
+        return flag;
+    }
+
+    /**
+     * 下载文件
+     * @param hostname FTP服务器地址
+     * @param port FTP服务器端口号
+     * @param username FTP登录帐号
+     * @param password FTP登录密码
+     * @param pathname FTP服务器文件目录
+     * @param filename 文件名称
+     * @param localpath 下载后的文件路径
+     * @return
+     */
+    public static boolean downloadFile(String hostname, int port, String username, String password, String pathname, String filename, String localpath){
+        boolean flag = false;
+        FTPClient ftpClient = new FTPClient();
+        try {
+            //连接FTP服务器
+            ftpClient.connect(hostname, port);
+            //登录FTP服务器
+            ftpClient.login(username, password);
+            //验证FTP服务器是否登录成功
+            int replyCode = ftpClient.getReplyCode();
+            if(!FTPReply.isPositiveCompletion(replyCode)){
+                return flag;
+            }
+            //切换FTP目录
+            ftpClient.changeWorkingDirectory(pathname);
+            FTPFile[] ftpFiles = ftpClient.listFiles();
+            for(FTPFile file : ftpFiles){
+                if(filename.equalsIgnoreCase(file.getName())){
+                    File localFile = new File(localpath + "/" + file.getName());
+                    OutputStream os = new FileOutputStream(localFile);
+                    ftpClient.retrieveFile(file.getName(), os);
+                    os.close();
+                }
+            }
+            ftpClient.logout();
+            flag = true;
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally{
+            if(ftpClient.isConnected()){
+                try {
+                    ftpClient.logout();
+                } catch (IOException e) {
+
+                }
+            }
+        }
+        return flag;
+    }
+
+
+    public static void main(String[] args) {
+        String hostname = "192.168.0.12";
+        int port = 2211;
+        String username = "ftp";
+        String password = "ftp@123";
+        String pathname = "";
+        String filename = "shangju.png";
+        String originfilename = "E:\\shangju.png";
+        FavFTPUtil.uploadFileFromProduction(hostname, port, username, password, pathname, filename, originfilename);
+
+    }
+}

+ 179 - 0
elab-core/src/main/java/com/elab/core/utils/FileUtils.java

@@ -0,0 +1,179 @@
+package com.elab.core.utils;
+
+import java.io.*;
+
+/**
+ * 文件操作工具
+ * @author liuhx on 2016/12/30 23:07
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class FileUtils {
+    /**
+     *
+     * 读取源文件内容
+     *
+     * @param filename
+     *            String 文件路径
+     * @throws IOException
+     * @return byte[] 文件内容
+     */
+    public static byte[] readFile(String filename) throws IOException {
+        File file = new File(filename);
+        if (filename == null || filename.equals("")) {
+            throw new NullPointerException("无效的文件路径");
+        }
+        long len = file.length();
+        byte[] bytes = new byte[(int) len];
+        BufferedInputStream bufferedInputStream = new BufferedInputStream(
+                new FileInputStream(file));
+        int r = bufferedInputStream.read(bytes);
+        if (r != len)
+            throw new IOException("读取文件不正确");
+        bufferedInputStream.close();
+        return bytes;
+    }
+
+    /**
+     * 将数据写入文件
+     *
+     * @param data
+     *            byte[]
+     * @throws IOException
+     */
+
+    public static void writeFile(byte[] data, String filename)
+            throws IOException {
+        File file = new File(filename);
+        file.getParentFile().mkdirs();
+        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(
+                new FileOutputStream(file));
+        bufferedOutputStream.write(data);
+        bufferedOutputStream.close();
+    }
+
+    /**
+     * 从jar文件里读取class
+     *
+     * @param filename
+     *            String
+     * @throws IOException
+     * @return byte[]
+     */
+
+    public byte[] readFileJar(String filename) throws IOException {
+        BufferedInputStream bufferedInputStream = new BufferedInputStream(
+                getClass().getResource(filename).openStream());
+        int len = bufferedInputStream.available();
+        byte[] bytes = new byte[len];
+        int r = bufferedInputStream.read(bytes);
+        if (len != r) {
+            bytes = null;
+            throw new IOException("读取文件不正确");
+        }
+        bufferedInputStream.close();
+        return bytes;
+    }
+
+    /** */
+    /**
+     *
+     * 读取网络流,为了防止中文的问题,在读取过程中没有进行编码转换,而且采取了动态的byte[]的方式获得所有的byte返回
+     *
+     * @param bufferedInputStream
+     *            BufferedInputStream
+     * @throws IOException
+     * @return byte[]
+     */
+
+    public byte[] readUrlStream(BufferedInputStream bufferedInputStream)
+            throws IOException {
+        byte[] bytes = new byte[100];
+        byte[] bytecount = null;
+        int n = 0;
+        int ilength = 0;
+        while ((n = bufferedInputStream.read(bytes)) >= 0) {
+            if (bytecount != null)
+                ilength = bytecount.length;
+            byte[] tempbyte = new byte[ilength + n];
+            if (bytecount != null) {
+                System.arraycopy(bytecount, 0, tempbyte, 0, ilength);
+            }
+            System.arraycopy(bytes, 0, tempbyte, ilength, n);
+            bytecount = tempbyte;
+            if (n < bytes.length)
+                break;
+        }
+
+        return bytecount;
+    }
+
+    /**
+     * 获取文件的真实后缀名。目前只支持JPG, GIF, PNG, BMP四种图片文件。
+     *
+     * @param bytes 文件字节流
+     * @return JPG, GIF, PNG or null
+     */
+    public static String getFileSuffix(byte[] bytes)
+    {
+        if ((bytes == null) || (bytes.length < 10)) {
+            return null;
+        }
+        if ((bytes[0] == 71) && (bytes[1] == 73) && (bytes[2] == 70)) {
+            return "GIF";
+        }
+        if ((bytes[1] == 80) && (bytes[2] == 78) && (bytes[3] == 71)) {
+            return "PNG";
+        }
+        if ((bytes[6] == 74) && (bytes[7] == 70) && (bytes[8] == 73) && (bytes[9] == 70)) {
+            return "JPG";
+        }
+        if ((bytes[0] == 66) && (bytes[1] == 77)) {
+            return "BMP";
+        }
+        return null;
+    }
+
+    /**
+     * 获取文件的真实媒体类型。目前只支持JPG, GIF, PNG, BMP四种图片文件。
+     *
+     * @param bytes 文件字节流
+     * @return 媒体类型(MEME-TYPE)
+     */
+    public static String getMimeType(byte[] bytes)
+    {
+        String suffix = getFileSuffix(bytes);
+        String mimeType;
+        if ("JPG".equals(suffix))
+        {
+            mimeType = "image/jpeg";
+        }
+        else
+        {
+            if ("GIF".equals(suffix))
+            {
+                mimeType = "image/gif";
+            }
+            else
+            {
+                if ("PNG".equals(suffix))
+                {
+                    mimeType = "image/png";
+                }
+                else
+                {
+                    if ("BMP".equals(suffix))
+                    {
+                        mimeType = "image/bmp";
+                    }
+                    else
+                    {
+                        mimeType = "application/octet-stream";
+                    }
+                }
+            }
+        }
+        return mimeType;
+    }
+
+}

+ 41 - 0
elab-core/src/main/java/com/elab/core/utils/FreeMarkerUtils.java

@@ -0,0 +1,41 @@
+package com.elab.core.utils;
+
+import freemarker.cache.StringTemplateLoader;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.Map;
+
+/**
+ * @author liuhx on 2017/1/2 15:07
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class FreeMarkerUtils {
+    /**
+     * 使用freemarker模版替换技术
+     *
+     * @param params
+     *            , 参数集合, params中可以包含对象及多级对象
+     * @param content
+     *            , 要替换的文本
+     * @return
+     * @throws IOException
+     * @throws TemplateException
+     */
+    public static String renderModel(Map<String, Object> params,
+                                     String content) throws IOException, TemplateException {
+        StringTemplateLoader loader = new StringTemplateLoader(); // 模版加载器
+        loader.putTemplate("chain", content);
+        Configuration config = new Configuration();
+        config.setTemplateLoader(loader);
+        Template template = config.getTemplate("chain", "UTF-8");
+        StringWriter out = new StringWriter();
+
+        template.process(params, out);
+        return out.toString();
+    }
+}

+ 60 - 0
elab-core/src/main/java/com/elab/core/utils/Ftp.java

@@ -0,0 +1,60 @@
+package com.elab.core.utils;
+
+/**
+ * ftp链接常量
+ *
+ */
+public class Ftp {
+
+    private String ipAddr;//ip地址
+
+    private Integer port;//端口号
+
+    private String userName;//用户名
+
+    private String pwd;//密码
+
+    private String path;//aaa路径
+
+    public String getIpAddr() {
+        return ipAddr;
+    }
+
+    public void setIpAddr(String ipAddr) {
+        this.ipAddr = ipAddr;
+    }
+
+    public Integer getPort() {
+        return port;
+    }
+
+    public void setPort(Integer port) {
+        this.port = port;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public String getPwd() {
+        return pwd;
+    }
+
+    public void setPwd(String pwd) {
+        this.pwd = pwd;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+
+}

+ 231 - 0
elab-core/src/main/java/com/elab/core/utils/FtpUtil.java

@@ -0,0 +1,231 @@
+package com.elab.core.utils;
+
+import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPFile;
+import org.apache.commons.net.ftp.FTPReply;
+
+import java.io.*;
+
+public class FtpUtil {
+
+
+    private static FTPClient ftp;
+
+    /**
+     * 获取ftp连接
+     * @param f
+     * @return
+     * @throws Exception
+     */
+    public static boolean connectFtp(Ftp f) throws Exception{
+        ftp=new FTPClient();
+        boolean flag=false;
+        int reply;
+        if (f.getPort()==null) {
+            ftp.connect(f.getIpAddr(),2121);
+        }else{
+            ftp.connect(f.getIpAddr(),f.getPort());
+        }
+        ftp.login(f.getUserName(), f.getPwd());
+        ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
+        reply = ftp.getReplyCode();
+        if (!FTPReply.isPositiveCompletion(reply)) {
+            ftp.disconnect();
+            return flag;
+        }
+        ftp.changeWorkingDirectory(f.getPath());
+        flag = true;
+        return flag;
+    }
+
+    /**
+     * 关闭ftp连接
+     */
+    public static void closeFtp(){
+        if (ftp!=null && ftp.isConnected()) {
+            try {
+                ftp.logout();
+                ftp.disconnect();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * ftp上传文件
+     * @param f
+     * @throws Exception
+     */
+    public static void upload(File f) throws Exception{
+//        if (f.isDirectory()) {
+//            ftp.makeDirectory(f.getName());
+//            ftp.changeWorkingDirectory(f.getName());
+            String[] files=f.list();
+            for(String fstr : files){
+                File file1=new File(f.getPath()+"/"+fstr);
+                if (file1.isDirectory()) {
+                    upload(file1);
+                    ftp.changeToParentDirectory();
+                }else{
+                    File file2=new File(f.getPath()+"/"+fstr);
+                    FileInputStream input=new FileInputStream(file2);
+                    ftp.storeFile(file2.getName(),input);
+                    input.close();
+                }
+            }
+//        }else{
+//            File file2=new File(f.getPath());
+//            FileInputStream input=new FileInputStream(file2);
+//            ftp.storeFile(file2.getName(),input);
+//            input.close();
+//        }
+    }
+
+    /**
+     * 下载链接配置
+     * @param f
+     * @param localBaseDir 本地目录
+     * @param remoteBaseDir 远程目录
+     * @throws Exception
+     */
+    public static void startDown(Ftp f,String localBaseDir,String remoteBaseDir ) throws Exception{
+        if (FtpUtil.connectFtp(f)) {
+
+            try {
+                FTPFile[] files = null;
+                boolean changedir = ftp.changeWorkingDirectory(remoteBaseDir);
+                if (changedir) {
+                    ftp.setControlEncoding("GBK");
+                    files = ftp.listFiles();
+                    for (int i = 0; i < files.length; i++) {
+                        try{
+                            downloadFile(files[i], localBaseDir, remoteBaseDir);
+                        }catch(Exception e){
+                            e.printStackTrace();
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+    }
+
+
+    /**
+     *
+     * 下载FTP文件
+     * 当你需要下载FTP文件的时候,调用此方法
+     * 根据<b>获取的文件名,本地地址,远程地址</b>进行下载
+     *
+     * @param ftpFile
+     * @param relativeLocalPath
+     * @param relativeRemotePath
+     */
+    private  static void downloadFile(FTPFile ftpFile, String relativeLocalPath,String relativeRemotePath) {
+        if (ftpFile.isFile()) {
+            if (ftpFile.getName().indexOf("?") == -1) {
+                OutputStream outputStream = null;
+                try {
+                    File locaFile= new File(relativeLocalPath+ ftpFile.getName());
+                    //判断文件是否存在,存在则返回
+                    if(locaFile.exists()){
+                        return;
+                    }else{
+                        outputStream = new FileOutputStream(relativeLocalPath+ ftpFile.getName());
+                        ftp.retrieveFile(ftpFile.getName(), outputStream);
+                        outputStream.flush();
+                        outputStream.close();
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                } finally {
+                    try {
+                        if (outputStream != null){
+                            outputStream.close();
+                        }
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        } else {
+            String newlocalRelatePath = relativeLocalPath + ftpFile.getName();
+            String newRemote = new String(relativeRemotePath+ ftpFile.getName().toString());
+            File fl = new File(newlocalRelatePath);
+            if (!fl.exists()) {
+                fl.mkdirs();
+            }
+            try {
+                newlocalRelatePath = newlocalRelatePath + '/';
+                newRemote = newRemote + "/";
+                String currentWorkDir = ftpFile.getName().toString();
+                boolean changedir = ftp.changeWorkingDirectory(currentWorkDir);
+                if (changedir) {
+                    FTPFile[] files = null;
+                    files = ftp.listFiles();
+                    for (int i = 0; i < files.length; i++) {
+                        downloadFile(files[i], newlocalRelatePath, newRemote);
+                    }
+                }
+                if (changedir){
+                    ftp.changeToParentDirectory();
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * FTP上传单个文件测试
+     */
+    public static void testUpload() {
+        FTPClient ftpClient = new FTPClient();
+        FileInputStream fis = null;
+
+        try {
+            ftpClient.connect("192.168.0.12", 2121);
+            boolean flag = ftpClient.login("ftpuser", "elab@201509");
+            System.out.println("flag:"+flag);
+            File srcFile = new File("E:\\soso\\readme.txt");
+            fis = new FileInputStream(srcFile);
+            //设置上传目录
+            ftpClient.changeWorkingDirectory("/product");
+            ftpClient.setBufferSize(1024);
+            ftpClient.setControlEncoding("GBK");
+            //设置文件类型(二进制)
+            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
+            ftpClient.storeFile("3.txt", fis);
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new RuntimeException("FTP客户端出错!", e);
+        } finally {
+//            IOUtils.closeQuietly(fis);
+            try {
+                ftpClient.disconnect();
+            } catch (IOException e) {
+                e.printStackTrace();
+                throw new RuntimeException("关闭FTP连接发生异常!", e);
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception{
+        /*Ftp f=new Ftp();
+        f.setIpAddr("192.168.0.12");
+        f.setUserName("ftpuser");
+        f.setPwd("elab@201509");
+        f.setPort(2121);
+        boolean flag = FtpUtil.connectFtp(f);
+        System.out.println("是否已连接:"+flag);
+        File file = new File("E:\\soso\\readme.txt");
+        FtpUtil.upload(file);//把文件上传在ftp上
+//        FtpUtil.startDown(f, "e:/",  "/product");//下载ftp文件测试
+        System.out.println("ok");*/
+        FtpUtil.testUpload();
+    }
+
+}

+ 258 - 0
elab-core/src/main/java/com/elab/core/utils/LogUtils.java

@@ -0,0 +1,258 @@
+//package com.elab.core.utils;
+//
+//import com.elab.core.log.ILogAdapter;
+//import com.elab.core.log.LogEntry;
+//import com.elab.core.log.LogLevel;
+//import com.elab.core.log.LogProvider;
+//import com.elab.core.log.adapter.Log4jFileAdapter;
+//import com.elab.core.serialization.SerializeFactory;
+//
+//import java.util.concurrent.ExecutorService;
+//import java.util.concurrent.Executors;
+//
+///**
+// * @author liuhx on 2017/1/2 14:40
+// * @version V1.0
+// * @email liuhx@elab-plus.com
+// */
+//public class LogUtils {
+//    private static final ExecutorService service = Executors.newCachedThreadPool();
+//    private static ILogAdapter logger1 = null;
+//    private static ILogAdapter logger2 = null;
+//
+//
+//    public LogUtils() {
+//    }
+//
+//    private static ILogAdapter getLogger() throws Exception{
+//        if(null == logger1){
+//            synchronized(Log4jFileAdapter.class){
+//                if(null == logger1){
+//                    return LogProvider.createDefault();
+//                }
+//            }
+//        }
+//        return logger1;
+//    }
+//
+//    private static ILogAdapter getLogger(String logType) throws Exception{
+//        if(null == logger2){
+//            synchronized(Log4jFileAdapter.class){
+//                if(null == logger2){
+//                    return LogProvider.create(logType);
+//                }
+//            }
+//        }
+//        return logger2;
+//    }
+//
+//
+//
+//    public static void send(final String model,final String message) {
+//        try {
+//            service.submit(new Runnable() {
+//                public void run() {
+//                    try {
+//                        getLogger().log(new LogEntry(model, message));
+//                    } catch (Exception e) {
+//                        e.printStackTrace();
+//                    }
+//                }
+//            });
+//        } catch (Exception var6) {
+//            var6.printStackTrace();
+//        } finally {
+//            Runtime.getRuntime().addShutdownHook(new Thread() {
+//                public void run() {
+//                    LogUtils.service.shutdownNow();
+//                }
+//            });
+//        }
+//    }
+//
+//    public static void send(final String logType, final String model,final String message) {
+//        try {
+//            service.submit(new Runnable() {
+//                public void run() {
+//                    try {
+//                        getLogger(logType).log(new LogEntry(model, message));
+//                    } catch (Exception e) {
+//                        // TODO Auto-generated catch block
+//                        e.printStackTrace();
+//                    }
+//                }
+//            });
+//        } catch (Exception var6) {
+//            var6.printStackTrace();
+//        } finally {
+//            Runtime.getRuntime().addShutdownHook(new Thread() {
+//                public void run() {
+//                    LogUtils.service.shutdownNow();
+//                }
+//            });
+//        }
+//    }
+//
+//
+//    public static void send(final String model,final String message, final LogLevel logLevel) {
+//        try {
+//            service.submit(new Runnable() {
+//                public void run() {
+//                    try {
+//                        getLogger().log(new LogEntry(model, message, logLevel));
+//                    } catch (Exception e) {
+//                        // TODO Auto-generated catch block
+//                        e.printStackTrace();
+//                    }
+//                }
+//            });
+//        } catch (Exception var6) {
+//            var6.printStackTrace();
+//        } finally {
+//            Runtime.getRuntime().addShutdownHook(new Thread() {
+//                public void run() {
+//                    LogUtils.service.shutdownNow();
+//                }
+//            });
+//        }
+//    }
+//
+//    public static void send(final String logType, final String model,final String message, final LogLevel logLevel) {
+//        try {
+//            service.submit(new Runnable() {
+//                public void run() {
+//                    try {
+//                        getLogger(logType).log(new LogEntry(model, message, logLevel));
+//                    } catch (Exception e) {
+//                        // TODO Auto-generated catch block
+//                        e.printStackTrace();
+//                    }
+//                }
+//            });
+//        } catch (Exception var6) {
+//            var6.printStackTrace();
+//        } finally {
+//            Runtime.getRuntime().addShutdownHook(new Thread() {
+//                public void run() {
+//                    LogUtils.service.shutdownNow();
+//                }
+//            });
+//        }
+//    }
+//
+//    public static void send(final String model,final Exception ex) {
+//        try {
+//            service.submit(new Runnable() {
+//                public void run() {
+//                    try {
+//                        getLogger().log(new LogEntry(model, SerializeFactory.getJsonSerializer().ToSerializedString(ex), LogLevel.Error));
+//                    } catch (Exception e) {
+//                        // TODO Auto-generated catch block
+//                        e.printStackTrace();
+//                    }
+//                }
+//            });
+//        } catch (Exception var6) {
+//            var6.printStackTrace();
+//        } finally {
+//            Runtime.getRuntime().addShutdownHook(new Thread() {
+//                public void run() {
+//                    LogUtils.service.shutdownNow();
+//                }
+//            });
+//        }
+//    }
+//
+//    public static void send(final String logType,final String model,final Exception ex) {
+//        try {
+//            service.submit(new Runnable() {
+//                public void run() {
+//                    try {
+//                        getLogger(logType).log(new LogEntry(model, SerializeFactory.getJsonSerializer().ToSerializedString(ex), LogLevel.Error));
+//                    } catch (Exception e) {
+//                        // TODO Auto-generated catch block
+//                        e.printStackTrace();
+//                    }
+//                }
+//            });
+//        } catch (Exception var6) {
+//            var6.printStackTrace();
+//        } finally {
+//            Runtime.getRuntime().addShutdownHook(new Thread() {
+//                public void run() {
+//                    LogUtils.service.shutdownNow();
+//                }
+//            });
+//        }
+//    }
+//
+//    public static void send(final String logType,final LogEntry entry) {
+//        try {
+//            service.submit(new Runnable() {
+//                public void run() {
+//                    try {
+//                        getLogger(logType).log(entry);
+//                    } catch (Exception e) {
+//                        // TODO Auto-generated catch block
+//                        e.printStackTrace();
+//                    }
+//                }
+//            });
+//        } catch (Exception var6) {
+//            var6.printStackTrace();
+//        } finally {
+//            Runtime.getRuntime().addShutdownHook(new Thread() {
+//                public void run() {
+//                    LogUtils.service.shutdownNow();
+//                }
+//            });
+//        }
+//    }
+//
+//    public static void send(final LogEntry entry) {
+//        try {
+//            service.submit(new Runnable() {
+//                public void run() {
+//                    try {
+//                        getLogger().log(entry);
+//                    } catch (Exception e) {
+//                        // TODO Auto-generated catch block
+//                        e.printStackTrace();
+//                    }
+//                }
+//            });
+//        } catch (Exception var6) {
+//            var6.printStackTrace();
+//        } finally {
+//            Runtime.getRuntime().addShutdownHook(new Thread() {
+//                public void run() {
+//                    LogUtils.service.shutdownNow();
+//                }
+//            });
+//        }
+//    }
+//
+//
+//
+//    public static void send(final Class classes,final String format, final String... message) {
+//        try {
+//            service.submit(new Runnable() {
+//                public void run() {
+//                    try {
+//                        getLogger().log(new LogEntry(classes.getName(), format, message));
+//                    } catch (Exception e) {
+//                        e.printStackTrace();
+//                    }
+//                }
+//            });
+//        } catch (Exception var6) {
+//            var6.printStackTrace();
+//        } finally {
+//            Runtime.getRuntime().addShutdownHook(new Thread() {
+//                public void run() {
+//                    LogUtils.service.shutdownNow();
+//                }
+//            });
+//        }
+//    }
+//}

+ 302 - 0
elab-core/src/main/java/com/elab/core/utils/MD5Utils.java

@@ -0,0 +1,302 @@
+package com.elab.core.utils;
+
+/**
+ * @author liuhx on 2017/1/2 15:04
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class MD5Utils {
+    static final int S11 = 7;
+
+    static final int S12 = 12;
+
+    static final int S13 = 17;
+
+    static final int S14 = 22;
+
+    static final int S21 = 5;
+
+    static final int S22 = 9;
+
+    static final int S23 = 14;
+
+    static final int S24 = 20;
+
+    static final int S31 = 4;
+
+    static final int S32 = 11;
+
+    static final int S33 = 16;
+
+    static final int S34 = 23;
+
+    static final int S41 = 6;
+
+    static final int S42 = 10;
+
+    static final int S43 = 15;
+
+    static final int S44 = 21;
+
+    static final byte PADDING[] = { -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0 };
+
+    public static long b2iu(byte b) {
+        return (b >= 0 ? b : b & 0xff);
+    }
+
+    public static String byteHEX(byte ib) {
+        char Digit[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a',
+                'b', 'c', 'd', 'e', 'f' };
+        char ob[] = new char[2];
+        ob[0] = Digit[ib >>> 4 & 0xf];
+        ob[1] = Digit[ib & 0xf];
+        String s = new String(ob);
+        return s;
+    }
+
+    public static String encode(String s) {
+        return new MD5Utils().getMD5ofStr(s);
+    }
+
+
+    public static void main(String args[]) {
+        System.out.println(MD5Utils.encode("todaysteel2011"));
+        // String password = MD5.encode("111111");
+        // String md5hash = MD5.md5Hash(password);
+        // String opensimpassword = MD5.encodeForOpensim("123456");
+        // System.out.println(password);
+        // System.out.println(md5hash);
+        // System.out.println(opensimpassword);
+    }
+
+    private long state[];
+
+    private long count[];
+
+    private byte buffer[];
+
+    public String digestHexStr;
+
+    private byte digest[];
+
+    public MD5Utils() {
+        state = new long[4];
+        count = new long[2];
+        buffer = new byte[64];
+        digest = new byte[16];
+        md5Init();
+    }
+
+    private void Decode(long output[], byte input[], int len) {
+        int i = 0;
+        for (int j = 0; j < len; j += 4) {
+            output[i] = b2iu(input[j]) | b2iu(input[j + 1]) << 8
+                    | b2iu(input[j + 2]) << 16 | b2iu(input[j + 3]) << 24;
+            i++;
+        }
+
+    }
+
+    private void Encode(byte output[], long input[], int len) {
+        int i = 0;
+        for (int j = 0; j < len; j += 4) {
+            output[j] = (byte) (int) (input[i] & 255L);
+            output[j + 1] = (byte) (int) (input[i] >>> 8 & 255L);
+            output[j + 2] = (byte) (int) (input[i] >>> 16 & 255L);
+            output[j + 3] = (byte) (int) (input[i] >>> 24 & 255L);
+            i++;
+        }
+
+    }
+
+    private long F(long x, long y, long z) {
+        return x & y | (x ^ 0L - 1L) & z;
+    }
+
+    private long FF(long a, long b, long c, long d, long x, long s, long ac) {
+        a += F(b, c, d) + x + ac;
+        a = (int) a << (int) s | (int) a >>> (int) (32 - s);
+        a += b;
+        return a;
+    }
+
+    private long G(long x, long y, long z) {
+        return x & z | y & (z ^ 0L - 1L);
+    }
+
+    public String getMD5ofStr(String inbuf) {
+
+        md5Init();
+
+        md5Update(inbuf.getBytes(), inbuf.length());
+        md5Final();
+        digestHexStr = "";
+        for (int i = 0; i < 16; i++) {
+            digestHexStr = String.valueOf(digestHexStr)
+                    + String.valueOf(byteHEX(digest[i]));
+        }
+
+        return digestHexStr;
+    }
+
+    private long GG(long a, long b, long c, long d, long x, long s, long ac) {
+        a += G(b, c, d) + x + ac;
+        a = (int) a << (int) s | (int) a >>> (int) (32 - s);
+        a += b;
+        return a;
+    }
+
+    private long H(long x, long y, long z) {
+        return x ^ y ^ z;
+    }
+
+    private long HH(long a, long b, long c, long d, long x, long s, long ac) {
+        a += H(b, c, d) + x + ac;
+        a = (int) a << (int) s | (int) a >>> (int) (32 - s);
+        a += b;
+        return a;
+    }
+
+    private long I(long x, long y, long z) {
+        return y ^ (x | z ^ 0L - 1L);
+    }
+
+    private long II(long a, long b, long c, long d, long x, long s, long ac) {
+        a += I(b, c, d) + x + ac;
+        a = (int) a << (int) s | (int) a >>> (int) (32 - s);
+        a += b;
+        return a;
+    }
+
+    private void md5Final() {
+        byte bits[] = new byte[8];
+        Encode(bits, count, 8);
+        int index = (int) (count[0] >>> 3) & 0x3f;
+        int padLen = index >= 56 ? 120 - index : 56 - index;
+        md5Update(PADDING, padLen);
+        md5Update(bits, 8);
+        Encode(digest, state, 16);
+    }
+
+    private void md5Init() {
+        count[0] = 0L;
+        count[1] = 0L;
+        state[0] = 0x67452301L;
+        state[1] = 0xefcdab89L;
+        state[2] = 0x98badcfeL;
+        state[3] = 0x10325476L;
+    }
+
+    private void md5Memcpy(byte output[], byte input[], int outpos, int inpos,
+                           int len) {
+        for (int i = 0; i < len; i++) {
+            output[outpos + i] = input[inpos + i];
+        }
+
+    }
+
+    private void md5Transform(byte block[]) {
+        long a = state[0];
+        long b = state[1];
+        long c = state[2];
+        long d = state[3];
+        long x[] = new long[16];
+        Decode(x, block, 64);
+        a = FF(a, b, c, d, x[0], 7L, 0xd76aa478L);
+        d = FF(d, a, b, c, x[1], 12L, 0xe8c7b756L);
+        c = FF(c, d, a, b, x[2], 17L, 0x242070dbL);
+        b = FF(b, c, d, a, x[3], 22L, 0xc1bdceeeL);
+        a = FF(a, b, c, d, x[4], 7L, 0xf57c0fafL);
+        d = FF(d, a, b, c, x[5], 12L, 0x4787c62aL);
+        c = FF(c, d, a, b, x[6], 17L, 0xa8304613L);
+        b = FF(b, c, d, a, x[7], 22L, 0xfd469501L);
+        a = FF(a, b, c, d, x[8], 7L, 0x698098d8L);
+        d = FF(d, a, b, c, x[9], 12L, 0x8b44f7afL);
+        c = FF(c, d, a, b, x[10], 17L, 0xffff5bb1L);
+        b = FF(b, c, d, a, x[11], 22L, 0x895cd7beL);
+        a = FF(a, b, c, d, x[12], 7L, 0x6b901122L);
+        d = FF(d, a, b, c, x[13], 12L, 0xfd987193L);
+        c = FF(c, d, a, b, x[14], 17L, 0xa679438eL);
+        b = FF(b, c, d, a, x[15], 22L, 0x49b40821L);
+        a = GG(a, b, c, d, x[1], 5L, 0xf61e2562L);
+        d = GG(d, a, b, c, x[6], 9L, 0xc040b340L);
+        c = GG(c, d, a, b, x[11], 14L, 0x265e5a51L);
+        b = GG(b, c, d, a, x[0], 20L, 0xe9b6c7aaL);
+        a = GG(a, b, c, d, x[5], 5L, 0xd62f105dL);
+        d = GG(d, a, b, c, x[10], 9L, 0x2441453L);
+        c = GG(c, d, a, b, x[15], 14L, 0xd8a1e681L);
+        b = GG(b, c, d, a, x[4], 20L, 0xe7d3fbc8L);
+        a = GG(a, b, c, d, x[9], 5L, 0x21e1cde6L);
+        d = GG(d, a, b, c, x[14], 9L, 0xc33707d6L);
+        c = GG(c, d, a, b, x[3], 14L, 0xf4d50d87L);
+        b = GG(b, c, d, a, x[8], 20L, 0x455a14edL);
+        a = GG(a, b, c, d, x[13], 5L, 0xa9e3e905L);
+        d = GG(d, a, b, c, x[2], 9L, 0xfcefa3f8L);
+        c = GG(c, d, a, b, x[7], 14L, 0x676f02d9L);
+        b = GG(b, c, d, a, x[12], 20L, 0x8d2a4c8aL);
+        a = HH(a, b, c, d, x[5], 4L, 0xfffa3942L);
+        d = HH(d, a, b, c, x[8], 11L, 0x8771f681L);
+        c = HH(c, d, a, b, x[11], 16L, 0x6d9d6122L);
+        b = HH(b, c, d, a, x[14], 23L, 0xfde5380cL);
+        a = HH(a, b, c, d, x[1], 4L, 0xa4beea44L);
+        d = HH(d, a, b, c, x[4], 11L, 0x4bdecfa9L);
+        c = HH(c, d, a, b, x[7], 16L, 0xf6bb4b60L);
+        b = HH(b, c, d, a, x[10], 23L, 0xbebfbc70L);
+        a = HH(a, b, c, d, x[13], 4L, 0x289b7ec6L);
+        d = HH(d, a, b, c, x[0], 11L, 0xeaa127faL);
+        c = HH(c, d, a, b, x[3], 16L, 0xd4ef3085L);
+        b = HH(b, c, d, a, x[6], 23L, 0x4881d05L);
+        a = HH(a, b, c, d, x[9], 4L, 0xd9d4d039L);
+        d = HH(d, a, b, c, x[12], 11L, 0xe6db99e5L);
+        c = HH(c, d, a, b, x[15], 16L, 0x1fa27cf8L);
+        b = HH(b, c, d, a, x[2], 23L, 0xc4ac5665L);
+        a = II(a, b, c, d, x[0], 6L, 0xf4292244L);
+        d = II(d, a, b, c, x[7], 10L, 0x432aff97L);
+        c = II(c, d, a, b, x[14], 15L, 0xab9423a7L);
+        b = II(b, c, d, a, x[5], 21L, 0xfc93a039L);
+        a = II(a, b, c, d, x[12], 6L, 0x655b59c3L);
+        d = II(d, a, b, c, x[3], 10L, 0x8f0ccc92L);
+        c = II(c, d, a, b, x[10], 15L, 0xffeff47dL);
+        b = II(b, c, d, a, x[1], 21L, 0x85845dd1L);
+        a = II(a, b, c, d, x[8], 6L, 0x6fa87e4fL);
+        d = II(d, a, b, c, x[15], 10L, 0xfe2ce6e0L);
+        c = II(c, d, a, b, x[6], 15L, 0xa3014314L);
+        b = II(b, c, d, a, x[13], 21L, 0x4e0811a1L);
+        a = II(a, b, c, d, x[4], 6L, 0xf7537e82L);
+        d = II(d, a, b, c, x[11], 10L, 0xbd3af235L);
+        c = II(c, d, a, b, x[2], 15L, 0x2ad7d2bbL);
+        b = II(b, c, d, a, x[9], 21L, 0xeb86d391L);
+        state[0] += a;
+        state[1] += b;
+        state[2] += c;
+        state[3] += d;
+    }
+
+    private void md5Update(byte inbuf[], int inputLen) {
+        byte block[] = new byte[64];
+        int index = (int) (count[0] >>> 3) & 0x3f;
+        if ((count[0] += inputLen << 3) < (inputLen << 3)) {
+            count[1]++;
+        }
+        count[1] += inputLen >>> 29;
+        int partLen = 64 - index;
+        int i;
+        if (inputLen >= partLen) {
+            md5Memcpy(buffer, inbuf, index, 0, partLen);
+            md5Transform(buffer);
+            for (i = partLen; i + 63 < inputLen; i += 64) {
+                md5Memcpy(block, inbuf, 0, i, 64);
+                md5Transform(block);
+            }
+
+            index = 0;
+        } else {
+            i = 0;
+        }
+        md5Memcpy(buffer, inbuf, index, i, inputLen - i);
+    }
+
+}

+ 147 - 0
elab-core/src/main/java/com/elab/core/utils/MapUtils.java

@@ -0,0 +1,147 @@
+package com.elab.core.utils;
+
+import java.util.*;
+
+/**
+ * 对Map集合的操作
+ * @author liuhx on 2016/12/17 21:10
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class MapUtils {
+
+    /**
+     * 根据传入的值,进行集合元素的删除
+     * @param obj
+     * @param iterator
+     */
+    private static void remove(Object obj,Iterator iterator){
+        if(obj instanceof String){
+            String str = (String)obj;
+            if(StringUtils.isEmpty(str) || "%null%".equals(str)){
+                iterator.remove();
+            }
+        }else if(obj instanceof Collection){
+            Collection col = (Collection)obj;
+            if(col==null||col.isEmpty()){
+                iterator.remove();
+            }
+
+        }else if(obj instanceof Map){
+            Map temp = (Map)obj;
+            if(temp==null||temp.isEmpty()){
+                iterator.remove();
+            }
+
+        }else if(obj instanceof Object[]){
+            Object[] array =(Object[])obj;
+            if(array==null||array.length<=0){
+                iterator.remove();
+            }
+        }else{
+            if(obj==null){
+                iterator.remove();
+            }
+        }
+    }
+
+    /**
+     * 移除map的空key
+     * @param map
+     * @return
+     */
+    public static void removeNullKey(Map map){
+        Set set = map.keySet();
+        for (Iterator iterator = set.iterator(); iterator.hasNext();) {
+            Object obj = (Object) iterator.next();
+            remove(obj, iterator);
+        }
+    }
+
+    /**
+     * 移除map中的value空值
+     * @param map
+     * @return
+     */
+    public static LinkedHashMap removeNullValue(LinkedHashMap map){
+        Set set = map.keySet();
+        for (Iterator iterator = set.iterator(); iterator.hasNext();) {
+            Object obj = iterator.next();
+            Object value = ObjectUtils.isNotEmpty(map.get(obj)) ? map.get(obj) : null;
+            remove(value, iterator);
+        }
+        return map;
+    }
+
+
+    /**
+     * 传入参数?替换成map中的key
+     * @param sql
+     * @param map
+     * @return
+     */
+    public static String questionMarkReplace(String sql, Map map) {
+        Set set = map.keySet();
+        for (Iterator iterator = set.iterator(); iterator.hasNext();) {
+            Object obj = iterator.next();
+            if (sql.trim().toLowerCase().startsWith("update")) {
+                sql = sql.replaceFirst("\\s*"+obj+"\\s*=\\s*\\?\\s*", " "+obj+"=:"+obj+" ");
+            } else {
+                sql = sql.replaceFirst("\\?", ":" + obj);
+            }
+        }
+        return sql;
+    }
+
+
+    /**
+     * 字符串空替换成对象null
+     * @param map
+     * @return
+     */
+    public static LinkedHashMap emptyFormatNull(LinkedHashMap map){
+        Set set = map.keySet();
+        for (Iterator iterator = set.iterator(); iterator.hasNext();) {
+            Object obj = (Object) iterator.next();
+            Object value = ObjectUtils.isNotEmpty(map.get(obj)) ? map.get(obj) : null;
+            if (null == value) {
+                map.put(obj, null);
+            }
+        }
+        return map;
+    }
+
+
+    public static void main(String[] args) {
+        LinkedHashMap map = new LinkedHashMap();
+//        map.put("b", "b");
+        map.put("c", "c");
+        map.put("a", "a");
+        map.put("f", "f");
+        map.put("e", "e");
+        map.put("d", "d");
+        String sql = questionMarkReplace("update table set a=?,c=?,b=?,d=? where f=? and e=?", map);
+
+
+        String updateSql = "update enumeration set  name =?,asdf=?,remark=:remark,sdfsdf=?,a=:a, c=:c, ty=? where  id =?";
+
+        while(true) {
+            if (updateSql.indexOf(":") > 0) {
+                updateSql = updateSql.replaceAll("(,?\\s*\\w*\\.?(?=[a-zA-Z|0-9])\\s*\\S+\\s*:[a-zA-Z|0-9]*+\\b\\s*\\)?)(\\s*and\\s*|\\s*or\\s*|\\s*)", "  ");
+                continue;
+            }else {
+                break;
+            }
+        }
+        /*if (updateSql.indexOf(":") > 0) {
+//            updateSql = updateSql.replaceAll("(,?\\s*\\w*\\.?remark\\s*\\S+\\s*:[a-zA-Z|0-9]*+\\b\\s*\\)?)(\\s*and\\s*|\\s*or\\s*|\\s*)", "  ");
+            updateSql = updateSql.replaceAll("(,?\\s*\\w*\\.?(?=[a-zA-Z|0-9])\\s*\\S+\\s*:[a-zA-Z|0-9]*+\\b\\s*\\)?)(\\s*and\\s*|\\s*or\\s*|\\s*)", "  ");
+
+//            updateSql = updateSql.replaceAll("(,?\\s*\\w*\\.?=+\\s*\\S+\\s*:+\\b\\s*\\)?)(\\s*and\\s*|\\s*or\\s*|\\s*)", "  ");
+
+        }*/
+        System.out.println(updateSql);
+
+    }
+
+}

+ 145 - 0
elab-core/src/main/java/com/elab/core/utils/MoneyUtils.java

@@ -0,0 +1,145 @@
+package com.elab.core.utils;
+
+import com.elab.core.exception.CoreException;
+
+/**
+ * @author liuhx on 2017/1/2 14:31
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class MoneyUtils {
+    private static final String[] ChineseNum = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
+
+    /**
+     * 阿拉伯数字转对应中文金额
+     * @param moneyValue 阿拉伯数字金额
+     * @return 中文金额
+     * @throws CoreException
+     */
+    public static String getChineseMoney(float moneyValue) throws CoreException {
+        String result = "";
+
+        if(Float.compare(moneyValue, new Float(0.0f)) == 0){
+            return ChineseNum[0];
+        }
+
+        if(moneyValue <0){
+            moneyValue *= -1;
+            result = "负";
+        }
+
+        int intMoney = Integer.parseInt(Float.toString(moneyValue*100));
+
+        String strMoney = Integer.toString(intMoney);
+
+        int moneyLength = strMoney.length();
+
+        StringBuilder strBuf= new StringBuilder(100);
+
+        if (moneyLength > 14) {
+            throw new CoreException("Money Value Is Too Large");
+        }
+
+        //处理亿部分
+        if (moneyLength > 10 && moneyLength <= 14){
+            strBuf.append(getSmallMoney(strMoney.substring(0, strMoney.length() - 10)));
+            strMoney = strMoney.substring(strMoney.length() - 10, 10);
+            strBuf.append("亿");
+        }
+
+        //处理万部分
+        if (moneyLength > 6)
+        {
+            strBuf.append(getSmallMoney(strMoney.substring(0, strMoney.length() - 6)));
+            strMoney = strMoney.substring(strMoney.length() - 6, 6);
+            strBuf.append("万");
+        }
+
+        //处理元部分
+        if (moneyLength > 2)
+        {
+            strBuf.append(getSmallMoney(strMoney.substring(0, strMoney.length() - 2)));
+            strMoney = strMoney.substring(strMoney.length() - 2, 2);
+            strBuf.append("元");
+        }
+
+        //处理角、分处理分
+        if (Integer.parseInt(strMoney) == 0)
+        {
+            strBuf.append("整");
+        }
+        else
+        {
+            if (moneyLength > 1)
+            {
+                int intJiao = Integer.parseInt(strMoney.substring(0, 1));
+                strBuf.append(ChineseNum[intJiao]);
+                if (intJiao != 0)
+                {
+                    strBuf.append("角");
+                }
+                strMoney = strMoney.substring(1, 1);
+            }
+
+            int intFen = Integer.parseInt(strMoney.substring(0, 1));
+            if (intFen != 0)
+            {
+                strBuf.append(ChineseNum[intFen]);
+                strBuf.append("分");
+            }
+        }
+        String temp = strBuf.toString();
+        while (temp.indexOf("零零") != -1)
+        {
+            temp.replaceAll("零零", "零");
+        }
+
+        temp.replaceAll("零亿", "亿");
+        temp.replaceAll("零万", "万");
+        temp.replaceAll("亿万", "亿");
+
+        return result + temp;
+    }
+
+    private static String getSmallMoney(String moneyValue)
+    {
+        int intMoney = Integer.parseInt(moneyValue);
+        if (intMoney == 0){
+            return "";
+        }
+
+        String strMoney = Integer.toString(intMoney);
+        int temp;
+        StringBuilder strBuf = new StringBuilder(10);
+        if (strMoney.length() == 4)
+        {
+            temp = Integer.parseInt(strMoney.substring(0, 1));
+            strMoney = strMoney.substring(1, strMoney.length() - 1);
+            strBuf.append(ChineseNum[temp]);
+            if (temp != 0)
+                strBuf.append("仟");
+        }
+        if (strMoney.length() == 3)
+        {
+            temp = Integer.parseInt(strMoney.substring(0, 1));
+            strMoney = strMoney.substring(1, strMoney.length() - 1);
+            strBuf.append(ChineseNum[temp]);
+            if (temp != 0)
+                strBuf.append("佰");
+        }
+        if (strMoney.length() == 2)
+        {
+            temp = Integer.parseInt(strMoney.substring(0, 1));
+            strMoney = strMoney.substring(1, strMoney.length() - 1);
+            strBuf.append(ChineseNum[temp]);
+            if (temp != 0)
+                strBuf.append("拾");
+        }
+        if (strMoney.length() == 1)
+        {
+            temp = Integer.parseInt(strMoney);
+            strBuf.append(ChineseNum[temp]);
+        }
+        return strBuf.toString();
+    }
+}

+ 319 - 0
elab-core/src/main/java/com/elab/core/utils/ObjectUtils.java

@@ -0,0 +1,319 @@
+package com.elab.core.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.elab.core.bean.BaseInfo;
+import com.elab.core.bean.PageModel;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.apache.commons.beanutils.BeanUtils;
+
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.regex.Pattern;
+
+/**
+ * @author liuhx on 2016/12/11 22:27
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils{
+
+    private static Pattern pattern = Pattern.compile("^[-+]?(([0-9]+)([.]([0-9]+))?|([.]([0-9]+))?)$");
+
+    public ObjectUtils() {
+    }
+
+    public static boolean isEmpty(Object obj) {
+        return obj == null || !StringUtils.isNotEmpty(obj.toString());
+    }
+
+    public static Object objIsNull(Object obj) {
+        return obj != null && !"null".toUpperCase().equals(obj.toString().toUpperCase()) ? obj : null;
+    }
+
+    public static String parseJsonNode(JSONObject value) {
+        if (value == null) {
+            return null;
+        } else {
+            String str = value.toJSONString();
+            return StringUtils.isNotEmpty(str) && !"null".equals(str) ? str : null;
+        }
+    }
+
+    public static Double objIsNullByZero(Object obj) {
+        if (obj != null && StringUtils.isNotEmpty(obj.toString())) {
+            Double value = parseDouble(obj);
+            return Double.valueOf(value == null ? 0.0D : value.doubleValue());
+        } else {
+            return Double.valueOf(BigDecimal.valueOf(0.0D).setScale(2, 1).doubleValue());
+        }
+    }
+
+    public static Double objIsNullByZero(JSON obj) {
+        if (obj != null && StringUtils.isNotEmpty(obj.toJSONString())) {
+            Double value = parseDouble((Object) obj.toJSONString());
+            return Double.valueOf(value == null ? 0.0D : value.doubleValue());
+        } else {
+            return Double.valueOf(BigDecimal.valueOf(0.0D).setScale(2, 1).doubleValue());
+        }
+    }
+
+    public static boolean isNotEmpty(Object obj) {
+        return obj != null && StringUtils.isNotEmpty(obj.toString());
+    }
+
+    public static boolean isNumber(Object value) {
+        if (value != null && StringUtils.isNotEmpty(value.toString())) {
+
+            return pattern.matcher(value.toString()).matches();
+        } else {
+            return false;
+        }
+    }
+
+    public static Double parseDouble(Object obj) {
+        if (obj != null && isNumber(obj)) {
+            BigDecimal bd = BigDecimal.valueOf(Double.parseDouble(obj.toString())).setScale(2, 1);
+            return Double.valueOf(bd.doubleValue());
+        } else {
+            return null;
+        }
+    }
+
+    public static Double parseDouble(JSON obj) {
+        if (obj != null && StringUtils.isNotEmpty(obj.toJSONString())) {
+            String text = obj.toJSONString();
+            return parseDouble((Object) text);
+        } else {
+            return null;
+        }
+    }
+
+    public static Double addition(Object obj1, Object obj2) {
+        if (isNumber(obj1) && isNumber(obj2)) {
+            BigDecimal bd = BigDecimal.valueOf(Double.parseDouble(obj1.toString())).add(BigDecimal.valueOf(Double.parseDouble(obj2.toString())));
+            return Double.valueOf(bd.setScale(2, 1).doubleValue());
+        } else {
+            return null;
+        }
+    }
+
+    public static Double subtract(Object obj1, Object obj2) {
+        if (isNumber(obj1) && isNumber(obj2)) {
+            BigDecimal bd = BigDecimal.valueOf(Double.parseDouble(obj1.toString())).subtract(BigDecimal.valueOf(Double.parseDouble(obj2.toString())));
+            return Double.valueOf(bd.setScale(2, 1).doubleValue());
+        } else {
+            return null;
+        }
+    }
+
+    public static String parseDateTime(Date date) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        String dateStr = sdf.format(sdf);
+        return dateStr;
+    }
+
+    /**
+     * 将一个date类型的数据转化成字符串
+     *
+     * @param date
+     * @return
+     */
+    public static String parseDate(Date date) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        String dateStr = sdf.format(sdf);
+        return dateStr;
+    }
+
+    /**
+     * 判断集合是否为空
+     *
+     * @param list
+     * @return
+     */
+    public static boolean listIsNull(List list) {
+        return list == null || list.size() <= 0;
+    }
+
+
+    public static String jsonNodeParseStr(JSON jsonNode) {
+        return jsonNode == null ? null : jsonNode.toString();
+    }
+
+    public static String objectParseJsonStr(Object object) {
+        return object == null ? null : JSON.toJSONString(object);
+    }
+
+    public static JSONObject strParseJsonNode(String jsonStr) {
+        if (StringUtils.isNotEmpty(jsonStr)) {
+            return JSONObject.parseObject(jsonStr);
+        }
+
+        return null;
+    }
+
+    /**
+     * 空字符串替换成null
+     *
+     * @param str
+     * @return
+     */
+    public static String strParseNull(String str) {
+        if (StringUtils.isNotEmpty(str)) {
+            return str;
+        }
+        return null;
+    }
+
+    public static ObjectNode newJsonNode() {
+        return (new ObjectMapper()).createObjectNode();
+    }
+
+    public static String parseJsonNodeNullStr(JsonNode value) {
+        if (value == null) {
+            return "";
+        } else {
+            String v = value.asText();
+            return isNotEmpty(v) && !"null".equals(v) ? v : "";
+        }
+    }
+
+    /**
+     * 修改集合中的属性值
+     * %s 表示原来属性位置的老的值
+     *
+     * @param list              需要更改的集合对象
+     * @param updatePropertyMap 修改属性的描述Map -> %s 表示老的值 [例如: 原来属性的值bbb,需要修改这个值,key的value为 aaa%s 结果就会 aaabbb
+     * @return
+     */
+    public static void updateBeanProperty(List list, Map<String, String> updatePropertyMap) {
+        updateBeanProperty(list, updatePropertyMap, false);
+    }
+
+    /**
+     * 修改集合中的属性值
+     * %s 表示原来属性位置的老的值
+     *
+     * @param list              需要更改的集合对象
+     * @param updatePropertyMap 修改属性的描述Map -> %s 表示老的值 [例如: 原来属性的值bbb,需要修改这个值,key的value为 aaa%s 结果就会 aaabbb
+     * @param isNull            为null的属性是否也需要修改,true 修改 , false 不修改
+     */
+    public static void updateBeanProperty(List list, Map<String, String> updatePropertyMap, boolean isNull) {
+        if (list == null || list.size() == 0) {
+            return;
+        }
+
+        for (int i = 0; i < list.size(); i++) {
+            Object t = list.get(i);
+            // 遍历map集合
+            for (Map.Entry<String, String> entry : updatePropertyMap.entrySet()) {
+                try {
+                    String key = entry.getKey();
+                    String value = entry.getValue();
+                    String property = BeanUtils.getProperty(t, key);
+                    if (isEmpty(value) || (!isNull && isEmpty(property))) {
+                        continue;
+                    }
+                    BeanUtils.setProperty(t, key, String.format(value, property));
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    /**
+     * 修改集合中的对象属性值
+     *
+     * @param list  需要修改的对象集合
+     * @param key   修改的属性名称
+     * @param value 修改成的值 , %s 表示老的值
+     */
+    public static void updateBeanProperty(List list, String key, String value) {
+        if (list == null || list.size() == 0) {
+            return;
+        }
+
+        for (int i = 0; i < list.size(); i++) {
+            Object t = list.get(i);
+            // 遍历map集合
+            try {
+                String property = BeanUtils.getProperty(t, key);
+                if (isEmpty(value) || isEmpty(property)) {
+                    continue;
+                }
+                BeanUtils.setProperty(t, key, String.format(value, property));
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * 将集合属性的值赋给另外一个对象,并且生成一个集合
+     *
+     * @param list        原始集合
+     * @param propertyMap 参数对应的Map,如果两个对象的属性名称一致,则可以不用传递,这里只要传入差异化的属性对应
+     * @param clazz       转换成的对象
+     * @param <T>
+     * @return
+     */
+    public static <T> List<T> copyListPropertyValue(List list, Map<String, String> propertyMap, Class<T> clazz) {
+        if (list == null || list.size() == 0) {
+            return null;
+        }
+        List resultList = new ArrayList();
+        for (int i = 0; i < list.size(); i++) {
+            try {
+                Object sourceObject = list.get(i);
+                Object newSourceObject = clazz.newInstance();
+                BeanUtils.copyProperties(newSourceObject, sourceObject);
+                // 遍历map集合
+                for (Map.Entry<String, String> entry : propertyMap.entrySet()) {
+                    String key = entry.getKey();
+                    String value = entry.getValue();
+                    String property = BeanUtils.getProperty(sourceObject, key);
+                    if (isNotEmpty(property)) {
+                        BeanUtils.setProperty(newSourceObject, value, property);
+                    }
+                }
+                resultList.add(newSourceObject);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return resultList;
+    }
+
+    public static void main(String[] args) {
+        BaseInfo info = new BaseInfo();
+        info.setMessage("aaaa");
+        BaseInfo info1 = new BaseInfo();
+        info1.setMessage("bbbb");
+        BaseInfo info2 = new BaseInfo();
+        info2.setMessage("cccc");
+        List<BaseInfo> list = new ArrayList<>();
+        list.add(info);
+        list.add(info1);
+        list.add(info2);
+//
+//        Map<String, String> updateMap = new HashMap<>();
+//        updateMap.put("message", "-----%s");
+//
+//        updateBeanProperty(list, updateMap);
+//        System.out.println(JSON.toJSONString(list));
+//
+//        BeanUtils.populate();
+
+        Map<String, String> propertyMap = new HashMap<>();
+        propertyMap.put("message", "orderby");
+
+        List<PageModel> pageModels = copyListPropertyValue(list, propertyMap, PageModel.class);
+        System.out.println(JSON.toJSONString(pageModels));
+
+    }
+
+}

+ 97 - 0
elab-core/src/main/java/com/elab/core/utils/RandomUtils.java

@@ -0,0 +1,97 @@
+package com.elab.core.utils;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Random;
+
+/**
+ * @author liuhx on 2017/1/2 15:03
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class RandomUtils {
+
+    private static Random randGen = null; // 随机数对象
+    private static Object initLock = new Object(); // 用于初始化一个生成随机数的空间对象
+    private static char numbersAndLetters[] = null; // 随机数生成的字符范围
+
+    /**
+     * 读取随机数字
+     *
+     * @param i
+     *            <int>(取值个数)
+     * @return String
+     */
+    public static final String randomString(int i) {
+
+        if (i < 1)
+            return null;
+        if (randGen == null)
+            synchronized (initLock) {
+                if (randGen == null) {
+                    randGen = new Random();
+                    numbersAndLetters = "0123456789abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                            .toCharArray();
+                }
+            }
+        char ac[] = new char[i];
+        for (int j = 0; j < ac.length; j++)
+            ac[j] = numbersAndLetters[randGen.nextInt(71)];
+
+        return new String(ac);
+    }
+
+    /**
+     * 读取随机数字
+     *
+     * @param i
+     *            <int>(取值个数)
+     * @return String
+     */
+    public static final String randomNum(int i) {
+        if (i < 1)
+            return null;
+        if (randGen == null)
+            synchronized (initLock) {
+                if (randGen == null) {
+                    randGen = new Random();
+                    numbersAndLetters = "0123456789".toCharArray();
+                }
+            }
+        char ac[] = new char[i];
+        for (int j = 0; j < ac.length; j++)
+            ac[j] = numbersAndLetters[randGen.nextInt(9)];
+        return new String(ac);
+    }
+
+    /**
+     * 读取日期时间及随机数组成的字符串
+     *
+     * @return String
+     */
+    public static String getDateTimeRandomStr() {
+        StringBuffer str = new StringBuffer();
+        Calendar calendar = new GregorianCalendar();
+        calendar.setTime(new Date());
+
+        str.append(calendar.get(Calendar.YEAR));
+        str.append(((String.valueOf(calendar.get(Calendar.MONTH)).length() < 2) ? "0"
+                + String.valueOf(calendar.get(Calendar.MONTH))
+                : String.valueOf(calendar.get(Calendar.MONTH))));
+        str.append(((String.valueOf(calendar.get(Calendar.DATE)).length() < 2) ? "0"
+                + String.valueOf(calendar.get(Calendar.DATE))
+                : String.valueOf(calendar.get(Calendar.DATE))));
+        str.append(((String.valueOf(calendar.get(Calendar.HOUR)).length() < 2) ? "0"
+                + String.valueOf(calendar.get(Calendar.HOUR))
+                : String.valueOf(calendar.get(Calendar.HOUR))));
+        str.append(((String.valueOf(calendar.get(Calendar.MINUTE)).length() < 2) ? "0"
+                + String.valueOf(calendar.get(Calendar.MINUTE))
+                : String.valueOf(calendar.get(Calendar.MINUTE))));
+        str.append(((String.valueOf(calendar.get(Calendar.SECOND)).length() < 2) ? "0"
+                + String.valueOf(calendar.get(Calendar.SECOND))
+                : String.valueOf(calendar.get(Calendar.SECOND))));
+        str.append((new Random()).nextFloat());
+        return str.toString();
+    }
+}

ファイルの差分が大きいため隠しています
+ 623 - 0
elab-core/src/main/java/com/elab/core/utils/StringUtils.java


+ 82 - 0
elab-core/src/main/java/com/elab/core/utils/UnderlineFormatCamel.java

@@ -0,0 +1,82 @@
+package com.elab.core.utils;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 下划线转驼峰法
+ * @author liuhx on 2017/4/5 10:47
+ * @version V1.0
+ * @email liuhx@elab-plus.com
+ */
+public class UnderlineFormatCamel {
+
+    private static Pattern pattern1=Pattern.compile("([A-Za-z\\d]+)(_)?");
+    private static Pattern pattern2=Pattern.compile("[A-Z]([a-z\\d]+)?");
+
+    /**
+     * 下划线转驼峰法
+     * @param line 源字符串
+     * @param smallCamel 大小驼峰,是否为小驼峰
+     * @return 转换后的字符串
+     */
+    public static String underlineToCamel(String line,boolean smallCamel) {
+        if(line==null||"".equals(line)){
+            return "";
+        }
+        StringBuffer sb=new StringBuffer();
+
+        Matcher matcher=pattern1.matcher(line);
+        while(matcher.find()){
+            String word=matcher.group();
+            sb.append(smallCamel&&matcher.start()==0?Character.toLowerCase(word.charAt(0)):Character.toUpperCase(word.charAt(0)));
+            int index=word.lastIndexOf('_');
+            if(index>0){
+                sb.append(word.substring(1, index).toLowerCase());
+            }else{
+                sb.append(word.substring(1).toLowerCase());
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 下划线转驼峰法,默认小驼峰(首字母小写)
+     * @param line 源字符串
+     * @return 转换后的字符串
+     */
+    public static String underlineToCamel(String line) {
+        return underlineToCamel(line, true);
+    }
+
+    /**
+     * 驼峰法转下划线
+     * @param line 源字符串
+     * @return 转换后的字符串
+     */
+    public static String camelToUnderline(String line){
+        if(line==null||"".equals(line)){
+            return "";
+        }
+        line=String.valueOf(line.charAt(0)).toUpperCase().concat(line.substring(1));
+        StringBuffer sb=new StringBuffer();
+
+        Matcher matcher=pattern2.matcher(line);
+        while(matcher.find()){
+            String word=matcher.group();
+            sb.append(word.toUpperCase());
+            sb.append(matcher.end()==line.length()?"":"_");
+        }
+        return sb.toString();
+    }
+
+    public static void main(String[] args) {
+        String line="I_HAVE_AN_IPANG3_PIG";
+        String camel=underlineToCamel(line,true);
+        System.out.println(camel);
+        String houseid = underlineToCamel("layout_id", false);
+        System.out.println(houseid);
+//        System.out.println(camel2Underline(camel));
+
+    }
+}

+ 29 - 0
elab-core/src/test/java/com/elab/test/model/User.java

@@ -0,0 +1,29 @@
+package com.elab.test.model;
+
+/**
+ * 测试用户实体
+ *
+ * @author Liukx
+ * @create 2018-05-04 17:49
+ * @email liukx@elab-plus.com
+ **/
+public class User {
+    private String username;
+    private String password;
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+}

+ 44 - 0
elab-core/src/test/java/com/elab/test/utils/ObjectUtilsCase.java

@@ -0,0 +1,44 @@
+package com.elab.test.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.elab.core.bean.BaseInfo;
+import com.elab.core.utils.ObjectUtils;
+import com.elab.test.model.User;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 对象工具类测试
+ *
+ * @author Liukx
+ * @create 2018-05-04 17:48
+ * @email liukx@elab-plus.com
+ **/
+public class ObjectUtilsCase {
+
+
+    @Test
+    public void copyListPropertyValue() {
+        BaseInfo info = new BaseInfo();
+        info.setMessage("aaaa");
+        BaseInfo info1 = new BaseInfo();
+        info1.setMessage("bbbb");
+        BaseInfo info2 = new BaseInfo();
+        info2.setMessage("cccc");
+        List<BaseInfo> list = new ArrayList<>();
+        list.add(info);
+        list.add(info1);
+        list.add(info2);
+
+        Map<String, String> propertyMap = new HashMap<>();
+        propertyMap.put("message", "username");
+
+        List<User> users = ObjectUtils.copyListPropertyValue(list, propertyMap, User.class);
+        System.out.println(JSON.toJSONString(users));
+    }
+
+}

+ 1 - 0
elab-core/src/test/resources/META-INF/app.properties

@@ -0,0 +1 @@
+app.name=elab-core1

+ 7 - 0
elab-core/src/test/resources/META-INF/cat/client.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE config>
+<config mode="client" xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:noNamespaceSchemaLocation="config.xsd">
+    <servers>
+        <server ip="192.168.0.90" ></server>
+    </servers>
+</config>

+ 59 - 0
elab-core/src/test/resources/META-INF/cat/config.xsd

@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
+	<xs:element name="config" type="ConfigType" />
+	<xs:complexType name="ConfigType">
+		<xs:sequence>
+			<xs:element name="base-log-dir" type="xs:string" minOccurs="0" maxOccurs="1" />
+			<xs:element name="servers">
+				<xs:complexType>
+					<xs:sequence minOccurs="0" maxOccurs="unbounded">
+						<xs:element name="server" type="ServerType" />
+					</xs:sequence>
+				</xs:complexType>
+			</xs:element>
+			<xs:element minOccurs="0" maxOccurs="unbounded" name="domain" type="DomainType" />
+			<xs:element name="bind" type="BindType" minOccurs="0" maxOccurs="1" />
+			<xs:element name="properties">
+				<xs:complexType>
+					<xs:sequence minOccurs="0" maxOccurs="unbounded">
+						<xs:element name="property" type="PropertyType" />
+					</xs:sequence>
+				</xs:complexType>
+			</xs:element>
+		</xs:sequence>
+		<xs:attribute name="mode" type="xs:string" use="required" />
+	</xs:complexType>
+	<xs:complexType name="ServerType">
+		<xs:simpleContent>
+			<xs:extension base="xs:string">
+				<xs:attribute name="ip" type="xs:string" />
+				<xs:attribute name="port" type="xs:int" default="2280" />
+				<xs:attribute name="enabled" type="xs:boolean" default="true" />
+			</xs:extension>
+		</xs:simpleContent>
+	</xs:complexType>
+	<xs:complexType name="DomainType">
+		<xs:simpleContent>
+			<xs:extension base="xs:string">
+				<xs:attribute name="id" type="xs:string" />
+				<xs:attribute name="ip" type="xs:string" />
+				<xs:attribute name="enabled" type="xs:boolean" />
+			</xs:extension>
+		</xs:simpleContent>
+	</xs:complexType>
+	<xs:complexType name="BindType">
+		<xs:simpleContent>
+			<xs:extension base="xs:string">
+				<xs:attribute name="ip" type="xs:string" />
+				<xs:attribute name="port" type="xs:string" default="2280" />
+			</xs:extension>
+		</xs:simpleContent>
+	</xs:complexType>
+	<xs:complexType name="PropertyType">
+		<xs:simpleContent>
+			<xs:extension base="xs:string">
+				<xs:attribute name="name" type="xs:string" />
+			</xs:extension>
+		</xs:simpleContent>
+	</xs:complexType>
+</xs:schema>

+ 0 - 0
elab-core/src/test/resources/dictionary/enumeration.xml


この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません