E1ED922C1E9526DD63272D7EC5C6CB77
2020-09-23 5c59454c8a12b1a19846c23c99cff612db037e4f
初始化
163个文件已添加
1个文件已修改
12586 ■■■■■ 已修改文件
.gitignore 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/$PRODUCT_WORKSPACE_FILE$ 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/.gitignore 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/compiler.xml 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/encodings.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__cglib_cglib_3_1.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__com_alibaba_druid_1_1_9.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__com_alibaba_fastjson_1_2_47.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__com_aliyun_oss_aliyun_sdk_oss_2_8_3.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__com_auth0_java_jwt_3_10_3.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__com_belerweb_pinyin4j_2_5_1.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__com_fasterxml_classmate_1_3_4.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_9_0.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_9_6.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_9_6.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_9_6.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_9_6.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_9_6.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__com_gitee_sunchenbin_mybatis_actable_mybatis_enhance_actable_1_1_1_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__com_github_jsqlparser_jsqlparser_2_0.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__com_github_pagehelper_pagehelper_5_1_11.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__com_google_code_gson_gson_2_8_5.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__com_google_zxing_core_3_3_0.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__com_google_zxing_javase_3_0_0.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__com_sun_mail_javax_mail_1_6_2.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__com_zaxxer_HikariCP_2_7_9.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__commons_beanutils_commons_beanutils_1_9_3.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__commons_codec_commons_codec_1_11.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__commons_collections_commons_collections_3_2_2.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__commons_io_commons_io_2_6.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__commons_lang_commons_lang_2_5.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__commons_logging_commons_logging_1_2.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__io_jsonwebtoken_jjwt_0_9_1.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__javax_activation_activation_1_1.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__javax_annotation_javax_annotation_api_1_3_2.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__javax_servlet_jsp_jsp_api_2_1.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__javax_servlet_jsp_jstl_jstl_api_1_2.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__javax_servlet_jstl_1_2.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__javax_servlet_servlet_api_2_5.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__javax_validation_validation_api_2_0_1_Final.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__junit_junit_4_12.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__log4j_log4j_1_2_14.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__mysql_mysql_connector_java_5_1_47.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__net_glxn_qrgen_1_4.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__net_sf_ezmorph_ezmorph_1_0_3.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__net_sf_json_lib_json_lib_jdk15_2_4.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__net_sourceforge_jexcelapi_jxl_2_6_12.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_apache_commons_commons_lang3_3_9.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_apache_commons_commons_pool2_2_5_0.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_apache_httpcomponents_httpclient_4_5_12.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_apache_httpcomponents_httpcore_4_4_13.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_apache_poi_poi_3_9.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_bouncycastle_bcprov_jdk15on_1_66.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_dom4j_dom4j_2_1_3.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_freemarker_freemarker_2_3_28.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_hibernate_validator_hibernate_validator_6_0_12_Final.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_jboss_logging_jboss_logging_3_3_2_Final.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_jdom_jdom_1_1_3.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_mybatis_mybatis_3_4_0.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_mybatis_mybatis_spring_1_3_0.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_mybatis_spring_boot_mybatis_spring_boot_autoconfigure_1_1_1.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_mybatis_spring_boot_mybatis_spring_boot_starter_1_1_1.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_ow2_asm_asm_4_2.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_projectlombok_lombok_1_16_22.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_25.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_boot_spring_boot_2_0_5_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_2_0_5_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_2_0_5_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_redis_1_4_2_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_jdbc_2_0_5_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_0_5_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_0_5_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_0_10_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_data_spring_data_keyvalue_2_0_10_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_data_spring_data_redis_2_0_10_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_spring_aop_5_0_9_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_spring_beans_5_0_9_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_spring_context_5_0_9_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_spring_context_support_5_0_9_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_spring_core_5_0_9_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_spring_expression_5_0_9_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_spring_jcl_5_0_9_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_spring_jdbc_5_0_9_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_spring_oxm_5_0_9_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_spring_tx_5_0_9_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_spring_web_5_0_9_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_springframework_spring_webmvc_5_0_9_RELEASE.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__org_yaml_snakeyaml_1_19.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/Maven__redis_clients_jedis_2_9_0.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/libraries/hx_demoboot.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/misc.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/modules.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/vcs.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hx-common.iml 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 268 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/annotation/Jurisdiction.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/common/CommonInit.java 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/exception/ParamException.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/exception/ServiceException.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/exception/TipsException.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/mp/util/CertUtil.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/mp/util/ClientResponseHandler.java 228 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/mp/util/CorpMpClientUtil.java 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/mp/util/CorpMpUtil.java 294 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/mp/util/HttpClientUtil.java 340 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/mp/util/HttpUtil.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/mp/util/HttpXmlUtils.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/mp/util/MD5Util.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/mp/util/MPWeixinBaseUtil.java 404 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/mp/util/MpUtil.java 357 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/mp/util/RequestHandler.java 273 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/mp/util/ResponseHandler.java 225 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/mp/util/TenpayHttpClient.java 559 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/mp/util/TenpayUtil.java 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/mp/util/WXPayUtil.java 458 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/mp/util/WXSignUtils.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/mp/util/WechatUtil.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/mp/util/XMLUtil.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/mybatisTool/SqlParam.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/mybatisTool/SqlSentence.java 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/resultTool/ResponseCode.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/resultTool/Result.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/Aes.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/AesUtil.java 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/BASE64.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/Base64Util.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/CheckCodeImageUtil.java 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/CreateNoTool.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/DateUtil.java 346 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/EmailUtil.java 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/ExcelUtil.java 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/FileUtil.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/FileUtils.java 342 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/GsonUtils.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/HttpResponse.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/HttpUtil.java 546 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/ImagesAddDomain.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/JwtConstant.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/JwtTool.java 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/MD5.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/MD5Util.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/MyRedisTemplate.java 139 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/NumberUtil.java 340 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/OSSUtil.java 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/QRCodeUtil.java 238 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/RegValidatorUtil.java 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/RequestMethod.java 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/SerializeUtil.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/SimpleEncrypt.java 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/SimpleTool.java 1053 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/StreamUtils.java 266 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/StringUtils.java 306 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/TempltUtil.java 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/TengXunMapUtil.java 191 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/ThreadPoolUtils.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hx/util/WebUtil.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qq/weixin/mp/aes/AesException.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qq/weixin/mp/aes/ByteGroup.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qq/weixin/mp/aes/PKCS7Encoder.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qq/weixin/mp/aes/SHA1.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qq/weixin/mp/aes/WXBizMsgCrypt.java 296 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qq/weixin/mp/aes/XMLParse.java 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/main.iml 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
@@ -21,3 +21,4 @@
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
/target/
.idea/$PRODUCT_WORKSPACE_FILE$
New file
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="masterDetails">
    <states>
      <state key="ProjectJDKs.UI">
        <settings>
          <last-edited>1.8</last-edited>
          <splitter-proportions>
            <option name="proportions">
              <list>
                <option value="0.2" />
              </list>
            </option>
          </splitter-proportions>
        </settings>
      </state>
    </states>
  </component>
</project>
.idea/.gitignore
New file
@@ -0,0 +1,2 @@
# Default ignored files
/workspace.xml
.idea/compiler.xml
New file
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="CompilerConfiguration">
    <annotationProcessing>
      <profile name="Maven default annotation processors profile" enabled="true">
        <sourceOutputDir name="target/generated-sources/annotations" />
        <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
        <outputRelativeToContentRoot value="true" />
        <module name="hx-common" />
      </profile>
    </annotationProcessing>
    <bytecodeTargetLevel>
      <module name="hx-common" target="1.8" />
    </bytecodeTargetLevel>
  </component>
  <component name="JavacSettings">
    <option name="ADDITIONAL_OPTIONS_OVERRIDE">
      <module name="hx-common" options="-parameters" />
    </option>
  </component>
</project>
.idea/encodings.xml
New file
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="Encoding">
    <file url="file://$PROJECT_DIR$" charset="UTF-8" />
  </component>
</project>
.idea/libraries/Maven__cglib_cglib_3_1.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: cglib:cglib:3.1">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/cglib/cglib/3.1/cglib-3.1.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/cglib/cglib/3.1/cglib-3.1-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/cglib/cglib/3.1/cglib-3.1-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__com_alibaba_druid_1_1_9.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: com.alibaba:druid:1.1.9">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/com/alibaba/druid/1.1.9/druid-1.1.9.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/com/alibaba/druid/1.1.9/druid-1.1.9-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/com/alibaba/druid/1.1.9/druid-1.1.9-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__com_alibaba_fastjson_1_2_47.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: com.alibaba:fastjson:1.2.47">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/com/alibaba/fastjson/1.2.47/fastjson-1.2.47.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/com/alibaba/fastjson/1.2.47/fastjson-1.2.47-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/com/alibaba/fastjson/1.2.47/fastjson-1.2.47-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__com_aliyun_oss_aliyun_sdk_oss_2_8_3.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: com.aliyun.oss:aliyun-sdk-oss:2.8.3">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/com/aliyun/oss/aliyun-sdk-oss/2.8.3/aliyun-sdk-oss-2.8.3.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/com/aliyun/oss/aliyun-sdk-oss/2.8.3/aliyun-sdk-oss-2.8.3-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/com/aliyun/oss/aliyun-sdk-oss/2.8.3/aliyun-sdk-oss-2.8.3-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__com_auth0_java_jwt_3_10_3.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: com.auth0:java-jwt:3.10.3">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/com/auth0/java-jwt/3.10.3/java-jwt-3.10.3.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/com/auth0/java-jwt/3.10.3/java-jwt-3.10.3-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/com/auth0/java-jwt/3.10.3/java-jwt-3.10.3-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__com_belerweb_pinyin4j_2_5_1.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: com.belerweb:pinyin4j:2.5.1">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/com/belerweb/pinyin4j/2.5.1/pinyin4j-2.5.1.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/com/belerweb/pinyin4j/2.5.1/pinyin4j-2.5.1-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/com/belerweb/pinyin4j/2.5.1/pinyin4j-2.5.1-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__com_fasterxml_classmate_1_3_4.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: com.fasterxml:classmate:1.3.4">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/classmate/1.3.4/classmate-1.3.4.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/classmate/1.3.4/classmate-1.3.4-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/classmate/1.3.4/classmate-1.3.4-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_9_0.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.9.0">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-annotations/2.9.0/jackson-annotations-2.9.0.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-annotations/2.9.0/jackson-annotations-2.9.0-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-annotations/2.9.0/jackson-annotations-2.9.0-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_9_6.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.6">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-core/2.9.6/jackson-core-2.9.6.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-core/2.9.6/jackson-core-2.9.6-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-core/2.9.6/jackson-core-2.9.6-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_9_6.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: com.fasterxml.jackson.core:jackson-databind:2.9.6">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-databind/2.9.6/jackson-databind-2.9.6.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-databind/2.9.6/jackson-databind-2.9.6-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-databind/2.9.6/jackson-databind-2.9.6-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_9_6.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.6">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.9.6/jackson-datatype-jdk8-2.9.6.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.9.6/jackson-datatype-jdk8-2.9.6-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.9.6/jackson-datatype-jdk8-2.9.6-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_9_6.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.6">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.9.6/jackson-datatype-jsr310-2.9.6.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.9.6/jackson-datatype-jsr310-2.9.6-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.9.6/jackson-datatype-jsr310-2.9.6-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_9_6.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.9.6">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/module/jackson-module-parameter-names/2.9.6/jackson-module-parameter-names-2.9.6.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/module/jackson-module-parameter-names/2.9.6/jackson-module-parameter-names-2.9.6-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/module/jackson-module-parameter-names/2.9.6/jackson-module-parameter-names-2.9.6-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__com_gitee_sunchenbin_mybatis_actable_mybatis_enhance_actable_1_1_1_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: com.gitee.sunchenbin.mybatis.actable:mybatis-enhance-actable:1.1.1.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/com/gitee/sunchenbin/mybatis/actable/mybatis-enhance-actable/1.1.1.RELEASE/mybatis-enhance-actable-1.1.1.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/com/gitee/sunchenbin/mybatis/actable/mybatis-enhance-actable/1.1.1.RELEASE/mybatis-enhance-actable-1.1.1.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/com/gitee/sunchenbin/mybatis/actable/mybatis-enhance-actable/1.1.1.RELEASE/mybatis-enhance-actable-1.1.1.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__com_github_jsqlparser_jsqlparser_2_0.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: com.github.jsqlparser:jsqlparser:2.0">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/com/github/jsqlparser/jsqlparser/2.0/jsqlparser-2.0.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/com/github/jsqlparser/jsqlparser/2.0/jsqlparser-2.0-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/com/github/jsqlparser/jsqlparser/2.0/jsqlparser-2.0-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__com_github_pagehelper_pagehelper_5_1_11.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: com.github.pagehelper:pagehelper:5.1.11">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/com/github/pagehelper/pagehelper/5.1.11/pagehelper-5.1.11.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/com/github/pagehelper/pagehelper/5.1.11/pagehelper-5.1.11-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/com/github/pagehelper/pagehelper/5.1.11/pagehelper-5.1.11-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__com_google_code_gson_gson_2_8_5.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: com.google.code.gson:gson:2.8.5">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/com/google/code/gson/gson/2.8.5/gson-2.8.5.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/com/google/code/gson/gson/2.8.5/gson-2.8.5-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/com/google/code/gson/gson/2.8.5/gson-2.8.5-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__com_google_zxing_core_3_3_0.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: com.google.zxing:core:3.3.0">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/com/google/zxing/core/3.3.0/core-3.3.0.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/com/google/zxing/core/3.3.0/core-3.3.0-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/com/google/zxing/core/3.3.0/core-3.3.0-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__com_google_zxing_javase_3_0_0.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: com.google.zxing:javase:3.0.0">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/com/google/zxing/javase/3.0.0/javase-3.0.0.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/com/google/zxing/javase/3.0.0/javase-3.0.0-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/com/google/zxing/javase/3.0.0/javase-3.0.0-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__com_sun_mail_javax_mail_1_6_2.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: com.sun.mail:javax.mail:1.6.2">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/com/sun/mail/javax.mail/1.6.2/javax.mail-1.6.2.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/com/sun/mail/javax.mail/1.6.2/javax.mail-1.6.2-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/com/sun/mail/javax.mail/1.6.2/javax.mail-1.6.2-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__com_zaxxer_HikariCP_2_7_9.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: com.zaxxer:HikariCP:2.7.9">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/com/zaxxer/HikariCP/2.7.9/HikariCP-2.7.9.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/com/zaxxer/HikariCP/2.7.9/HikariCP-2.7.9-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/com/zaxxer/HikariCP/2.7.9/HikariCP-2.7.9-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__commons_beanutils_commons_beanutils_1_9_3.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: commons-beanutils:commons-beanutils:1.9.3">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/commons-beanutils/commons-beanutils/1.9.3/commons-beanutils-1.9.3.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/commons-beanutils/commons-beanutils/1.9.3/commons-beanutils-1.9.3-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/commons-beanutils/commons-beanutils/1.9.3/commons-beanutils-1.9.3-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__commons_codec_commons_codec_1_11.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: commons-codec:commons-codec:1.11">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/commons-codec/commons-codec/1.11/commons-codec-1.11.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/commons-codec/commons-codec/1.11/commons-codec-1.11-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/commons-codec/commons-codec/1.11/commons-codec-1.11-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__commons_collections_commons_collections_3_2_2.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: commons-collections:commons-collections:3.2.2">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__commons_io_commons_io_2_6.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: commons-io:commons-io:2.6">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/commons-io/commons-io/2.6/commons-io-2.6.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/commons-io/commons-io/2.6/commons-io-2.6-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/commons-io/commons-io/2.6/commons-io-2.6-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__commons_lang_commons_lang_2_5.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: commons-lang:commons-lang:2.5">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/commons-lang/commons-lang/2.5/commons-lang-2.5.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/commons-lang/commons-lang/2.5/commons-lang-2.5-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/commons-lang/commons-lang/2.5/commons-lang-2.5-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__commons_logging_commons_logging_1_2.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: commons-logging:commons-logging:1.2">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/commons-logging/commons-logging/1.2/commons-logging-1.2.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/commons-logging/commons-logging/1.2/commons-logging-1.2-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/commons-logging/commons-logging/1.2/commons-logging-1.2-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__io_jsonwebtoken_jjwt_0_9_1.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: io.jsonwebtoken:jjwt:0.9.1">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/io/jsonwebtoken/jjwt/0.9.1/jjwt-0.9.1.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/io/jsonwebtoken/jjwt/0.9.1/jjwt-0.9.1-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/io/jsonwebtoken/jjwt/0.9.1/jjwt-0.9.1-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__javax_activation_activation_1_1.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: javax.activation:activation:1.1">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/javax/activation/activation/1.1/activation-1.1.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/javax/activation/activation/1.1/activation-1.1-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/javax/activation/activation/1.1/activation-1.1-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__javax_annotation_javax_annotation_api_1_3_2.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: javax.annotation:javax.annotation-api:1.3.2">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/javax/annotation/javax.annotation-api/1.3.2/javax.annotation-api-1.3.2.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/javax/annotation/javax.annotation-api/1.3.2/javax.annotation-api-1.3.2-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/javax/annotation/javax.annotation-api/1.3.2/javax.annotation-api-1.3.2-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__javax_servlet_jsp_jsp_api_2_1.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: javax.servlet.jsp:jsp-api:2.1">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/javax/servlet/jsp/jsp-api/2.1/jsp-api-2.1.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/javax/servlet/jsp/jsp-api/2.1/jsp-api-2.1-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/javax/servlet/jsp/jsp-api/2.1/jsp-api-2.1-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__javax_servlet_jsp_jstl_jstl_api_1_2.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: javax.servlet.jsp.jstl:jstl-api:1.2">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/javax/servlet/jsp/jstl/jstl-api/1.2/jstl-api-1.2.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/javax/servlet/jsp/jstl/jstl-api/1.2/jstl-api-1.2-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/javax/servlet/jsp/jstl/jstl-api/1.2/jstl-api-1.2-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__javax_servlet_jstl_1_2.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: javax.servlet:jstl:1.2">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/javax/servlet/jstl/1.2/jstl-1.2.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/javax/servlet/jstl/1.2/jstl-1.2-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/javax/servlet/jstl/1.2/jstl-1.2-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__javax_servlet_servlet_api_2_5.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: javax.servlet:servlet-api:2.5">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/javax/servlet/servlet-api/2.5/servlet-api-2.5.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/javax/servlet/servlet-api/2.5/servlet-api-2.5-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/javax/servlet/servlet-api/2.5/servlet-api-2.5-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__javax_validation_validation_api_2_0_1_Final.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: javax.validation:validation-api:2.0.1.Final">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/javax/validation/validation-api/2.0.1.Final/validation-api-2.0.1.Final.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/javax/validation/validation-api/2.0.1.Final/validation-api-2.0.1.Final-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/javax/validation/validation-api/2.0.1.Final/validation-api-2.0.1.Final-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__junit_junit_4_12.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: junit:junit:4.12">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.12/junit-4.12.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.12/junit-4.12-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.12/junit-4.12-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__log4j_log4j_1_2_14.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: log4j:log4j:1.2.14">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/log4j/log4j/1.2.14/log4j-1.2.14.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/log4j/log4j/1.2.14/log4j-1.2.14-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/log4j/log4j/1.2.14/log4j-1.2.14-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__mysql_mysql_connector_java_5_1_47.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: mysql:mysql-connector-java:5.1.47">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/mysql/mysql-connector-java/5.1.47/mysql-connector-java-5.1.47.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/mysql/mysql-connector-java/5.1.47/mysql-connector-java-5.1.47-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/mysql/mysql-connector-java/5.1.47/mysql-connector-java-5.1.47-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__net_glxn_qrgen_1_4.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: net.glxn:qrgen:1.4">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/net/glxn/qrgen/1.4/qrgen-1.4.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/net/glxn/qrgen/1.4/qrgen-1.4-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/net/glxn/qrgen/1.4/qrgen-1.4-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__net_sf_ezmorph_ezmorph_1_0_3.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: net.sf.ezmorph:ezmorph:1.0.3">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/net/sf/ezmorph/ezmorph/1.0.3/ezmorph-1.0.3.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/net/sf/ezmorph/ezmorph/1.0.3/ezmorph-1.0.3-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/net/sf/ezmorph/ezmorph/1.0.3/ezmorph-1.0.3-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__net_sf_json_lib_json_lib_jdk15_2_4.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: net.sf.json-lib:json-lib:jdk15:2.4">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/net/sf/json-lib/json-lib/2.4/json-lib-2.4-jdk15.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/net/sf/json-lib/json-lib/2.4/json-lib-2.4-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/net/sf/json-lib/json-lib/2.4/json-lib-2.4-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__net_sourceforge_jexcelapi_jxl_2_6_12.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: net.sourceforge.jexcelapi:jxl:2.6.12">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/net/sourceforge/jexcelapi/jxl/2.6.12/jxl-2.6.12.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/net/sourceforge/jexcelapi/jxl/2.6.12/jxl-2.6.12-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/net/sourceforge/jexcelapi/jxl/2.6.12/jxl-2.6.12-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_apache_commons_commons_lang3_3_9.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.apache.commons:commons-lang3:3.9">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-lang3/3.9/commons-lang3-3.9.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-lang3/3.9/commons-lang3-3.9-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-lang3/3.9/commons-lang3-3.9-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_apache_commons_commons_pool2_2_5_0.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.apache.commons:commons-pool2:2.5.0">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-pool2/2.5.0/commons-pool2-2.5.0.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-pool2/2.5.0/commons-pool2-2.5.0-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-pool2/2.5.0/commons-pool2-2.5.0-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_apache_httpcomponents_httpclient_4_5_12.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.apache.httpcomponents:httpclient:4.5.12">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpclient/4.5.12/httpclient-4.5.12.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpclient/4.5.12/httpclient-4.5.12-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpclient/4.5.12/httpclient-4.5.12-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_apache_httpcomponents_httpcore_4_4_13.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.apache.httpcomponents:httpcore:4.4.13">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpcore/4.4.13/httpcore-4.4.13.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpcore/4.4.13/httpcore-4.4.13-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpcore/4.4.13/httpcore-4.4.13-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_apache_poi_poi_3_9.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.apache.poi:poi:3.9">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/apache/poi/poi/3.9/poi-3.9.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/apache/poi/poi/3.9/poi-3.9-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/apache/poi/poi/3.9/poi-3.9-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_bouncycastle_bcprov_jdk15on_1_66.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.bouncycastle:bcprov-jdk15on:1.66">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/bouncycastle/bcprov-jdk15on/1.66/bcprov-jdk15on-1.66.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/bouncycastle/bcprov-jdk15on/1.66/bcprov-jdk15on-1.66-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/bouncycastle/bcprov-jdk15on/1.66/bcprov-jdk15on-1.66-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_dom4j_dom4j_2_1_3.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.dom4j:dom4j:2.1.3">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/dom4j/dom4j/2.1.3/dom4j-2.1.3.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/dom4j/dom4j/2.1.3/dom4j-2.1.3-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/dom4j/dom4j/2.1.3/dom4j-2.1.3-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_freemarker_freemarker_2_3_28.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.freemarker:freemarker:2.3.28">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/freemarker/freemarker/2.3.28/freemarker-2.3.28.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/freemarker/freemarker/2.3.28/freemarker-2.3.28-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/freemarker/freemarker/2.3.28/freemarker-2.3.28-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.hamcrest:hamcrest-core:1.3">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_hibernate_validator_hibernate_validator_6_0_12_Final.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.hibernate.validator:hibernate-validator:6.0.12.Final">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/hibernate/validator/hibernate-validator/6.0.12.Final/hibernate-validator-6.0.12.Final.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/hibernate/validator/hibernate-validator/6.0.12.Final/hibernate-validator-6.0.12.Final-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/hibernate/validator/hibernate-validator/6.0.12.Final/hibernate-validator-6.0.12.Final-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_jboss_logging_jboss_logging_3_3_2_Final.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.jboss.logging:jboss-logging:3.3.2.Final">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/jboss/logging/jboss-logging/3.3.2.Final/jboss-logging-3.3.2.Final.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/jboss/logging/jboss-logging/3.3.2.Final/jboss-logging-3.3.2.Final-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/jboss/logging/jboss-logging/3.3.2.Final/jboss-logging-3.3.2.Final-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_jdom_jdom_1_1_3.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.jdom:jdom:1.1.3">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/jdom/jdom/1.1.3/jdom-1.1.3.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/jdom/jdom/1.1.3/jdom-1.1.3-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/jdom/jdom/1.1.3/jdom-1.1.3-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_mybatis_mybatis_3_4_0.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.mybatis:mybatis:3.4.0">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/mybatis/mybatis/3.4.0/mybatis-3.4.0.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/mybatis/mybatis/3.4.0/mybatis-3.4.0-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/mybatis/mybatis/3.4.0/mybatis-3.4.0-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_mybatis_mybatis_spring_1_3_0.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.mybatis:mybatis-spring:1.3.0">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/mybatis/mybatis-spring/1.3.0/mybatis-spring-1.3.0.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/mybatis/mybatis-spring/1.3.0/mybatis-spring-1.3.0-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/mybatis/mybatis-spring/1.3.0/mybatis-spring-1.3.0-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_mybatis_spring_boot_mybatis_spring_boot_autoconfigure_1_1_1.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:1.1.1">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/mybatis/spring/boot/mybatis-spring-boot-autoconfigure/1.1.1/mybatis-spring-boot-autoconfigure-1.1.1.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/mybatis/spring/boot/mybatis-spring-boot-autoconfigure/1.1.1/mybatis-spring-boot-autoconfigure-1.1.1-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/mybatis/spring/boot/mybatis-spring-boot-autoconfigure/1.1.1/mybatis-spring-boot-autoconfigure-1.1.1-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_mybatis_spring_boot_mybatis_spring_boot_starter_1_1_1.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:1.1.1">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/mybatis/spring/boot/mybatis-spring-boot-starter/1.1.1/mybatis-spring-boot-starter-1.1.1.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/mybatis/spring/boot/mybatis-spring-boot-starter/1.1.1/mybatis-spring-boot-starter-1.1.1-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/mybatis/spring/boot/mybatis-spring-boot-starter/1.1.1/mybatis-spring-boot-starter-1.1.1-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_ow2_asm_asm_4_2.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.ow2.asm:asm:4.2">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/ow2/asm/asm/4.2/asm-4.2.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/ow2/asm/asm/4.2/asm-4.2-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/ow2/asm/asm/4.2/asm-4.2-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_projectlombok_lombok_1_16_22.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.projectlombok:lombok:1.16.22">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/projectlombok/lombok/1.16.22/lombok-1.16.22.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/projectlombok/lombok/1.16.22/lombok-1.16.22-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/projectlombok/lombok/1.16.22/lombok-1.16.22-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_25.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.slf4j:slf4j-api:1.7.25">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_boot_spring_boot_2_0_5_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework.boot:spring-boot:2.0.5.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot/2.0.5.RELEASE/spring-boot-2.0.5.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot/2.0.5.RELEASE/spring-boot-2.0.5.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot/2.0.5.RELEASE/spring-boot-2.0.5.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_2_0_5_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.0.5.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-autoconfigure/2.0.5.RELEASE/spring-boot-autoconfigure-2.0.5.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-autoconfigure/2.0.5.RELEASE/spring-boot-autoconfigure-2.0.5.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-autoconfigure/2.0.5.RELEASE/spring-boot-autoconfigure-2.0.5.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_2_0_5_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework.boot:spring-boot-starter:2.0.5.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter/2.0.5.RELEASE/spring-boot-starter-2.0.5.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter/2.0.5.RELEASE/spring-boot-starter-2.0.5.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter/2.0.5.RELEASE/spring-boot-starter-2.0.5.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_redis_1_4_2_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework.boot:spring-boot-starter-data-redis:1.4.2.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-data-redis/1.4.2.RELEASE/spring-boot-starter-data-redis-1.4.2.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-data-redis/1.4.2.RELEASE/spring-boot-starter-data-redis-1.4.2.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-data-redis/1.4.2.RELEASE/spring-boot-starter-data-redis-1.4.2.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_jdbc_2_0_5_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.0.5.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-jdbc/2.0.5.RELEASE/spring-boot-starter-jdbc-2.0.5.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-jdbc/2.0.5.RELEASE/spring-boot-starter-jdbc-2.0.5.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-jdbc/2.0.5.RELEASE/spring-boot-starter-jdbc-2.0.5.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_0_5_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework.boot:spring-boot-starter-json:2.0.5.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-json/2.0.5.RELEASE/spring-boot-starter-json-2.0.5.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-json/2.0.5.RELEASE/spring-boot-starter-json-2.0.5.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-json/2.0.5.RELEASE/spring-boot-starter-json-2.0.5.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_0_5_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework.boot:spring-boot-starter-web:2.0.5.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-web/2.0.5.RELEASE/spring-boot-starter-web-2.0.5.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-web/2.0.5.RELEASE/spring-boot-starter-web-2.0.5.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-web/2.0.5.RELEASE/spring-boot-starter-web-2.0.5.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_0_10_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework.data:spring-data-commons:2.0.10.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/data/spring-data-commons/2.0.10.RELEASE/spring-data-commons-2.0.10.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/data/spring-data-commons/2.0.10.RELEASE/spring-data-commons-2.0.10.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/data/spring-data-commons/2.0.10.RELEASE/spring-data-commons-2.0.10.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_data_spring_data_keyvalue_2_0_10_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework.data:spring-data-keyvalue:2.0.10.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/data/spring-data-keyvalue/2.0.10.RELEASE/spring-data-keyvalue-2.0.10.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/data/spring-data-keyvalue/2.0.10.RELEASE/spring-data-keyvalue-2.0.10.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/data/spring-data-keyvalue/2.0.10.RELEASE/spring-data-keyvalue-2.0.10.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_data_spring_data_redis_2_0_10_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework.data:spring-data-redis:2.0.10.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/data/spring-data-redis/2.0.10.RELEASE/spring-data-redis-2.0.10.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/data/spring-data-redis/2.0.10.RELEASE/spring-data-redis-2.0.10.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/data/spring-data-redis/2.0.10.RELEASE/spring-data-redis-2.0.10.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_spring_aop_5_0_9_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework:spring-aop:5.0.9.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-aop/5.0.9.RELEASE/spring-aop-5.0.9.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-aop/5.0.9.RELEASE/spring-aop-5.0.9.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-aop/5.0.9.RELEASE/spring-aop-5.0.9.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_spring_beans_5_0_9_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework:spring-beans:5.0.9.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-beans/5.0.9.RELEASE/spring-beans-5.0.9.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-beans/5.0.9.RELEASE/spring-beans-5.0.9.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-beans/5.0.9.RELEASE/spring-beans-5.0.9.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_spring_context_5_0_9_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework:spring-context:5.0.9.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-context/5.0.9.RELEASE/spring-context-5.0.9.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-context/5.0.9.RELEASE/spring-context-5.0.9.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-context/5.0.9.RELEASE/spring-context-5.0.9.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_spring_context_support_5_0_9_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework:spring-context-support:5.0.9.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-context-support/5.0.9.RELEASE/spring-context-support-5.0.9.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-context-support/5.0.9.RELEASE/spring-context-support-5.0.9.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-context-support/5.0.9.RELEASE/spring-context-support-5.0.9.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_spring_core_5_0_9_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework:spring-core:5.0.9.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-core/5.0.9.RELEASE/spring-core-5.0.9.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-core/5.0.9.RELEASE/spring-core-5.0.9.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-core/5.0.9.RELEASE/spring-core-5.0.9.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_spring_expression_5_0_9_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework:spring-expression:5.0.9.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-expression/5.0.9.RELEASE/spring-expression-5.0.9.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-expression/5.0.9.RELEASE/spring-expression-5.0.9.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-expression/5.0.9.RELEASE/spring-expression-5.0.9.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_spring_jcl_5_0_9_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework:spring-jcl:5.0.9.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-jcl/5.0.9.RELEASE/spring-jcl-5.0.9.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-jcl/5.0.9.RELEASE/spring-jcl-5.0.9.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-jcl/5.0.9.RELEASE/spring-jcl-5.0.9.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_spring_jdbc_5_0_9_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework:spring-jdbc:5.0.9.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-jdbc/5.0.9.RELEASE/spring-jdbc-5.0.9.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-jdbc/5.0.9.RELEASE/spring-jdbc-5.0.9.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-jdbc/5.0.9.RELEASE/spring-jdbc-5.0.9.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_spring_oxm_5_0_9_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework:spring-oxm:5.0.9.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-oxm/5.0.9.RELEASE/spring-oxm-5.0.9.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-oxm/5.0.9.RELEASE/spring-oxm-5.0.9.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-oxm/5.0.9.RELEASE/spring-oxm-5.0.9.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_spring_tx_5_0_9_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework:spring-tx:5.0.9.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-tx/5.0.9.RELEASE/spring-tx-5.0.9.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-tx/5.0.9.RELEASE/spring-tx-5.0.9.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-tx/5.0.9.RELEASE/spring-tx-5.0.9.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_spring_web_5_0_9_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework:spring-web:5.0.9.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-web/5.0.9.RELEASE/spring-web-5.0.9.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-web/5.0.9.RELEASE/spring-web-5.0.9.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-web/5.0.9.RELEASE/spring-web-5.0.9.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_springframework_spring_webmvc_5_0_9_RELEASE.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.springframework:spring-webmvc:5.0.9.RELEASE">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-webmvc/5.0.9.RELEASE/spring-webmvc-5.0.9.RELEASE.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-webmvc/5.0.9.RELEASE/spring-webmvc-5.0.9.RELEASE-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-webmvc/5.0.9.RELEASE/spring-webmvc-5.0.9.RELEASE-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__org_yaml_snakeyaml_1_19.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: org.yaml:snakeyaml:1.19">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/org/yaml/snakeyaml/1.19/snakeyaml-1.19.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/org/yaml/snakeyaml/1.19/snakeyaml-1.19-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/org/yaml/snakeyaml/1.19/snakeyaml-1.19-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/Maven__redis_clients_jedis_2_9_0.xml
New file
@@ -0,0 +1,13 @@
<component name="libraryTable">
  <library name="Maven: redis.clients:jedis:2.9.0">
    <CLASSES>
      <root url="jar://$MAVEN_REPOSITORY$/redis/clients/jedis/2.9.0/jedis-2.9.0.jar!/" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$MAVEN_REPOSITORY$/redis/clients/jedis/2.9.0/jedis-2.9.0-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$MAVEN_REPOSITORY$/redis/clients/jedis/2.9.0/jedis-2.9.0-sources.jar!/" />
    </SOURCES>
  </library>
</component>
.idea/libraries/hx_demoboot.xml
New file
@@ -0,0 +1,9 @@
<component name="libraryTable">
  <library name="hx-demoboot">
    <CLASSES>
      <root url="jar://$PROJECT_DIR$/target/hx-demoboot.jar!/" />
    </CLASSES>
    <JAVADOC />
    <SOURCES />
  </library>
</component>
.idea/misc.xml
New file
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="MavenProjectsManager">
    <option name="originalFiles">
      <list>
        <option value="$PROJECT_DIR$/pom.xml" />
      </list>
    </option>
  </component>
  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
    <output url="file://$PROJECT_DIR$/out" />
  </component>
</project>
.idea/modules.xml
New file
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectModuleManager">
    <modules>
      <module fileurl="file://$PROJECT_DIR$/hx-common.iml" filepath="$PROJECT_DIR$/hx-common.iml" />
      <module fileurl="file://$PROJECT_DIR$/src/main/main.iml" filepath="$PROJECT_DIR$/src/main/main.iml" />
    </modules>
  </component>
</project>
.idea/vcs.xml
New file
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="VcsDirectoryMappings">
    <mapping directory="" vcs="Git" />
  </component>
</project>
hx-common.iml
New file
@@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
  <component name="FacetManager">
    <facet type="Spring" name="Spring">
      <configuration />
    </facet>
    <facet type="web" name="Web">
      <configuration>
        <webroots />
      </configuration>
    </facet>
  </component>
  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
    <output url="file://$MODULE_DIR$/target/classes" />
    <output-test url="file://$MODULE_DIR$/target/test-classes" />
    <content url="file://$MODULE_DIR$">
      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
      <excludeFolder url="file://$MODULE_DIR$/target" />
    </content>
    <orderEntry type="inheritedJdk" />
    <orderEntry type="sourceFolder" forTests="false" />
    <orderEntry type="library" name="Maven: com.sun.mail:javax.mail:1.6.2" level="project" />
    <orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
    <orderEntry type="library" name="Maven: com.aliyun.oss:aliyun-sdk-oss:2.8.3" level="project" />
    <orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.66" level="project" />
    <orderEntry type="library" name="Maven: org.dom4j:dom4j:2.1.3" level="project" />
    <orderEntry type="library" name="Maven: org.jdom:jdom:1.1.3" level="project" />
    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.13" level="project" />
    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.12" level="project" />
    <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
    <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.11" level="project" />
    <orderEntry type="library" name="Maven: cglib:cglib:3.1" level="project" />
    <orderEntry type="library" name="Maven: org.ow2.asm:asm:4.2" level="project" />
    <orderEntry type="library" name="Maven: com.google.zxing:core:3.3.0" level="project" />
    <orderEntry type="library" name="Maven: net.glxn:qrgen:1.4" level="project" />
    <orderEntry type="library" name="Maven: com.google.zxing:javase:3.0.0" level="project" />
    <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.9" level="project" />
    <orderEntry type="library" name="Maven: commons-io:commons-io:2.6" level="project" />
    <orderEntry type="library" name="Maven: org.apache.poi:poi:3.9" level="project" />
    <orderEntry type="library" name="Maven: redis.clients:jedis:2.9.0" level="project" />
    <orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.5.0" level="project" />
    <orderEntry type="library" name="Maven: com.auth0:java-jwt:3.10.3" level="project" />
    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.9.6" level="project" />
    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.9.0" level="project" />
    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.6" level="project" />
    <orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
    <orderEntry type="library" name="Maven: javax.servlet.jsp.jstl:jstl-api:1.2" level="project" />
    <orderEntry type="library" name="Maven: javax.servlet:servlet-api:2.5" level="project" />
    <orderEntry type="library" name="Maven: javax.servlet.jsp:jsp-api:2.1" level="project" />
    <orderEntry type="library" name="Maven: javax.servlet:jstl:1.2" level="project" />
    <orderEntry type="library" name="Maven: com.gitee.sunchenbin.mybatis.actable:mybatis-enhance-actable:1.1.1.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: org.freemarker:freemarker:2.3.28" level="project" />
    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:1.4.2.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.0.10.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:2.0.10.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.0.10.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: org.springframework:spring-tx:5.0.9.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.0.9.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.0.9.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.0.9.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: org.projectlombok:lombok:1.16.22" level="project" />
    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.0.5.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.0.5.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.0.5.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.0.5.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: javax.annotation:javax.annotation-api:1.3.2" level="project" />
    <orderEntry type="library" name="Maven: org.springframework:spring-core:5.0.9.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.0.9.RELEASE" level="project" />
    <orderEntry type="library" scope="RUNTIME" name="Maven: org.yaml:snakeyaml:1.19" level="project" />
    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.0.5.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.6" level="project" />
    <orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.6" level="project" />
    <orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.9.6" level="project" />
    <orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.12.Final" level="project" />
    <orderEntry type="library" name="Maven: javax.validation:validation-api:2.0.1.Final" level="project" />
    <orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.3.2.Final" level="project" />
    <orderEntry type="library" name="Maven: com.fasterxml:classmate:1.3.4" level="project" />
    <orderEntry type="library" name="Maven: org.springframework:spring-web:5.0.9.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.0.9.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.0.9.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: org.springframework:spring-context:5.0.9.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: org.springframework:spring-expression:5.0.9.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:1.1.1" level="project" />
    <orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:1.1.1" level="project" />
    <orderEntry type="library" name="Maven: org.mybatis:mybatis:3.4.0" level="project" />
    <orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:1.3.0" level="project" />
    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.0.5.RELEASE" level="project" />
    <orderEntry type="library" name="Maven: com.zaxxer:HikariCP:2.7.9" level="project" />
    <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.25" level="project" />
    <orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.0.9.RELEASE" level="project" />
    <orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:5.1.47" level="project" />
    <orderEntry type="library" name="Maven: com.alibaba:druid:1.1.9" level="project" />
    <orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.47" level="project" />
    <orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.5" level="project" />
    <orderEntry type="library" name="Maven: net.sf.json-lib:json-lib:jdk15:2.4" level="project" />
    <orderEntry type="library" name="Maven: com.belerweb:pinyin4j:2.5.1" level="project" />
    <orderEntry type="library" name="Maven: net.sourceforge.jexcelapi:jxl:2.6.12" level="project" />
    <orderEntry type="library" name="Maven: log4j:log4j:1.2.14" level="project" />
    <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.9.3" level="project" />
    <orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
    <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.5" level="project" />
    <orderEntry type="library" name="Maven: net.sf.ezmorph:ezmorph:1.0.3" level="project" />
    <orderEntry type="library" name="Maven: junit:junit:4.12" level="project" />
    <orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
    <orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.1.11" level="project" />
    <orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:2.0" level="project" />
  </component>
</module>
pom.xml
New file
@@ -0,0 +1,268 @@
<?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.hx.gitee</groupId>
        <artifactId>hx-parent</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>hx-common</artifactId>
    <packaging>jar</packaging>
    <dependencies>
        <!--发送邮件-->
        <dependency>
            <groupId>com.sun.mail</groupId>
            <artifactId>javax.mail</artifactId>
        </dependency>
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
        </dependency>
        <!--微信支付用到的包-->
        <dependency>
            <groupId>org.dom4j</groupId>
            <artifactId>dom4j</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jdom</groupId>
            <artifactId>jdom</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
        </dependency>
        <!--<dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </dependency>-->
        <!--生成二维码支持包-->
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
        </dependency>
        <dependency>
            <groupId>net.glxn</groupId>
            <artifactId>qrgen</artifactId>
        </dependency>
        <!-- 字符串工具类jar:StringUtils -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
        </dependency>
        <!-- excel2003使用的jar -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <!-- mybatis自动生成 -->
        <dependency>
            <groupId>com.gitee.sunchenbin.mybatis.actable</groupId>
            <artifactId>mybatis-enhance-actable</artifactId>
        </dependency>
        <!-- 模板生成jar -->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>jcl-over-slf4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.hibernate</groupId>
                    <artifactId>hibernate-validator</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId><exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <classifier>jdk15</classifier>
        </dependency>
        <dependency>
            <groupId>com.belerweb</groupId>
            <artifactId>pinyin4j</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sourceforge.jexcelapi</groupId>
            <artifactId>jxl</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>commons-logging</artifactId>
                    <groupId>commons-logging</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sf.ezmorph</groupId>
            <artifactId>ezmorph</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
        </dependency>
    </dependencies>
    <build>
        <finalName>hx-demoboot</finalName>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                    <include>**/*.tld</include>
                    <include>**/*.tpl</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <excludes>
                    <exclude>profile-active/**</exclude>
                </excludes>
            </resource>
            <resource>
                <directory>${runtime.env}</directory>
            </resource>
        </resources>
    </build>
</project>
src/main/java/com/hx/annotation/Jurisdiction.java
New file
@@ -0,0 +1,25 @@
package com.hx.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**权限注解
 * @author chenjiahe
 * @version 2019年09月14日 下午6:13:37
 */
//表示注解加在接口、类、枚举等
@Target(ElementType.METHOD)
//VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息
@Retention(RetentionPolicy.RUNTIME)
//将此注解包含在javadoc中
@Documented
//允许子类继承父类中的注解
@Inherited
public @interface Jurisdiction {
    /**权限名*/
     String privilege();
}
src/main/java/com/hx/common/CommonInit.java
New file
@@ -0,0 +1,97 @@
package com.hx.common;
import com.hx.exception.ParamException;
import com.hx.exception.ServiceException;
import com.hx.mybatisTool.SqlParam;
import com.hx.mybatisTool.SqlSentence;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.request.WebRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**公共初始化
 * @author ChenJiaHe
 * @Date 2020-06-11
 */
public class CommonInit {
    /*请不要声明变量,会导致不安全,因为这个是单列*/
    protected HttpServletRequest request = null;
    protected HttpSession session = null;
    //只需要加上下面这段即可,注意不能忘记注解
    @InitBinder
    public void initBinder(WebDataBinder binder, WebRequest request) {
        //转换日期 注意这里的转化要和传进来的字符串的格式一直 如2015-9-9 就应该为yyyy-MM-dd
        DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));// CustomDateEditor为自定义日期编辑器
    }
    public HttpServletRequest getRequest() {
        //获取参数对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        request = attributes.getRequest();
        return request;
    }
    public HttpSession getSession() {
        //获取参数对象
        session = getRequest() .getSession();
        return session;
    }
    /**
     * 获取request里某个属性
     * @param attrName 属性名称
     * @return 对象
     */
    public Object getRequestAttribute(String attrName)
    {
        return getRequest().getAttribute(attrName);
    }
    /**
     * 设置一个request属性
     * @param attrName 属性名称
     * @param attrObject 属性值
     */
    public void setRequestAttribute(String attrName, Object attrObject) {
        getRequest().setAttribute(attrName, attrObject);
    }
    /**
     * 抛出服务异常
     * @param msg 错误信息
     */
    public void throwServiceException(String msg)
    {
        throw new ServiceException(msg);
    }
    /**
     * 抛出参数异常
     * @param msg 错误信息
     */
    public void throwParamException(String msg)
    {
        throw new ParamException(msg);
    }
}
src/main/java/com/hx/exception/ParamException.java
New file
@@ -0,0 +1,12 @@
package com.hx.exception;
/** 参数异常
 * @author ChenJiaHe
 * @Date 2020-06-19
 */
public class ParamException extends RuntimeException {
    public ParamException(String message) {
        super(message);
    }
}
src/main/java/com/hx/exception/ServiceException.java
New file
@@ -0,0 +1,34 @@
package com.hx.exception;
/** 判断异常/业务异常
 * @author ChenJiaHe
 * @Date 2020-06-19
 */
public class ServiceException extends RuntimeException {
    private Integer code;
    public ServiceException(String message) {
        super(message);
    }
    public ServiceException(String message, Integer code) {
        super(message);
        this.code = code;
    }
    public ServiceException(String message, Throwable cause, Integer code) {
        super(message, cause);
        this.code = code;
    }
    public ServiceException(Throwable cause, Integer code) {
        super(cause);
        this.code = code;
    }
    //@Override
    public int getCode() {
        return this.code;
    }
}
src/main/java/com/hx/exception/TipsException.java
New file
@@ -0,0 +1,35 @@
package com.hx.exception;
/**
 * 前端提示异常
 * @author ChenJiaHe
 * @Date 2020-06-19
 */
public class TipsException extends RuntimeException {
    private Integer code;
    public TipsException(String message) {
        super(message);
    }
    public TipsException(String message, Integer code) {
        super(message);
        this.code = code;
    }
    public TipsException(String message, Throwable cause, Integer code) {
        super(message, cause);
        this.code = code;
    }
    public TipsException(Throwable cause, Integer code) {
        super(cause);
        this.code = code;
    }
    //@Override
    public int getCode() {
        return this.code;
    }
}
src/main/java/com/hx/mp/util/CertUtil.java
New file
@@ -0,0 +1,31 @@
package com.hx.mp.util;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
@SuppressWarnings("deprecation")
public class CertUtil {
    /**
     * 加载证书
     */
    public static SSLConnectionSocketFactory initCert(String certPath, String mchId) throws Exception {
        FileInputStream instream = null;
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        instream = new FileInputStream(new File(certPath));
        keyStore.load(instream, mchId.toCharArray());
        if (null != instream) {
            instream.close();
        }
        SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore,mchId.toCharArray()).build();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        return sslsf;
    }
}
src/main/java/com/hx/mp/util/ClientResponseHandler.java
New file
@@ -0,0 +1,228 @@
package com.hx.mp.util;
import org.jdom.JDOMException;
import java.io.IOException;
import java.util.*;
/**
 * ��̨Ӧ����<br/>
 * ========================================================================<br/>
 * api˵����<br/>
 * getKey()/setKey(),��ȡ/������Կ<br/>
 * getContent() / setContent(), ��ȡ/����ԭʼ����<br/>
 * getParameter()/setParameter(),��ȡ/���ò���ֵ<br/>
 * getAllParameters(),��ȡ���в���<br/>
 * isTenpaySign(),�Ƿ�Ƹ�ͨǩ��,true:�� false:��<br/>
 * getDebugInfo(),��ȡdebug��Ϣ<br/>
 *
 * ========================================================================<br/>
 *
 */
public class ClientResponseHandler {
    /** Ӧ��ԭʼ���� */
    private String content;
    /** Ӧ��IJ��� */
    @SuppressWarnings("rawtypes")
    private SortedMap parameters;
    /** debug��Ϣ */
    private String debugInfo;
    /** ��Կ */
    private String key;
    /** �ַ� */
    private String charset;
    /*@SuppressWarnings("rawtypes")
    public ClientResponseHandler() {
        this.content = "";
        this.parameters = new TreeMap();
        this.debugInfo = "";
        this.key = "";
        this.charset = "UTF-8";
    }*/
    public ClientResponseHandler() {
        this.content = "";
        this.parameters = new TreeMap();
        this.debugInfo = "";
        this.key = "";
        this.charset = "UTF-8";
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) throws Exception {
        this.content = content;
        this.doParse();
    }
    /**
     * ��ȡ����ֵ
     *
     * @param parameter
     *            �������
     * @return String
     */
    public String getParameter(String parameter) {
        String s = (String) this.parameters.get(parameter);
        return (null == s) ? "" : s;
    }
    /**
     * ���ò���ֵ
     *
     * @param parameter
     *            �������
     * @param parameterValue
     *            ����ֵ
     */
    @SuppressWarnings("unchecked")
    public void setParameter(String parameter, String parameterValue) {
        String v = "";
        if (null != parameterValue) {
            v = parameterValue.trim();
        }
        this.parameters.put(parameter, v);
    }
    /**
     * �������еIJ���
     *
     * @return SortedMap
     */
    @SuppressWarnings("rawtypes")
    public SortedMap getAllParameters() {
        return this.parameters;
    }
    public String getDebugInfo() {
        return debugInfo;
    }
    /**
     * ��ȡ��Կ
     */
    public String getKey() {
        return key;
    }
    /**
     * ������Կ
     */
    public void setKey(String key) {
        this.key = key;
    }
    public String getCharset() {
        return this.charset;
    }
    public void setCharset(String charset) {
        this.charset = charset;
    }
    /**
     * �Ƿ�Ƹ�ͨǩ��,������:���������a-z����,������ֵ�IJ���μ�ǩ��
     *
     * @return boolean
     */
    @SuppressWarnings("rawtypes")
    public boolean isTenpaySign() {
        StringBuffer sb = new StringBuffer();
        Set es = this.parameters.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (!"sign".equals(k) && null != v && !"".equals(v)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + this.getKey());
        System.out.println("返回的参数:" + sb);
        // ���ժҪ
        String sign = MD5Util.MD5Encode(sb.toString(), this.charset)
                .toUpperCase();
        String tenpaySign = this.getParameter("sign").toUpperCase();
        // debug��Ϣ
        this.setDebugInfo(sb.toString() + " => sign:" + sign + " tenpaySign:"
                + tenpaySign);
        Boolean b = tenpaySign.equals(sign);
        System.out.println("验证返回来的数据是否微信返回的:" + b);
        return b;
    }
    /**
     * �Ƿ�Ƹ�ͨǩ��
     *
     * @param signParameterArray
     *            ǩ��IJ�������
     * @return boolean
     */
    protected boolean isTenpaySign(String signParameterArray[]) {
        StringBuffer signPars = new StringBuffer();
        for (int index = 0; index < signParameterArray.length; index++) {
            String k = signParameterArray[index];
            String v = this.getParameter(k);
            if (null != v && !"".equals(v)) {
                signPars.append(k + "=" + v + "&");
            }
        }
        signPars.append("key=" + this.getKey());
        // ���ժҪ
        String sign = MD5Util.MD5Encode(signPars.toString(), this.charset)
                .toLowerCase();
        String tenpaySign = this.getParameter("sign").toLowerCase();
        // debug��Ϣ
        this.setDebugInfo(signPars.toString() + " => sign:" + sign
                + " tenpaySign:" + tenpaySign);
        return tenpaySign.equals(sign);
    }
    protected void setDebugInfo(String debugInfo) {
        this.debugInfo = debugInfo;
    }
    /**
     * ����XML����
     */
    @SuppressWarnings("rawtypes")
    protected void doParse() throws JDOMException, IOException, JDOMException {
        String xmlContent = this.getContent();
        // ����xml,�õ�map
        Map m = XMLUtil.doXMLParse(xmlContent);
        // ���ò���
        Iterator it = m.keySet().iterator();
        while (it.hasNext()) {
            String k = (String) it.next();
            String v = (String) m.get(k);
            this.setParameter(k, v);
        }
    }
}
src/main/java/com/hx/mp/util/CorpMpClientUtil.java
New file
@@ -0,0 +1,169 @@
package com.hx.mp.util;
import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.apache.commons.io.IOUtils;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.MessageFormat;
/**
 * 企业微信客户工具
 */
public class CorpMpClientUtil {
   /**生成联系我按钮参数的链接(生成config_id)*/
   public static final String CREATE_CONTACT_ID_URL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_contact_way?access_token=";
   /**获取企业客户详情链接*/
   public static final String GET_CLIENT_DETAIL_URL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get";
   /**添加客户联系人标签*/
   public static final String ADD_TAG = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_corp_tag?access_token=";
   /**删除客户联系人标签*/
   public static final String DEL_TAG = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_corp_tag?access_token=";
   /**客户关联企业微信的标签url*/
   public static final String RELATION_TAG = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/mark_tag?access_token=";
    /**生成企业成员联系我的id-单人
     * @param accessToken 企业的accessToken
     * @param userId 企业成员的userId
     * @param state 企业自定义的state参数,用于区分不同的添加渠道,在调用“获取外部联系人详情”时会返回该参数值,不超过30个字符
     * @param remark 联系方式的备注信息,用于助记,不超过30个字符
     * @return
     */
   public static JSONObject createContactId(String accessToken,String userId,String state,String remark){
       String configId = null;
       JSONObject data = new JSONObject();
       data.put("type",1);
       data.put("scene",1);
       data.put("state",state);
       data.put("remark",remark);
       JSONArray userIds = new JSONArray();
       userIds.add(userId);
       data.put("user",userIds);
       //请求,返回格式
       /*{
           "errcode": 0,
               "errmsg": "ok",
               "config_id":"42b34949e138eb6e027c123cba77fAAA"  
       }*/
       return HttpURLUtil(CREATE_CONTACT_ID_URL+accessToken,data.toString());
   }
    /**获取企业客户详情信息
     * @param accessToken 企业的accessToken
     * @param externalUserId 外部人员的userId
     * @return
     */
   public static JSONObject getClientData(String accessToken,String externalUserId){
       return HttpURLUtil(GET_CLIENT_DETAIL_URL+"?access_token="+accessToken+"&external_userid="+externalUserId,null);
   }
    /** 添加客户联系人标签,
     *如果要向指定的标签组下添加标签,需要填写group_id参数;如果要创建一个全新的标签组以及标签,
     *则需要通过group_name参数指定新标签组名称,如果填写的groupname已经存在,则会在此标签组下新建标签
     * @param accessToken 企业的accessToken
     * @param groupId 组id(组名称和组id必填一个)
     * @param groupName 组名称 组名称和组id必填一个)
     * @param groupOrder 组排序,不填默认企业微信生成规则
     * @param tagArray 数组,格式:[{ "name": "TAG_NAME_1", "order": 1 }]
     * @return
     */
   public static JSONObject addTable(String accessToken,String groupId,String groupName,String groupOrder,JSONArray tagArray){
       JSONObject data = new JSONObject();
       data.put("group_id",groupId);
       data.put("group_name",groupName);
       data.put("order",groupOrder);
       data.put("tag",tagArray);
       return HttpURLUtil(ADD_TAG+accessToken,data.toString());
   }
    /**删除客户联系人标签
     * groupArr和tagArr不可同时为空。
     * 如果一个标签组下所有的标签均被删除,则标签组会被自动删除。
     * @param accessToken 企业的accessToken
     * @param groupArr 组id数组
     * @param tagArr 标签id数组
     * @return
     */
   public static JSONObject delTable(String accessToken,JSONArray groupArr,String tagArr){
       JSONObject data = new JSONObject();
       data.put("tag_id",tagArr);
       data.put("group_id",groupArr);
       return HttpURLUtil(DEL_TAG+accessToken,data.toString());
   }
    /**
     * 客户关联企业微信的标签
     * 注意:请确保external_userid是userid的外部联系人。
     * add_tag和remove_tag不可同时为空。
     * @param accessToken 企业的accessToken
     * @param userId 企业成员的userid
     * @param externalUserId 外部联系人的id
     * @param addTag 新增的标签id(企业标签的id)数组
     * @param removeTag 删除的标签id(企业标签的id)数组
     * @return
     */
    public static JSONObject relationTag(String accessToken,String userId,String externalUserId
            ,JSONArray addTag,JSONArray removeTag){
        JSONObject data = new JSONObject();
        data.put("userid",userId);
        data.put("external_userid",externalUserId);
        data.put("add_tag",addTag);
        data.put("remove_tag",removeTag);
        return HttpURLUtil(RELATION_TAG+accessToken,data.toString());
    }
    /** 请求http协议 获取信息工具 **/
    public static JSONObject HttpURLUtil(String url, String data) {
        HttpURLConnection con = null;
        URL u = null;
        String wxMsgXml = null;
        JSONObject obj = null;
        try {
            u = new URL(url);
            con = (HttpURLConnection) u.openConnection();
            con.setRequestMethod("POST");
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setUseCaches(false);
            con.setReadTimeout(5000);
            con.setRequestProperty("Charset", "UTF-8");
            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            if (data != null) {
                OutputStream os = con.getOutputStream();
                os.write(data.getBytes("utf-8"));
            }
            if (con.getResponseCode() != 200)
                throw new RuntimeException("请求url失败");
            // 读取返回内容
            wxMsgXml = IOUtils.toString(con.getInputStream(), "utf-8");
            obj = JSONObject.fromObject(wxMsgXml);
            // //System.out.println("HttpURLUtil:"+wxMsgXml);
        } catch (Exception e) {
            e.printStackTrace();
            obj = new JSONObject();
            try {
                obj.put("status", 1);
                obj.put("errMsg", e.getMessage());
            } catch (JSONException e1) {
                e1.printStackTrace();
            }
        } finally {
            if (con != null) {
                con.disconnect();
            }
        }
        return obj;
    }
}
src/main/java/com/hx/mp/util/CorpMpUtil.java
New file
@@ -0,0 +1,294 @@
package com.hx.mp.util;
import com.hx.exception.TipsException;
import com.hx.util.StringUtils;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.apache.commons.io.IOUtils;
import org.apache.poi.util.SystemOutLogger;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.MessageFormat;
/**
 * 企业微信工具类
 */
public class CorpMpUtil {
    /**链接-获取应用accessToken*/
    public static final String URL_GET_ACCESS_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={0}&corpsecret={1}";
    /**链接-获取session信息*/
    public static final String URL_CODE_2_SESSION = "https://qyapi.weixin.qq.com/cgi-bin/miniprogram/jscode2session?access_token={0}&js_code={1}&grant_type=authorization_code";
    /**链接-添加标签*/
    public static final String URL_ADD_LABEL = "https://qyapi.weixin.qq.com/cgi-bin/tag/create?access_token={0}";
    /**链接-添加部门*/
    public static final String URL_ADD_DEPARTMENT = "https://qyapi.weixin.qq.com/cgi-bin/department/create?access_token={0}";
    /**链接-修改部门*/
    public static final String URL_UPDATE_DEPARTMENT = "https://qyapi.weixin.qq.com/cgi-bin/department/update?access_token={0}";
    /**链接-删除部门*/
    public static final String URL_DELETE_DEPARTMENT = "https://qyapi.weixin.qq.com/cgi-bin/department/delete?access_token={0}&id={1}";
    /**链接-添加成员*/
    public static final String URL_ADD_USER = "https://qyapi.weixin.qq.com/cgi-bin/user/create?access_token={0}";
    /**链接-更新成员*/
    public static final String URL_UPDATE_USER = "https://qyapi.weixin.qq.com/cgi-bin/user/update?access_token={0}";
    /**链接-删除成员*/
    public static final String URL_DELETE_USER = "https://qyapi.weixin.qq.com/cgi-bin/user/delete?access_token={0}&userid={1}";
    /**链接-成员详情*/
    public static final String URL_INFO_USER = "https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token={0}&userid={1}";
    /**发送消息*/
    public static final String URL_MESSAGE_SEND = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=";
    /**
     * 添加工作人员
     * @param at 访问at
     * @param userId 用户id
     * @param name 名称
     * @param depId 部门id
     * @param position 职位
     * @param tel 电话
     * @param email 邮箱
     * @return 返回
     */
    public static int addUser(String at, String userId, String name, int depId
            , String position,String tel,String email) {
        if(StringUtils.isEmpty(tel)&&StringUtils.isEmpty(email)){
            throw new TipsException("添加企业微信手机号和邮箱不能都为空!");
        }
        JSONObject obj = new JSONObject();
        obj.put("userid", userId);
        obj.put("name", name);
        obj.put("department", depId);
        obj.put("position", position);
        obj.put("mobile", tel);
        obj.put("email", email);
        obj = HttpURLUtil(MessageFormat.format(URL_ADD_USER, at), obj.toString());
        if(obj != null) {
            return obj.optInt("errcode", -1);
        }
        return -1;
    }
    /**
     * 更新工作人员
     * @param at 访问at
     * @param userId 用户id
     * @param name 名称
     * @param depId 部门id
     * @param position 职位
     * @param tel 电话
     * @param email 邮箱
     * @return 返回
     */
    public static int updateUser(String at, String userId, String name, int depId
            , String position,String tel,String email) {
        JSONObject obj = new JSONObject();
        obj.put("userid", userId);
        obj.put("name", name);
        obj.put("department", depId);
        obj.put("position", position);
        obj.put("mobile", tel);
        obj.put("email", email);
        obj = HttpURLUtil(MessageFormat.format(URL_UPDATE_USER, at), obj.toString());
        if(obj != null && obj.optInt("errcode", -1) == 0) {
            return obj.optInt("errcode", -1);
        }
        return -1;
    }
    /**
     * 删除工作人员
     * @param at 访问at
     * @param userId 用户id
     * @return 返回
     */
    public static int deleteUser(String at, String userId) {
        JSONObject obj = new JSONObject();
        obj.put("userid", userId);
        obj = HttpURLUtil(MessageFormat.format(URL_DELETE_USER, at,userId), obj.toString());
        if(obj != null) {
            return obj.optInt("errcode", -1);
        }
        return -1;
    }
    /**
     * 工作人员判断是否存在企业微信
     * @param at 访问at
     * @param userId 用户id
     * @return 返回
     */
    public static int infoUser(String at, String userId) {
        JSONObject obj = new JSONObject();
        obj.put("userid", userId);
        obj = HttpURLUtil(MessageFormat.format(URL_INFO_USER, at,userId), obj.toString());
        System.out.println("userId:"+userId);
        System.out.println("obj:"+obj.toString());
        if(obj != null) {
            return obj.optInt("errcode", -1);
        }
        return -1;
    }
    /**
     * 添加部门
     * @param name 部门名称
     * @return id
     */
    public static int addDepartment(String at, String name, int parentId) {
        JSONObject obj = new JSONObject();
        obj.put("name", name);
        obj.put("parentid", parentId);
        obj = HttpURLUtil(MessageFormat.format(URL_ADD_DEPARTMENT, at), obj.toString());
        if(obj != null && obj.optInt("errcode", -1) == 0) {
            return obj.optInt("id", -1);
        }
        return -1;
    }
    /**
     * 更新部门
     * @param name 部门名称
     * @param deaprtId 部门id
     * @param parentid 父类部门id,可以为空
     * @return  状态,0成功
     */
    public static int updateDepartment(String at, String name, int deaprtId,int parentid) {
        JSONObject obj = new JSONObject();
        obj.put("name", name);
        obj.put("id", deaprtId);
        obj.put("parentid", parentid);
        obj = HttpURLUtil(MessageFormat.format(URL_UPDATE_DEPARTMENT, at), obj.toString());
        return obj.optInt("errcode", -1);
    }
    /**删除部门
     * 删除的部门不能是根部门且没有成员
     * @param deaprtId 部门id
     * @return 状态,0成功
     */
    public static int deleteDepartment(String at,int deaprtId) {
        JSONObject obj = new JSONObject();
        obj.put("id", deaprtId);
        obj = HttpURLUtil(MessageFormat.format(URL_DELETE_DEPARTMENT,at,deaprtId), obj.toString());
        System.out.println("删除部门:"+obj.toString());
        return obj.optInt("errcode", -1);
    }
    /**发送企业应用消息
     * @param accessToken 企业accessToken
     * @param data 发送数据结构
     * @return
     */
    public static JSONObject messageSend(String accessToken,String data){
        return HttpURLUtil(URL_MESSAGE_SEND+accessToken,data);
    }
    /**添加用户标签,标签名称不能重复
     * @param at 访问at
     * @param label 标签名称
     * @return 返回 -1失败,0成功,1已存在
     */
    public static int addLabel(String at, String label) {
        String url = MessageFormat.format(URL_ADD_LABEL, at);
        JSONObject obj = new JSONObject();
        obj.put("tagname", label);
        obj = HttpURLUtil(url, obj.toString());
        System.out.println("obj....:"+obj.toString());
        if(obj != null ) {
            int errcode = obj.optInt("errcode", -1);
            if( errcode== 0){
                //上传成功
                return obj.optInt("tagid", -1);
            }if(errcode == 40071){
                //标签已经存在
                return 1;
            }
        }
        return -1;
    }
    /**
     * 获取应用accessToken
     * @param corpId 企业id
     * @param appSecret 应用密钥
     * @return
     * @throws Exception
     */
    public static JSONObject getApplicationAccessToken(String corpId, String appSecret) {
        String url = MessageFormat.format(URL_GET_ACCESS_TOKEN, corpId, appSecret);
        JSONObject obj = HttpURLUtil(url, null);
        return obj;
    }
    /**
     * 使用临时登录凭证code获取 session_key、用户userId以及用户所在企业的corpId等信息
     * @param accessToken 访问token
     * @param code 临时code
     * @return
     */
    public static JSONObject code2Session(String accessToken, String code) {
        String url = MessageFormat.format(URL_CODE_2_SESSION, accessToken, code);
        JSONObject obj = HttpURLUtil(url, null);
        return obj;
    }
    /** 请求http协议 获取信息工具 **/
    public static JSONObject HttpURLUtil(String url, String data) {
        HttpURLConnection con = null;
        URL u = null;
        String wxMsgXml = null;
        JSONObject obj = null;
        try {
            u = new URL(url);
            con = (HttpURLConnection) u.openConnection();
            con.setRequestMethod("POST");
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setUseCaches(false);
            con.setReadTimeout(5000);
            con.setRequestProperty("Charset", "UTF-8");
            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            if (data != null) {
                OutputStream os = con.getOutputStream();
                os.write(data.getBytes("utf-8"));
            }
            if (con.getResponseCode() != 200)
                throw new RuntimeException("请求url失败");
            // 读取返回内容
            wxMsgXml = IOUtils.toString(con.getInputStream(), "utf-8");
            obj = JSONObject.fromObject(wxMsgXml);
            // //System.out.println("HttpURLUtil:"+wxMsgXml);
        } catch (Exception e) {
            e.printStackTrace();
            obj = new JSONObject();
            try {
                obj.put("status", 1);
                obj.put("errMsg", e.getMessage());
            } catch (JSONException e1) {
                e1.printStackTrace();
            }
        } finally {
            if (con != null) {
                con.disconnect();
            }
        }
        return obj;
    }
}
src/main/java/com/hx/mp/util/HttpClientUtil.java
New file
@@ -0,0 +1,340 @@
package com.hx.mp.util;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
/**
 * Http�ͻ��˹�����<br/>
 * �����ڲ������࣬�벻Ҫ���ⲿ���á�
 * @author miklchen
 *
 */
public class HttpClientUtil {
    public static final String SunX509 = "SunX509";
    public static final String JKS = "JKS";
    public static final String PKCS12 = "PKCS12";
    public static final String TLS = "TLS";
    /**
     * get HttpURLConnection
     * @param strUrl url��ַ
     * @return HttpURLConnection
     * @throws IOException
     */
    public static HttpURLConnection getHttpURLConnection(String strUrl)
            throws IOException {
        URL url = new URL(strUrl);
        HttpURLConnection httpURLConnection = (HttpURLConnection) url
                .openConnection();
        return httpURLConnection;
    }
    /**
     * get HttpsURLConnection
     * @param strUrl url��ַ
     * @return HttpsURLConnection
     * @throws IOException
     */
    public static HttpsURLConnection getHttpsURLConnection(String strUrl)
            throws IOException {
        URL url = new URL(strUrl);
        HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url
                .openConnection();
        return httpsURLConnection;
    }
    /**
     * ��ȡ�����ѯ����url
     * @param strUrl
     * @return String
     */
    public static String getURL(String strUrl) {
        if(null != strUrl) {
            int indexOf = strUrl.indexOf("?");
            if(-1 != indexOf) {
                return strUrl.substring(0, indexOf);
            }
            return strUrl;
        }
        return strUrl;
    }
    /**
     * ��ȡ��ѯ��
     * @param strUrl
     * @return String
     */
    public static String getQueryString(String strUrl) {
        if(null != strUrl) {
            int indexOf = strUrl.indexOf("?");
            if(-1 != indexOf) {
                return strUrl.substring(indexOf+1, strUrl.length());
            }
            return "";
        }
        return strUrl;
    }
    /**
     * ��ѯ�ַ�ת����Map<br/>
     * name1=key1&name2=key2&...
     * @param queryString
     * @return
     */
    @SuppressWarnings("rawtypes")
    public static Map queryString2Map(String queryString) {
        if(null == queryString || "".equals(queryString)) {
            return null;
        }
        Map m = new HashMap();
        String[] strArray = queryString.split("&");
        for(int index = 0; index < strArray.length; index++) {
            String pair = strArray[index];
            HttpClientUtil.putMapByPair(pair, m);
        }
        return m;
    }
    /**
     * �Ѽ�ֵ�����Map<br/>
     * pair:name=value
     * @param pair name=value
     * @param m
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static void putMapByPair(String pair, Map m) {
        if(null == pair || "".equals(pair)) {
            return;
        }
        int indexOf = pair.indexOf("=");
        if(-1 != indexOf) {
            String k = pair.substring(0, indexOf);
            String v = pair.substring(indexOf+1, pair.length());
            if(null != k && !"".equals(k)) {
                m.put(k, v);
            }
        } else {
            m.put(pair, "");
        }
    }
    /**
     * BufferedReaderת����String<br/>
     * ע��:���ر���Ҫ���д���
     * @param reader
     * @return String
     * @throws IOException
     */
    public static String bufferedReader2String(BufferedReader reader) throws IOException {
        StringBuffer buf = new StringBuffer();
        String line = null;
        while( (line = reader.readLine()) != null) {
            buf.append(line);
            buf.append("\r\n");
        }
        return buf.toString();
    }
    /**
     * �������<br/>
     * ע��:���ر���Ҫ���д���
     * @param out
     * @param data
     * @param len
     * @throws IOException
     */
    public static void doOutput(OutputStream out, byte[] data, int len)
            throws IOException {
        int dataLen = data.length;
        int off = 0;
        while (off < data.length) {
            if (len >= dataLen) {
                out.write(data, off, dataLen);
                off += dataLen;
            } else {
                out.write(data, off, len);
                off += len;
                dataLen -= len;
            }
            // ˢ�»�����
            out.flush();
        }
    }
    /**
     * ��ȡSSLContext
     * @param trustFile
     * @param trustPasswd
     * @param keyFile
     * @param keyPasswd
     * @return
     * @throws NoSuchAlgorithmException
     * @throws KeyStoreException
     * @throws IOException
     * @throws CertificateException
     * @throws UnrecoverableKeyException
     * @throws KeyManagementException
     */
    public static SSLContext getSSLContext(
            FileInputStream trustFileInputStream, String trustPasswd,
            FileInputStream keyFileInputStream, String keyPasswd)
            throws NoSuchAlgorithmException, KeyStoreException,
            CertificateException, IOException, UnrecoverableKeyException,
            KeyManagementException {
        // ca
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(HttpClientUtil.SunX509);
        KeyStore trustKeyStore = KeyStore.getInstance(HttpClientUtil.JKS);
        trustKeyStore.load(trustFileInputStream, HttpClientUtil
                .str2CharArray(trustPasswd));
        tmf.init(trustKeyStore);
        final char[] kp = HttpClientUtil.str2CharArray(keyPasswd);
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(HttpClientUtil.SunX509);
        KeyStore ks = KeyStore.getInstance(HttpClientUtil.PKCS12);
        ks.load(keyFileInputStream, kp);
        kmf.init(ks, kp);
        SecureRandom rand = new SecureRandom();
        SSLContext ctx = SSLContext.getInstance(HttpClientUtil.TLS);
        ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), rand);
        return ctx;
    }
    /**
     * ��ȡCA֤����Ϣ
     * @param cafile CA֤���ļ�
     * @return Certificate
     * @throws CertificateException
     * @throws IOException
     */
    public static Certificate getCertificate(File cafile)
            throws CertificateException, IOException {
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        FileInputStream in = new FileInputStream(cafile);
        Certificate cert = cf.generateCertificate(in);
        in.close();
        return cert;
    }
    /**
     * �ַ�ת����char����
     * @param str
     * @return char[]
     */
    public static char[] str2CharArray(String str) {
        if(null == str) return null;
        return str.toCharArray();
    }
    /**
     * �洢ca֤���JKS��ʽ
     * @param cert
     * @param alias
     * @param password
     * @param out
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws CertificateException
     * @throws IOException
     */
    public static void storeCACert(Certificate cert, String alias,
            String password, OutputStream out) throws KeyStoreException,
            NoSuchAlgorithmException, CertificateException, IOException {
        KeyStore ks = KeyStore.getInstance("JKS");
        ks.load(null, null);
        ks.setCertificateEntry(alias, cert);
        // store keystore
        ks.store(out, HttpClientUtil.str2CharArray(password));
    }
    public static InputStream String2Inputstream(String str) {
        return new ByteArrayInputStream(str.getBytes());
    }
    /**
     * InputStreamת����Byte
     * ע��:���ر���Ҫ���д���
     * @param in
     * @return byte
     * @throws Exception
     */
    public static byte[] InputStreamTOByte(InputStream in) throws IOException{
        int BUFFER_SIZE = 4096;
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] data = new byte[BUFFER_SIZE];
        int count = -1;
        while((count = in.read(data,0,BUFFER_SIZE)) != -1)
            outStream.write(data, 0, count);
        data = null;
        byte[] outByte = outStream.toByteArray();
        outStream.close();
        return outByte;
    }
    /**
     * InputStreamת����String
     * ע��:���ر���Ҫ���д���
     * @param in
     * @param encoding ����
     * @return String
     * @throws Exception
     */
    public static String InputStreamTOString(InputStream in,String encoding) throws IOException{
        return new String(InputStreamTOByte(in),encoding);
    }
}
src/main/java/com/hx/mp/util/HttpUtil.java
New file
@@ -0,0 +1,31 @@
package com.hx.mp.util;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
public class HttpUtil {
    /**
     * 发送post请求
     *
     * @param url
     *            请求地址
     * @param outputEntity
     *            发送内容
     * @param isLoadCert
     *            是否加载证书
     */
    public static CloseableHttpResponse Post(String url, String outputEntity, boolean isLoadCert, String certPath, String mchId) throws Exception {
        HttpPost httpPost = new HttpPost(url);
        // 得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
        httpPost.addHeader("Content-Type", "text/xml");
        httpPost.setEntity(new StringEntity(outputEntity, "UTF-8"));
        if (isLoadCert) {
            // 加载含有证书的http请求
            return HttpClients.custom().setSSLSocketFactory(CertUtil.initCert(certPath, mchId)).build().execute(httpPost);
        } else {
            return HttpClients.custom().build().execute(httpPost);
        }
    }
}
src/main/java/com/hx/mp/util/HttpXmlUtils.java
New file
@@ -0,0 +1,63 @@
package com.hx.mp.util;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.xml.sax.InputSource;
import java.io.IOException;
import java.io.StringReader;
import java.util.*;
public class HttpXmlUtils {
    @SuppressWarnings("rawtypes")
    public static String transferXml(SortedMap<Object, Object> parameters) {
        Document document = DocumentHelper.createDocument();
        Element root = document.addElement("xml");
        Set es = parameters.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            Element ToUserName = root.addElement(k);
            ToUserName.addText(v);
        }
        String queryString = document.asXML();// 转为String
        queryString = queryString.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "").trim();
        // System.out.println("企业端付款参数:"+queryString);
        return queryString;
    }
    @SuppressWarnings("unchecked")
    public static Map<String, String> parseRefundXml(String refundXml) throws JDOMException, IOException {
        StringReader read = new StringReader(refundXml);
        // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
        InputSource source = new InputSource(read);
        // 创建一个新的SAXBuilder
        SAXBuilder sb = new SAXBuilder();
        // 通过输入源构造一个Document
        Document doc;
        doc = (Document) sb.build(source);
        Element root = doc.getRootElement();// 指向根节点
        List<Element> list = root.elements();
        Map<String, String> refundOrderMap = new HashMap<String, String>();
        if (list != null && list.size() > 0) {
            for (Element element : list) {
                refundOrderMap.put(element.getName(), element.getText());
            }
            return refundOrderMap;
        }
        return null;
    }
}
src/main/java/com/hx/mp/util/MD5Util.java
New file
@@ -0,0 +1,43 @@
package com.hx.mp.util;
import java.security.MessageDigest;
public class MD5Util {
    private static String byteArrayToHexString(byte b[]) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++)
            resultSb.append(byteToHexString(b[i]));
        return resultSb.toString();
    }
    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0)
            n += 256;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }
    public static String MD5Encode(String origin, String charsetname) {
        String resultString = null;
        try {
            resultString = new String(origin);
            MessageDigest md = MessageDigest.getInstance("MD5");
            if (charsetname == null || "".equals(charsetname))
                resultString = byteArrayToHexString(md.digest(resultString
                        .getBytes()));
            else
                resultString = byteArrayToHexString(md.digest(resultString
                        .getBytes(charsetname)));
        } catch (Exception exception) {
        }
        return resultString;
    }
    private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
}
src/main/java/com/hx/mp/util/MPWeixinBaseUtil.java
New file
@@ -0,0 +1,404 @@
package com.hx.mp.util;
import com.hx.util.OSSUtil;
import com.hx.util.SimpleTool;
import com.hx.util.StringUtils;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Component;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
 * 微信获取权限基本工具类
 * @author ChenJiaHe
 * @Date 2020-07-14
 */
@Component
public class MPWeixinBaseUtil {
    // 类型
    private static final String GRANT_TYPE = "client_credential";
    /**获取access_token链接*/
    private static final String GETACCESS_TOKENURL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=";
    /**通过code获取小程序信息链接*/
    private static final String JSCODE2SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session?";
    /**发送订阅消息通知链接*/
    private static final String SEND_SUBSCRIBE_MESSAGE = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=";
    //生成小程序二维码地址(方形)
    public static final String MAKE_TWOCODE_SQUARE_URL = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=";
    //生成小程序二维码地址(圆形)
    public static final String MAKE_TWOCODE_ROUND_URL = "https://api.weixin.qq.com/wxa/getwxacode?access_token=";
    //生成无限二维码
    public static final String URL_UNLIMIT_SQUARE = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={0}";
    //////////////////////////////////////////////////
    /** (小程序)通过code换取网页授权access_token/如果是snsapi_base模式的授权,这里就可以拿到openId了 ***/
    public static JSONObject getJscode2session(String appid,String secret,String code) {
        return HttpURLUtil(JSCODE2SESSION_URL+"appid="+appid+"&secret="+secret
                +"&grant_type=authorization_code&js_code=" + code,null);
    }
    /**发送订阅消息通知**/
    public static JSONObject sendSubscribeMessage(String data,String accessToken){
        return HttpURLUtil(SEND_SUBSCRIBE_MESSAGE+accessToken,data);
    }
    /** 获取access_token */
    public static JSONObject getAccessToken(String appid,String secret) throws Exception {
        String access_token;
        // 通过WX接口获取access_token
        JSONObject obj = getApplication_Access_tokenForUrl(appid,secret);
        return obj;
    }
    /** 从weixin接口获取Access_token **/
    public static JSONObject getApplication_Access_tokenForUrl(String appid,String secret) {
        return HttpURLUtil(GETACCESS_TOKENURL+GRANT_TYPE +"&appid="+appid +"&secret="+secret,null);
    }
    /**生成无限二维码,并上传到OSS*/
    public static String createUnlimitQrCode(String at, String scene, String page, int width, boolean autoColor,
                                             JSONObject lineColor, boolean isHyaline, String fileName, String keyId,
                                             String keySecret, String endPoint, String bucket)
    {
        String imgUrl = null;
        InputStream in = null;
        HttpURLConnection conn = null;
        try {
            //生成发送数据
            JSONObject obj = new JSONObject();
            obj.put("scene", scene);
            obj.put("width", width);
            obj.put("page", page);
            obj.put("auto_color", autoColor);
            obj.put("line_color", lineColor);
            obj.put("is_hyaline", isHyaline);
            // 创建url资源
            URL url = new URL(StringUtils.format(URL_UNLIMIT_SQUARE, at));
            // 建立http连接
            conn = (HttpURLConnection) url.openConnection();
            // 设置允许输出
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 设置不用缓存
            conn.setUseCaches(false);
            // 设置传递方式
            conn.setRequestMethod("POST");
            // 设置维持长连接
            conn.setRequestProperty("Connection", "Keep-Alive");
            // 设置文件字符集:
            conn.setRequestProperty("Charset", "UTF-8");
            // 设置文件类型:
            conn.setRequestProperty("contentType", "application/json");
            // 开始连接请求
            conn.connect();
            OutputStream out = conn.getOutputStream();
            // 写入请求的字符串
            out.write((obj.toString()).getBytes());
            out.flush();
            out.close();
            // 请求返回的状态
            if (conn.getResponseCode() == 200) {
                // 请求返回的数据
                in = conn.getInputStream();
                imgUrl = OSSUtil.uploadImg(fileName, in, keyId, keySecret, endPoint, bucket);
                conn.disconnect();
                conn = null;
            }
            if (in != null) {
                in.close();
                in = null;
            }
            if (conn != null) {
                conn.disconnect();
                conn = null;
            }
        }catch (Exception e)
        {
            e.printStackTrace();
            if (in != null) {
                try {
                    in.close();
                }catch (Exception ep)
                {
                    ep.printStackTrace();
                }
                in = null;
            }
            if (conn != null) {
                conn.disconnect();
                conn = null;
            }
        }
        return imgUrl;
    }
    /**生成小程序二维码工具(方形)
     * path 二维码跳转链接
     * width 二维码宽度,默认是430
     * saveUrl 保存图片的全路径
     * seeUrl 显示图片路径
     * appid 小程序配置
     * secret 小程序配置
     * return 二维码显示图片链接
     * @throws Exception
     * */
    public static String twoCodeImgSquare(String at, String path,Integer width,String saveUrl,
                                          String seeUrl,String appid,String secret) throws Exception {
        if(!SimpleTool.checkNotNull(width)) {
            width = 430;
        }
        //生成发送数据
        JSONObject obj = new JSONObject();
        obj.put("path", path);
        obj.put("width", width);
        //二维码图片路径
        String codeUrl = "";
        codeUrl = HttpURLUtilMakeCodeImg(MAKE_TWOCODE_SQUARE_URL+at,obj,saveUrl,seeUrl);
        if(SimpleTool.checkNotNull(codeUrl)){
            if(!codeUrl.startsWith("/")){
                codeUrl = "/"+codeUrl;
            }
        }
        return codeUrl;
    }
    public static String twoCodeImgSquare(String at, String path,Integer width, String fileName, String keyId,
                                          String keySecret, String endPoint, String bucket) throws Exception {
        if(!SimpleTool.checkNotNull(width)) {
            width = 430;
        }
        //生成发送数据
        JSONObject obj = new JSONObject();
        obj.put("path", path);
        obj.put("width", width);
        String imgUrl = null;
        InputStream in = null;
        HttpURLConnection conn = null;
        try {
            // 创建url资源
            URL url = new URL(MAKE_TWOCODE_SQUARE_URL + at);
            // 建立http连接
            conn = (HttpURLConnection) url.openConnection();
            // 设置允许输出
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 设置不用缓存
            conn.setUseCaches(false);
            // 设置传递方式
            conn.setRequestMethod("POST");
            // 设置维持长连接
            conn.setRequestProperty("Connection", "Keep-Alive");
            // 设置文件字符集:
            conn.setRequestProperty("Charset", "UTF-8");
            // 设置文件类型:
            conn.setRequestProperty("contentType", "application/json");
            // 开始连接请求
            conn.connect();
            OutputStream out = conn.getOutputStream();
            // 写入请求的字符串
            out.write((obj.toString()).getBytes());
            out.flush();
            out.close();
            // 请求返回的状态
            if (conn.getResponseCode() == 200) {
                // 请求返回的数据
                in = conn.getInputStream();
                imgUrl = OSSUtil.uploadImg(fileName, in, keyId, keySecret, endPoint, bucket);
                conn.disconnect();
                conn = null;
            }
            if (in != null) {
                in.close();
                in = null;
            }
            if (conn != null) {
                conn.disconnect();
                conn = null;
            }
        }catch (Exception e)
        {
            e.printStackTrace();
            if (in != null) {
                try {
                    in.close();
                }catch (Exception ep)
                {
                    ep.printStackTrace();
                }
                in = null;
            }
            if (conn != null) {
                conn.disconnect();
                conn = null;
            }
        }
        return imgUrl;
    }
    /** 生成二维码的图片 返回图片路径
     * urlx 执行链接
     * objx 数据
     * saveUrl 保存图片路径
     * seeUrl 显示图片路径
     *
     *  **/
    public static String HttpURLUtilMakeCodeImg(String urlx,JSONObject objx,String saveUrl,String seeUrl) throws IOException {
        String realpath = null;
        // 创建url资源
        URL url = new URL(urlx);
        // 建立http连接
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        // 设置允许输出
        conn.setDoOutput(true);
        conn.setDoInput(true);
        // 设置不用缓存
        conn.setUseCaches(false);
        // 设置传递方式
        conn.setRequestMethod("POST");
        // 设置维持长连接
        conn.setRequestProperty("Connection", "Keep-Alive");
        // 设置文件字符集:
        conn.setRequestProperty("Charset", "UTF-8");
        // 转换为字节数组
        // byte[] data = (objx.toString()).getBytes();
        // 设置文件长度
        // conn.setRequestProperty("Content-Length",String.valueOf(data.length));
        // 设置文件类型:
        conn.setRequestProperty("contentType", "application/json");
        // 开始连接请求
        conn.connect();
        OutputStream out = conn.getOutputStream();
        // 写入请求的字符串
        out.write((objx.toString()).getBytes());
        out.flush();
        out.close();
        // 请求返回的状态
        if (conn.getResponseCode() == 200) {
            System.out.println("连接成功");
            // 请求返回的数据
            InputStream in = conn.getInputStream();
            ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
            byte[] temp = new byte[1024];
            int rc = 0;
            while ((rc = in.read(temp, 0, 100)) > 0) {
                swapStream.write(temp, 0, rc);
            }
            byte[] buffer2 = swapStream.toByteArray();
            String base64 = Base64.encodeBase64String(buffer2);
            //生成名称
            java.util.Random r=new java.util.Random();
            StringBuilder str=new StringBuilder();//定义变长字符串
            for(int i=0;i<8;i++){
                str.append(r.nextInt(10));
            }
            Date date = new Date();
            SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
            String imgName = sf.format(date);
            imgName = imgName+str.toString();
            //文件保存位置
            File saveDir = new File(saveUrl);
            if(!saveDir.exists()){
                saveDir.mkdir();
            }
            File file = new File(saveDir+"/"+imgName+".png");
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(buffer2);
            if(fos!=null){
                fos.close();
            }
            if(in!=null){
                in.close();
            }
            realpath = seeUrl+"/"+imgName+".png";
        } else {
            System.out.println("no++");
        }
        return realpath;
    }
    /** 请求http协议 获取信息工具 **/
    private static JSONObject HttpURLUtil(String url,String data) {
        HttpURLConnection con = null;
        URL u;
        String wxMsgXml;
        JSONObject obj;
        try {
            u = new URL(url);
            con = (HttpURLConnection) u.openConnection();
            con.setRequestMethod("POST");
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setUseCaches(false);
            con.setReadTimeout(5000);
            con.setRequestProperty("Charset", "UTF-8");
            con.setRequestProperty("Content-Type",
                    "application/x-www-form-urlencoded");
            if (data != null) {
                OutputStream os = con.getOutputStream();
                os.write(data.getBytes("utf-8"));
            }
            if (con.getResponseCode() != 200)
                throw new RuntimeException("请求url失败");
            // 读取返回内容
            wxMsgXml = IOUtils.toString(con.getInputStream(), StandardCharsets.UTF_8);
            // 判断返回参数是否正确/成功
            obj = JSONObject.fromObject(wxMsgXml);
            // System.out.println("HttpURLUtil:"+wxMsgXml);
        } catch (Exception e) {
            e.printStackTrace();
            obj = new JSONObject();
            try {
                obj.put("status", 1);
                obj.put("errMsg", e.getMessage());
            } catch (JSONException e1) {
                e1.printStackTrace();
            }
        } finally {
            if (con != null) {
                con.disconnect();
            }
        }
        return obj;
    }
}
src/main/java/com/hx/mp/util/MpUtil.java
New file
@@ -0,0 +1,357 @@
package com.hx.mp.util;
import com.hx.util.StringUtils;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.Timestamp;
import java.text.MessageFormat;
import java.util.Date;
/**
 * 微信小程序工具类
 */
public class MpUtil {
    /** 请求access_token */
    public static final String URL_ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";
    /** 请求服务器IP地址 */
    public static final String URL_SERVER_ADDR = "https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=";
    /** 微信js的code换去sessionKey */
    public static final String JSCODE2SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&grant_type=authorization_code&js_code=";
    /** 请求小程序码 **/
    public static final String URL_WXACODE = "https://api.weixin.qq.com/wxa/getwxacode?access_token=";
    /** 请求小程序码-无数量限制 **/
    public static final String URL_WXACODEUNLIMIT = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=";
    /** 请求小程序二维码 */
    public static final String URL_QRCODE = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=";
    /** 发模版消息 */
    public static final String URL_SEND_TEMP_MSG = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=";
    /** 设置发票授权字段 */
    public static final String URL_SET_TICKET_FIELD = "https://api.weixin.qq.com/card/invoice/setbizattr?action=set_auth_field&access_token=";
    /** 获取发票ticket */
    public static final String URL_GET_TICKET_TICKET = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=wx_card&access_token=";
    /** 获取发票授权页链接 */
    public static final String URL_GET_TICKET_AUTH_LINK = "https://api.weixin.qq.com/card/invoice/getauthurl?access_token=";
    /** 查询发票授权字段 */
    public static final String URL_GET_AUTH_FIELD = "https://api.weixin.qq.com/card/invoice/getauthdata?access_token=";
    /** 设置 支付后开发票 */
    public static final String URL_SET_PAY_INVOICE = "https://api.weixin.qq.com/card/invoice/setbizattr?action=set_pay_mch&access_token=";
    /** 查询支付后开发票 */
    public static final String URL_GET_PAY_INVOICE = "https://api.weixin.qq.com/card/invoice/setbizattr?action=get_pay_mch&access_token=";
    /** 发送客服消息 */
    public static final String URL_SEND_KF_MSG = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=";
    /*************************************************
     * 小程序
     *************************/
    /** 利用code换取sessionKey */
    public static JSONObject jsCode2session(String code, String appId, String appSecret) {
        JSONObject obj = new JSONObject();
        String url = StringUtils.format(JSCODE2SESSION_URL, appId, appSecret) + code;
        obj = HttpURLUtil(url, null);
        return obj;
    }
    /** 获取小程序二维码图片 */
    public static String getQrCode(String accessToken, String jsonParam)
            throws Exception {
        JSONObject obj = HttpURLUtilJson(URL_QRCODE + accessToken, jsonParam);
        String qrStr = obj.optString("data");
        return qrStr;
    }
    /** 从weixin接口获取Access_token **/
    public static JSONObject getApplication_Access_tokenForUrl(String appId, String appSecret)
            throws Exception {
        String url = MessageFormat.format(URL_ACCESS_TOKEN, appId, appSecret);
        JSONObject obj = HttpURLUtil(url, null);
        return obj;
    }
    /** 请求http协议 获取信息工具 **/
    public static InputStream HttpURLUtilStream(String url, String data) {
        HttpURLConnection con = null;
        URL u = null;
        try {
            u = new URL(url);
            con = (HttpURLConnection) u.openConnection();
            con.setRequestMethod("POST");
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setUseCaches(false);
            con.setReadTimeout(200000);
            con.setRequestProperty("Charset", "UTF-8");
            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            if (data != null) {
                OutputStream os = con.getOutputStream();
                os.write(data.getBytes("utf-8"));
            }
            if (con.getResponseCode() != 200)
                throw new RuntimeException("请求url失败");
            return con.getInputStream();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (con != null) {
                con.disconnect();
            }
        }
        return null;
    }
    /** 获取二维码图片 **/
    public static JSONObject HttpURLUtilJson(String urlx, String objx) {
        JSONObject jo = new JSONObject();
        try {
            // 创建url资源
            URL url = new URL(urlx);
            // 建立http连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            // 设置允许输出
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 设置不用缓存
            conn.setUseCaches(false);
            // 设置传递方式
            conn.setRequestMethod("POST");
            // 设置维持长连接
            conn.setRequestProperty("Connection", "Keep-Alive");
            // 设置文件字符集:
            conn.setRequestProperty("Charset", "UTF-8");
            // 设置文件类型:
            conn.setRequestProperty("contentType", "application/json");
            // 开始连接请求
            conn.connect();
            OutputStream out = conn.getOutputStream();
            // 写入请求的字符串
            out.write(objx.getBytes());
            out.flush();
            out.close();
            // 请求返回的状态
            if (conn.getResponseCode() == 200) {
                // 请求返回的数据
                InputStream in = conn.getInputStream();
                try {
                    ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
                    byte[] temp = new byte[1024];
                    int rc = 0;
                    while ((rc = in.read(temp, 0, 100)) > 0) {
                        swapStream.write(temp, 0, rc);
                    }
                    byte[] buffer = swapStream.toByteArray();
                    String base64 = Base64.encodeBase64String(buffer);
                    jo.put("data", base64);
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            } else {
                // System.out.println("no++");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return jo;
    }
    /** 请求http协议 获取信息工具 **/
    public static JSONObject HttpURLUtil(String url, String data) {
        HttpURLConnection con = null;
        URL u = null;
        String wxMsgXml = null;
        JSONObject obj = null;
        try {
            u = new URL(url);
            con = (HttpURLConnection) u.openConnection();
            con.setRequestMethod("POST");
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setUseCaches(false);
            con.setReadTimeout(5000);
            con.setRequestProperty("Charset", "UTF-8");
            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            if (data != null) {
                OutputStream os = con.getOutputStream();
                os.write(data.getBytes("utf-8"));
            }
            if (con.getResponseCode() != 200)
                throw new RuntimeException("请求url失败");
            // 读取返回内容
            wxMsgXml = IOUtils.toString(con.getInputStream(), "utf-8");
            obj = JSONObject.fromObject(wxMsgXml);
            // //System.out.println("HttpURLUtil:"+wxMsgXml);
        } catch (Exception e) {
            e.printStackTrace();
            obj = new JSONObject();
            try {
                obj.put("status", 1);
                obj.put("errMsg", e.getMessage());
            } catch (JSONException e1) {
                e1.printStackTrace();
            }
        } finally {
            if (con != null) {
                con.disconnect();
            }
        }
        return obj;
    }
    /** 发送模版消息 **/
    public static JSONObject sendTempMsg(String accessToken, String jsonStr) {
        JSONObject obj = HttpURLUtil(URL_SEND_TEMP_MSG + accessToken, jsonStr);
        return obj;
    }
    public static Integer DateToTimestamp(Date time) {
        Timestamp ts = new Timestamp(time.getTime());
        return (int) ((ts.getTime()) / 1000);
    }
    /**
     * 发送链接客服消息
     *
     * @throws JSONException
     */
    public static String sendKfLinkMsg(String at, String openId, String title, String description, String url,
                                       String imgUrl) throws JSONException {
        String result = "fail";
        JSONObject obj = new JSONObject();
        obj.put("touser", openId);
        obj.put("msgtype", "link");
        JSONObject pObj = new JSONObject();
        pObj.put("title", title);
        pObj.put("description", description);
        pObj.put("url", url);
        pObj.put("thumb_url", imgUrl);
        obj.put("link", pObj);
        JSONObject rObj = HttpURLUtil(URL_SEND_KF_MSG + at, obj.toString());
        // System.out.println("rObj==="+rObj);
        if (rObj != null) {
            if (rObj.optInt("errcode", -1) == 0) {
                result = "suc";
            } else {
                result = rObj.optString("errmsg");
            }
        }
        rObj = null;
        obj = null;
        return result;
    }
    /**
     * 发送图片客户消息
     *
     * @param access_token
     *            access_token
     * @param toUser
     *            用户openid
     * @param media_id
     *            素材id
     * @return
     */
    public static String sendKfImageMsg(String access_token, String toUser, String media_id) {
        String result = "fail";
        try {
            JSONObject obj = new JSONObject();
            obj.put("touser", toUser);
            obj.put("msgtype", "image");
            JSONObject pObj = new JSONObject();
            pObj.put("media_id", media_id);
            obj.put("image", pObj);
            JSONObject rObj = HttpURLUtil(URL_SEND_KF_MSG + access_token, obj.toString());
            System.out.println("rObj==" + rObj.toString());
            if (rObj != null) {
                if (rObj.optInt("errcode", -1) == 0) {
                    result = "suc";
                } else {
                    result = rObj.optString("errmsg");
                }
            }
            rObj = null;
            obj = null;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    /**
     * 发送文本客户消息
     *
     * @param access_token
     *            access_token
     * @param toUser
     *            用户openid
     * @return
     */
    public static String sendKfTextMsg(String access_token, String toUser, String content) {
        String result = "fail";
        try {
            JSONObject obj = new JSONObject();
            obj.put("touser", toUser);
            obj.put("msgtype", "text");
            JSONObject pObj = new JSONObject();
            pObj.put("content", content);
            obj.put("text", pObj);
            JSONObject rObj = HttpURLUtil(URL_SEND_KF_MSG + access_token, obj.toString());
            if (rObj != null) {
                if (rObj.optInt("errcode", -1) == 0) {
                    result = "suc";
                } else {
                    result = rObj.optString("errmsg");
                }
            }
            rObj = null;
            obj = null;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    /** 获取小程序码图片 */
    public static String getWXACode(String accessToken, String jsonParam, String path)
            throws Exception {
        JSONObject obj = HttpURLUtilJson(URL_WXACODE + accessToken, jsonParam);
        String qrStr = obj.optString("data");
        return qrStr;
    }
    /** 获取小程序码图片 */
    public static String getWXACodeUnlimit(String accessToken, String jsonParam, String path)
            throws Exception {
        JSONObject obj = HttpURLUtilJson(URL_WXACODEUNLIMIT + accessToken, jsonParam);
        String qrStr = obj.optString("data");
        return qrStr;
    }
}
src/main/java/com/hx/mp/util/RequestHandler.java
New file
@@ -0,0 +1,273 @@
package com.hx.mp.util;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * �������� ��������̳д��࣬��дcreateSign�������ɡ�
 *JX
 *linhan
 */
public class RequestHandler {
    /** ���url��ַ */
    private String gateUrl;
    /** ��Կ */
    private String key;
    /** ����IJ��� */
    @SuppressWarnings("rawtypes")
    private SortedMap parameters;
    /** debug��Ϣ */
    private String debugInfo;
    private HttpServletRequest request;
    private HttpServletResponse response;
    /**
     * ���캯��
     *
     * @param request
     * @param response
     */
    /*@SuppressWarnings("rawtypes")
    public RequestHandler(HttpServletRequest request,
            HttpServletResponse response) {
        this.request = request;
        this.response = response;
        this.gateUrl = "https://gw.tenpay.com/gateway/pay.htm";
        this.key = "";
        this.parameters = new TreeMap();
        this.debugInfo = "";
    }*/
    /**
     * ���캯��
     * @param request
     * @param response
     */
    public RequestHandler(HttpServletRequest request, HttpServletResponse response) {
        this.request = request;
        this.response = response;
        this.gateUrl = "https://gw.tenpay.com/gateway/pay.htm";
        this.key = "";
        this.parameters = new TreeMap();
        this.debugInfo = "";
    }
    /**
     * ��ʼ������
     */
    public void init() {
        // nothing to do
    }
    /**
     * ��ȡ��ڵ�ַ,�������ֵ
     */
    public String getGateUrl() {
        return gateUrl;
    }
    /**
     * ������ڵ�ַ,�������ֵ
     */
    public void setGateUrl(String gateUrl) {
        this.gateUrl = gateUrl;
    }
    /**
     * ��ȡ��Կ
     */
    public String getKey() {
        return key;
    }
    /**
     * 秘钥
     */
    public void setKey(String key) {
        this.key = key;
    }
    /**
     * ��ȡ����ֵ
     *
     * @param parameter
     *            �������
     * @return String
     */
    public String getParameter(String parameter) {
        String s = (String) this.parameters.get(parameter);
        return (null == s) ? "" : s;
    }
    /**
     * ���ò���ֵ
     *
     * @param parameter
     *            �������
     * @param parameterValue
     *            ����ֵ
     */
    @SuppressWarnings("unchecked")
    public void setParameter(String parameter, String parameterValue) {
        String v = "";
        if (null != parameterValue) {
            v = parameterValue.trim();
        }
        this.parameters.put(parameter, v);
    }
    /**
     * �������еIJ���
     *
     * @return SortedMap
     */
    @SuppressWarnings("rawtypes")
    public SortedMap getAllParameters() {
        return this.parameters;
    }
    /**
     * ��ȡdebug��Ϣ
     */
    public String getDebugInfo() {
        return debugInfo;
    }
    /**
     * ��ȡ����������URL
     *
     * @return String
     * @throws UnsupportedEncodingException
     */
    /*@SuppressWarnings("rawtypes")
    public String getRequestURL() throws UnsupportedEncodingException {
        this.createSign();
        StringBuffer sb = new StringBuffer();
        String enc = TenpayUtil.getCharacterEncoding(this.request,
                this.response);
        Set es = this.parameters.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (!"spbill_create_ip".equals(k)) {
                sb.append(k + "=" + URLEncoder.encode(v, enc) + "&");
            } else {
                sb.append(k + "=" + v.replace(".", "%2E") + "&");
            }
        }
        // ȥ�����һ��&
        String reqPars = sb.substring(0, sb.lastIndexOf("&"));
        return this.getGateUrl() + "?" + reqPars;
    }*/
    /**
     * ��ȡ����������URL
     * @return String
     * @throws UnsupportedEncodingException
     */
    public String getRequestURL() throws UnsupportedEncodingException {
        this.createSign();
        StringBuffer sb = new StringBuffer();
        String enc = TenpayUtil.getCharacterEncoding(this.request, this.response);
        Set es = this.parameters.entrySet();
        Iterator it = es.iterator();
        while(it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            String k = (String)entry.getKey();
            String v = (String)entry.getValue();
            if(!"spbill_create_ip".equals(k)) {
                sb.append(k + "=" + URLEncoder.encode(v, enc) + "&");
            } else {
                sb.append(k + "=" + v.replace(".", "%2E") + "&");
            }
        }
        //ȥ�����һ��&
        String reqPars = sb.substring(0, sb.lastIndexOf("&"));
        return this.getGateUrl() + "?" + reqPars;
    }
    public void doSend() throws UnsupportedEncodingException, IOException {
        this.response.sendRedirect(this.getRequestURL());
    }
    /**
     * TODO 生成签名
     */
    @SuppressWarnings("rawtypes")
    public String createSign() {
        StringBuffer sb = new StringBuffer();
        Set es = this.parameters.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (null != v && !"".equals(v) && !"sign".equals(k)
                    && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + this.getKey());
System.out.println("sb="+sb);
        String enc = TenpayUtil.getCharacterEncoding(this.request,
                this.response);
        String sign = MD5Util.MD5Encode(sb.toString(), enc).toUpperCase();
        this.setParameter("sign", sign);
        // debug��Ϣ
        this.setDebugInfo(sb.toString() + " => sign:" + sign);
        return sign;
    }
    /**
     * ����debug��Ϣ
     */
    protected void setDebugInfo(String debugInfo) {
        this.debugInfo = debugInfo;
    }
    protected HttpServletRequest getHttpServletRequest() {
        return this.request;
    }
    protected HttpServletResponse getHttpServletResponse() {
        return this.response;
    }
}
src/main/java/com/hx/mp/util/ResponseHandler.java
New file
@@ -0,0 +1,225 @@
package com.hx.mp.util;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * Ӧ������ Ӧ������̳д��࣬��дisTenpaySign�������ɡ�
 *JX
 *linhan
 */
public class ResponseHandler {
    /** ��Կ */
    private String key;
    /** Ӧ��IJ��� */
    @SuppressWarnings("rawtypes")
    private SortedMap parameters;
    /** debug��Ϣ */
    private String debugInfo;
    private HttpServletRequest request;
    private HttpServletResponse response;
    private String uriEncoding;
    /**
     * ���캯��
     *
     * @param request
     * @param response
     */
    @SuppressWarnings("rawtypes")
    public ResponseHandler(HttpServletRequest request,
            HttpServletResponse response) {
        this.request = request;
        this.response = response;
        this.key = "";
        this.parameters = new TreeMap();
        this.debugInfo = "";
        this.uriEncoding = "";
        Map m = this.request.getParameterMap();
        Iterator it = m.keySet().iterator();
        while (it.hasNext()) {
            String k = (String) it.next();
            String v = ((String[]) m.get(k))[0];
            this.setParameter(k, v);
        }
    }
    /**
     * ��ȡ��Կ
     */
    public String getKey() {
        return key;
    }
    /**
     * ������Կ
     */
    public void setKey(String key) {
        this.key = key;
    }
    /**
     * ��ȡ����ֵ
     *
     * @param parameter
     *            �������
     * @return String
     */
    public String getParameter(String parameter) {
        String s = (String) this.parameters.get(parameter);
        return (null == s) ? "" : s;
    }
    /**
     * ���ò���ֵ
     *
     * @param parameter
     *            �������
     * @param parameterValue
     *            ����ֵ
     */
    @SuppressWarnings("unchecked")
    public void setParameter(String parameter, String parameterValue) {
        String v = "";
        if (null != parameterValue) {
            v = parameterValue.trim();
        }
        this.parameters.put(parameter, v);
    }
    /**
     * �������еIJ���
     *
     * @return SortedMap
     */
    @SuppressWarnings("rawtypes")
    public SortedMap getAllParameters() {
        return this.parameters;
    }
    /**
     * �Ƿ�Ƹ�ͨǩ��,������:���������a-z����,������ֵ�IJ���μ�ǩ��
     *
     * @return boolean
     */
    @SuppressWarnings("rawtypes")
    public boolean isTenpaySign() {
        StringBuffer sb = new StringBuffer();
        Set es = this.parameters.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (!"sign".equals(k) && null != v && !"".equals(v)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + this.getKey());
        // ���ժҪ
        String enc = TenpayUtil.getCharacterEncoding(this.request,
                this.response);
        String sign = MD5Util.MD5Encode(sb.toString(), enc).toLowerCase();
        String tenpaySign = this.getParameter("sign").toLowerCase();
        // debug��Ϣ
        this.setDebugInfo(sb.toString() + " => sign:" + sign + " tenpaySign:"
                + tenpaySign);
        return tenpaySign.equals(sign);
    }
    /**
     * ���ش������Ƹ�ͨ��������
     *
     * @param msg
     *            : Success or fail��
     * @throws IOException
     */
    public void sendToCFT(String msg) throws IOException {
        String strHtml = msg;
        PrintWriter out = this.getHttpServletResponse().getWriter();
        out.println(strHtml);
        out.flush();
        out.close();
    }
    /**
     * ��ȡuri����
     *
     * @return String
     */
    public String getUriEncoding() {
        return uriEncoding;
    }
    /**
     * ����uri����
     *
     * @param uriEncoding
     * @throws UnsupportedEncodingException
     */
    @SuppressWarnings("rawtypes")
    public void setUriEncoding(String uriEncoding)
            throws UnsupportedEncodingException {
        if (!"".equals(uriEncoding.trim())) {
            this.uriEncoding = uriEncoding;
            // ����ת��
            String enc = TenpayUtil.getCharacterEncoding(request, response);
            Iterator it = this.parameters.keySet().iterator();
            while (it.hasNext()) {
                String k = (String) it.next();
                String v = this.getParameter(k);
                v = new String(v.getBytes(uriEncoding.trim()), enc);
                this.setParameter(k, v);
            }
        }
    }
    /**
     * ��ȡdebug��Ϣ
     */
    public String getDebugInfo() {
        return debugInfo;
    }
    /**
     * ����debug��Ϣ
     */
    protected void setDebugInfo(String debugInfo) {
        this.debugInfo = debugInfo;
    }
    protected HttpServletRequest getHttpServletRequest() {
        return this.request;
    }
    protected HttpServletResponse getHttpServletResponse() {
        return this.response;
    }
}
src/main/java/com/hx/mp/util/TenpayHttpClient.java
New file
@@ -0,0 +1,559 @@
package com.hx.mp.util;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
/**
 * �Ƹ�ͨhttp����https����ͨ�ſͻ���<br/>
 * ========================================================================<br/>
 * api˵����<br/>
 * setReqContent($reqContent),�����������ݣ�����post��get������get��ʽ�ṩ<br/>
 * getResContent(), ��ȡӦ������<br/>
 * setMethod(method),�������󷽷�,post����get<br/>
 * getErrInfo(),��ȡ������Ϣ<br/>
 * setCertInfo(certFile, certPasswd),����֤�飬˫��httpsʱ��Ҫʹ��<br/>
 * setCaInfo(caFile), ����CA����ʽδpem���������򲻼��<br/>
 * setTimeOut(timeOut)�� ���ó�ʱʱ�䣬��λ��<br/>
 * getResponseCode(), ȡ���ص�http״̬��<br/>
 * call(),������ýӿ�<br/>
 * getCharset()/setCharset(),�ַ����<br/>
 *
 * ========================================================================<br/>
 *
 */
public class TenpayHttpClient {
    private static final String USER_AGENT_VALUE =
        "Mozilla/4.0 (compatible; MSIE 6.0; Windows XP)";
    private static final String JKS_CA_FILENAME =
        "tenpay_cacert.jks";
    private static final String JKS_CA_ALIAS = "tenpay";
    private static final String JKS_CA_PASSWORD = "";
    /** ca֤���ļ� */
    private File caFile;
    /** ֤���ļ� */
    private File certFile;
    /** ֤������ */
    private String certPasswd;
    /** �������ݣ�����post��get������get��ʽ�ṩ */
    private String reqContent;
    /** Ӧ������ */
    private String resContent;
    /** ���󷽷� */
    private String method;
    /** ������Ϣ */
    private String errInfo;
    /** ��ʱʱ��,����Ϊ��λ */
    private int timeOut;
    /** httpӦ����� */
    private int responseCode;
    /** �ַ���� */
    private String charset;
    private InputStream inputStream;
    private RequestHandler reqHandler;//方便取值所用(quan)
    /*public TenpayHttpClient() {
        this.caFile = null;
        this.certFile = null;
        this.certPasswd = "";
        this.reqContent = "";
        this.resContent = "";
        this.method = "POST";
        this.errInfo = "";
        this.timeOut = 30;//30��
        this.responseCode = 0;
        this.charset = "UTF-8";
        this.inputStream = null;
    }*/
    public TenpayHttpClient() {
        this.caFile = null;
        this.certFile = null;
        this.certPasswd = "";
        this.reqContent = "";
        this.resContent = "";
        this.method = "POST";
        this.errInfo = "";
        this.timeOut = 30;//30��
        this.responseCode = 0;
        this.charset = "UTF-8";
        this.inputStream = null;
    }
    /**
     * ����֤����Ϣ
     * @param certFile ֤���ļ�
     * @param certPasswd ֤������
     */
    public void setCertInfo(File certFile, String certPasswd) {
        this.certFile = certFile;
        this.certPasswd = certPasswd;
    }
    /**
     * ����ca
     * @param caFile
     */
    public void setCaInfo(File caFile) {
        this.caFile = caFile;
    }
    /**
     * ������������
     * @param reqContent ��������
     */
    public void setReqContent(String reqContent) {
        this.reqContent = reqContent;
    }
    /**
     * ��ȡ�������
     * @return String
     * @throws IOException
     */
    public String getResContent() {
        try {
            this.doResponse();
        } catch (IOException e) {
            this.errInfo = e.getMessage();
            //return "";
        }
        return this.resContent;
    }
    /**
     * �������󷽷�post����get
     * @param method ���󷽷�post/get
     */
    public void setMethod(String method) {
        this.method = method;
    }
    /**
     * ��ȡ������Ϣ
     * @return String
     */
    public String getErrInfo() {
        return this.errInfo;
    }
    /**
     * ���ó�ʱʱ��,����Ϊ��λ
     * @param timeOut ��ʱʱ��,����Ϊ��λ
     */
    public void setTimeOut(int timeOut) {
        this.timeOut = timeOut;
    }
    /**
     * ��ȡhttp״̬��
     * @return int
     */
    public int getResponseCode() {
        return this.responseCode;
    }
    /**
     * ִ��http���á�true:�ɹ� false:ʧ��
     * @return boolean
     */
/*    public boolean call() {
        boolean isRet = false;
        //http
        if(null == this.caFile && null == this.certFile) {
            System.out.println("没有CA");
            try {
                this.callHttp();
                isRet = true;
            } catch (IOException e) {
                this.errInfo = e.getMessage();
            }
            return isRet;
        }
        //https
        try {
            this.callHttps();
            isRet = true;
        } catch (UnrecoverableKeyException e) {
            this.errInfo = e.getMessage();
        } catch (KeyManagementException e) {
            this.errInfo = e.getMessage();
        } catch (CertificateException e) {
            this.errInfo = e.getMessage();
        } catch (KeyStoreException e) {
            this.errInfo = e.getMessage();
        } catch (NoSuchAlgorithmException e) {
            this.errInfo = e.getMessage();
        } catch (IOException e) {
            this.errInfo = e.getMessage();
        }
        return isRet;
    }*/
    /**
     * ִ��http���á�true:�ɹ� false:ʧ��
     * @return boolean
     */
    public boolean call() {
        boolean isRet = false;
        //http
        if(null == this.caFile && null == this.certFile) {
            System.out.println("没有CA");
            try {
                this.callHttp();
                isRet = true;
            } catch (IOException e) {
                this.errInfo = e.getMessage();
            }
            return isRet;
        }
        //https
        try {
            this.callHttps();
            isRet = true;
        } catch (UnrecoverableKeyException e) {
            this.errInfo = e.getMessage();
        } catch (KeyManagementException e) {
            this.errInfo = e.getMessage();
        } catch (CertificateException e) {
            this.errInfo = e.getMessage();
        } catch (KeyStoreException e) {
            this.errInfo = e.getMessage();
        } catch (NoSuchAlgorithmException e) {
            this.errInfo = e.getMessage();
        } catch (IOException e) {
            this.errInfo = e.getMessage();
        }
        return isRet;
    }
    protected void callHttp() throws IOException {
        if("POST".equals(this.method.toUpperCase())) {
            String url = HttpClientUtil.getURL(this.reqContent);
            System.out.println("tenpayHttpClient:url:"+url);
            //String queryString = HttpClientUtil.getQueryString(this.reqContent);
            //byte[] postData = queryString.getBytes(this.charset);
            String queryString = createXmlPosData();
            byte[] postData = queryString.getBytes(this.charset);
            this.httpPostMethod(url, postData);
            return ;
        }
        this.httpGetMethod(this.reqContent);
    }
    protected void callHttps() throws IOException, CertificateException,
            KeyStoreException, NoSuchAlgorithmException,
            UnrecoverableKeyException, KeyManagementException {
        // caĿ¼
        String caPath = this.caFile.getParent();
        System.out.println("caPath:"+caPath);
        File jksCAFile = new File(caPath + "/"
                + TenpayHttpClient.JKS_CA_FILENAME);
        if (!jksCAFile.isFile()) {
            X509Certificate cert = (X509Certificate) HttpClientUtil
                    .getCertificate(this.caFile);
            FileOutputStream out = new FileOutputStream(jksCAFile);
            // store jks file
            HttpClientUtil.storeCACert(cert, TenpayHttpClient.JKS_CA_ALIAS,
                    TenpayHttpClient.JKS_CA_PASSWORD, out);
            out.close();
        }
        FileInputStream trustStream = new FileInputStream(jksCAFile);
        FileInputStream keyStream = new FileInputStream(this.certFile);
        SSLContext sslContext = HttpClientUtil.getSSLContext(trustStream,
                TenpayHttpClient.JKS_CA_PASSWORD, keyStream, this.certPasswd);
        //�ر���
        keyStream.close();
        trustStream.close();
        if("POST".equals(this.method.toUpperCase())) {
            String url = HttpClientUtil.getURL(this.reqContent);
            //原本是直接参数转为字节数组的,现在组拼xml
            //String queryString = HttpClientUtil.getQueryString(this.reqContent);//获取链接下面的内容
            //byte[] postData = queryString.getBytes(this.charset);//把参数转为字节数组
            //先获取参数
            String queryString = createXmlPosData();
            byte[] postData = queryString.getBytes(this.charset);//把参数转为字节数组
            this.httpsPostMethod(url, postData, sslContext);
            return ;
        }
        this.httpsGetMethod(this.reqContent, sslContext);
    }
    /**
     * ��http post��ʽͨ��
     * @param url
     * @param postData
     * @throws IOException
     */
    protected void httpPostMethod(String url, byte[] postData)
            throws IOException {
        HttpURLConnection conn = HttpClientUtil.getHttpURLConnection(url);
        this.doPost(conn, postData);
    }
    /**
     * ��http get��ʽͨ��
     *
     * @param url
     * @throws IOException
     */
    protected void httpGetMethod(String url) throws IOException {
        HttpURLConnection httpConnection =
            HttpClientUtil.getHttpURLConnection(url);
        this.setHttpRequest(httpConnection);
        httpConnection.setRequestMethod("GET");
        this.responseCode = httpConnection.getResponseCode();
        this.inputStream = httpConnection.getInputStream();
    }
    /**
     * ��https get��ʽͨ��
     * @param url
     * @param sslContext
     * @throws IOException
     */
    protected void httpsGetMethod(String url, SSLContext sslContext)
            throws IOException {
        SSLSocketFactory sf = sslContext.getSocketFactory();
        HttpsURLConnection conn = HttpClientUtil.getHttpsURLConnection(url);
        conn.setSSLSocketFactory(sf);
        this.doGet(conn);
    }
    //提交https post 数据 s
    protected void httpsPostMethod(String url, byte[] postData,
            SSLContext sslContext) throws IOException {
        SSLSocketFactory sf = sslContext.getSocketFactory();
        HttpsURLConnection conn = HttpClientUtil.getHttpsURLConnection(url);
        conn.setSSLSocketFactory(sf);
        this.doPost(conn, postData);
    }
    /**
     * ����http����Ĭ������
     * @param httpConnection
     */
    protected void setHttpRequest(HttpURLConnection httpConnection) {
        //�������ӳ�ʱʱ��
        httpConnection.setConnectTimeout(this.timeOut * 1000);
        //User-Agent
        httpConnection.setRequestProperty("User-Agent",
                TenpayHttpClient.USER_AGENT_VALUE);
        //��ʹ�û���
        httpConnection.setUseCaches(false);
        //�����������
        httpConnection.setDoInput(true);
        httpConnection.setDoOutput(true);
    }
    /**
     * ����Ӧ��
     * @throws IOException
     */
    protected void doResponse() throws IOException {
        if(null == this.inputStream) {
            return;
        }
        //��ȡӦ������
        this.resContent=HttpClientUtil.InputStreamTOString(this.inputStream,this.charset);
    //    System.out.println("tenpayHttpClinet:385:"+resContent);
        //�ر�������
        this.inputStream.close();
    }
    /**
     * post��ʽ����
     * @param conn
     * @param postData
     * @throws IOException
     */
    protected void doPost(HttpURLConnection conn, byte[] postData)
            throws IOException {
        // ��post��ʽͨ��
        conn.setRequestMethod("POST");
        // ��������Ĭ������
        this.setHttpRequest(conn);
        // Content-Type
        conn.setRequestProperty("Content-Type",
                "application/x-www-form-urlencoded");
        BufferedOutputStream out = new BufferedOutputStream(conn
                .getOutputStream());
        final int len = 1024; // 1KB
        HttpClientUtil.doOutput(out, postData, len);
        // �ر���
        out.close();
        // ��ȡ��Ӧ����״̬��
        this.responseCode = conn.getResponseCode();
        // ��ȡӦ��������
        this.inputStream = conn.getInputStream();
    }
    /**
     * get��ʽ����
     * @param conn
     * @throws IOException
     */
    protected void doGet(HttpURLConnection conn) throws IOException {
        //��GET��ʽͨ��
        conn.setRequestMethod("GET");
        //��������Ĭ������
        this.setHttpRequest(conn);
        //��ȡ��Ӧ����״̬��
        this.responseCode = conn.getResponseCode();
        //��ȡӦ��������
        this.inputStream = conn.getInputStream();
    }
    public void setRequestHandler(RequestHandler reqHandler) {
        this.reqHandler = reqHandler;
    }
    //组建xml格式传递参数
    @SuppressWarnings({ "rawtypes", "unused" })
    public String createXmlPosData(){
        //先获取参数
        Document document = DocumentHelper.createDocument();
        Element root = document.addElement("xml");
        if(reqHandler==null)throw new RuntimeException("请先设入reqHandler");
        SortedMap parameters = reqHandler.getAllParameters();
        Set es = reqHandler.getAllParameters().entrySet();
        Iterator it = es.iterator();
        while(it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            String k = (String)entry.getKey();
            String v = (String)entry.getValue();
            Element ToUserName = root.addElement(k);
            ToUserName.addText(v);
        }
        String queryString = document.asXML();//转为String
        queryString = queryString.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "").trim();
        System.out.println("xml:"+queryString);
        return queryString;
    }
}
src/main/java/com/hx/mp/util/TenpayUtil.java
New file
@@ -0,0 +1,132 @@
package com.hx.mp.util;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TenpayUtil {
    /**
     * �Ѷ���ת�����ַ�
     * @param obj
     * @return String ת�����ַ�,������Ϊnull,�򷵻ؿ��ַ�.
     */
    public static String toString(Object obj) {
        if(obj == null)
            return "";
        return obj.toString();
    }
    /**
     * �Ѷ���ת��Ϊint��ֵ.
     *
     * @param obj
     *            �����ֵĶ���.
     * @return int ת�������ֵ,�Բ���ת���Ķ��󷵻�0��
     */
    public static int toInt(Object obj) {
        int a = 0;
        try {
            if (obj != null)
                a = Integer.parseInt(obj.toString());
        } catch (Exception e) {
        }
        return a;
    }
    /**
     * ��ȡ��ǰʱ�� yyyyMMddHHmmss
     * @return String
     */
    public static String getCurrTime() {
        Date now = new Date();
        SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String s = outFormat.format(now);
        return s;
    }
    /**
     * ��ȡ��ǰ���� yyyyMMdd
     * @param date
     * @return String
     */
    public static String formatDate(Date date) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        String strDate = formatter.format(date);
        return strDate;
    }
    /**
     * ȡ��һ��ָ�����ȴ�С�����������.
     *
     * @param length
     *            int �趨��ȡ�������ij��ȡ�lengthС��11
     * @return int ������ɵ������
     */
    public static int buildRandom(int length) {
        int num = 1;
        double random = Math.random();
        if (random < 0.1) {
            random = random + 0.1;
        }
        for (int i = 0; i < length; i++) {
            num = num * 10;
        }
        return (int) ((random * num));
    }
    /**
     * ��ȡ�����ַ�
     * @param request
     * @param response
     * @return String
     */
    public static String getCharacterEncoding(HttpServletRequest request,
            HttpServletResponse response) {
        if(null == request || null == response) {
            return "utf-8";
        }
        String enc = request.getCharacterEncoding();
        if(null == enc || "".equals(enc)) {
            enc = response.getCharacterEncoding();
        }
        if(null == enc || "".equals(enc)) {
            enc = "utf-8";
        }
        return enc;
    }
    /**
     * ��ȡunixʱ�䣬��1970-01-01 00:00:00��ʼ������
     * @param date
     * @return long
     */
    public static long getUnixTime(Date date) {
        if( null == date ) {
            return 0;
        }
        return date.getTime()/1000;
    }
    /**
     * ʱ��ת�����ַ�
     * @param date ʱ��
     * @param formatType ��ʽ������
     * @return String
     */
    public static String date2String(Date date, String formatType) {
        SimpleDateFormat sdf = new SimpleDateFormat(formatType);
        return sdf.format(date);
    }
}
src/main/java/com/hx/mp/util/WXPayUtil.java
New file
@@ -0,0 +1,458 @@
package com.hx.mp.util;
import com.hx.exception.ServiceException;
import com.hx.util.SimpleTool;
import net.sf.json.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import javax.net.ssl.SSLContext;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.util.*;
/** 微信支付/退款
 * @author ChenJiaHe
 */
public class WXPayUtil {
    // 退款接口连接
    private static final String REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
     /**查询订单链接*/
    @SuppressWarnings("unused")
    private static final String QUERY_URL = "https://api.mch.weixin.qq.com/pay/orderquery";
    /**同意下单链接*/
    private static final String FIRST_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    // 企业付款
    private static final String CORP_PAY_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
    /** 企业付款*/
    public static JSONObject qdCorpPay(String appId, String orderNo, String certPath, String mchid, String mchKey, String openId, String payFee, String desc)
            throws Exception {
        SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
        parameters.put("mch_appid", appId);
        parameters.put("mchid", mchid);
        parameters.put("partner_trade_no", orderNo);
        parameters.put("nonce_str", UUID.randomUUID().toString().substring(0, 30));
        parameters.put("openid", openId);
        parameters.put("check_name", "NO_CHECK");
        parameters.put("amount", payFee);
        parameters.put("spbill_create_ip", "8.8.8.8");
        parameters.put("desc", desc);
        String sign = WXSignUtils.createSign("UTF-8", parameters, mchKey);
        parameters.put("sign", sign);
        String xmlInfo = HttpXmlUtils.transferXml(parameters);
        JSONObject returnObj = new JSONObject();
        try {
            CloseableHttpResponse response = HttpUtil.Post(CORP_PAY_URL, xmlInfo, true, certPath, mchid);
            String transfersXml = EntityUtils.toString(response.getEntity(), "utf-8");
            // System.out.println("渠道端企业付款:" + transfersXml);
            Map<String, String> transferMap = HttpXmlUtils.parseRefundXml(transfersXml);
            boolean bl = false;
            if (transferMap.size() > 0) {
                if (transferMap.get("return_code").equals("SUCCESS")) {
                    // 通讯成功
                    if (transferMap.get("result_code").equals("SUCCESS")) {
                        // 成功需要进行的逻辑操作
                        returnObj.put("status", "suc");
                    } else {
                        bl = true;
                        returnObj.put("status", "fail");
                        returnObj.put("errMsg", transferMap.get("err_code") + "|" + transferMap.get("err_code_des"));
                    }
                } else {
                    bl = true;
                    // 通讯不成功
                    returnObj.put("status", "fail");
                    returnObj.put("errMsg", transferMap.get("return_msg"));
                }
            } else {
                bl = true;
                returnObj.put("status", "fail");
                returnObj.put("errMsg", "返回为空");
            }
            if (bl) {
                System.out.println("企业付款失败:" + transfersXml);
            }
        } catch (Exception e) {
            e.printStackTrace();
            returnObj.put("status", "fail");
            returnObj.put("errMsg", e.getMessage());
        }
        return returnObj;
    }
    /**统一支付
     * @param request 方法获取
     * @param appId  小程序号
     * @param partner  商户号
     * @param key  秘钥
     * @param notifyUrl  回调链接
     * @param out_trade_no  订单号
     * @param body 商品描述
     * @param total_fee 支付金额
     * @param openid 用户openId
     * @param attach 附带数据包
     * @param notifyUrl 回调通知地址
     * @param trade_type 交易类型
     * @return JSON  status = "SUC"为成功
     */
    public static JSONObject unifiedPay(HttpServletRequest request,String appId,String partner,String key,String notifyUrl,String out_trade_no, String body, String total_fee, String openid,
            String attach,String trade_type) throws Exception {
        if (!SimpleTool.checkNotNull(notifyUrl)) {
            throw new ServiceException("支付功能故障!");
        }
        // 创建查询请求对象
        RequestHandler reqHandler = new RequestHandler(null, null);
        // 通信对象
        TenpayHttpClient httpClient = new TenpayHttpClient();
        // 应答对象
        ClientResponseHandler resHandler = new ClientResponseHandler();
        // -----------------------------
        // 设置请求参数
        // -----------------------------
        // reqHandler.init();
        reqHandler.setKey(key);
        reqHandler.setGateUrl(FIRST_ORDER_URL);// 请求URL
        // -----------------------------
        // 设置接口参数(sign后台自动生成)
        // -----------------------------
        reqHandler.setParameter("appid", appId); // 公众号/小程序
        reqHandler.setParameter("mch_id", partner); // 商户号
        reqHandler.setParameter("nonce_str", SimpleTool.getUUIDName().substring(0, 30));// 随机乱码
        reqHandler.setParameter("body", body);// 商品描述
        reqHandler.setParameter("out_trade_no", out_trade_no);// 商户订单号
        reqHandler.setParameter("total_fee", total_fee);// 总金额
        reqHandler.setParameter("spbill_create_ip", "8.8.8.8");// 终端IP
        reqHandler.setParameter("notify_url",notifyUrl);// 通知地址
        reqHandler.setParameter("trade_type", trade_type);// 交易类型
                                                          // JSAPI,NATIVE,APP
        reqHandler.setParameter("openid", openid);// openId
        reqHandler.setParameter("attach", attach);// 附带数据包
        // -----------------------------
        // 设置通信参数
        // -----------------------------
        // 设置请求返回的等待时间
        httpClient.setTimeOut(5);
        // 设置ca证书
        // httpClient.setCaInfo(new File(CA_PATH));
        // 设置个人(商户)证书
        // httpClient.setCertInfo(new File(CERT_PATH), CERT_PWD);
        // 设置发送类型POST
        httpClient.setMethod("POST");
        // 设置请求内容(生成sign)
        String requestUrl = reqHandler.getRequestURL();// 组拼https://www.baidu.com?a=x&b=xx
        httpClient.setReqContent(requestUrl);// https://www.baidu.com?a=x&b=xx
        String rescontent = "null";
        httpClient.setRequestHandler(reqHandler);// 把处理对象,像是参数各种东西都设置进去方便获取(quan)
        // 返回出去的对象(状态,错误原因,该操作相关信息(参数,返回值))
        JSONObject returnObj = new JSONObject();
        // 后台调用
        if (httpClient.call()) {
            System.out.println("统一下单,成功cll了::");
            // 设置结果参数
            rescontent = httpClient.getResContent();
            System.out.println("统一下单返回结果:" + rescontent);
            resHandler.setContent(rescontent);// 解析xml
            resHandler.setKey(key);
            // 获取返回参数
            String return_code = resHandler.getParameter("return_code");
            String return_msg = resHandler.getParameter("return_msg");
            // 判断签名及结果
            if (resHandler.isTenpaySign() && "SUCCESS".equals(return_code)) {
                String prepay_id = resHandler.getParameter("prepay_id");// 预支付交易会话标识
                String code_url = resHandler.getParameter("code_url");// 二维码链接
                String result_code = resHandler.getParameter("result_code");// 业务结果
                String appid = resHandler.getParameter("appid");// 公众账号ID
                String mch_id = resHandler.getParameter("mch_id");// 商户号
                String nonce_str = resHandler.getParameter("nonce_str");// 随机码
                String sign = resHandler.getParameter("sign");// 签名
                if (result_code.equals("SUCCESS")) {
                    returnObj.put("status", "suc");
                    returnObj.put("sign", sign);
                    returnObj.put("nonce_str", nonce_str);
                    returnObj.put("mch_id", mch_id);
                    returnObj.put("appid", appid);
                    returnObj.put("prepay_id", prepay_id);
                    returnObj.put("code_url", code_url);
                    returnObj.put("out_trade_no", out_trade_no);
                } else {
                    String errMsg = "[ERROR]result_code:" + resHandler.getParameter("result_code") + " err_code:"
                            + resHandler.getParameter("err_code") + "err_code_des:"
                            + resHandler.getParameter("err_code_des");
                    // 错误时,返回结果未签名,记录retcode、retmsg看失败详情。
                    returnObj.put("status", "ERROR-C");
                    returnObj.put("errMsg", errMsg);
                }
            } else {
                String errMsg = "return_code:" + return_code + "err_code:" + resHandler.getParameter("err_code")
                        + " return_msg:" + return_msg;
                // 错误时,返回结果未签名,记录retcode、retmsg看失败详情。
                returnObj.put("status", "ERROR-B");
                returnObj.put("errMsg", errMsg);
            }
        } else {
            // 有可能因为网络原因,请求已经处理,但未收到应答。
            returnObj.put("status", "ERROR-A");
            returnObj.put("errMsg", httpClient.getResponseCode() + ":" + httpClient.getErrInfo());
        }
        // 获取debug信息,建议把请求、应答内容、debug信息,通信返回码写入日志,方便定位问题
        String detail = "http res:" + httpClient.getResponseCode() + "," + httpClient.getErrInfo() + ";" + "req url:"
                + requestUrl + ";" + ";" + "req debug:" + reqHandler.getDebugInfo() + ";" + "res content:" + rescontent
                + ";" + "res debug:" + resHandler.getDebugInfo() + ";";
        returnObj.put("detail", detail);
        return returnObj;
    }
    /**处理信息
     */
    public static JSONObject paymentData(JSONObject payObj,String key){
        JSONObject wxObj = new JSONObject();
        /**统一下单*/
        String payStatus = payObj.getString("status");
        if (payStatus.equals("suc")) {
            // JSONObject payObj = po.getJSONObject("inf");
            String appId = payObj.getString("appid");
            String nonceStr = payObj.getString("nonce_str");
            String prepay_id = payObj.getString("prepay_id");
            // JSAPI调用支付返回的数据
            String timeStamp = SimpleTool.getTenTime(new Date()).toString();
            String signType = "MD5";
            String packagef = "prepay_id=" + prepay_id;
            RequestHandler reqHandler = new RequestHandler(null, null);
            reqHandler.setParameter("appId", appId);
            reqHandler.setParameter("nonceStr", nonceStr);
            reqHandler.setParameter("timeStamp", timeStamp);
            reqHandler.setParameter("package", packagef);
            reqHandler.setParameter("signType", signType);
            reqHandler.setKey(key);
            String paySign = reqHandler.createSign();// 生成签名
            wxObj.put("orderNo", payObj.getString("out_trade_no"));
            wxObj.put("paySign", paySign);
            wxObj.put("appId", appId);
            wxObj.put("nonceStr", nonceStr);
            wxObj.put("package", packagef);
            wxObj.put("timeStamp", timeStamp);
        } else {
            throw new RuntimeException(payObj.toString());
        }
        return wxObj;
    }
    /**
     * 退款
     * @param appId 小程序/公众号 appId
     * @param partner 商户号
     * @param key 商户号秘钥
     * @param certPath 个人商户证书
     * @param out_trade_no 商户订单号
     * @param transaction_id 财付通订单号(微信订单号)
     * @param out_refund_no 商户退单号
     * @param total_fee 订单总额(单位:分)
     * @param refund_fee 退款金额(单位:分)
     * @return JSON status="SUCCESS"(成功) (状态,错误原因,该操作相关信息(参数,返回值))
     */
    public static JSONObject refund(String appId,String partner,String key,String certPath,String out_trade_no, String transaction_id, String out_refund_no, String total_fee,
            String refund_fee) {
         try{
             KeyStore keyStore = KeyStore.getInstance("PKCS12");
             FileInputStream instream = new FileInputStream(new File(certPath));
             try {
                 keyStore.load(instream,partner.toCharArray());
             }finally {
                 instream.close();
             }
             // Trust own CA and all self-signed certs
             SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore,partner.toCharArray()).build();
             // Allow TLSv1 protocol only
             SSLConnectionSocketFactory sslsf;
            sslsf = new SSLConnectionSocketFactory(
                    sslcontext, new String[] { "TLSv1" }, null,
                    SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            CloseableHttpClient httpclient = HttpClients.custom()
                     .setSSLSocketFactory(sslsf).build();
             HttpPost httppost = new HttpPost(REFUND_URL);
             String xml = wxPayRefundData(appId,partner,key,out_trade_no, transaction_id, total_fee, out_refund_no, refund_fee);
             try {
                 StringEntity se = new StringEntity(xml);
                 httppost.setEntity(se);
                 System.out.println("executing request" + httppost.getRequestLine());
                 CloseableHttpResponse responseEntry = httpclient.execute(httppost);
                 try {
                     HttpEntity entity = responseEntry.getEntity();
                     System.out.println(responseEntry.getStatusLine());
                     if (entity != null) {
                         SAXReader saxReader = new SAXReader();
                         Document document = saxReader.read(entity.getContent());
                         Element rootElt = document.getRootElement();
                         String resultCode = rootElt.elementText("result_code");
                         JSONObject result = new JSONObject();
                         if(resultCode.equals("SUCCESS")){
                             result.put("weixinPayUrl", rootElt.elementText("code_url"));
                             result.put("prepayId", rootElt.elementText("prepay_id"));
                             result.put("msg","success");
                             String refund_id = rootElt.elementText("refund_id");//微信退款单号
                             String r_out_refund_no=rootElt.elementText("out_refund_no");
                             String errMsg = "商户号"+r_out_refund_no+"的退款流水号是:"+refund_id;
                             result.put("status", "SUCCESS");
                             result.put("errMsg", errMsg);
                             result.put("refund_id", refund_id);
                         }else{
                             String errMsg = "[ERROR]result_code:" + rootElt.elementText("result_code")+
                                     " err_code:" + rootElt.elementText("err_code");
                             //错误时,返回结果未签名,记录retcode、retmsg看失败详情。
                             result.put("errMsg", errMsg);
                             result.put("status","false");
                             result.put("msg",rootElt.elementText("err_code_des"));
                         }
                         return result;
                     }
                     EntityUtils.consume(entity);
                 }
                 finally {
                     responseEntry.close();
                 }
             }
             finally {
                 httpclient.close();
             }
             return null;
         }catch(Exception e){
             e.printStackTrace();
             JSONObject result = new JSONObject();
             result.put("status","error");
             result.put("msg",e.getMessage());
             return result;
         }
    }
    /** 封装参数数据
     * @param appId 小程序/公众号 appId
     * @param partner 商户号
     * @param key 商户号秘钥
     * @param out_trade_no 商户订单号
     * @param transaction_id 财付通订单号(微信订单号)
     * @param out_refund_no 商户退单号
     * @param total_fee 订单总额(单位:分)
     * @param refund_fee 退款金额(单位:分)
     * @return
     */
    public static String wxPayRefundData(String appId,String partner,String key,String out_trade_no, String transaction_id,String out_refund_no,String total_fee,String refund_fee) {
        StringBuffer xml = new StringBuffer();
        String data = null;
        try {
            String nonceStr = SimpleTool.getUUIDName().substring(0,30);
            xml.append("</xml>");
            SortedMap<String,String> parameters = new TreeMap<String,String>();
            parameters.put("appid",appId);
            parameters.put("mch_id",partner);
            parameters.put("nonce_str", nonceStr);
            parameters.put("out_trade_no", out_trade_no);
            parameters.put("transaction_id", transaction_id);
            parameters.put("out_refund_no", out_refund_no);
            parameters.put("fee_type", "CNY");
            parameters.put("total_fee", total_fee);//总金额
            parameters.put("refund_fee", refund_fee);//退款金额
            parameters.put("op_user_id",partner);
            parameters.put("sign", createSign(parameters,key));
            data =SortedMaptoXml(parameters);
        } catch (Exception e) {
            System.err.println(e.getMessage());
            return null;
        }
        return data;
    }
    /**
     * 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
     */
    public static String createSign(SortedMap<String, String> packageParams, String AppKey) {
        StringBuffer sb;
        sb = new StringBuffer();
        Set es = packageParams.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + AppKey);
        String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
        return sign;
    }
    /**
     * @Author: HONGLINCHEN
     * @Description:请求值转换为xml格式 SortedMap转xml
     * @param params
     * @Date: 2017-9-7 17:18
     */
    private static String SortedMaptoXml(SortedMap<String,String> params) {
        StringBuilder sb = new StringBuilder();
        Set es = params.entrySet();
        Iterator it = es.iterator();
        sb.append("<xml>\n");
        while(it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            String k = (String)entry.getKey();
            Object v = entry.getValue();
            sb.append("<"+k+">");
            sb.append(v);
            sb.append("</"+k+">\n");
        }
        sb.append("</xml>");
        return sb.toString();
    }
}
src/main/java/com/hx/mp/util/WXSignUtils.java
New file
@@ -0,0 +1,33 @@
package com.hx.mp.util;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
public class WXSignUtils {
    /**
     * 微信支付签名算法sign
     * @param characterEncoding
     * @param parameters
     * @return
     */
    @SuppressWarnings("rawtypes")
    public static String createSign(String characterEncoding, SortedMap<Object,Object> parameters, String key){
        StringBuffer sb = new StringBuffer();
        Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序)
        Iterator it = es.iterator();
        while(it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            String k = (String)entry.getKey();
            Object v = entry.getValue();
            if(null != v && !"".equals(v)
                    && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + key);
        String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
        return sign;
    }
}
src/main/java/com/hx/mp/util/WechatUtil.java
New file
@@ -0,0 +1,77 @@
package com.hx.mp.util;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import net.sf.json.JSONObject;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class WechatUtil {
    public static boolean initialized = false;
    //log4j日志
    private static Logger logger = LoggerFactory.getLogger(WechatUtil.class.getName());
    public static JSONObject encryptedData(String encryptedData, String session_key, String iv) throws Exception {
        JSONObject encrypted_obj = null;
         byte[] resultByte  =decrypt(Base64.decode(encryptedData),
                 Base64.decode(session_key),
                 Base64.decode(iv));
             if(null != resultByte && resultByte.length > 0){
                 String userInfo = new String(resultByte, "UTF-8");
                 encrypted_obj = JSONObject.fromObject(userInfo);
             }else{
                 logger.error("获取unionid解密失败:encryptedData="+encryptedData+";session_key="+session_key+";iv="+iv);
             }
        return encrypted_obj;
    }
    /**
     * AES解密
     * @param content 密文
     * @return
     * @throws InvalidAlgorithmParameterException
     * @throws NoSuchProviderException
     */
    public static byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws Exception {
        initialize();
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
        Key sKeySpec = new SecretKeySpec(keyByte, "AES");
        cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化
        byte[] result = cipher.doFinal(content);
        return result;
    }
    public static void initialize(){
        if (initialized) return;
        Security.addProvider(new BouncyCastleProvider());
        initialized = true;
    }
    //生成iv
    public static AlgorithmParameters generateIV(byte[] iv) throws Exception{
        AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
        params.init(new IvParameterSpec(iv));
        return params;
    }
}
src/main/java/com/hx/mp/util/XMLUtil.java
New file
@@ -0,0 +1,109 @@
package com.hx.mp.util;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
 * xml������
 *JX
 *linhan
 */
public class XMLUtil {
    /**
     * ����xml,���ص�һ��Ԫ�ؼ�ֵ�ԡ�����һ��Ԫ�����ӽڵ㣬��˽ڵ��ֵ���ӽڵ��xml��ݡ�
     * @param strxml
     * @return
     * @throws JDOMException
     * @throws IOException
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static Map doXMLParse(String strxml) throws JDOMException, IOException {
        strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");
        if(null == strxml || "".equals(strxml)) {
            return null;
        }
        Map m = new HashMap();
        InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(in);
        Element root = doc.getRootElement();
        List list = root.getChildren();
        Iterator it = list.iterator();
        while(it.hasNext()) {
            Element e = (Element) it.next();
            String k = e.getName();
            String v = "";
            List children = e.getChildren();
            if(children.isEmpty()) {
                v = e.getTextNormalize();
            } else {
                v = XMLUtil.getChildrenText(children);
            }
            m.put(k, v);
        }
        //�ر���
        in.close();
        return m;
    }
    /**
     * ��ȡ�ӽ���xml
     * @param children
     * @return String
     */
    @SuppressWarnings("rawtypes")
    public static String getChildrenText(List children) {
        StringBuffer sb = new StringBuffer();
        if(!children.isEmpty()) {
            Iterator it = children.iterator();
            while(it.hasNext()) {
                Element e = (Element) it.next();
                String name = e.getName();
                String value = e.getTextNormalize();
                List list = e.getChildren();
                sb.append("<" + name + ">");
                if(!list.isEmpty()) {
                    sb.append(XMLUtil.getChildrenText(list));
                }
                sb.append(value);
                sb.append("</" + name + ">");
            }
        }
        return sb.toString();
    }
    /**
     * ��ȡxml�����ַ�
     * @param strxml
     * @return
     * @throws IOException
     * @throws JDOMException
     */
    public static String getXMLEncoding(String strxml) throws JDOMException, IOException {
        InputStream in = HttpClientUtil.String2Inputstream(strxml);
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(in);
        in.close();
        return (String)doc.getProperty("encoding");
    }
}
src/main/java/com/hx/mybatisTool/SqlParam.java
New file
@@ -0,0 +1,75 @@
package com.hx.mybatisTool;
import java.util.Map;
import com.hx.exception.TipsException;
import com.hx.util.SimpleTool;
/**
 * mybatis 自定义处理sql语句
 * @author chenjiahe
 * @Data: 2020-06-08
 */
public class SqlParam {
    private String whereSentence = "1=1";
    private String updateSentence;
    private Map<String,Object> m;
    /********************mother****************************/
    /**
     * 查询的语句
     * @param sql 如:id = #{m.userId} order by age
     * @param values 存放的值如:values.put("userId","123456")
     */
    public void sqlWhere(String sql,Map<String,Object> values) {
        if(!SimpleTool.checkNotNull(values)){
            throw new TipsException("values is null");
        }
        if(!SimpleTool.checkNotNull(sql)) {
            sql = "1=1";
        }
        whereSentence = sql;
        m = values;
    }
    /**
     * 更新语句的语句
     * @param sql 如:name = #{m.name},age = ? Where id = #{m.id}
     * @param values 存放的值
     */
    public void sqlUpdate(String sql,Map<String,Object> values) {
        if(!SimpleTool.checkNotNull(values)){
            throw new TipsException("values is null");
        }
        m = values;
        updateSentence = sql;
    }
    /************************************************************************/
    public String getWhereSentence() {
        return whereSentence;
    }
    public void setWhereSentence(String whereSentence) {
        this.whereSentence = whereSentence;
    }
    public String getUpdateSentence() {
        return updateSentence;
    }
    public void setUpdateSentence(String updateSentence) {
        this.updateSentence = updateSentence;
    }
    public Map<String, Object> getM() {
        return m;
    }
    public void setM(Map<String, Object> m) {
        this.m = m;
    }
}
src/main/java/com/hx/mybatisTool/SqlSentence.java
New file
@@ -0,0 +1,161 @@
package com.hx.mybatisTool;
import com.hx.exception.TipsException;
import com.hx.util.StringUtils;
import java.util.Map;
/**
 * mybatis 自定义处理sql语句
 * @author chenjiahe
 * @Data: 2020-06-08
 */
public class SqlSentence {
    private String sqlSentence;
    private Map<String,Object> m;
    /**类型*/
    private Integer type = TYPE_NORMAL;
    /**排序*/
    private String orderBy;
    /**开始页数*/
    private Integer startPage = 0;
    /**每页数量*/
    private Integer pageNum = 0;
    //////////////////////////////////////////////////////////////
    /**正常*/
    public static final int TYPE_NORMAL = 0;
    /**动态*/
    public static final int TYPE_DYN = 1;
    /********************mother****************************/
    public SqlSentence()
    {
    }
    public SqlSentence(Class c, String where, Map<String, Object> values)
    {
        if(StringUtils.isEmpty(where))
        {
            throw new TipsException("sql is null");
        }
        if(values == null)
        {
            throw new TipsException("values is null");
        }
        sqlSentence = "select * from " + c.getSimpleName()+ " where " + where;
        m = values;
    }
    public SqlSentence(String where, Map<String, Object> values)
    {
        if(StringUtils.isEmpty(where))
        {
            throw new TipsException("sql is null");
        }
        if(values == null)
        {
            throw new TipsException("values is null");
        }
        sqlSentence = where;
        m = values;
    }
    /**
     * sql整条语句
     * @param sql 如:select * from user Where name = #{m.userName} order by age desc
     * @param values 存放的值如:values.put("userName","ChenJiaHe")
     */
    public void sqlSentence(String sql,Map<String,Object> values) {
        if(StringUtils.isEmpty(sql))
        {
            throw new TipsException("sql is null");
        }
        if(values == null)
        {
            throw new TipsException("values is null");
        }
        sqlSentence = sql;
        m = values;
    }
    /**
     * 设置动态查询
     * @param map 查询
     */
    public void setDynSql(Map<String, Object> map)
    {
        this.type = TYPE_DYN;
        this.m = map;
    }
    /************************************************************************/
    public Map<String, Object> getM() {
        return m;
    }
    public void setM(Map<String, Object> m) {
        this.m = m;
    }
    public String getSqlSentence() {
        return sqlSentence;
    }
    public void setSqlSentence(String sqlSentence) {
        this.sqlSentence = sqlSentence;
    }
    public Integer getType() {
        return type;
    }
    public void setType(Integer type) {
        this.type = type;
    }
    public String getOrderBy() {
        return orderBy;
    }
    public void setOrderBy(String orderBy) {
        this.orderBy = orderBy;
    }
    public Integer getStartPage() {
        return startPage;
    }
    public void setStartPage(Integer startPage) {
        this.startPage = startPage;
    }
    public Integer getPageNum() {
        return pageNum;
    }
    public void setPageNum(Integer pageNum) {
        this.pageNum = pageNum;
    }
    public Integer getStartIndex()
    {
        return (startPage - 1) * pageNum;
    }
}
src/main/java/com/hx/resultTool/ResponseCode.java
New file
@@ -0,0 +1,27 @@
package com.hx.resultTool;
/**
 * 统一状态码
 * @author chenjiahe
 * @Data: 2020-06-20
 */
public final class ResponseCode {
    /*成功*/
    public static final String SUCCESS = "100";
    /*错误提示,前端根据这个码弹出提示*/
    public static final String ERROR_TIPS="200";
    /*参数验证错误*/
    public static final String ERROR_PARAMS_VALIDATOR="205";
    /*业务验证错误*/
    public static final String ERROR_SERVICE_VALIDATOR="300";
    /*系统数据错误*/
    public static final String ERROR_DATA_VALIDATOR="400";
    /*登录有误*/
    public static final String ERROR_LOGIN="603";
    /*系统异常*/
    public static final String ERROR_SYSTEM = "999";
}
src/main/java/com/hx/resultTool/Result.java
New file
@@ -0,0 +1,84 @@
package com.hx.resultTool;
import java.io.Serializable;
/**
 * 统一返回格式
 * @author chenjiahe
 * @Data: 2020-06-20
 */
public class Result implements Serializable {
    private static final long serialVersionUID = -3948389268046368059L;
    private String code;
    private String msg;
    private Object data;
    public Result() {}
    public Result(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    public static Result success() {
        Result Result = new Result();
        Result.setCode(ResponseCode.SUCCESS);
        Result.setMsg("SUCCESS");
        return Result;
    }
    public static Result success(Object data) {
        Result Result = new Result();
        Result.setCode(ResponseCode.SUCCESS);
        Result.setData(data);
        Result.setMsg("SUCCESS");
        return Result;
    }
    public static Result failure(String code, String msg) {
        Result Result = new Result();
        Result.setCode(code);
        Result.setMsg(msg);
        return Result;
    }
    public static Result failure(String code, String msg, Object data) {
        Result Result = new Result();
        Result.setCode(code);
        Result.setMsg(msg);
        Result.setData(data);
        return Result;
    }
    /*******************************************************************************/
    public String getCode() {
        return this.code;
    }
    public void setCode(final String code) {
        this.code = code;
    }
    public String getMsg() {
        return this.msg;
    }
    public void setMsg(final String msg) {
        this.msg = msg;
    }
    public Object getData() {
        return this.data;
    }
    public void setData(final Object data) {
        this.data = data;
    }
}
src/main/java/com/hx/util/Aes.java
New file
@@ -0,0 +1,113 @@
package com.hx.util;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
/**
 * AES加密工具类
 */
public class Aes {
    /**
     * 将二进制转换成16进制
     *
     * @param buf 字节数组
     * @return
     */
    public 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.toUpperCase());
        }
        return sb.toString();
    }
    /**
     * 将16进制转换为二进制
     *
     * @param hexStr 16进制字符
     * @return
     */
    public static byte[] parseHexStr2Byte(String hexStr) {
        if (hexStr.length() < 1)
            return null;
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
            result[i] = (byte) (high * 16 + low);
        }
        return result;
    }
    /**
     * 加密
     * @param str 待加密字符串
     * @param secret 密钥
     * @return
     */
    public static byte[] encrypt(String str, String secret) {
        if (null != str) {
            byte[] bytes = null;
            try {
                Base64 base64 = new Base64();
                String ALGORITHM = "AES";
                SecretKey desKey = new SecretKeySpec(secret.getBytes("UTF-8"), ALGORITHM);// 生成密钥
                Cipher c;
                c = Cipher.getInstance(ALGORITHM);
                c.init(Cipher.ENCRYPT_MODE, desKey);
                bytes = c.doFinal(str.getBytes("UTF-8"));
                return bytes;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    /**
     * 解密
     * @param str 待解密字符串
     * @param secret 密钥
     * @return
     */
    public static byte[] decrypt(byte[] str, String secret) {
        try {
            String ALGORITHM = "AES";
            SecretKey desKey = new SecretKeySpec(secret.getBytes("UTF-8"), ALGORITHM);// 生成密钥
            Cipher c = Cipher.getInstance(ALGORITHM);
            c.init(Cipher.DECRYPT_MODE, desKey);
            return c.doFinal(str);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public static void main(String[] args) throws UnsupportedEncodingException {
        String content = "apiKey=phitabfaceapi&userId=o5W1it6Pvqn6vPX6E1BGERH8J1lw";
        String password = "phitabfacesecret";
        byte[] encode = encrypt(content, password);
        String code = parseByte2HexStr(encode);
        System.out.println("密文字符串:" + code);
        //16进制字符串转成字节数组
        byte[] decode = parseHexStr2Byte(code);
        // 解密
        byte[] decryptResult = decrypt(decode, password);
        System.out.println("解密后:" + new String(decryptResult, "UTF-8")); //不转码会乱码
    }
}
src/main/java/com/hx/util/AesUtil.java
New file
@@ -0,0 +1,126 @@
package com.hx.util;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
/**
 * AES加解密工具
 * 使用该类,需要行替换local_policy.jar及us_export_policy.jar
 * @author ChenJiaHe
 *
 */
public class AesUtil {
    /**16位加密秘钥*/
    public static final String SECRET = "huoXiong16816888";
    /**
     * AES加密
     *
     * @param str
     *            需要加密的明文
     * @param secret
     *            秘钥
     * @return 加密后的密文(base64编码字符串)
     */
    public static String aesEncryp(String str, String secret) {
        if (null != str) {
            byte[] bytes = null;
            try {
                Base64 base64 = new Base64();
                String ALGORITHM = "AES";
                SecretKey deskey = new SecretKeySpec(secret.getBytes("UTF-8"), ALGORITHM);// 生成密钥
                Cipher c;
                c = Cipher.getInstance(ALGORITHM);
                c.init(Cipher.ENCRYPT_MODE, deskey);
                bytes = c.doFinal(str.getBytes("UTF-8"));
                if (bytes != null) {
                    return new String(base64.encode(bytes));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    /**
     * AES解密
     *
     * @param str
     *            需要解密的秘文
     * @param secret
     *            秘钥
     * @return 解密后的明文
     */
    public static String aesDecryp(String str, String secret) {
        try {
            Base64 base64 = new Base64();
            String ALGORITHM = "AES";
            SecretKey deskey = new SecretKeySpec(secret.getBytes("UTF-8"), ALGORITHM);// 生成密钥
            Cipher c = Cipher.getInstance(ALGORITHM);
            c.init(Cipher.DECRYPT_MODE, deskey);
            return new String(c.doFinal(base64.decode(str.getBytes("UTF-8"))), "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * AES加密(固定秘钥)
     *
     * @param str 需要加密的明文
     * @return 加密后的密文(base64编码字符串)
     */
    public static String aesEncryp(String str) {
        String secret = SECRET;
        if (null != str) {
            byte[] bytes = null;
            try {
                Base64 base64 = new Base64();
                String ALGORITHM = "AES";
                SecretKey deskey = new SecretKeySpec(secret.getBytes("UTF-8"), ALGORITHM);// 生成密钥
                Cipher c;
                c = Cipher.getInstance(ALGORITHM);
                c.init(Cipher.ENCRYPT_MODE, deskey);
                bytes = c.doFinal(str.getBytes("UTF-8"));
                if (bytes != null) {
                    return new String(base64.encode(bytes));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    /**
     * AES解密(固定秘钥)
     *
     * @param str 需要解密的秘文
     * @return 解密后的明文
     */
    public static String aesDecryp(String str) {
        String secret = SECRET;
        try {
            Base64 base64 = new Base64();
            String ALGORITHM = "AES";
            SecretKey deskey = new SecretKeySpec(secret.getBytes("UTF-8"), ALGORITHM);// 生成密钥
            Cipher c = Cipher.getInstance(ALGORITHM);
            c.init(Cipher.DECRYPT_MODE, deskey);
            return new String(c.doFinal(base64.decode(str.getBytes("UTF-8"))), "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
src/main/java/com/hx/util/BASE64.java
New file
@@ -0,0 +1,51 @@
package com.hx.util;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
 * BASE64加密解密
 */
public class BASE64
{
    /**
     * BASE64解密
   * @param key
     * @return
     * @throws Exception
     */
    public static byte[] decryptBASE64(String key) {
        byte[] t = new byte[]{};
        try{
            t = (new BASE64Decoder()).decodeBuffer(key);
        }catch (Exception e) {
            e.printStackTrace();
        }
        return t;
    }
    /**
     * BASE64加密
   * @param key
     * @return
     * @throws Exception
     */
    public static String encryptBASE64(byte[] key){
        String s = "";
        try{
            s = (new BASE64Encoder()).encodeBuffer(key);
        }catch (Exception e) {
            e.printStackTrace();
        }
        return s;
    }
    public static void main(String[] args) throws Exception
    {
        String data = BASE64.encryptBASE64("123456789".getBytes());
        System.out.println("加密前:"+data);
        byte[] byteArray = BASE64.decryptBASE64(data);
        System.out.println("解密后:"+new String(byteArray));
    }
}
src/main/java/com/hx/util/Base64Util.java
New file
@@ -0,0 +1,65 @@
package com.hx.util;
/**
 * Base64 工具类
 */
public class Base64Util {
    private static final char last2byte = (char) Integer.parseInt("00000011", 2);
    private static final char last4byte = (char) Integer.parseInt("00001111", 2);
    private static final char last6byte = (char) Integer.parseInt("00111111", 2);
    private static final char lead6byte = (char) Integer.parseInt("11111100", 2);
    private static final char lead4byte = (char) Integer.parseInt("11110000", 2);
    private static final char lead2byte = (char) Integer.parseInt("11000000", 2);
    private static final char[] encodeTable = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
    public Base64Util() {
    }
    public static String encode(byte[] from) {
        StringBuilder to = new StringBuilder((int) ((double) from.length * 1.34D) + 3);
        int num = 0;
        char currentByte = 0;
        int i;
        for (i = 0; i < from.length; ++i) {
            for (num %= 8; num < 8; num += 6) {
                switch (num) {
                    case 0:
                        currentByte = (char) (from[i] & lead6byte);
                        currentByte = (char) (currentByte >>> 2);
                    case 1:
                    case 3:
                    case 5:
                    default:
                        break;
                    case 2:
                        currentByte = (char) (from[i] & last6byte);
                        break;
                    case 4:
                        currentByte = (char) (from[i] & last4byte);
                        currentByte = (char) (currentByte << 2);
                        if (i + 1 < from.length) {
                            currentByte = (char) (currentByte | (from[i + 1] & lead2byte) >>> 6);
                        }
                        break;
                    case 6:
                        currentByte = (char) (from[i] & last2byte);
                        currentByte = (char) (currentByte << 4);
                        if (i + 1 < from.length) {
                            currentByte = (char) (currentByte | (from[i + 1] & lead4byte) >>> 4);
                        }
                }
                to.append(encodeTable[currentByte]);
            }
        }
        if (to.length() % 4 != 0) {
            for (i = 4 - to.length() % 4; i > 0; --i) {
                to.append("=");
            }
        }
        return to.toString();
    }
}
src/main/java/com/hx/util/CheckCodeImageUtil.java
New file
@@ -0,0 +1,96 @@
package com.hx.util;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import javax.imageio.ImageIO;
/**
 * 验证码生成器
 * @author ChenJiaHe
 * @Date 2020-06-17
 */
public class CheckCodeImageUtil {
    private final static int WIDTH = 60;
    private final static int HEIGHT = 20;
    private static char[] generateCheckCode() {
        // ������֤����ַ��
        String chars = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        char[] rands = new char[4];
        for (int i = 0; i < 4; i++) {
            int rand = (int) (Math.random() * 35);
            rands[i] = chars.charAt(rand);
        }
        return rands;
    }
    private static void drawRands(Graphics g, char[] rands) {
        g.setColor(Color.BLACK);
        g.setFont(new Font(null, Font.ITALIC | Font.BOLD, 18));
        // �ڲ�ͬ�ĸ߶��������֤���ÿ���ַ�
        g.drawString("" + rands[0], 1, 17);
        g.drawString("" + rands[1], 16, 15);
        g.drawString("" + rands[2], 31, 18);
        g.drawString("" + rands[3], 46, 16);
    }
    private static void drawBackground(Graphics g) {
        // ������
        g.setColor(new Color(0xDCDCDC));
        g.fillRect(0, 0, WIDTH, HEIGHT);
        // ������120�����ŵ�
        for (int i = 0; i < 120; i++) {
            int x = (int) (Math.random() * WIDTH);
            int y = (int) (Math.random() * HEIGHT);
            int red = (int) (Math.random() * 255);
            int green = (int) (Math.random() * 255);
            int blue = (int) (Math.random() * 255);
            g.setColor(new Color(red, green, blue));
            g.drawOval(x, y, 1, 0);
        }
    }
    public static String[] createImage(String id)
    {
        ByteArrayOutputStream bos = null;
        String reStr = "";
        char[] rands = null;
        try {
            BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
            Graphics g = image.getGraphics();
            rands = generateCheckCode();
            drawBackground(g);
            drawRands(g, rands);
            g.dispose();
            bos = new ByteArrayOutputStream();
            ImageIO.write(image, "JPEG", bos);
            byte[] buf = bos.toByteArray();
            reStr = Base64.getEncoder().encodeToString(buf);
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(bos != null)
            {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                bos = null;
            }
        }
        return new String[] {new String(rands),reStr};
    }
}
src/main/java/com/hx/util/CreateNoTool.java
New file
@@ -0,0 +1,46 @@
package com.hx.util;
import java.util.Random;
public class CreateNoTool {
    /**获取随机秘钥(数字与大写字母组合)
     *
     * @param y
     *            随机数位数
     * @return
     */
    public static String randomKey(Integer y) {
        String[] data = new String[] {
                "0","1","2","3","4","5","6","7","8","9"
                ,"A","B","C","D","E","F","G","H","I","J"
                ,"K","L","M","N","O","P","Q","R","S","T"
                ,"U","V","W","S","Y","Z"
        };
        String no = "";
        Random r = new Random();
        for (int i = 0; i < y; i++) {
            no += data[r.nextInt(data.length-1)];
        }
        return no;
    }
    /**获取随机秘钥(数字)
     *
     * @param y
     *            随机数位数
     * @return
     */
    public static String randomKeyNumber(Integer y) {
        String[] data = new String[] {
                "0","1","2","3","4","5","6","7","8","9"
        };
        String no = "";
        Random r = new Random();
        for (int i = 0; i < y; i++) {
            no += data[r.nextInt(data.length-1)];
        }
        return no;
    }
}
src/main/java/com/hx/util/DateUtil.java
New file
@@ -0,0 +1,346 @@
package com.hx.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
public class DateUtil {
    private static SimpleDateFormat Format_1 = new SimpleDateFormat("yyyyMMdd");
    private static SimpleDateFormat Format_2 = new SimpleDateFormat("yyyyMMddHHmmss");
    private static SimpleDateFormat Format_3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private static SimpleDateFormat Format_4 = new SimpleDateFormat("yyyy-MM-dd");
    private static SimpleDateFormat Format_5 = new SimpleDateFormat("HH:mm:ss");
    private static SimpleDateFormat Format_6 = new SimpleDateFormat("yyyyMM");
    private static SimpleDateFormat Format_7 = new SimpleDateFormat("MM月dd日 HH:mm");
    private static SimpleDateFormat Format_8 = new SimpleDateFormat("yyyy年MM月");
    private static SimpleDateFormat Format_9 = new SimpleDateFormat("MM-dd");
    private static SimpleDateFormat Format_10 = new SimpleDateFormat("yyyy年MM月dd日");
    private static SimpleDateFormat Format_11 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
    private static SimpleDateFormat Format_12 = new SimpleDateFormat("yyyyMMddHHmm");
    private static SimpleDateFormat Format_13 = new SimpleDateFormat("yyyy/MM/dd");
    private static SimpleDateFormat Format_14 = new SimpleDateFormat("yyyy-MM");
    private static SimpleDateFormat Format_15 = new SimpleDateFormat("yyyyMMddHHmmssSSS");
    private static SimpleDateFormat Format_16 = new SimpleDateFormat("yyyy/MM/dd HH:mm");
    private static SimpleDateFormat Format_17 = new SimpleDateFormat("HH:mm");
    /**时间格式转化
     * @param date 时间
     * @param format 时间格式
     * @return 返回的时间格式字符串
     */
    public static String dateFormat(Date date, String format) {
        if(!SimpleTool.checkNotNull(date)){
            return "";
        }
        SimpleDateFormat df = new SimpleDateFormat(format);//设置日期格式
        return df.format(date);
    }
    /**
     * 转换成yyyyMMdd格式的日期字符串
     *
     * @param date
     * @return
     */
    public static String formatDate(Date date) {
        return Format_1.format(date);
    }
    /**
     * 转换成yyyyMMddHHmmss格式的日期字符串
     *
     * @param date
     * @return
     */
    public static String formatDate_1(Date date) {
        return Format_2.format(date);
    }
    /**
     * 转换成yyyy-MM-dd HH:mm:ss格式的日期字符串
     *
     * @param date
     * @return
     */
    public static String formatDate_2(Date date) {
        return date == null ? null : Format_3.format(date);
    }
    /**
     * 转换成yyyy-MM-dd格式的日期字符串
     *
     * @param date
     * @return
     */
    public static String formatDate_3(Date date) {
        return date != null ? Format_4.format(date) : null;
    }
    /**
     * 转换成HH:mm:ss格式的日期字符串
     *
     * @param date
     * @return
     */
    public static String formatDate_4(Date date) {
        return Format_5.format(date);
    }
    /**
     * 转换成yyyyMM格式的日期字符串
     *
     * @param date
     * @return
     */
    public static String formatDate_5(Date date) {
        return Format_6.format(date);
    }
    /**
     * 转换成mm月dd日 HH:mm格式的日期字符串
     *
     * @param date
     * @return
     */
    public static String formatDate_6(Date date) {
        return Format_7.format(date);
    }
    /**
     * 转换成yyyy年mm月格式的日期字符串
     *
     * @param date
     * @return
     */
    public static String formatDate_7(Date date) {
        return Format_8.format(date);
    }
    /**
     * 转换成mm-dd格式的日期字符串
     *
     * @param date
     * @return
     */
    public static String formatDate_8(Date date) {
        return Format_9.format(date);
    }
    /**
     * 转换成yyyy年MM月dd日格式的日期字符串
     *
     * @param date
     * @return
     */
    public static String formatDate_9(Date date) {
        return Format_10.format(date);
    }
    /**
     * 转换成yyyyMMddHHmm格式的日期字符串
     *
     * @param date
     * @return
     */
    public static String formatDate_11(Date date) {
        return Format_12.format(date);
    }
    /**
     * 转换成yyyy年MM月dd日 HH:mm:ss格式的日期字符串
     *
     * @param date
     * @return
     */
    public static String formatDate_10(Date date) {
        return Format_11.format(date);
    }
    /**
     * 转换成yyyy/MM/dd 格式的日期字符串
     *
     * @param date
     * @return
     */
    public static String formatDate_13(Date date) {
        return Format_13.format(date);
    }
    /**
     * 转换成yyyy-MM 格式的日期字符串
     *
     * @param date
     * @return
     */
    public static String formatDate_14(Date date) {
        return Format_14.format(date);
    }
    /**
     * 转换成yyyyMMddHHmmssSSS格式的日期字符串
     *
     * @param date
     * @return
     */
    public static String formatDate_15(Date date) {
        return Format_15.format(date);
    }
    /**
     * 转换成yyyy/MM/dd HH:mm格式的日期字符串
     *
     * @param date
     * @return
     */
    public static String formatDate_16(Date date) {
        return Format_16.format(date);
    }
    /**
     * 转换成HH:mm格式的日期字符串
     *
     * @param date
     * @return
     */
    public static String formatDate_17(Date date) {
        return Format_17.format(date);
    }
    /**
     * 转换成字符串yyyyMMddHHmmss成日�?
     *
     * @param str
     * @return
     * @throws Exception
     */
    public static Date parseString(String str) throws Exception {
        return Format_2.parse(str);
    }
    /**
     * 转换成字符串到指定的日期
     *
     * @param str
     * @param format
     * @return
     * @throws Exception
     */
    public static Date parseString(String str, String format) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.parse(str);
    }
    /**时间上分钟叠加
     * @Author: ChenJiaHe
     * @param dateTime 时间
     * @param min 分钟
     * @return
     */
    public static Date addMin(Date dateTime,int min){
        Calendar c = Calendar.getInstance();
        c.setTime(dateTime);
        c.add(Calendar.MINUTE, min);
        return c.getTime();
    }
    /**时间上小时叠加
     * @Author: ChenJiaHe
     * @param dateTime 时间
     * @param hour 小时
     * @return
     */
    public static Date addhour(Date dateTime,int hour){
        Calendar c = Calendar.getInstance();
        c.setTime(dateTime);
        c.add(Calendar.HOUR, hour);
        return c.getTime();
    }
    /**时间上天数叠加
     * @Author: ChenJiaHe
     * @param dateTime 时间
     * @param dayNum 天数
     * @return
     */
    public static Date addDay(Date dateTime,int dayNum){
        Calendar c = Calendar.getInstance();
        c.setTime(dateTime);
        c.add(Calendar.DATE, dayNum);
        return c.getTime();
    }
    /**
     * 转换成字符串到指定的日期
     *
     * @param date
     * @param format
     * @return
     * @throws Exception
     */
    public static String formatDate(Date date, String format) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.CHINA);
        return sdf.format(date);
    }
    /**日期转星期
     * @param dateTime 字符串时间
     * @param format 字符串时间格式
     * @param returnType 返回类型 0星期几1周几
     * @return 数据
     */
    public static String dateToWeek(String dateTime,String format,Integer returnType) throws ParseException {
        SimpleDateFormat f = new SimpleDateFormat(format);
        String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
        if(SimpleTool.checkNotNull(returnType)&&returnType==1){
            weekDays  = new String[]{"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
        }
        Calendar cal = Calendar.getInstance(); // 获得一个日历
        Date datet = null;
        datet = f.parse(dateTime);
        cal.setTime(datet);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1; // 指示一个星期中的某天。
        if (w < 0)
            w = 0;
        return weekDays[w];
    }
    /**日期转星期
     * @param dateTime 时间
     * @param returnType 返回类型 0星期几1周几
     * @return 数据
     */
    public static String dateToWeek(Date dateTime,Integer returnType) {
        String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
        if(SimpleTool.checkNotNull(returnType)&&returnType==1){
            weekDays  = new String[]{"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
        }
        Calendar cal = Calendar.getInstance(); // 获得一个日历
        cal.setTime(dateTime);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1; // 指示一个星期中的某天。
        if (w < 0)
            w = 0;
        return weekDays[w];
    }
    /**判断两个时间是不是同一天*/
    public static boolean timeEqual(Date startTime,Date endTime){
       if(startTime == null || endTime==null){
           return false;
       }
       boolean status = false;
       if(formatDate(startTime,"yyyyMMdd").equals(formatDate(endTime,"yyyyMMdd"))){
           status = false;
       }
       return status;
    }
}
src/main/java/com/hx/util/EmailUtil.java
New file
@@ -0,0 +1,120 @@
package com.hx.util;
import com.sun.mail.util.MailSSLSocketFactory;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.util.Properties;
/**邮件处理工具
 * @author ChenJiaHe
 * @Date 2020-07-06
 */
public class EmailUtil {
    /**
     * 发送带附件的邮件
     *
     * @param receive
     *            收件人
     * @param subject
     *            邮件主题
     * @param msg
     *            邮件内容
     * @param filename
     *            附件地址
     * @param from
     *            发件人电子邮箱
     * @param pass
     *            发件人电子邮箱密码
     * @return
     * @throws GeneralSecurityException
     */
    public static boolean sendMail(String receive, String subject, String msg, String filename,
                                   String from,String pass)
            throws GeneralSecurityException {
        if (StringUtils.isEmpty(receive)) {
            return false;
        }
        // 指定发送邮件的主机为 smtp.qq.com   smtp.163.com
        String host = "smtp.qq.com"; // 邮件服务器
        // 获取系统属性
        Properties properties = System.getProperties();
        // 设置邮件服务器
        properties.setProperty("mail.smtp.host", host);
        properties.put("mail.smtp.auth", "true");
        MailSSLSocketFactory sf = new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);
        properties.put("mail.smtp.ssl.enable", "true");
        properties.put("mail.smtp.ssl.socketFactory", sf);
        // 获取默认session对象
        Session session = Session.getDefaultInstance(properties, new Authenticator() {
            public PasswordAuthentication getPasswordAuthentication() { // qq邮箱服务器账户、第三方登录授权码
                return new PasswordAuthentication(from, pass); // 发件人邮件用户名、密码
            }
        });
        try {
            // 创建默认的 MimeMessage 对象
            MimeMessage message = new MimeMessage(session);
            // Set From: 头部头字段
            message.setFrom(new InternetAddress(from));
            // Set To: 头部头字段
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(receive));
            // Set Subject: 主题文字
            message.setSubject(subject);
            // 创建消息部分
            BodyPart messageBodyPart = new MimeBodyPart();
            // 消息
            messageBodyPart.setText(msg);
            // 创建多重消息
            Multipart multipart = new MimeMultipart();
            // 设置文本消息部分
            multipart.addBodyPart(messageBodyPart);
            // 附件部分
            messageBodyPart = new MimeBodyPart();
            // 设置要发送附件的文件路径
            if(SimpleTool.checkNotNull(filename)){
                DataSource source = new FileDataSource(filename);
                if(!SimpleTool.checkNotNull(source)){
                    throw new RuntimeException("获取附件失败!");
                }
                messageBodyPart.setDataHandler(new DataHandler(source));
                // messageBodyPart.setFileName(filename);
                // 处理附件名称中文(附带文件路径)乱码问题
                //messageBodyPart.setFileName(MimeUtility.encodeText(source.getName()));
                messageBodyPart.setFileName(new String(source.getName().toString().getBytes("UTF-8")));
                multipart.addBodyPart(messageBodyPart);
            }
            // 发送完整消息
            message.setContent(multipart);
            // 发送消息
            Transport.send(message);
            // System.out.println("Sent message successfully....");
            return true;
        } catch (MessagingException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return false;
    }
}
src/main/java/com/hx/util/ExcelUtil.java
New file
@@ -0,0 +1,201 @@
package com.hx.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import com.hx.exception.TipsException;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.Cell;
import org.springframework.web.multipart.MultipartFile;
/**
 *
 * @author hjr
 */
public final class ExcelUtil {
    /**
     * @param excelName
     *         文件名称
     * @param outPath
     *             保存路径
     * @param headList
     *        Excel文件Head标题集合
     * @param fieldList
     *        Excel文件Field标题集合 根据field来寻找位置填充表格
     * @param dataList
     *        Excel文件数据内容部分
     * @throws Exception
     */
    public static String createExcel(String outPath, String excelName,
            String[] headList, String[] fieldList,
            List<Map<String, Object>> dataList) throws Exception {
        String filePath = null;
        // 创建新的Excel 工作簿
        HSSFWorkbook workbook = new HSSFWorkbook();
        // 在Excel工作簿中建一工作表,其名为缺省值
        // 如要新建一名为"效益指标"的工作表,其语句为:
        // HSSFSheet sheet = workbook.createSheet("效益指标");
        HSSFSheet sheet = workbook.createSheet();
        // 在索引0的位置创建行(最顶端的行)
        HSSFRow row = sheet.createRow(0);
        // ===============================================================
        for (int i = 0; i < headList.length; i++) {
            // 在索引0的位置创建单元格(左上端)
            HSSFCell cell = row.createCell(i);
            // 定义单元格为字符串类型
            cell.setCellType(HSSFCell.CELL_TYPE_STRING);
            // 在单元格中输入一些内容
            cell.setCellValue(headList[i]);
        }
        // ===============================================================
        if (dataList != null) {
            for (int n = 0; n < dataList.size(); n++) {
                // 在索引1的位置创建行
                HSSFRow row_value = sheet.createRow(n + 1);
                Map<String, Object> dataMap = dataList.get(n);
                // ===============================================================
                for (int i = 0; i < fieldList.length; i++) {
                    // 在索引0的位置创建单元格(左上端)
                    HSSFCell cell = row_value.createCell(i);
                    // 定义单元格为字符串类型
                    cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                    // 在单元格中输入一些内容
                    cell.setCellValue(objToString(dataMap.get(fieldList[i])));
                }
                // ===============================================================
            }
        }
        // 新建一输出文件流
        File file = SimpleTool.createFile(outPath,excelName);
        FileOutputStream fOut = new FileOutputStream(file);
        // 把相应的Excel 工作簿存盘
        workbook.write(fOut);
        fOut.flush();
        // 操作结束,关闭文件
        fOut.close();
        if(outPath.endsWith("/")){
            filePath = outPath + excelName;
        }else{
            filePath = outPath +"/"+ excelName;
        }
        return filePath;
    }
    private static String objToString(Object obj) {
        if (obj == null) {
            return "";
        } else {
            if (obj instanceof String) {
                return (String) obj;
            } else if (obj instanceof Date) {
                return null;// DateUtil.dateToString((Date)
                            // obj,DateUtil.DATESTYLE_SHORT_EX);
            } else {
                return obj.toString();
            }
        }
    }
    /**
     * 读取 Excel文件内容
     *
     * @param file
     * @param header 是否包括表头
     * @return
     * @throws Exception
     */
    public static List<List<String>> readExcelByeFileData(MultipartFile file, boolean header) throws Exception {
        String fileName = file.getOriginalFilename();
        if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {
            throw new TipsException("上传文件格式不正确");
        }
        // 结果集
        List<List<String>> list = new ArrayList<>();
        HSSFWorkbook hssfworkbook = new HSSFWorkbook(file.getInputStream());
        // 遍历该表格中所有的工作表,i表示工作表的数量 getNumberOfSheets表示工作表的总数
        for(int s=0;s<hssfworkbook.getNumberOfSheets();s++) {
            HSSFSheet hssfsheet = hssfworkbook.getSheetAt(s);
            int col = 0;
            // 遍历该行所有的行,j表示行数 getPhysicalNumberOfRows行的总数 去除标题
            for (int j = 0; j < hssfsheet.getPhysicalNumberOfRows(); j++) {
                HSSFRow hssfrow = hssfsheet.getRow(j);
                if(hssfrow!=null){
                    if(j == 0) {
                        col = hssfrow.getPhysicalNumberOfCells();
                        if(!header) {
                            //不包括表头
                            continue;
                        }
                    }
                    // 单行数据
                    List<String> arrayString = new ArrayList<>();
                    for (int i = 0; i < col; i++) {
                        HSSFCell cell = hssfrow.getCell(i);
                        if (cell == null) {
                            arrayString.add("");
                        } else if (cell.getCellType() == 0) {
                            // arrayString[i] = new Double(cell.getNumericCellValue()).toString();
                            if (HSSFCell.CELL_TYPE_NUMERIC == cell.getCellType()) {
                                short format = cell.getCellStyle().getDataFormat();
                                if(format == 14 || format == 31 || format == 57 || format == 58){
                                    //日期(中文时间格式的)
                                    Date d = cell.getDateCellValue();
                                    DateFormat formater = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                                    // DateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                    arrayString.add(formater.format(d));
                                    //arrayString[i] = formater.format(d);
                                }else if (HSSFDateUtil.isCellDateFormatted(cell)) {
                                    Date d = cell.getDateCellValue();
                                    //DateFormat formater = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
                                    DateFormat formater = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                                    arrayString.add(formater.format(d));
                                    //arrayString[i] = formater.format(d);
                                } else {
                                    if(HSSFCell.CELL_TYPE_STRING == cell.getCellType()){
                                        arrayString.add(cell.getStringCellValue());
                                        //arrayString[i] =cell.getStringCellValue();
                                    }else if(HSSFCell.CELL_TYPE_FORMULA==cell.getCellType()){
                                        arrayString.add(cell.getCellFormula());
                                        //arrayString[i] =cell.getCellFormula();
                                    }else if(HSSFCell.CELL_TYPE_NUMERIC== cell.getCellType()){
                                        HSSFDataFormatter dataFormatter = new HSSFDataFormatter();
                                        arrayString.add(dataFormatter.formatCellValue(cell));
                                        //arrayString[i] =dataFormatter.formatCellValue(cell);
                                    }
                                }
                            }
                        } else if(cell.getCellType() == Cell.CELL_TYPE_BLANK){
                            arrayString.add("");
                            //arrayString[i] = "";
                        } else { // 如果EXCEL表格中的数据类型为字符串型
                            arrayString.add(cell.getStringCellValue().trim());
                            //arrayString[i] = cell.getStringCellValue().trim();
                        }
                    }
                    list.add(arrayString);
                }
            }
        }
        return list;
    }
}
src/main/java/com/hx/util/FileUtil.java
New file
@@ -0,0 +1,74 @@
package com.hx.util;
import java.io.*;
/**
 * 文件读取工具类
 * @author ChenJiaHe
 * @Date 2020-06-17
 */
public class FileUtil {
    /**
     * 读取文件内容,作为字符串返回
     */
    public static String readFileAsString(String filePath) throws IOException {
        File file = new File(filePath);
        if (!file.exists()) {
            throw new FileNotFoundException(filePath);
        }
        if (file.length() > 1024 * 1024 * 1024) {
            throw new IOException("File is too large");
        }
        StringBuilder sb = new StringBuilder((int) (file.length()));
        // 创建字节输入流
        FileInputStream fis = new FileInputStream(filePath);
        // 创建一个长度为10240的Buffer
        byte[] bbuf = new byte[10240];
        // 用于保存实际读取的字节数
        int hasRead = 0;
        while ( (hasRead = fis.read(bbuf)) > 0 ) {
            sb.append(new String(bbuf, 0, hasRead));
        }
        fis.close();
        return sb.toString();
    }
    /**
     * 根据文件路径读取byte[] 数组
     */
    public static byte[] readFileByBytes(String filePath) throws IOException {
        File file = new File(filePath);
        if (!file.exists()) {
            throw new FileNotFoundException(filePath);
        } else {
            ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length());
            BufferedInputStream in = null;
            try {
                in = new BufferedInputStream(new FileInputStream(file));
                short bufSize = 1024;
                byte[] buffer = new byte[bufSize];
                int len1;
                while (-1 != (len1 = in.read(buffer, 0, bufSize))) {
                    bos.write(buffer, 0, len1);
                }
                byte[] var7 = bos.toByteArray();
                return var7;
            } finally {
                try {
                    if (in != null) {
                        in.close();
                    }
                } catch (IOException var14) {
                    var14.printStackTrace();
                }
                bos.close();
            }
        }
    }
}
src/main/java/com/hx/util/FileUtils.java
New file
@@ -0,0 +1,342 @@
package com.hx.util;
import com.hx.exception.TipsException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/** 文件处理工具
 * @author ChenJiaHe
 * @Date 2020-06-17
 */
public class FileUtils {
    private final static Logger logger = LoggerFactory.getLogger(FileUtils.class);
    private static int BUFFER_SIZE = 1024;
    /**
     * @param path
     * @MethodName fileIsExists
     * @Description 文件是否存在
     * @Author ChenJiaHe
     * @Date 2019/9/7 9:13
     * @Since JDK 1.8
     */
    public static boolean fileIsExists(String path) {
        File file = new File(path);
        if (file.exists()) {
            return true;
        } else {
            return false;
        }
    }
    /**
     * @param sourceFile
     * @param targetFile
     * @MethodName copyFile
     * @Description 复制文件
     * @Author ChenJiaHe
     * @Date 2019/9/7 9:36
     * @Since JDK 1.8
     */
    public static void copyFile(File sourceFile, File targetFile) throws IOException {
        BufferedInputStream inputStream = null;
        BufferedOutputStream outputStream = null;
        try {
            inputStream = new BufferedInputStream(new FileInputStream(sourceFile));
            outputStream = new BufferedOutputStream(new FileOutputStream(targetFile));
            byte[] b = new byte[BUFFER_SIZE];
            int len;
            while ((len = inputStream.read(b)) != -1) {
                outputStream.write(b, 0, len);
            }
            outputStream.flush();
        } catch (Exception e) {
            logger.error("copy file error", e);
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
        }
    }
    /**
     * @param path
     * @param fileType 文件类型,0 = 文件夹 1 = 文件
     * @MethodName getAllFiles
     * @Description 讀取文件夹下的,不包括子文件夹内
     * @Author ChenJiaHe
     * @Date 2019/9/17 15:56
     * @Since JDK 1.8
     */
    public static List<String> getAllFiles(String path, String fileType) {
        List<String> fileList = new ArrayList<>();
        File fileDic = new File(path);
        File[] files = fileDic.listFiles();
        for (File file : files) {
            if ("1".equals(fileType)) {
                if (file.isFile()) {
                    fileList.add(file.toString());
                }
            }
            if ("0".equals(fileType)) {
                if (file.isDirectory()) {
                    fileList.add(file.toString());
                }
            }
        }
        return fileList;
    }
    /**
     * @param path
     * @MethodName getFolderFiles
     * @Description 递归获取所有包括子文件夹的文件
     * @Author ChenJiaHe
     * @Date 2019/9/17 16:11
     * @Since JDK 1.8
     */
    public static void getAllFileName(String path, List<String> listFileName) {
        try {
            File file = new File(path);
            File[] files = file.listFiles();
            String[] names = file.list();
            if (names != null) {
                String[] completNames = new String[names.length];
                for (int i = 0; i < names.length; i++) {
                    completNames[i] = path + names[i];
                }
                listFileName.addAll(Arrays.asList(completNames));
            }
            for (File a : files) {
                // 如果文件夹下有子文件夹,获取子文件夹下的所有文件全路径。
                if (a.isDirectory()) {
                    getAllFileName(a.getAbsolutePath() + "\\", listFileName);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 读取文件内容,作为字符串返回
     */
    public static String readFileAsString(String filePath) throws IOException {
        File file = new File(filePath);
        if (!file.exists()) {
            throw new FileNotFoundException(filePath);
        }
        if (file.length() > 1024 * 1024 * 1024) {
            throw new IOException("File is too large");
        }
        StringBuilder sb = new StringBuilder((int) (file.length()));
        // 创建字节输入流
        FileInputStream fis = new FileInputStream(filePath);
        // 创建一个长度为10240的Buffer
        byte[] bbuf = new byte[10240];
        // 用于保存实际读取的字节数
        int hasRead = 0;
        while ( (hasRead = fis.read(bbuf)) > 0 ) {
            sb.append(new String(bbuf, 0, hasRead));
        }
        fis.close();
        return sb.toString();
    }
    /**
     * 根据文件路径读取byte[] 数组
     */
    public static byte[] readFileByBytes(String filePath) throws IOException {
        File file = new File(filePath);
        if (!file.exists()) {
            throw new FileNotFoundException(filePath);
        } else {
            ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length());
            BufferedInputStream in = null;
            try {
                in = new BufferedInputStream(new FileInputStream(file));
                short bufSize = 1024;
                byte[] buffer = new byte[bufSize];
                int len1;
                while (-1 != (len1 = in.read(buffer, 0, bufSize))) {
                    bos.write(buffer, 0, len1);
                }
                byte[] var7 = bos.toByteArray();
                return var7;
            } finally {
                try {
                    if (in != null) {
                        in.close();
                    }
                } catch (IOException var14) {
                    var14.printStackTrace();
                }
                bos.close();
            }
        }
    }
    /**
     *  2020-06-29
     *  cjh
     * 图片格式判断
     * */
    public static boolean imageFormatJudge(MultipartFile firs) {
        String imageName = firs.getOriginalFilename();
        //截取格式
        String suffix =imageName.substring(imageName.lastIndexOf(".") + 1);
        //格式字母转小写
        suffix = suffix.toLowerCase();
        //进行判断
        if(suffix.equals("png")) {
            return true;
        }else if(suffix.equals("jpg")){
            return true;
        }else if(suffix.equals("jpeg")){
            return true;
        }else {
            return false;
        }
    }
    /**图片上传的方法
     * 保存到服务器里面的
     * @param platformIconFile 图片文件
     * @param unifiedFolder NG指向的前端文件夹(统一文件夹),如:user/local/images/
     * @param saveFolder 保存到的文件夹,如:/bananer/
     * @param autoDateFolder 是否生成日期文件夹
     * @return 图片路径
     * 2020-06-29 ChenJiaHe
     */
    public static String handleFileUpload(MultipartFile platformIconFile,String unifiedFolder,String saveFolder
            ,boolean autoDateFolder) {
        String fileName = "";
        try {
            if(platformIconFile == null) {
                throw new TipsException("请上传图片!");
            }
            if(!imageFormatJudge(platformIconFile)) {
                throw new TipsException("请上传png、jpg和jpeg格式的图片!");
            }
            //设置图片大小
           // String.format("%.1f",platformIconFile.getSize()/1024.0);
            if(autoDateFolder){
                if(saveFolder.endsWith("/")){
                    saveFolder = saveFolder+dateFormat(new Date(),"yyyyMM")+"/";
                }else{
                    saveFolder = saveFolder+"/"+dateFormat(new Date(),"yyyyMM")+"/";
                }
            }
            fileName = dateFormat(new Date(),"yyyyMMddHHmmssSSS");
            if(unifiedFolder.endsWith("/")){
                if(saveFolder.startsWith("/")){
                    saveFolder = saveFolder.replaceFirst("/","");
                    unifiedFolder  = unifiedFolder + saveFolder;
                }else{
                    unifiedFolder  = unifiedFolder+saveFolder;
                }
            }else{
                if(saveFolder.startsWith("/")){
                    unifiedFolder  = unifiedFolder + saveFolder;
                }else{
                    unifiedFolder  = unifiedFolder+"/"+saveFolder;
                }
            }
            fileName = saveFolder+fileUp(platformIconFile,unifiedFolder,fileName);
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
        return fileName;
    }
    /**
     * 2020-06-29 ChenJiaHe
     * @param file             //文件对象
     * @param filePath        //上传路径
     * @param fileName        //文件名
     * @return  文件名
     */
    public static String fileUp(MultipartFile file, String filePath, String fileName){
        String extName = ""; // 扩展名格式:
        try {
            if (file.getOriginalFilename().lastIndexOf(".") >= 0){
                extName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
            }
            copyFile(file.getInputStream(), filePath, fileName+extName).replaceAll("-", "");
        } catch (IOException e) {
            System.out.println(e);
        }
        return fileName+extName;
    }
    /**
          * 写文件到当前目录的upload目录中
          *
          * @param in
          * @param fileName
          * @throws IOException
          */
    private static String copyFile(InputStream in, String dir, String realName)throws IOException {
        File file = new File(dir, realName);
        file.setWritable(true);
        if (!file.exists()) {
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            file.createNewFile();
        }
        org.apache.commons.io.FileUtils.copyInputStreamToFile(in, file);
        return realName;
    }
    /**
     *
     * @param date 时间
     * @param format 时间格式
     * @return 返回的时间格式字符串
     */
    public static String dateFormat(Date  date,String format) {
        SimpleDateFormat df = new SimpleDateFormat(format);//设置日期格式
        return df.format(date);
    }
    /**
     * @param stream 文件流
     * @param saveUrl 保存到的文件夹
     * @param fileName 文件图片
     * @return
     * @throws IOException
     */
    public static File inputStreamToFile(InputStream stream,String saveUrl,String fileName) throws IOException {
        if(saveUrl.endsWith("/")){
            saveUrl = saveUrl + fileName;
        }else{
            saveUrl = saveUrl +"/"+ fileName;
        }
        File targetFile = new File(saveUrl);
        org.apache.commons.io.FileUtils.copyInputStreamToFile(stream, targetFile);
        return targetFile;
    }
}
src/main/java/com/hx/util/GsonUtils.java
New file
@@ -0,0 +1,29 @@
/*
 * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
 */
package com.hx.util;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException;
import java.lang.reflect.Type;
/**
 * Json工具类.
 */
public class GsonUtils {
    private static Gson gson = new GsonBuilder().create();
    public static String toJson(Object value) {
        return gson.toJson(value);
    }
    public static <T> T fromJson(String json, Class<T> classOfT) throws JsonParseException {
        return gson.fromJson(json, classOfT);
    }
    public static <T> T fromJson(String json, Type typeOfT) throws JsonParseException {
        return (T) gson.fromJson(json, typeOfT);
    }
}
src/main/java/com/hx/util/HttpResponse.java
New file
@@ -0,0 +1,32 @@
package com.hx.util;
public class HttpResponse {
    private int code;
    private String content;
    public HttpResponse(int status, String content) {
        this.code = status;
        this.content = content;
    }
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public String toString(){
        return new StringBuilder("[ code = ").append(code)
                .append(" , content = ").append(content).append(" ]").toString();
    }
}
src/main/java/com/hx/util/HttpUtil.java
New file
@@ -0,0 +1,546 @@
package com.hx.util;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.apache.commons.io.IOUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.activation.MimetypesFileTypeMap;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
 * http 工具类
 */
public class HttpUtil {
    /**multipart/form-data 格式发送数据时各个部分分隔符的前缀,必须为 --*/
    private static final String BOUNDARY_PREFIX = "--";
    /**回车换行,用于一行的结尾*/
    private static final String LINE_END = "\r\n";
    public static String post(String requestUrl, String accessToken, String params)
            throws Exception {
        String contentType = "application/x-www-form-urlencoded";
        return HttpUtil.post(requestUrl, accessToken, contentType, params);
    }
    public static String post(String requestUrl, String accessToken, String contentType, String params)
            throws Exception {
        String encoding = "UTF-8";
        if (requestUrl.contains("nlp")) {
            encoding = "GBK";
        }
        return HttpUtil.post(requestUrl, accessToken, contentType, params, encoding);
    }
    public static String post(String requestUrl, String accessToken, String contentType, String params, String encoding)
            throws Exception {
        String url = requestUrl + "?access_token=" + accessToken;
        return HttpUtil.postGeneralUrl(url, contentType, params, encoding);
    }
    public static String postGeneralUrl(String generalUrl, String contentType, String params, String encoding)
            throws Exception {
        URL url = new URL(generalUrl);
        // 打开和URL之间的连接
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        // 设置通用的请求属性
        connection.setRequestProperty("Content-Type", contentType);
        connection.setRequestProperty("Connection", "Keep-Alive");
        connection.setUseCaches(false);
        connection.setDoOutput(true);
        connection.setDoInput(true);
        // 得到请求的输出流对象
        DataOutputStream out = new DataOutputStream(connection.getOutputStream());
        out.write(params.getBytes(encoding));
        out.flush();
        out.close();
        // 建立实际的连接
        connection.connect();
        // 获取所有响应头字段
        Map<String, List<String>> headers = connection.getHeaderFields();
        // 遍历所有的响应头字段
        for (String key : headers.keySet()) {
            System.err.println(key + "--->" + headers.get(key));
        }
        // 定义 BufferedReader输入流来读取URL的响应
        BufferedReader in = null;
        in = new BufferedReader(
                new InputStreamReader(connection.getInputStream(), encoding));
        String result = "";
        String getLine;
        while ((getLine = in.readLine()) != null) {
            result += getLine;
        }
        in.close();
        System.err.println("result:" + result);
        return result;
    }
    /** 请求http协议 获取信息工具 **/
    public static JSONObject HttpURLUtil(String url, String data) {
        HttpURLConnection con = null;
        URL u = null;
        String wxMsgXml = null;
        JSONObject obj = null;
        try {
            u = new URL(url);
            con = (HttpURLConnection) u.openConnection();
            con.setRequestMethod("POST");
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setUseCaches(false);
            con.setReadTimeout(5000);
            con.setRequestProperty("Charset", "UTF-8");
            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            if (data != null) {
                OutputStream os = con.getOutputStream();
                os.write(data.getBytes("utf-8"));
            }
            if (con.getResponseCode() != 200)
                throw new RuntimeException("请求url失败");
            // 读取返回内容
            wxMsgXml = IOUtils.toString(con.getInputStream(), "utf-8");
            obj = JSONObject.fromObject(wxMsgXml);
            // //System.out.println("HttpURLUtil:"+wxMsgXml);
        } catch (Exception e) {
            e.printStackTrace();
            obj = new JSONObject();
            try {
                obj.put("status", 1);
                obj.put("errMsg", e.getMessage());
            } catch (JSONException e1) {
                e1.printStackTrace();
            }
        } finally {
            if (con != null) {
                con.disconnect();
            }
        }
        return obj;
    }
    /** 请求http协议 获取信息工具 **/
    public static JSONObject HttpURLUtilJson(String url, String data) {
        HttpURLConnection con = null;
        URL u = null;
        String wxMsgXml = null;
        JSONObject obj = null;
        try {
            u = new URL(url);
            con = (HttpURLConnection) u.openConnection();
            con.setRequestMethod("POST");
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setUseCaches(false);
            con.setReadTimeout(5000);
            con.setRequestProperty("Charset", "UTF-8");
            con.setRequestProperty("Content-Type", "application/json");
            if (data != null) {
                OutputStream os = con.getOutputStream();
                os.write(data.getBytes("utf-8"));
            }
            if (con.getResponseCode() != 200)
                throw new RuntimeException("请求url失败");
            // 读取返回内容
            wxMsgXml = IOUtils.toString(con.getInputStream(), "utf-8");
            obj = JSONObject.fromObject(wxMsgXml);
            // //System.out.println("HttpURLUtil:"+wxMsgXml);
        } catch (Exception e) {
            e.printStackTrace();
            obj = new JSONObject();
            try {
                obj.put("status", 1);
                obj.put("errMsg", e.getMessage());
            } catch (JSONException e1) {
                e1.printStackTrace();
            }
        } finally {
            if (con != null) {
                con.disconnect();
            }
        }
        return obj;
    }
    /**
     * post 请求:以表单方式提交数据
     * <p>
     * 由于 multipart/form-data 不是 http 标准内容,而是属于扩展类型,
     * 因此需要自己构造数据结构,具体如下:
     * <p>
     * 1、首先,设置 Content-Type
     * <p>
     * Content-Type: multipart/form-data; boundary=${bound}
     * <p>
     * 其中${bound} 是一个占位符,代表我们规定的分割符,可以自己任意规定,
     * 但为了避免和正常文本重复了,尽量要使用复杂一点的内容
     * <p>
     * 2、设置主体内容
     * <p>
     * --${bound}
     * Content-Disposition: form-data; name="userName"
     * <p>
     * Andy
     * --${bound}
     * Content-Disposition: form-data; name="file"; filename="测试.excel"
     * Content-Type: application/octet-stream
     * <p>
     * 文件内容
     * --${bound}--
     * <p>
     * 其中${bound}是之前头信息中的分隔符,如果头信息中规定是123,那这里也要是123;
     * 可以很容易看到,这个请求提是多个相同部分组成的:
     * 每一部分都是以--加分隔符开始的,然后是该部分内容的描述信息,然后一个回车换行,然后是描述信息的具体内容;
     * 如果传送的内容是一个文件的话,那么还会包含文件名信息以及文件内容类型。
     * 上面第二部分是一个文件体的结构,最后以--分隔符--结尾,表示请求体结束
     *
     * @param urlStr      请求的url
     * @param filePathMap key 参数名,value 文件的路径
     * @param keyValues   普通参数的键值对
     * @param headers
     * @return
     * @throws IOException
     */
    public static HttpResponse postFormData(String urlStr, Map<String, String> filePathMap, Map<String, Object> keyValues, Map<String, Object> headers) throws IOException {
        HttpResponse response;
        HttpURLConnection conn = getHttpURLConnection(urlStr, headers);
        //分隔符,可以任意设置,这里设置为 MyBoundary+ 时间戳(尽量复杂点,避免和正文重复)
        String boundary = "MyBoundary" + System.currentTimeMillis();
        //设置 Content-Type 为 multipart/form-data; boundary=${boundary}
        conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
        //发送参数数据
        try (DataOutputStream out = new DataOutputStream(conn.getOutputStream())) {
            //发送普通参数
            if (keyValues != null && !keyValues.isEmpty()) {
                for (Map.Entry<String, Object> entry : keyValues.entrySet()) {
                    writeSimpleFormField(boundary, out, entry);
                }
            }
            //发送文件类型参数
            if (filePathMap != null && !filePathMap.isEmpty()) {
                for (Map.Entry<String, String> filePath : filePathMap.entrySet()) {
                    writeFile(filePath.getKey(), filePath.getValue(), boundary, out);
                }
            }
            //写结尾的分隔符--${boundary}--,然后回车换行
            String endStr = BOUNDARY_PREFIX + boundary + BOUNDARY_PREFIX + LINE_END;
            out.write(endStr.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
            response = new HttpResponse(500, e.getMessage());
            return response;
        }
        return getHttpResponse(conn);
    }
    public static HttpResponse postFormData(String urlStr, Map<String, MultipartFile> filePathMap, Map<String, Object> keyValues) throws IOException {
        HttpResponse response;
        HttpURLConnection conn = getHttpURLConnection(urlStr, null);
        //分隔符,可以任意设置,这里设置为 MyBoundary+ 时间戳(尽量复杂点,避免和正文重复)
        String boundary = "MyBoundary" + System.currentTimeMillis();
        //设置 Content-Type 为 multipart/form-data; boundary=${boundary}
        conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
        //发送参数数据
        try (DataOutputStream out = new DataOutputStream(conn.getOutputStream())) {
            //发送普通参数
            if (keyValues != null && !keyValues.isEmpty()) {
                for (Map.Entry<String, Object> entry : keyValues.entrySet()) {
                    writeSimpleFormField(boundary, out, entry);
                }
            }
            //发送文件类型参数
            if (filePathMap != null && !filePathMap.isEmpty()) {
                for (Map.Entry<String, MultipartFile> filePath : filePathMap.entrySet()) {
                    writeFile(filePath.getKey(), filePath.getValue(), boundary, out);
                }
            }
            //写结尾的分隔符--${boundary}--,然后回车换行
            String endStr = BOUNDARY_PREFIX + boundary + BOUNDARY_PREFIX + LINE_END;
            out.write(endStr.getBytes());
        } catch (Exception e) {
            response = new HttpResponse(500, e.getMessage());
            return response;
        }
        return getHttpResponse(conn);
    }
    /**
     * 获得连接对象
     *
     * @param urlStr
     * @param headers
     * @return
     * @throws IOException
     */
    private static HttpURLConnection getHttpURLConnection(String urlStr, Map<String, Object> headers) throws IOException {
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        //设置超时时间
        conn.setConnectTimeout(50000);
        conn.setReadTimeout(50000);
        //允许输入流
        conn.setDoInput(true);
        //允许输出流
        conn.setDoOutput(true);
        //不允许使用缓存
        conn.setUseCaches(false);
        //请求方式
        conn.setRequestMethod("POST");
        //设置编码 utf-8
        conn.setRequestProperty("Charset", "UTF-8");
        //设置为长连接
        conn.setRequestProperty("connection", "keep-alive");
        //设置其他自定义 headers
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, Object> header : headers.entrySet()) {
                conn.setRequestProperty(header.getKey(), header.getValue().toString());
            }
        }
        return conn;
    }
    private static HttpResponse getHttpResponse(HttpURLConnection conn) {
        HttpResponse response;
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
            int responseCode = conn.getResponseCode();
            StringBuilder responseContent = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                responseContent.append(line);
            }
            response = new HttpResponse(responseCode, responseContent.toString());
        } catch (Exception e) {
            e.printStackTrace();
            response = new HttpResponse(500, e.getMessage());
        }
        return response;
    }
    /**
     * 写文件类型的表单参数
     *
     * @param paramName 参数名
     * @param filePath  文件路径
     * @param boundary  分隔符
     * @param out
     * @throws IOException
     */
    private static void writeFile(String paramName, String filePath, String boundary,
                                  DataOutputStream out) {
        try (BufferedReader fileReader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath)))) {
            /**
             * 写分隔符--${boundary},并回车换行
             */
            String boundaryStr = BOUNDARY_PREFIX + boundary + LINE_END;
            out.write(boundaryStr.getBytes());
            /**
             * 写描述信息(文件名设置为上传文件的文件名):
             * 写 Content-Disposition: form-data; name="参数名"; filename="文件名",并回车换行
             * 写 Content-Type: application/octet-stream,并两个回车换行
             */
            String fileName = new File(filePath).getName();
            String contentDispositionStr = String.format("Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"", paramName, fileName) + LINE_END;
            out.write(contentDispositionStr.getBytes());
            String contentType = "Content-Type: application/octet-stream" + LINE_END + LINE_END;
            out.write(contentType.getBytes());
            String line;
            while ((line = fileReader.readLine()) != null) {
                out.write(line.getBytes());
            }
            //回车换行
            out.write(LINE_END.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 写文件类型的表单参数
     *
     * @param paramName 参数名
     * @param multipartFile  文件
     * @param boundary  分隔符
     * @param out
     * @throws IOException
     */
    private static void writeFile(String paramName, MultipartFile multipartFile, String boundary,
                                  DataOutputStream out) {
        try (BufferedReader fileReader = new BufferedReader(new InputStreamReader(multipartFile.getInputStream()))) {
            /**
             * 写分隔符--${boundary},并回车换行
             */
            String boundaryStr = BOUNDARY_PREFIX + boundary + LINE_END;
            out.write(boundaryStr.getBytes());
            /**
             * 写描述信息(文件名设置为上传文件的文件名):
             * 写 Content-Disposition: form-data; name="参数名"; filename="文件名",并回车换行
             * 写 Content-Type: application/octet-stream,并两个回车换行
             */
            String fileName = multipartFile.getName();
            String contentDispositionStr = String.format("Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"", paramName, fileName) + LINE_END;
            out.write(contentDispositionStr.getBytes());
            String contentType = "Content-Type: application/octet-stream" + LINE_END + LINE_END;
            out.write(contentType.getBytes());
            String line;
            while ((line = fileReader.readLine()) != null) {
                out.write(line.getBytes());
            }
            //回车换行
            out.write(LINE_END.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 写普通的表单参数
     *
     * @param boundary 分隔符
     * @param out
     * @param entry    参数的键值对
     * @throws IOException
     */
    private static void writeSimpleFormField(String boundary, DataOutputStream out, Map.Entry<String, Object> entry) throws IOException {
        //写分隔符--${boundary},并回车换行
        String boundaryStr = BOUNDARY_PREFIX + boundary + LINE_END;
        out.write(boundaryStr.getBytes());
        //写描述信息:Content-Disposition: form-data; name="参数名",并两个回车换行
        String contentDispositionStr = String.format("Content-Disposition: form-data; name=\"%s\"", entry.getKey()) + LINE_END + LINE_END;
        out.write(contentDispositionStr.getBytes());
        //写具体内容:参数值,并回车换行
        String valueStr = entry.getValue().toString() + LINE_END;
        out.write(valueStr.getBytes());
    }
    public static String formUpload(String urlStr, Map<String, String> textMap,
                                    Map<String, String> fileMap,String contentType) {
        String res = "";
        HttpURLConnection conn = null;
        // boundary就是request头和上传文件内容的分隔符
        String BOUNDARY = "---------------------------123821742118716";
        try {
            URL url = new URL(urlStr);
            conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(30000);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "Keep-Alive");
            // conn.setRequestProperty("User-Agent","Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)");
            conn.setRequestProperty("Content-Type","multipart/form-data; boundary=" + BOUNDARY);
            OutputStream out = new DataOutputStream(conn.getOutputStream());
            // text
            if (textMap != null) {
                StringBuffer strBuf = new StringBuffer();
                Iterator iter = textMap.entrySet().iterator();
                while (iter.hasNext()) {
                    Map.Entry entry = (Map.Entry) iter.next();
                    String inputName = (String) entry.getKey();
                    String inputValue = (String) entry.getValue();
                    if (inputValue == null) {
                        continue;
                    }
                    strBuf.append("\r\n").append("--").append(BOUNDARY).append("\r\n");
                    strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"\r\n\r\n");
                    strBuf.append(inputValue);
                }
                out.write(strBuf.toString().getBytes());
            }
            // file
            if (fileMap != null) {
                Iterator iter = fileMap.entrySet().iterator();
                while (iter.hasNext()) {
                    Map.Entry entry = (Map.Entry) iter.next();
                    String inputName = (String) entry.getKey();
                    String inputValue = (String) entry.getValue();
                    if (inputValue == null) {
                        continue;
                    }
                    File file = new File(inputValue);
                    String filename = file.getName();
                    //没有传入文件类型,同时根据文件获取不到类型,默认采用application/octet-stream
                    contentType = new MimetypesFileTypeMap().getContentType(file);
                    //contentType非空采用filename匹配默认的图片类型
                    if(!"".equals(contentType)){
                        if (filename.endsWith(".png")) {
                            contentType = "image/png";
                        }else if (filename.endsWith(".jpg") || filename.endsWith(".jpeg") || filename.endsWith(".jpe")) {
                            contentType = "image/jpeg";
                        }else if (filename.endsWith(".gif")) {
                            contentType = "image/gif";
                        }else if (filename.endsWith(".ico")) {
                            contentType = "image/image/x-icon";
                        }
                    }
                    if (contentType == null || "".equals(contentType)) {
                        contentType = "application/octet-stream";
                    }
                    StringBuffer strBuf = new StringBuffer();
                    strBuf.append("\r\n").append("--").append(BOUNDARY).append("\r\n");
                    strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"; filename=\"" + filename + "\"\r\n");
                    strBuf.append("Content-Type:" + contentType + "\r\n\r\n");
                    out.write(strBuf.toString().getBytes());
                    DataInputStream in = new DataInputStream(new FileInputStream(file));
                    int bytes = 0;
                    byte[] bufferOut = new byte[1024];
                    while ((bytes = in.read(bufferOut)) != -1) {
                        out.write(bufferOut, 0, bytes);
                    }
                    in.close();
                }
            }
            byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
            out.write(endData);
            out.flush();
            out.close();
            // 读取返回数据
            StringBuffer strBuf = new StringBuffer();
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line = null;
            while ((line = reader.readLine()) != null) {
                strBuf.append(line).append("\n");
            }
            res = strBuf.toString();
            reader.close();
            reader = null;
        } catch (Exception e) {
            System.out.println("发送POST请求出错。" + urlStr);
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.disconnect();
                conn = null;
            }
        }
        return res;
    }
}
src/main/java/com/hx/util/ImagesAddDomain.java
New file
@@ -0,0 +1,84 @@
package com.hx.util;
import net.sf.json.JSONArray;
/**图片路径加上域名
 * @author ChenJiaHe
 * @Date 2020-07-07
 */
public class ImagesAddDomain {
    /**
     * 图片路径加上域名
     * @param arrString 图片JSON字符串数组
     * @param domainName 域名
     * @return
     */
    public static JSONArray imagesAddDomain(String arrString, String domainName){
        JSONArray arr = new JSONArray();
        if(SimpleTool.checkNotNull(arrString)){
            JSONArray images = JSONArray.fromObject(arrString);
            for(int i = 0;i<images.size();i++){
                if(images.getString(i).indexOf("http")!=-1){
                    arr.add(images.getString(i));
                }else{
                    arr.add(urlAddDomain(images.getString(i),domainName));
                }
            }
        }
        return arr;
    }
    /**
     * 图片路径加上域名
     * @param imagesArr 图片数组
     * @param domainName 域名
     * @return
     */
    public static JSONArray imagesAddDomain(JSONArray imagesArr, String domainName){
        JSONArray arr = new JSONArray();
        if(SimpleTool.checkNotNull(imagesArr)){
            for(int i = 0;i<imagesArr.size();i++){
                if(imagesArr.getString(i).indexOf("http")!=-1){
                    arr.add(imagesArr.getString(i));
                }else{
                    arr.add(urlAddDomain(imagesArr.getString(i),domainName));
                }
            }
        }
        return arr;
    }
    /**
     * 图片路径加上域名
     * @param imagesUrl 图片路径
     * @param domainName 域名
     * @return
     */
    public static String urlAddDomain(String imagesUrl, String domainName){
        if(StringUtils.isEmpty(domainName)){
            return imagesUrl;
        }
        if(SimpleTool.checkNotNull(imagesUrl)){
            if(imagesUrl.indexOf("http")!=-1){
                return imagesUrl;
            }
            if(domainName.endsWith("/")){
                if(imagesUrl.startsWith("/")){
                    imagesUrl = imagesUrl.replaceFirst("/","");
                    imagesUrl = domainName+imagesUrl;
                }else{
                    imagesUrl = domainName+imagesUrl;
                }
            }else{
                if(imagesUrl.startsWith("/")){
                    imagesUrl = domainName+imagesUrl;
                }else{
                    imagesUrl = domainName+"/"+imagesUrl;
                }
            }
        }
        return imagesUrl;
    }
}
src/main/java/com/hx/util/JwtConstant.java
New file
@@ -0,0 +1,54 @@
package com.hx.util;
import com.alibaba.fastjson.JSONObject;
import io.jsonwebtoken.Claims;
/**
 * JWT 具备配置
 * @author chenjiahe
 * @Data 2020-06-09
 */
public class JwtConstant {
    public static void main(String[] args) {
        //每新开一个项目就重新生成JWT_SECERT秘钥
        //String s = BASE64.encryptBASE64("hx-haoqi168".getBytes());
        //System.out.println("s:"+s);
        JSONObject obj = new JSONObject();
        obj.put("id", "111");
        obj.put("adminRoleId", "22");
         String token = JwtTool.createJWT("111", obj.toString(), 300);
         System.out.println("token:"+token);
         //eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxMTEiLCJzdWIiOiLkuprpurvot4wiLCJpc3MiOiJ1c2VyIiwiaWF0IjoxNTkxODY4NjAxLCJleHAiOjE1OTE4Njg5MDF9.8m_TgK8m49r35-qQRQ0cGjL4r_jBlaVqb318vM00qrE
    }
    public static String JWT_ERRCODE_EXPIRE = "登录有效期已过!";
    public static String JWT_ERRCODE_FAIL = "登录无效,请重新登录!";
    public static String JWT_SECERT = "aGFvcWkxNjg=";//生成JWT的秘钥
    private Claims claims;
    private boolean success;
    private String errCode;
    /*************************************************************************/
    public Claims getClaims() {
        return claims;
    }
    public void setClaims(Claims claims) {
        this.claims = claims;
    }
    public boolean isSuccess() {
        return success;
    }
    public void setSuccess(boolean success) {
        this.success = success;
    }
    public String getErrCode() {
        return errCode;
    }
    public void setErrCode(String errCode) {
        this.errCode = errCode;
    }
}
src/main/java/com/hx/util/JwtTool.java
New file
@@ -0,0 +1,93 @@
package com.hx.util;
import java.util.Date;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.SignatureException;
/**
 * 生成token (登录,或者其他)
 * @author chenjiahe
 * @Data 20200609
 */
public class JwtTool {
    /**
     * 签发JWT
     * @param id 标识
     * @param subject 可以是JSON数据 尽可能少
     * @param ttlMillis 有效时间长度(秒),为空你认证时间
     * @return  String
     *
     */
    public static String createJWT(String id, String subject, long ttlMillis) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        SecretKey secretKey = generalKey();
        JwtBuilder builder = Jwts.builder()
                .setId(id)
                .setSubject(subject)   // 主题
                .setIssuer("user")     // 签发者
                .setIssuedAt(now)      // 签发时间
                .signWith(signatureAlgorithm, secretKey); // 签名算法以及密匙
        if (SimpleTool.checkNotNull(ttlMillis)&&ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis*1000;
            Date expDate = new Date(expMillis);
            builder.setExpiration(expDate); // 过期时间
        }
        return builder.compact();
    }
    /**
     * 验证JWT
     * @param jwtStr
     * @return JwtConstant
     */
    public static JwtConstant validateJWT(String jwtStr) {
        JwtConstant checkResult = new JwtConstant();
        Claims claims = null;
        try {
            claims = parseJWT(jwtStr);
            checkResult.setSuccess(true);
            checkResult.setClaims(claims);
        } catch (ExpiredJwtException e) {
            checkResult.setErrCode(JwtConstant.JWT_ERRCODE_EXPIRE);
            checkResult.setSuccess(false);
        } catch (SignatureException e) {
            checkResult.setErrCode(JwtConstant.JWT_ERRCODE_FAIL);
            checkResult.setSuccess(false);
        } catch (Exception e) {
            checkResult.setErrCode(JwtConstant.JWT_ERRCODE_FAIL);
            checkResult.setSuccess(false);
        }
        return checkResult;
    }
    public static SecretKey generalKey() {
        byte[] encodedKey = BASE64.decryptBASE64(JwtConstant.JWT_SECERT);
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }
    /**
     *
     * 解析JWT字符串
     * @param jwt
     * @return
     * @throws Exception
     */
    public static Claims parseJWT(String jwt) throws Exception {
        SecretKey secretKey = generalKey();
        return Jwts.parser()
            .setSigningKey(secretKey)
            .parseClaimsJws(jwt)
            .getBody();
    }
}
src/main/java/com/hx/util/MD5.java
New file
@@ -0,0 +1,64 @@
package com.hx.util;
import java.security.MessageDigest;
public class MD5 {
    private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
    public static String byteArrayToHexString(byte[] b) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++) {
            resultSb.append(byteToHexString(b[i]));
        }
        return resultSb.toString();
    }
    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0)
            n = 256 + n;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }
    public static String MD5Encode(String origin) {
        String resultString = null;
        try {
            resultString = new String(origin);
            MessageDigest md = MessageDigest.getInstance("MD5");
            resultString = byteArrayToHexString(md.digest(resultString
                    .getBytes()));
        } catch (Exception ex) {
        }
        return resultString;
    }
    /**密码加密 **/
    public static String encryption(String str){
        try{
             MessageDigest md5 = MessageDigest.getInstance("MD5");
             md5.update(str.getBytes());
             byte b[] = md5.digest();
             int i ;
             StringBuffer buf = new StringBuffer("");
             for(int j = 0;j<b.length;j++){
                 i = b[j];
                 if(i<0)
                     i+=256;
                 if(i<116)
                     buf.append("0");
                 buf.append(Integer.toHexString(i));
             }
             str = buf.toString().substring(8, 24);    //十六位
        }catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("加密程序错误!");
        }
        return str;
    }
}
src/main/java/com/hx/util/MD5Util.java
New file
@@ -0,0 +1,48 @@
package com.hx.util;
import java.security.MessageDigest;
public class MD5Util {
    private static String byteArrayToHexString(byte b[]) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++)
            resultSb.append(byteToHexString(b[i]));
        return resultSb.toString();
    }
    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0)
            n += 256;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }
    /**
     * @param origin 加密信息
     * @param charsetname 加密信息的字符串名称(可以为空)
     * @return
     */
    public static String MD5Encode(String origin, String charsetname) {
        String resultString = null;
        try {
            resultString = new String(origin);
            MessageDigest md = MessageDigest.getInstance("MD5");
            if (charsetname == null || "".equals(charsetname))
                resultString = byteArrayToHexString(md.digest(resultString
                        .getBytes()));
            else
                resultString = byteArrayToHexString(md.digest(resultString
                        .getBytes(charsetname)));
        } catch (Exception exception) {
        }
        return resultString;
    }
    private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
}
src/main/java/com/hx/util/MyRedisTemplate.java
New file
@@ -0,0 +1,139 @@
package com.hx.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
 * @PackageName com.hx.util
 * @ProjectName hx-parent
 * @Author: ChenJiaHe
 * @Date: Create in 16:51 2019/7/22
 * @Description:
 * @Copyright Copyright (c) 2019, hx01@163.com All Rights Reserved.
 */
@Component
public class MyRedisTemplate<E> {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SerializeUtil<E> serialize;
    public static ListOperations<String, String> list;
    /**
     * 根据键值获取value
     * @param key
     * @return
     */
    public E get(String key) {
        ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
        return key == null ? null : serialize.unserialize(opsForValue.get(key));
    }
    /**
     * 设置键值对(无超时时间)
     * @param key
     * @param value
     * @return
     */
    public boolean set(String key, E value) {
        ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
        try {
            opsForValue.set(key, serialize.serialize(value));
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 设置键值对 (设置有效时间,以秒为单位)
     *
     * @param key
     * @param value
     * @param expire
     * @return boolean
     */
    public boolean set(String key, E value, long expire) {
        ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
        try {
            opsForValue.set(key, serialize.serialize(value), expire, TimeUnit.SECONDS);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 根据key删除键值对
     *
     * @param key
     * @return
     */
    public boolean delete(String key) {
        try {
            redisTemplate.delete(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    /*
     * 模拟队列
     */
    /**
     * lpush 进队列
     *
     * @param key
     * @param value
     * @return
     */
    public Long lpush(String key, String value) {
        list = redisTemplate.opsForList();
        try {
            Long leftPush = list.leftPush(key, value);
            return leftPush;
        } catch (Exception e) {
            e.printStackTrace();
            return Long.valueOf(-1);
        }
    }
    /**
     * rpop 出队列
     *
     * @param key
     * @return
     */
    public String rpop(String key) {
        list = redisTemplate.opsForList();
        try {
            return list.rightPop(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 返回指定队列(list)名队列长度
     *
     * @param key
     * @return
     */
    public Long llen(String key) {
        list = redisTemplate.opsForList();
        return list.size(key);
    }
}
src/main/java/com/hx/util/NumberUtil.java
New file
@@ -0,0 +1,340 @@
package com.hx.util;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
/**
 * 数字工具
 *
 * @author mgchen
 *
 */
public class NumberUtil {
    private static DecimalFormat fmt = new DecimalFormat("0.00");
    private static DecimalFormat fmtOne = new DecimalFormat("0.0");
    private static DecimalFormat fmtThree = new DecimalFormat("0.000");
    /**
     * 获取指定格式的Double 类型数据
     * @param e
     *            要转换的数据源
     **/
    public static Double getTypeDouble(Double e) {
        fmt.setRoundingMode(RoundingMode.HALF_UP); // 保留小数点后两位并四舍五入,确保价钱准确
        Double d = Double.valueOf(fmt.format(e));
        return d;
    }
    /**
     * 获取指定格式的Double 类型数据
     *
     * @param e
     *            要转换的数据源
     **/
    public static Double getTypeDouble1(Double e) {
        fmtOne.setRoundingMode(RoundingMode.HALF_UP); // 保留小数点后两位并四舍五入,确保价钱准确
        Double d = Double.valueOf(fmtOne.format(e));
        return d;
    }
    public static Double getTypeDouble2(Double e) {
        fmtThree.setRoundingMode(RoundingMode.HALF_UP); // 保留小数点后两位并四舍五入,确保价钱准确
        Double d = Double.valueOf(fmtThree.format(e));
        return d;
    }
    /**
     * 把存储的分字符串转成元的浮点数 例如100到1.0
     */
    public static Double getYunFromFenStr(String fenStr) {
        return getTypeDouble(Integer.parseInt(fenStr) * 1.0 / 100);
    }
    /**
     * 把存储的分转成元的浮点数 例如100到1.0
     */
    public static Double getYunFromFen(Integer fen) {
        if (fen == null) {
            return 0D;
        }
        return getTypeDouble(fen * 1.0 / 100);
    }
    /**
     * 把存储的厘转成元的浮点数 例如1000到1.0
     */
    public static Double getYunFromLi(int li) {
        return getTypeDouble2(li * 1.0 / 1000);
    }
    /**
     * 把存储的数值转为百分比
     *
     * @param rate
     * @return
     */
    public static Double getRateFromInt(int rate) {
        return getTypeDouble(rate * 1.0 / 100);
    }
    /** 浮点数四舍五入取整 */
    public static int getRoundHalfUp(double tar) {
        return new BigDecimal(tar).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
    }
    /** 浮点数四舍五入取整 */
    public static int getRoundHalfDown(double tar) {
        Double d = Math.floor(tar);
        return d.intValue();
    }
    /**
     * 把一个double的字符串乘100 返回整数
     *
     * @return int 整数
     */
    public static int getYunFromFen(String str) {
        // BigDecimal b1 = new BigDecimal(str);
        // BigDecimal b2 = new BigDecimal("100");
        // return b1.multiply(b2).intValue();
        return multiply(str, "100").intValue();
    }
    /** 获取两位小数的整数 */
    public static int getTwoDecimalInt(Double d) {
        return Double.valueOf(fmt.format(d)).intValue();
    }
    /**
     * num1 除以num2 得到百分百 保留一位小数
     *
     * @param num1
     * @param num2
     * @return
     */
    public static Double getPercentage(Integer num1, Integer num2) {
        Double reNum = 0d;
        if (num1 == null || num2 == null || num1 == 0 || num2 == 0) {
            return reNum;
        }
        BigDecimal b1 = new BigDecimal(num1 * 100);
        BigDecimal b2 = new BigDecimal(num2);
        reNum = b1.divide(b2, 1, BigDecimal.ROUND_HALF_UP).doubleValue();
        return reNum;
    }
    /**
     * 将一个数除以100
     *
     * @param fen
     * @return Double
     */
    public static Double fenForYuan(int fen) {
        // BigDecimal b1 = new BigDecimal(fen);
        // BigDecimal b2 = new BigDecimal(100);
        // return b1.divide(b2).doubleValue();
        return divide(fen, 100);
    }
    /**
     * 将一个数除以100
     *
     * @param fen
     * @return Double
     */
    public static Double fenForYuan(String fen) {
        // BigDecimal b1 = new BigDecimal(fen);
        // BigDecimal b2 = new BigDecimal(100);
        // return b1.divide(b2).doubleValue();
        return divide(fen, "100");
    }
    public static void main(String[] args) {
        double d = 299999d;
        System.out.println(getTwoOfDouble(d));
    }
    /**
     * 两个数相除
     *
     * @param num1
     *            数字1
     * @param num2
     *            数字2
     * @return
     */
    public static Double divide(int num1, int num2) {
        return divide(num1 * 1D, num2 * 1D);
    }
    /**
     * 两个数相除- 保留两位小数点
     *
     * @param num1
     *            数字1
     * @param num2
     *            数字2
     * @return
     */
    public static Double divide(String num1, String num2) {
        return divide(Double.parseDouble(num1), Double.parseDouble(num1), 2);
    }
    /**
     * 两个数相除- 保留两位小数点
     *
     * @param num1
     *            数字1
     * @param num2
     *            数字2
     * @return
     */
    public static Double divide(Double num1, Double num2) {
        return divide(num1, num2, 2);
    }
    /**
     * 两个数相除
     *
     * @param num1
     *            数字1
     * @param num2
     *            数字2
     * @param scale
     *            小数位数, 默认保留2位
     * @return
     */
    public static Double divide(Double num1, Double num2, Integer scale) {
        if (scale == null || scale < 0) {
            scale = 2;
        }
        BigDecimal b1 = new BigDecimal(num1);
        BigDecimal b2 = new BigDecimal(num2);
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }
    /**
     *
     * 两个数相除
     *
     * @param num1
     *            数字1
     * @param num2
     *            数字2
     * @param scale
     *            小数位数, 默认保留2位
     * @return
     */
    public static Double divideDown(Double num1, Double num2, Integer scale) {
        if (scale == null || scale < 0) {
            scale = 2;
        }
        BigDecimal b1 = new BigDecimal(num1);
        BigDecimal b2 = new BigDecimal(num2);
        return b1.divide(b2, scale, BigDecimal.ROUND_DOWN).doubleValue();
    }
    /**
     * 两个Double数相乘
     *
     * @param num1
     * @param num2
     * @return Double
     *
     */
    public static Double multiply(Double num1, Double num2) {
        return multiply(num1.toString(), num2.toString());
    }
    /**
     * 两个Double数相乘
     *
     * @param num1
     * @param num2
     * @return Double
     *
     */
    public static Double multiply(String num1, String num2) {
        BigDecimal b1 = new BigDecimal(num1);
        BigDecimal b2 = new BigDecimal(num2);
        return b1.multiply(b2).doubleValue();
    }
    /**
     * 两个Double数相减
     *
     * @param v1
     * @param v2
     * @return Double
     */
    public static Double subtract(Double v1, Double v2) {
        return subtract(v2.toString(), v2.toString());
    }
    /**
     * 两个Double数相减
     *
     * @param v1
     * @param v2
     * @return Double
     */
    public static Double subtract(String v1, String v2) {
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.subtract(b2).doubleValue();
    }
    /**
     * 两个Double数相加
     *
     * @param v1
     * @param v2
     * @return Double
     */
    public static Double add(Double v1, Double v2) {
        return add(v1.toString(), v2.toString());
    }
    /**
     * 两个Double数相加
     *
     * @param v1
     * @param v2
     * @return Double
     */
    public static Double add(String v1, String v2) {
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.add(b2).doubleValue();
    }
    /** 从元转化为分,元为2位小数 */
    public static int getFenFromYun(String doubleStr) {
        return getRoundHalfUp(Double.parseDouble(doubleStr) * 100);
    }
    /**获取两位小数的字符串*/
    public static String getTwoOfDouble(double value)
    {
        String str = value + "";
        //如果有小数点,则两位小数
        int pointIndex = str.indexOf(".");
        if(pointIndex != -1)
        {
            int len = str.length();
            if(len - (pointIndex + 1) > 2)
            {
                return str.substring(0, pointIndex + 3);
            }
        }
        return str;
    }
}
src/main/java/com/hx/util/OSSUtil.java
New file
@@ -0,0 +1,126 @@
package com.hx.util;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.OSSObject;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
public class OSSUtil {
    private static OSSClient ossClient;
    public static OSSClient getOSSClient(String keyId, String keySecret, String endPoint)
    {
        if(ossClient == null)
        {
            ossClient = new OSSClient(endPoint, keyId, keySecret);
        }
        return ossClient;
    }
    /** 后端调用上传图片 */
    public static String uploadImg(String fileName, File imgFile, String keyId, String keySecret, String endPoint, String bucket) throws IOException {
        // // 压缩到文件夹
        // Thumbnails.of(imgFile).scale(1f).outputQuality(0.8f).toFile(SimpleToof.getRealpath("/upload/image/")
        // + imgName);
        // File file = new File(SimpleToof.getRealpath("/upload/image/") + imgName);
        // 创建OSSClient实例。
        OSSClient ossClient = new OSSClient("https://" + endPoint, keyId, keySecret);
        // 上传文件。<yourLocalFile>由本地文件路径加文件名包括后缀组成,例如/users/local/myfile.txt。
        // 判断压缩后的大小
        // if (file.length() > imgFile.length()) {
        ossClient.putObject(bucket, fileName, imgFile);
        // } else {
        // ossClient.putObject(BUCKET, fileName, file);
        // }
        // 关闭OSSClient。
        ossClient.shutdown();
        return "https://" + bucket + "." + endPoint + "/" + fileName;
    }
    /** 后端调用上传图片 */
    public static String uploadImg(String fileName, MultipartFile imgFile, String keyId, String keySecret, String endPoint, String bucket) {
        try {
            // 创建OSSClient实例。
            OSSClient ossClient = new OSSClient("https://" + endPoint, keyId, keySecret);
            ossClient.putObject(bucket, fileName, imgFile.getInputStream());
            ossClient.shutdown();
            return "https://" + bucket + "." + endPoint + "/" + fileName;
        }catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }
    /** 后端调用上传图片 */
    public static String uploadImg(String fileName, InputStream is, String keyId, String keySecret, String endPoint, String bucket) {
        try {
            // 创建OSSClient实例。
            OSSClient ossClient = new OSSClient("https://" + endPoint, keyId, keySecret);
            ossClient.putObject(bucket, fileName, is);
            ossClient.shutdown();
            return "https://" + bucket + "." + endPoint + "/" + fileName;
        }catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }
    public static byte[] getObject(String key, String keyId, String keySecret, String endPoint, String bucket) {
        byte[] resultByte = null;
        InputStream is = null;
        ByteArrayOutputStream swapStream = null;
        try {
            OSSObject ossObject = getOSSClient(keyId, keySecret, endPoint).getObject(bucket, key);
            is = ossObject.getObjectContent();
            swapStream = new ByteArrayOutputStream();
            byte[] buff = new byte[1024]; //buff用于存放循环读取的临时数据
            int rc = 0;
            while ((rc = is.read(buff, 0, 1024)) > 0) {
                swapStream.write(buff, 0, rc);
            }
            resultByte = swapStream.toByteArray(); //in_b为转换之后的结果
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(is != null)
            {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                is = null;
            }
            if(swapStream != null)
            {
                try {
                    swapStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                swapStream = null;
            }
        }
        return resultByte;
    }
}
src/main/java/com/hx/util/QRCodeUtil.java
New file
@@ -0,0 +1,238 @@
package com.hx.util;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import javax.imageio.ImageIO;
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
public class QRCodeUtil {
    // 二维码颜色==黑色
    private static final int BLACK = 0xFF000000;
    // 二维码颜色==白色
    private static final int WHITE = 0xFFFFFFFF;
    // 二维码图片格式==jpg和png两种
    private static final List<String> IMAGE_TYPE = new ArrayList<>();
    static {
        IMAGE_TYPE.add("jpg");
        IMAGE_TYPE.add("png");
    }
    /**
     * zxing方式生成二维码
     * 注意:
     * 1,文本生成二维码的方法独立出来,返回image流的形式,可以输出到页面
     * 2,设置容错率为最高,一般容错率越高,图片越不清晰, 但是只有将容错率设置高一点才能兼容logo图片
     * 3,logo图片默认占二维码图片的20%,设置太大会导致无法解析
     *
     * @param content  二维码包含的内容,文本或网址
     * @param path     生成的二维码图片存放位置
     * @param size     生成的二维码图片尺寸 可以自定义或者默认(250)
     * @param logoPath logo的存放位置
     * @param autoDateFolder 在存放链接上生成日期文件夹,格式是yyyyMM
     */
    public static String QRCodeCreate(String content, String path, Integer size, String logoPath,Boolean autoDateFolder) {
        try {
            Date newDate = new Date();
            if(autoDateFolder){
                if(autoDateFolder){
                    if(path.endsWith("/")){
                        path = path+dateFormat(newDate,"yyyyMM")+"/";
                    }else{
                        path = path+"/"+dateFormat(newDate,"yyyyMM")+"/";
                    }
                }
            }
            path = path+newDate.getTime()+".jpg";
            //图片类型
            String imageType = "jpg";
            //获取二维码流的形式,写入到目录文件中
            BufferedImage image = getBufferedImage(content, size, logoPath);
            //获得随机数
            Random random = new Random();
            //生成二维码存放文件
            File file = new File(path);
            if (!file.exists()) {
                file.mkdirs();
            }
            ImageIO.write(image, imageType, file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return path;
    }
    /**
     * 二维码流的形式,包含文本内容
     *
     * @param content  二维码文本内容
     * @param size     二维码尺寸
     * @param logoPath logo的存放位置
     * @return
     */
    public static BufferedImage getBufferedImage(String content, Integer size, String logoPath) {
        if (size == null || size <= 0) {
            size = 250;
        }
        BufferedImage image = null;
        try {
            // 设置编码字符集
            Map<EncodeHintType, Object> hints = new HashMap<>();
            //设置编码
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            //设置容错率最高
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            hints.put(EncodeHintType.MARGIN, 1);
            // 1、生成二维码
            MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
            BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, size, size, hints);
            // 2、获取二维码宽高
            int codeWidth = bitMatrix.getWidth();
            int codeHeight = bitMatrix.getHeight();
            // 3、将二维码放入缓冲流
            image = new BufferedImage(codeWidth, codeHeight, BufferedImage.TYPE_INT_RGB);
            for (int i = 0; i < codeWidth; i++) {
                for (int j = 0; j < codeHeight; j++) {
                    // 4、循环将二维码内容定入图片
                    image.setRGB(i, j, bitMatrix.get(i, j) ? BLACK : WHITE);
                }
            }
            //判断是否写入logo图片
            if (logoPath != null && !"".equals(logoPath)) {
                File logoPic = new File(logoPath);
                if (logoPic.exists()) {
                    Graphics2D g = image.createGraphics();
                    BufferedImage logo = ImageIO.read(logoPic);
                    int widthLogo = logo.getWidth(null) > image.getWidth() * 2 / 10 ? (image.getWidth() * 2 / 10) : logo.getWidth(null);
                    int heightLogo = logo.getHeight(null) > image.getHeight() * 2 / 10 ? (image.getHeight() * 2 / 10) : logo.getHeight(null);
                    int x = (image.getWidth() - widthLogo) / 2;
                    int y = (image.getHeight() - heightLogo) / 2;
                    // 开始绘制图片
                    g.drawImage(logo, x, y, widthLogo, heightLogo, null);
                    g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);
                    //边框宽度
                    g.setStroke(new BasicStroke(2));
                    //边框颜色
                    g.setColor(Color.WHITE);
                    g.drawRect(x, y, widthLogo, heightLogo);
                    g.dispose();
                    logo.flush();
                    image.flush();
                }
            }
        } catch (WriterException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return image;
    }
    /**
     * 给二维码图片添加Logo
     *
     * @param qrPic   二维码图片
     * @param logoPic logo图片
     * @param path    合成后的图片存储目录
     */
    public static boolean zxingCodeCreate(File qrPic, File logoPic, String path) {
        try {
            String imageType = path.substring(path.lastIndexOf(".") + 1).toLowerCase();
            if (!IMAGE_TYPE.contains(imageType)) {
                return false;
            }
            if (!qrPic.isFile() && !logoPic.isFile()) {
                return false;
            }
            //读取二维码图片,并构建绘图对象
            BufferedImage image = ImageIO.read(qrPic);
            Graphics2D g = image.createGraphics();
            //读取Logo图片
            BufferedImage logo = ImageIO.read(logoPic);
            //设置logo的大小,最多20%0
            int widthLogo = logo.getWidth(null) > image.getWidth() * 2 / 10 ? (image.getWidth() * 2 / 10) : logo.getWidth(null);
            int heightLogo = logo.getHeight(null) > image.getHeight() * 2 / 10 ? (image.getHeight() * 2 / 10) : logo.getHeight(null);
            // 计算图片放置位置,默认在中间
            int x = (image.getWidth() - widthLogo) / 2;
            int y = (image.getHeight() - heightLogo) / 2;
            // 开始绘制图片
            g.drawImage(logo, x, y, widthLogo, heightLogo, null);
            g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);
            //边框宽度
            g.setStroke(new BasicStroke(2));
            //边框颜色
            g.setColor(Color.WHITE);
            g.drawRect(x, y, widthLogo, heightLogo);
            g.dispose();
            logo.flush();
            image.flush();
            File newFile = new File(path);
            if (!newFile.exists()) {
                newFile.mkdirs();
            }
            ImageIO.write(image, imageType, newFile);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 二维码的解析方法
     *
     * @param path 二维码图片目录
     * @return
     */
    public static Result zxingCodeAnalyze(String path) {
        try {
            MultiFormatReader formatReader = new MultiFormatReader();
            File file = new File(path);
            if (file.exists()) {
                BufferedImage image = ImageIO.read(file);
                LuminanceSource source = new BufferedImageLuminanceSource(image);
                Binarizer binarizer = new HybridBinarizer(source);
                BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
                Map hints = new HashMap();
                hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
                Result result = formatReader.decode(binaryBitmap, hints);
                return result;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     *
     * @param date 时间
     * @param format 时间格式
     * @return 返回的时间格式字符串
     */
    public static String dateFormat(Date  date,String format) {
        SimpleDateFormat df = new SimpleDateFormat(format);//设置日期格式
        return df.format(date);
    }
}
src/main/java/com/hx/util/RegValidatorUtil.java
New file
@@ -0,0 +1,254 @@
package com.hx.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 正则表达式验证工�?
 * @author mgchen
 *
 */
public class RegValidatorUtil {
    /**
    * 验证邮箱
    *
    * @param str 待验证的字符
    * @return 如果是符合的字符�?,返回 <b>true </b>,否则�? <b>false </b>
    */
    public static boolean isEmail(String str) {
        String regex = "^([\\w-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([\\w-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$";
        return match(regex, str);
    }
    /**
    * 验证IP地址
    *
    * @param str 待验证的字符�?
    * @return 如果是符合格式的字符�?,返回 <b>true </b>,否则�? <b>false </b>
    */
    public static boolean isIP(String str) {
        String num = "(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)";
        String regex = "^" + num + "\\." + num + "\\." + num + "\\." + num + "$";
        return match(regex, str);
    }
    /**
    * 验证网址Url
    *
    * @param str 待验证的字符�?
    * @return 如果是符合格式的字符�?,返回 <b>true </b>,否则�? <b>false </b>
    */
    public static boolean IsUrl(String str) {
        String regex = "http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?";
        return match(regex, str);
    }
    /**
    * 验证电话号码
    *
    * @param str 待验证的字符�?
    * @return 如果是符合格式的字符�?,返回 <b>true </b>,否则�? <b>false </b>
    */
    public static boolean IsTelephone(String str) {
        String regex = "^(\\d{3,4}-)?\\d{6,8}$";
        return match(regex, str);
    }
    /**
    * 验证输入密码条件(字符与数据同时出�?)
    *
    * @param str 待验证的字符�?
    * @return 如果是符合格式的字符�?,返回 <b>true </b>,否则�? <b>false </b>
    */
    public static boolean IsPassword(String str) {
        String regex = "[A-Za-z0-9]+";
        return match(regex, str);
    }
    /**
    * 验证输入密码长度 (6-18�?)
    *
    * @param str 待验证的字符�?
    * @return 如果是符合格式的字符�?,返回 <b>true </b>,否则�? <b>false </b>
    */
    public static boolean IsPasswLength(String str) {
        String regex = "^\\d{6,18}$";
        return match(regex, str);
    }
    /**
    * 验证输入邮政编号
    *
    * @param str 待验证的字符�?
    * @return 如果是符合格式的字符�?,返回 <b>true </b>,否则�? <b>false </b>
    */
    public static boolean IsPostalcode(String str) {
        String regex = "^\\d{6}$";
        return match(regex, str);
    }
    /**
    * 验证输入手机号码
    *
    * @param str 待验证的字符�?
    * @return 如果是符合格式的字符�?,返回 <b>true </b>,否则�? <b>false </b>
    */
    public static boolean IsHandset(String str) {
        String regex = "^[1]+[3,5]+\\d{9}$";
        return match(regex, str);
    }
    /**
    * 验证输入身份证号
    *
    * @param str 待验证的字符�?
    * @return 如果是符合格式的字符�?,返回 <b>true </b>,否则�? <b>false </b>
    */
    public static boolean IsIDcard(String str) {
        String regex = "(^\\d{18}$)|(^\\d{15}$)";
        return match(regex, str);
    }
    /**
    * 验证输入两位小数
    *
    * @param str 待验证的字符�?
    * @return 如果是符合格式的字符�?,返回 <b>true </b>,否则�? <b>false </b>
    */
    public static boolean IsDecimal(String str) {
        String regex = "^[0-9]+(.[0-9]{2})?$";
        return match(regex, str);
    }
    /**
    * 验证输入�?年的12个月
    *
    * @param str 待验证的字符�?
    * @return 如果是符合格式的字符�?,返回 <b>true </b>,否则�? <b>false </b>
    */
    public static boolean IsMonth(String str) {
        String regex = "^(0?[[1-9]|1[0-2])$";
        return match(regex, str);
    }
    /**
    * 验证输入�?个月�?31�?
    *
    * @param str 待验证的字符�?
    * @return 如果是符合格式的字符�?,返回 <b>true </b>,否则�? <b>false </b>
    */
    public static boolean IsDay(String str) {
        String regex = "^((0?[1-9])|((1|2)[0-9])|30|31)$";
        return match(regex, str);
    }
    /**
    * 验证日期时间
    *
    * @param str 待验证的字符�?
    * @return 如果是符合网�?格式的字符串,返回 <b>true </b>,否则�? <b>false </b>
    */
    public static boolean isDate(String str) {
        // 严格验证时间格式�?(匹配[2002-01-31], [1997-04-30],
        // [2004-01-01])不匹�?([2002-01-32], [2003-02-29], [04-01-01])
        // String regex =
        // "^((((19|20)(([02468][048])|([13579][26]))-02-29))|((20[0-9][0-9])|(19[0-9][0-9]))-((((0[1-9])|(1[0-2]))-((0[1-9])|(1\\d)|(2[0-8])))|((((0[13578])|(1[02]))-31)|(((01,3-9])|(1[0-2]))-(29|30)))))$";
        // 没加时间验证的YYYY-MM-DD
        // String regex =
        // "^((((1[6-9]|[2-9]\\d)\\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-0?2-(0?[1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$";
        // 加了时间验证的YYYY-MM-DD 00:00:00
        String regex = "^((((1[6-9]|[2-9]\\d)\\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-0?2-(0?[1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-)) (20|21|22|23|[0-1]?\\d):[0-5]?\\d:[0-5]?\\d$";
        return match(regex, str);
    }
    /**
    * 验证数字输入
    *
    * @param str 待验证的字符�?
    * @return 如果是符合格式的字符�?,返回 <b>true </b>,否则�? <b>false </b>
    */
    public static boolean IsNumber(String str) {
        String regex = "^[0-9]*$";
        return match(regex, str);
    }
    /**
    * 验证非零的正整数
    *
    * @param str 待验证的字符�?
    * @return 如果是符合格式的字符�?,返回 <b>true </b>,否则�? <b>false </b>
    */
    public static boolean IsIntNumber(String str) {
        String regex = "^[1-9][0-9]*$";
        return match(regex, str);
    }
    /**
    * 验证大写字母
    *
    * @param str 待验证的字符�?
    * @return 如果是符合格式的字符�?,返回 <b>true </b>,否则�? <b>false </b>
    */
    public static boolean IsUpChar(String str) {
        String regex = "^[A-Z]+$";
        return match(regex, str);
    }
    /**
    * 验证小写字母
    *
    * @param str 待验证的字符�?
    * @return 如果是符合格式的字符�?,返回 <b>true </b>,否则�? <b>false </b>
    */
    public static boolean IsLowChar(String str) {
        String regex = "^[a-z]+$";
        return match(regex, str);
    }
    /**
    * 验证验证输入字母
    *
    * @param str 待验证的字符�?
    * @return 如果是符合格式的字符�?,返回 <b>true </b>,否则�? <b>false </b>
    */
    public static boolean IsLetter(String str) {
        String regex = "^[A-Za-z]+$";
        return match(regex, str);
    }
    /**
    * 验证验证输入汉字
    *
    * @param str 待验证的字符�?
    * @return 如果是符合格式的字符�?,返回 <b>true </b>,否则�? <b>false </b>
    */
    public static boolean IsChinese(String str) {
        String regex = "^[\u4e00-\u9fa5],{0,}$";
        return match(regex, str);
    }
    /**
    * 验证验证输入字符�?
    *
    * @param str 待验证的字符�?
    * @return 如果是符合格式的字符�?,返回 <b>true </b>,否则�? <b>false </b>
    */
    public static boolean IsLength(String str) {
        String regex = "^.{8,}$";
        return match(regex, str);
    }
    /**
    * @param regex
    * 正则表达式字符串
    * @param str
    * 要匹配的字符�?
    * @return 如果str 符合 regex的正则表达式格式,返回true, 否则返回 false;
    */
    private static boolean match(String regex, String str) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        return matcher.matches();
    }
}
src/main/java/com/hx/util/RequestMethod.java
New file
@@ -0,0 +1,152 @@
package com.hx.util;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class RequestMethod {
    /**
     * 发送Post请求
     * @param path 请求路径
     * @param params 请求参数
     * @param encoding 编码
     * @return 服务器端内容
     */
    public static String sendPOSTRequest(String path, Map<String, String> params, String encoding) throws Exception{
        StringBuilder data = new StringBuilder();
        if(params!=null && !params.isEmpty()){
            for(Map.Entry<String, String> entry : params.entrySet()){
                data.append(entry.getKey()).append("=");
                data.append(URLEncoder.encode(entry.getValue(), encoding));
                data.append("&");
            }
            data.deleteCharAt(data.length() - 1);
        }
        byte[] entity = data.toString().getBytes();//生成实体数据
        HttpURLConnection conn = (HttpURLConnection) new URL(path).openConnection();
        conn.setConnectTimeout(5000);
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);//允许对外输出数据
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setRequestProperty("Content-Length", String.valueOf(entity.length));
        OutputStream outStream = conn.getOutputStream();
        outStream.write(entity);
        if(conn.getResponseCode() == 200){
            return StreamUtils.InputStreamTOString(conn.getInputStream()) ;
        }
        return null;
    }
    /**
     * 发送Post请求
     * @param path 请求路径
     * @param content 发送内容
     * @param encoding 编码
     * @return 服务器端内容
     */
    public static String sendPOSTRequest(String path, String content, String encoding){
        //byte[] entity = content.toString().getBytes();//生成实体数据
        try{
            HttpURLConnection conn = (HttpURLConnection) new URL(path).openConnection();
            conn.setConnectTimeout(5000);
            conn.setRequestMethod("POST");
            conn.setDoOutput(true);//允许对外输出数据
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestProperty("Charset", "utf-8");
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            //conn.setRequestProperty("Content-Length", String.valueOf(entity.length));
            OutputStreamWriter outStream = new OutputStreamWriter(conn.getOutputStream(),"UTF-8");
            outStream.write(content);
            outStream.flush();
            if(conn.getResponseCode() == 200){
                return StreamUtils.InputStreamTOString(conn.getInputStream());
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 发送Post请求
     * @param path 请求路径
     * @param entity 发送内容
     * @param encoding 编码
     * @return 服务器端内容
     */
    public static String sendPOSTRequest(String path, byte[] entity, String encoding) throws Exception{
        System.out.println("entity:" + entity.length);
        HttpURLConnection conn = (HttpURLConnection) new URL(path).openConnection();
        conn.setConnectTimeout(5000);
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);//允许对外输出数据
        conn.setRequestProperty("Content-Type", "application/octet-stream");
        conn.setRequestProperty("Accept", "application/octet-stream");
        conn.setRequestProperty("Content-Length", String.valueOf(entity.length));
        OutputStream outStream = conn.getOutputStream();
        outStream.write(entity);
        if(conn.getResponseCode() == 200){
            return StreamUtils.InputStreamTOString(conn.getInputStream());
        }
        return null;
    }
    /**
     * 发送GET请求
     * @param path 请求路径
     * @param params 请求参数
     * @return 服务器端内容
     */
    public static String sendGETRequest(String path, Map<String, String> params, String ecoding) throws Exception{
        // http://192.168.1.100:8080/web/ManageServlet?title=xxx&timelength=90
        StringBuilder url = new StringBuilder(path);
        if(params!=null){
            url.append("?");
                for(Map.Entry<String, String> entry : params.entrySet()){
                    url.append(entry.getKey()).append("=");
                    url.append(URLEncoder.encode(entry.getValue(), ecoding));
                    url.append("&");
                }
            url.deleteCharAt(url.length() - 1);
        }
        HttpURLConnection conn = (HttpURLConnection)new URL(url.toString()).openConnection();
        conn.setConnectTimeout(5000);
        conn.setRequestMethod("GET");
        if(conn.getResponseCode() == 200){
            return StreamUtils.InputStreamTOString(conn.getInputStream()) ;
        }
        return null;
    }
    public static String msg(InputStream in) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String line;
        List<String> lines  = new ArrayList<String>();
        while((line = br.readLine())!=null){
            lines.add(line);
        }
        if(lines.size()>0){
            String f = lines.get(0);
            if(f.indexOf("200")!=-1){
                String e = lines.get(lines.size()-1);
                return e;
            }else{
                return null;
            }
        }else{
            return null;
        }
    }
}
src/main/java/com/hx/util/SerializeUtil.java
New file
@@ -0,0 +1,72 @@
package com.hx.util;
import org.springframework.stereotype.Component;
import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
/**
 * @PackageName com.hx.util
 * @ProjectName hx-parent
 * @Author: ChenJiaHe
 * @Date: Create in 16:52 2019/7/22
 * @Description:
 * @Copyright Copyright (c) 2019, hx01@163.com All Rights Reserved.
 */
@Component
public class SerializeUtil<E> {
    public String serialize(E object) {
        ObjectOutputStream oos = null;
        ByteArrayOutputStream baos = null;
        try {
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(object);
            String str = baos.toString("ISO-8859-1");
            return URLEncoder.encode(str, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                baos.close();
                oos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    @SuppressWarnings("unchecked")
    public E unserialize(String serializeStr) {
        String readStr = "";
        if (serializeStr == null || "".equals(serializeStr)) {
            return null;
        }
        try {
            readStr = URLDecoder.decode(serializeStr, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        ObjectInputStream ois = null;
        InputStream bais = null;
        try {
            bais = new ByteArrayInputStream(readStr.getBytes("ISO-8859-1"));
            ois = new ObjectInputStream(bais);
            return (E) ois.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                ois.close();
                bais.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}
src/main/java/com/hx/util/SimpleEncrypt.java
New file
@@ -0,0 +1,104 @@
package com.hx.util;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/***
 * �?单的加密程序,和解密程序
 *
 * @author mq.c
 *
 */
public class SimpleEncrypt {
    /**
     * 获取指定长度随机的字符串
     *
     * @param getNum
     * @return
     */
    private static String generateCheckCode(Integer getNum) {
        // abcdefghijklmnopqrstuvwxyz
        // String chars =
        // "123456789.AB2CD3EF7G;HI5JK5LMN/OPQR8ST.UVW7X9YZ?~!@#$%^&*()_+{}:>?<|/.,';][=-";
        // String chars =
        // "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@#$%^&*()_+{}|:<>?/.,';][\\=-";
        String chars = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789abcdefghijklmnopqrstuvwxyz._?";
        String[] charsx = chars.split("");
        // String[] charsx = chars.split("");
        List<String> list = Arrays.asList(charsx);
        Collections.shuffle(list);
        StringBuffer buff = new StringBuffer();
        Random random = new Random();
        for (int i = 0; i < getNum; i++) {
            int rand = random.nextInt(list.size());
            // buff.append(chars.charAt(rand));
            buff.append(list.get(rand));
        }
        return buff.toString();
    }
    /**
     * 对字符串进行简易加密(不要在意那种很容易被人破解的小细节)
     * 该加密采用"前面13位随机码"+dataString+"后9位随机码",组拼成一个字符串,进行BASE64加密得出的加密值
     *
     * @param dataString
     *            要进行加密的数据源
     * @return
     */
    public static String simpleEnCode(String dataString) {
        // 组拼随机值
        String ranString = generateCheckCode(13).toString() + dataString + generateCheckCode(9).toString();
        System.out.println(ranString);
        // 进行加密 sun.misc.BASE64Encoder.BASE64Encoder()
        String enCode = new BASE64Encoder().encodeBuffer(ranString.getBytes());
        return enCode;
    }
    /***
     * 对用com.bang.units.SimpleEncrypt.simpleEnCode加密过的字符串进行解密
     *
     * 该加密采用"前面13位随机码"+dataString+"后9位随机码",组拼成一个字符串,进行BASE64加密得出的加密值
     *
     * @param dataString
     *            要进行解密的数据源
     * @return
     */
    public static String simpleDeCode(String dataString) throws Exception {
        // 进行解密sun.misc.BASE64Decoder.BASE64Decoder()
        byte[] enCode = new BASE64Decoder().decodeBuffer(dataString);
        // 解得随机值
        String ranString = new String(enCode);
        // System.out.println("simpleDeCode:" + ranString);
        // 截取出有效位置参数
        String daString = ranString.substring(13, ranString.length() - 9);
        return daString;
    }
    public static void main(String[] args) throws Exception {
        String chars = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ?~!@#$%^&*()_+{}:>?<|/.,';][=-`";
        String[] charsx = chars.split("");
        List<String> list = Arrays.asList(charsx);
        Collections.shuffle(list);
        // for (String string : list) {
        // System.out.println(string);
        // }
        String str = "15648sadf";
        String eStr = simpleEnCode(str);
        System.out.println(eStr);
        String dStr = simpleDeCode(eStr);
        System.out.println(dStr);
    }
}
src/main/java/com/hx/util/SimpleTool.java
New file
@@ -0,0 +1,1053 @@
package com.hx.util;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.FileNameMap;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.IOUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDataFormatter;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
public class SimpleTool {
    public static SimpleDateFormat myformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public static DecimalFormat fmt = new DecimalFormat("0.00");
    public static Byte[] lock = new Byte[] {0};
    /**
     * 后台格式构建返回值格式列表-后台获取列表
     * @param count 返回总条数
     * @return JSONObject 特定格式的JSONObject
     */
    public static JSONObject resAdminLsit(Integer status,String errMsg,JSONArray arr,Integer count){
        JSONObject fObj = new JSONObject();
        try{
            fObj.put("code", status);
            fObj.put("count", count);
            fObj.put("msg", errMsg);
            fObj.put("data", arr);
        }catch (Exception e) {
            e.printStackTrace();
        }
        return fObj;
    }
    /**
     * 获取指定格式的Double 类型数据
     *
     * @param type
     *            转换格式的类型 默认为 "#.#"
     * @param e
     *            要转换的数据源
     **/
    public static Double getTypeDouble(String type, Double e) {
        if (!checkNotNull(type))
            type = "0.00";
        fmt = new DecimalFormat(type);
        fmt.setRoundingMode(RoundingMode.HALF_UP); // 保留小数点后两位并四舍五入,确保价钱准确
        Double d = Double.valueOf(fmt.format(e));
        return d;
    }
    /**
     * 首字母大写
     *
     * @param str
     */
    public static String capitalized(String str) {
        if ("".equals(str.trim()) || str == null) {
            return "";
        }
        String key = str.substring(0, 1).toUpperCase();
        String keys = key + str.substring(1, str.length());
        return keys;
    }
    /** 判断参数是否为null,如果null抛出对应异常 */
    public static void checkErrMsg(Object obj, String errMsg) {
        if (!checkNotNull(obj))
            throw new RuntimeException(errMsg);
    }
    /*** 创建文件(自动生成文件夹。)(需要真实路径) **/
    public static File createFile(String mkdirPath, String fileName) throws IOException {
        System.out.println(mkdirPath + fileName);
        // mkdirPath =
        // "E:\\work\\soft\\MyEclipse\\apache-tomcat-7.0.61\\webapps\\ROOT\\";
        File f = new File(mkdirPath);
        if (!f.exists()) {
            f.mkdirs();
        }
        File file = new File(f, fileName);
        if (!file.exists()) {
            file.createNewFile();
        }
        // System.out.println(file.getAbsolutePath());
        return file;
    }
    /**
     * 构建返回值格式
     *
     * @param status
     *            返回状态
     * @param errMsg
     *            返回附带信息
     * @param inf
     *            返回实体值
     * @return JSONObject 特定格式的JSONObject
     */
    public static JSONObject res(Integer status, String errMsg, JSONObject inf) {
        JSONObject res = new JSONObject();
        JSONObject fObj = new JSONObject();
        try {
            res.put("status", status);
            res.put("errMsg", errMsg);
            fObj.put("res", res);
            fObj.put("inf", inf);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fObj;
    }
    /**
     * Date类型转换为10位时间戳
     *
     * @param time
     * @return
     */
    public static Integer DateToTimestamp(Date time) {
        Timestamp ts = new Timestamp(time.getTime());
        return (int) ((ts.getTime()) / 1000);
    }
    /** 判断当前时间是什么时候 **/
    public static Boolean IsTime(Date date, Integer year, Integer month, Integer day, Integer hour, Integer minute) {
        Calendar cal = new GregorianCalendar();
        cal.setTime(date);
        if (year != null) {
            int iyear = cal.get(Calendar.YEAR);
            if (iyear != year)
                return false;
        }
        if (month != null) {
            int imonth = cal.get(Calendar.MONTH);// 获取月份(月份从0开始计算的)
            imonth = imonth + 1;
            if (imonth != month)
                return false;
        }
        if (day != null) {
            int iday = cal.get(Calendar.DATE);// 获取日
            if (iday != day)
                return false;
        }
        if (hour != null) {
            int ihour = cal.get(Calendar.HOUR_OF_DAY);// 24小时 0- 23
            if (ihour != hour)
                return false;
        }
        if (minute != null) {
            int iminute = cal.get(Calendar.MINUTE);
            if (iminute != minute)
                return false;
        }
        // Boolean b = yearTag && monthTag && dayTag && hourTag && minuteTag;
        return true;
    }
    /**
     * 根据具体时间属性判断是否相同
     *
     */
    public static Boolean DateEquals(Date date1, Date date2, Boolean year, Boolean month, Boolean day, Boolean hour,
            Boolean minute) {
        Calendar calendar1 = new GregorianCalendar();
        Calendar calendar2 = new GregorianCalendar();
        calendar1.setTime(date1);
        calendar2.setTime(date2);
        if (year) {
            if (calendar1.get(Calendar.YEAR) != calendar2.get(Calendar.YEAR)) {
                return false;
            }
        }
        if (month) {
            if (calendar1.get(Calendar.MONTH) != calendar2.get(Calendar.MONTH)) {
                return false;
            }
        }
        if (day) {
            if (calendar1.get(Calendar.DATE) != calendar2.get(Calendar.DATE)) {
                return false;
            }
        }
        if (year) {
            if (calendar1.get(Calendar.HOUR_OF_DAY) != calendar2.get(Calendar.HOUR_OF_DAY)) {
                return false;
            }
        }
        if (year) {
            if (calendar1.get(Calendar.MINUTE) != calendar2.get(Calendar.MINUTE)) {
                return false;
            }
        }
        // Boolean b = yearTag && monthTag && dayTag && hourTag && minuteTag;
        return true;
    }
    /** 获取10位数时间戳 */
    public static Integer getTenTime(Date date) {
        Timestamp ts = new Timestamp(date.getTime());
        return (int) ((ts.getTime()) / 1000);
    }
    /**
     * 获取指定日期的明天 difDay 把日期往后增加一天.整数往后推,负数往前移动
     *
     * @return date
     */
    @SuppressWarnings("static-access")
    public static Date getDetailDay(Date today, int difDay) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(today);
        calendar.add(calendar.DATE, difDay);// 把日期往后增加一天.整数往后推,负数往前移动
        Date d = calendar.getTime();
        return d;
    }
   /**
     * 获取想要的格式的时间
     *
     * @return String
     */
    public static String getTypeDate(String type, Date date) {
        if (date == null)
            return null;
        if (SimpleTool.checkNotNull(type)) {
            myformat = new SimpleDateFormat(type);
            String returnDate = myformat.format(date);
            myformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return returnDate;
        } else {
            String returnDate = myformat.format(date);
            return returnDate;
        }
    }
    /**
     * 比较两个时间天数差 startTime - endTime
     *
     * @param type
     *            (无效)
     * @return String
     * @throws ParseException
     */
    public static int getDiffDate(String type, Date startTime, Date endTime) throws ParseException {
        type = "yyyyMMdd";
        SimpleDateFormat myformat = new SimpleDateFormat(type);
        int i = 0;
        i = (int) ((myformat.parse(myformat.format(startTime)).getTime()
                - myformat.parse(myformat.format(endTime)).getTime()) / (1000 * 60 * 60 * 24));
        // return
        // myformat.parse(myformat.format(date1)).compareTo(myformat.parse(myformat.format(date2)));
        return i;
    }
    /**
     * 得到两个时间的分钟差 date1 - date2 这个是个奇葩。但是整型了。
     *
     * @return int
     * @throws ParseException
     */
    public static int getLeftDateForMinue(Date date1, Date date2) throws ParseException {
        long times = date1.getTime() - date2.getTime();
        times = times / (1000 * 60);
        return (int) times;
    }
    /**把字符串转为特定时间格式
     *
     * @param type 时间格式
     * @param sDate 字符串时间(可以为空)
     * @return date
     * @throws ParseException
     */
    public static Date parseStringForDate(String type, String sDate){
        Date date = null;
        try {
            if(SimpleTool.checkNotNull(sDate)) {
                SimpleDateFormat myformat = new SimpleDateFormat(type);
                date = myformat.parse(sDate);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return date;
    }
    /**
     * 判断是否为空
     */
    public static boolean checkNotNull(Object o) {
        boolean b = false;
        if (o != null && !"".equals(o)&&!"undefined".equals(o)&&!" ".equals(o)) {
            b = true;
        }
        return b;
    }
    /**
     * 判断是否为空 (多个)
     */
    public static boolean checkNotNullM(Object[] os) {
        boolean b = true;
        for (Object o : os) {
            if (o == null || "".equals(o))
                return false;
        }
        return b;
    }
    /**
     * 获取服务器端的webapps路径
     *
     * @return
     */
    public String findServerPath() {
        String classPath = this.getClass().getClassLoader().getResource("/").getPath();
        try {
            classPath = URLDecoder.decode(classPath, "gb2312");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String[] strPath = classPath.split("/");
        String path = "";
        for (int i = 0; i < strPath.length; i++) {
            if (i > 0 && i <= 3) {
                path = path + strPath[i] + "/";
            }
        }
        return path;
    }
    /**
     * 删除文件 输入真是路径
     */
    public static void deleteFile(String sPath) {
        File file = new File(sPath);
        // 判断目录或文件是否存在
        if (file.exists()) {
            // 判断是否为文件
            if (file.isFile()) { // 为文件时调用删除文件方法
                deleteFileForOne(sPath);
            } else { // 为目录时调用删除目录方法
                throw new RuntimeException("dir is no del");
                // deleteDirectory(sPath);
            }
        }
    }
    /**
     * 删除目录(文件夹)以及目录下的文件
     *
     * @param sPath
     *            被删除目录的文件路径
     * @return 目录删除成功返回true,否则返回false
     */
    public static boolean deleteDirectory(String sPath) {
        // 如果sPath不以文件分隔符结尾,自动添加文件分隔符
        if (!sPath.endsWith(File.separator)) {
            sPath = sPath + File.separator;
        }
        File dirFile = new File(sPath);
        // 如果dir对应的文件不存在,或者不是一个目录,则退出
        if (!dirFile.exists() || !dirFile.isDirectory()) {
            return false;
        }
        Boolean flag = true;
        // 删除文件夹下的所有文件(包括子目录)
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            // 删除子文件
            if (files[i].isFile()) {
                flag = deleteFileForOne(files[i].getAbsolutePath());
                if (!flag)
                    break;
            } // 删除子目录
            else {
                flag = deleteDirectory(files[i].getAbsolutePath());
                if (!flag)
                    break;
            }
        }
        if (!flag)
            return false;
        // 删除当前目录
        if (dirFile.delete()) {
            return true;
        } else {
            return false;
        }
    }
    /**
     * 删除单个文件
     *
     * @param sPath
     *            被删除文件的文件名
     * @return 单个文件删除成功返回true,否则返回false
     */
    public static boolean deleteFileForOne(String sPath) {
        Boolean flag = false;
        File file = new File(sPath);
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists()) {
            file.delete();
            flag = true;
        }
        return flag;
    }
    /**
     * 获取uuid
     */
    public static String getUUIDName() {
        return UUID.randomUUID().toString();
    }
    /** 获取异常信息 **/
    public static String getExceptionMsg(Exception e) {
        StringBuffer emsg = new StringBuffer();
        if (e != null) {
            StackTraceElement[] st = e.getStackTrace();
            for (StackTraceElement stackTraceElement : st) {
                String exclass = stackTraceElement.getClassName();
                String method = stackTraceElement.getMethodName();
                emsg.append("[类:" + exclass + "]调用---" + method + "----时在第" + stackTraceElement.getLineNumber()
                        + "行代码处发生异常!异常类型:" + e.toString() + "(" + e.getMessage() + ")\r\n");
            }
        }
        return emsg.toString();
    }
    /**
     * 获取指定格式的Double 类型数据
     *
     *            转换格式的类型 默认为 "#.##"
     * @param e
     *            要转换的数据源
     **/
    public static Double getTypeDouble(Double e) {
        fmt.setRoundingMode(RoundingMode.HALF_UP); // 保留小数点后两位并四舍五入,确保价钱准确
        Double d = Double.valueOf(fmt.format(e));
        return d;
    }
    /**
     * SHA1 加密
     *
     * @param decript
     * @return
     */
    public static String SHA1(String decript) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            digest.update(decript.getBytes());
            byte messageDigest[] = digest.digest();
            // Create Hex String
            StringBuffer hexString = new StringBuffer();
            // 字节数组转换为 十六进制 数
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexString.append(0);
                }
                hexString.append(shaHex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
    public static String getLocalIP() {
        InetAddress addr = null;
        try {
            addr = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        byte[] ipAddr = addr.getAddress();
        String ipAddrStr = "";
        for (int i = 0; i < ipAddr.length; i++) {
            if (i > 0) {
                ipAddrStr += ".";
            }
            ipAddrStr += ipAddr[i] & 0xFF;
        }
        // System.out.println("i am ip:......"+ipAddrStr);
        return ipAddrStr;
    }
    /**随机生成字符串(0-9)
      *
      * @param lengthCount 长度
      * @return
      */
    public static String generateCardNo(Integer lengthCount) {
         if(!SimpleTool.checkNotNull(lengthCount)) {
             lengthCount = 6;
         }
         java.util.Random r=new java.util.Random();
         StringBuilder str = new StringBuilder();//定义变长字符串
         for(int i=0;i<lengthCount;i++){
             str.append(r.nextInt(10));
         }
         return str.toString();
     }
     /**判断是不是视频文件
      * @param fileName 文件名称
      * @return boolean true是视频文件
      */
    public static boolean getMimeType(String fileName) {
         boolean b = false;
        FileNameMap fileNameMap = URLConnection.getFileNameMap();
        String type = fileNameMap.getContentTypeFor(fileName);
        //是视频type是为空的
        if(!checkNotNull(type)) {
            b = true;
        }
        return b;
     }
    /**
     * 判断是否为视频
     * @param fileName
     * @return
     */
    public static String isVideo(String fileName) {
        FileNameMap fileNameMap = URLConnection.getFileNameMap();
        String type = fileNameMap.getContentTypeFor(fileName);
        return type;
    }
    /**判断是否是中文*/
    public static boolean isChineseChar(String str){
        boolean temp = false;
        Pattern p=Pattern.compile("[\u4e00-\u9fa5]");
        Matcher m=p.matcher(str);
        if(m.find()){
            temp =  true;
            }
        return temp;
    }
    /**去除字符串中不是中文的字符
     *
     */
    public static String deleteNoChinese(String str){
        String name="";
        if(checkNotNull(str)){
            for(int i=0;i<str.length();i++){
                String s = str.substring(i, i+1);
                if(isChineseChar(s)){
                    name = name +s;
                }
            }
        }
        return name;
    }
    /**生成字母(全部是中文的)*/
    public static String convertHanzi3Pinyin(String hanzi,boolean full){
        hanzi = deleteNoChinese(hanzi);
        hanzi = convertHanzi2Pinyin(hanzi,false);
        return hanzi;
    }
    /***获取字符串拼音的第一个字母(大写)**/
    public static String convertStringPinyinOne(String hanzi) {
        if(SimpleTool.checkNotNull(hanzi)) {
            //转化为便宜
            hanzi = convertHanzi2Pinyin(hanzi,false);
            //转化大写
            hanzi = hanzi.toUpperCase();
            /*//获取第一个
            byte[] datas = hanzi.getBytes();
            if(datas.length>0) {
                byte[] datas2 = new byte[] {datas[0]};
                hanzi = new String(datas2);
            }else {
                hanzi = "";
            }*/
        }
        return hanzi;
    }
    /***将汉字转成拼音(取首字母或全拼)
     * @param hanzi
     * @param full 是否全拼
     * @return
     */
    public static String convertHanzi2Pinyin(String hanzi,boolean full){
        //获取第一个字
       /* if(checkNotNull(hanzi)){
            boolean isHave = true;
            Integer l = hanzi.length();
            Integer index = 0;
            while (isHave) {
                String hanzi2 = hanzi.substring(index,index+1);
                if(isChineseChar(hanzi2)){
                    isHave = false;
                    hanzi = hanzi2;
                }else{
                    if(index<l-1){
                        index++;
                    }else{
                        isHave = false;
                    }
                }
            }
        }
        */
        //去除所有的空格
        if(checkNotNull(hanzi)){
            hanzi = hanzi.replaceAll(" ", "");
        }
        /***
        * ^[\u2E80-\u9FFF]+$ 匹配所有东亚区的语言
        * ^[\u4E00-\u9FFF]+$ 匹配简体和繁体
        * ^[\u4E00-\u9FA5]+$ 匹配简体
        */
        String regExp="^[\u4E00-\u9FFF]+$";
        StringBuffer sb=new StringBuffer();
        if(hanzi==null||"".equals(hanzi.trim())){
            return "";
        }
        String pinyin="";
        for(int i=0;i<hanzi.length();i++){
            char unit=hanzi.charAt(i);
            if(match(String.valueOf(unit),regExp)){//是汉字,则转拼音
                pinyin=convertSingleHanzi2Pinyin(unit);
                if(full){
                    sb.append(pinyin);
                }else{
                    sb.append(pinyin.charAt(0));
                }
            }else{
                sb.append(unit);
            }
        }
        return sb.toString();
    }
    /***将单个汉字转成拼音
     * @param hanzi
     * @return
     */
    private static String convertSingleHanzi2Pinyin(char hanzi){
         HanyuPinyinOutputFormat outputFormat = new HanyuPinyinOutputFormat();
         outputFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
         String[] res;
         StringBuffer sb=new StringBuffer();
         try {
             res = PinyinHelper.toHanyuPinyinStringArray(hanzi,outputFormat);
             sb.append(res[0]);//对于多音字,只用第一个拼音
         } catch (Exception e) {
             e.printStackTrace();
             return "";
         }
         return sb.toString();
     }
    /***@param str 源字符串
      * @param regex 正则表达式
      * @return 是否匹配
      */
    public static boolean match(String str,String regex){
        Pattern pattern=Pattern.compile(regex);
          Matcher matcher=pattern.matcher(str);
          return matcher.find();
      }
    /** 读取 Excel文件内容(3.24 quan)
     *
     * @param excel_name  File
     * @return
     * @throws Exception
     */
    public static List<String[]> readExcelByeFile2(File excel_name) throws Exception {
        // 结果集
        List<String[]> list = new ArrayList<String[]>();
        HSSFWorkbook hssfworkbook = new HSSFWorkbook(new FileInputStream(excel_name));
        // 遍历该表格中所有的工作表,i表示工作表的数量 getNumberOfSheets表示工作表的总数
        HSSFSheet hssfsheet = hssfworkbook.getSheetAt(0);
        // 遍历该行所有的行,j表示行数 getPhysicalNumberOfRows行的总数
        for (int j = 0; j < hssfsheet.getPhysicalNumberOfRows(); j++) {
            HSSFRow hssfrow = hssfsheet.getRow(j);
            if(hssfrow!=null){
            int col = hssfrow.getPhysicalNumberOfCells();
            // 单行数据
            String[] arrayString = new String[col];
            for (int i = 0; i < col; i++) {
                HSSFCell cell = hssfrow.getCell(i);
                if (cell == null) {
                    arrayString[i] = "";
                } else if (cell.getCellType() == 0) {
                    // arrayString[i] = new Double(cell.getNumericCellValue()).toString();
                     short format = cell.getCellStyle().getDataFormat();
                        SimpleDateFormat sdf = null;
                        if(format == 14 || format == 31 || format == 57 || format == 58){
                            //日期
                            sdf = new SimpleDateFormat("yyyy-MM-dd");
                        }else if (format == 20 || format == 32) {
                            //时间
                            sdf = new SimpleDateFormat("HH:mm");
                        }else if (HSSFCell.CELL_TYPE_NUMERIC == cell.getCellType()) {
                          if (HSSFDateUtil.isCellDateFormatted(cell)) {
                            Date d = cell.getDateCellValue();
                            DateFormat formater = new SimpleDateFormat("yyyy年");
                            // DateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            arrayString[i] = formater.format(d);
                           } else {
                               arrayString[i] = new BigDecimal(cell.getNumericCellValue()).toString();
                        }
                    }
                } else {// 如果EXCEL表格中的数据类型为字符串型
                    arrayString[i] = cell.getStringCellValue().trim();
                }
            }
            list.add(arrayString);
        }
        }
        return list;
    }
    /**
     * 读取 Excel文件内容
     *
     * @param excel_name
     * @param header 是否包括表头
     * @return
     * @throws Exception
     */
    public static List<String[]> readExcelByeFileData(File excel_name,boolean header) throws Exception {
        // 结果集
        List<String[]> list = new ArrayList<String[]>();
        HSSFWorkbook hssfworkbook = new HSSFWorkbook(new FileInputStream(
                excel_name));
        // 遍历该表格中所有的工作表,i表示工作表的数量 getNumberOfSheets表示工作表的总数
        for(int s=0;s<hssfworkbook.getNumberOfSheets();s++) {
            HSSFSheet hssfsheet = hssfworkbook.getSheetAt(s);
            int col = 0;
            // 遍历该行所有的行,j表示行数 getPhysicalNumberOfRows行的总数 去除标题
            for (int j = 0; j < hssfsheet.getPhysicalNumberOfRows(); j++) {
                HSSFRow hssfrow = hssfsheet.getRow(j);
                if(hssfrow!=null){
                    if(j == 0) {
                        col = hssfrow.getPhysicalNumberOfCells();
                        if(!header) {
                            //不包括表头
                            continue;
                        }
                    }
                    // 单行数据
                    String[] arrayString = new String[col];
                    for (int i = 0; i < col; i++) {
                        HSSFCell cell = hssfrow.getCell(i);
                        if (cell == null) {
                            arrayString[i] = "";
                        } else if (cell.getCellType() == 0) {
                            // arrayString[i] = new Double(cell.getNumericCellValue()).toString();
                            if (HSSFCell.CELL_TYPE_NUMERIC == cell.getCellType()) {
                                short format = cell.getCellStyle().getDataFormat();
                                if(format == 14 || format == 31 || format == 57 || format == 58){
                                    //日期(中文时间格式的)
                                    Date d = cell.getDateCellValue();
                                    DateFormat formater = new SimpleDateFormat("yyyy年");
                                    // DateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                    arrayString[i] = formater.format(d);
                                }else if (HSSFDateUtil.isCellDateFormatted(cell)) {
                                    Date d = cell.getDateCellValue();
                                    DateFormat formater = new SimpleDateFormat("yyyy年");
                                    // DateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                    arrayString[i] = formater.format(d);
                                } else {
                                    if(HSSFCell.CELL_TYPE_STRING == cell.getCellType()){
                                        arrayString[i] =cell.getStringCellValue();
                                    }else if(HSSFCell.CELL_TYPE_FORMULA==cell.getCellType()){
                                        arrayString[i] =cell.getCellFormula();
                                    }else if(HSSFCell.CELL_TYPE_NUMERIC== cell.getCellType()){
                                        HSSFDataFormatter dataFormatter = new HSSFDataFormatter();
                                        arrayString[i] =dataFormatter.formatCellValue(cell);
                                    }
                                }
                            }
                        } else if(cell.getCellType() == Cell.CELL_TYPE_BLANK){
                            arrayString[i] = "";
                        } else { // 如果EXCEL表格中的数据类型为字符串型
                            arrayString[i] = cell.getStringCellValue().trim();
                        }
                    }
                    list.add(arrayString);
                }
            }
        }
        return list;
    }
    /**
     * 读取 Excel文件内容(学校信息专用)
     *
     * @param excel_name
     * @return
     * @throws Exception
     */
    public static List<String[]> readExcelByeFile(File excel_name) throws Exception {
        // 结果集
        List<String[]> list = new ArrayList<String[]>();
        HSSFWorkbook hssfworkbook = new HSSFWorkbook(new FileInputStream(
                excel_name));
        // 遍历该表格中所有的工作表,i表示工作表的数量 getNumberOfSheets表示工作表的总数
        for(int s=0;s<hssfworkbook.getNumberOfSheets();s++) {
            HSSFSheet hssfsheet = hssfworkbook.getSheetAt(s);
            int col = 0;
            // 遍历该行所有的行,j表示行数 getPhysicalNumberOfRows行的总数 去除标题
            for (int j = 0; j < hssfsheet.getPhysicalNumberOfRows(); j++) {
                HSSFRow hssfrow = hssfsheet.getRow(j);
                if(hssfrow!=null){
                    if(j == 0) {
                        col = hssfrow.getPhysicalNumberOfCells();
                    }else {
                        //                int col = hssfrow.getPhysicalNumberOfCells();
                        // 单行数据
                        String[] arrayString = new String[col];
                        for (int i = 0; i < col; i++) {
                            HSSFCell cell = hssfrow.getCell(i);
                            if (cell == null) {
                                arrayString[i] = "";
                            } else if (cell.getCellType() == 0) {
                                // arrayString[i] = new Double(cell.getNumericCellValue()).toString();
                                if (HSSFCell.CELL_TYPE_NUMERIC == cell.getCellType()) {
                                    short format = cell.getCellStyle().getDataFormat();
                                    if(format == 14 || format == 31 || format == 57 || format == 58){
                                        //日期(中文时间格式的)
                                        Date d = cell.getDateCellValue();
                                        DateFormat formater = new SimpleDateFormat("yyyy年");
                                        // DateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                        arrayString[i] = formater.format(d);
                                    }else if (HSSFDateUtil.isCellDateFormatted(cell)) {
                                        Date d = cell.getDateCellValue();
                                        DateFormat formater = new SimpleDateFormat("yyyy年");
                                        // DateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                        arrayString[i] = formater.format(d);
                                    } else {
                                        if(HSSFCell.CELL_TYPE_STRING == cell.getCellType()){
                                            arrayString[i] =cell.getStringCellValue();
                                        }else if(HSSFCell.CELL_TYPE_FORMULA==cell.getCellType()){
                                            arrayString[i] =cell.getCellFormula();
                                        }else if(HSSFCell.CELL_TYPE_NUMERIC== cell.getCellType()){
                                            HSSFDataFormatter dataFormatter = new HSSFDataFormatter();
                                            arrayString[i] =dataFormatter.formatCellValue(cell);
                                        }
                                    }
                                }
                            } else if(cell.getCellType() == Cell.CELL_TYPE_BLANK){
                                arrayString[i] = "";
                            } else { // 如果EXCEL表格中的数据类型为字符串型
                                cell.setCellType(Cell.CELL_TYPE_STRING);
                                String name = cell.getStringCellValue().trim();
                                if(name.equals("-")) {
                                    arrayString[i] = "";
                                }else {
                                    arrayString[i] = name;
                                }
                            }
                        }
                        list.add(arrayString);
                    }
                }
            }
        }
        return list;
    }
    /**获取字符串里面的数字,按顺序排序*/
    public static String stringNumber(String data) {
        String da = null;
        String regEc = "[^0-9]";
        Pattern pattern = Pattern.compile(regEc);
        Matcher m = pattern.matcher(data);
        da = m.replaceAll("").trim();
        return da;
    }
     /**
     * @param url:请求url
     * @param content: 请求体(参数)
     * @return errorStr:错误信息;status:状态码,response:返回数据
     * @throws JSONException
     */
    public static JSONObject requestData(String url, String content) throws JSONException {
        JSONObject obj = new JSONObject();
        String errMsg_r = "";
        String status_r = "0";
        String response = "";
        //PrintWriter out = null;
        DataOutputStream out = null;
        BufferedReader in = null;
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            HttpURLConnection httpUrlConnection = (HttpURLConnection) conn;
            // 设置请求属性
            httpUrlConnection.setRequestProperty("Content-type", "application/json;charset=UTF-8");
            //httpUrlConnection.setRequestProperty("Content-Type", "application/json");
            //httpUrlConnection.setRequestProperty("Charset", "UTF-8");
            httpUrlConnection.setRequestProperty("x-adviewrtb-version", "2.1");
            // 发送POST请求必须设置如下两行
            httpUrlConnection.setDoOutput(true);
            httpUrlConnection.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new DataOutputStream(httpUrlConnection.getOutputStream());
            //out = new PrintWriter(httpUrlConnection.getOutputStream());
            // 发送请求参数
            //out.write(content);
            out.write(content.getBytes("UTF-8"));
            // flush输出流的缓冲
            out.flush();
            httpUrlConnection.connect();
            // 定义BufferedReader输入流来读取URL的响应
            // in = new BufferedReader(new InputStreamReader(httpUrlConnection.getInputStream()));
            String wxMsgXml = IOUtils.toString(httpUrlConnection.getInputStream(), "utf-8");
            System.out.println("wxMsgXml:"+wxMsgXml);
           if(SimpleTool.checkNotNull(wxMsgXml)) {
               obj = JSONObject.fromObject(wxMsgXml);
           }
           /* String line;
            while ((line = in.readLine()) != null) {
                response += line;
            }  */
            status_r = new Integer(httpUrlConnection.getResponseCode()).toString();
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常!" + e);
            errMsg_r = e.getMessage();
            e.printStackTrace();
        }
        // 使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) { out.close();}
                if (in != null) {in.close();}
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        obj.put("errMsg_r", errMsg_r);
        obj.put("status_r", status_r);
        return obj;
    }
    /**随机生成字数(整数)(包括 0)
      * @param maxNumber 最大值
      * @return
      */
    public static Integer randomData(Integer maxNumber) {
         java.util.Random r=new java.util.Random();
         return r.nextInt(maxNumber);
     }
      private static final String[] HEADERS_TO_TRY = {"X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP",
                "HTTP_X_FORWARDED_FOR", "HTTP_X_FORWARDED", "HTTP_X_CLUSTER_CLIENT_IP", "HTTP_CLIENT_IP",
                "HTTP_FORWARDED_FOR", "HTTP_FORWARDED", "HTTP_VIA", "REMOTE_ADDR", "X-Real-IP"};
        /**
         * getClientIpAddress:(获取用户ip,可穿透代理). <br/>
         * @param request
         * @return
         * @author chenjiahe
         * @Date 2018年3月2日下午4:41:47
         * @since JDK 1.7
         */
        public static String getClientIpAddress(HttpServletRequest request) {
            for (String header : HEADERS_TO_TRY) {
                String ip = request.getHeader(header);
                if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
                    return ip;
                }
            }
            return request.getRemoteAddr();
        }
}
src/main/java/com/hx/util/StreamUtils.java
New file
@@ -0,0 +1,266 @@
package com.hx.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
public class StreamUtils {
    final static int BUFFER_SIZE = 4096;
    /**
     * ��InputStreamת����String
     *
     * @param in
     *            InputStream
     * @return String
     * @throws Exception
     *
     */
    public static String InputStreamTOString(InputStream in) {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] data = new byte[BUFFER_SIZE];
        String string = null;
        int count = 0;
        try {
            while ((count = in.read(data, 0, BUFFER_SIZE)) != -1)
                outStream.write(data, 0, count);
        } catch (IOException e) {
            e.printStackTrace();
        }
        data = null;
        try {
            string = new String(outStream.toByteArray(), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return string;
    }
    /**
     * ��InputStreamת����ij���ַ�����String
     *
     * @param in
     * @param encoding
     * @return
     * @throws Exception
     */
    public static String InputStreamTOString(InputStream in, String encoding) {
        String string = null;
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] data = new byte[BUFFER_SIZE];
        int count = -1;
        try {
            while ((count = in.read(data, 0, BUFFER_SIZE)) != -1)
                outStream.write(data, 0, count);
        } catch (IOException e) {
            e.printStackTrace();
        }
        data = null;
        try {
            string = new String(outStream.toByteArray(), encoding);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return string;
    }
    /**
     * ��Stringת����InputStream
     *
     * @param in
     * @return
     * @throws Exception
     */
    public static InputStream StringTOInputStream(String in) throws Exception {
        ByteArrayInputStream is = new ByteArrayInputStream(in.getBytes("UTF-8"));
        return is;
    }
    /**
     * ��Stringת����InputStream
     *
     * @param in
     * @return
     * @throws Exception
     */
    public static byte[] StringTObyte(String in) {
        byte[] bytes = null;
        try {
            bytes = InputStreamTOByte(StringTOInputStream(in));
        } catch (IOException e) {
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bytes;
    }
    /**
     * ��InputStreamת����byte����
     *
     * @param in
     *            InputStream
     * @return byte[]
     * @throws IOException
     */
    public static byte[] InputStreamTOByte(InputStream in) throws IOException {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] data = new byte[BUFFER_SIZE];
        int count = -1;
        while ((count = in.read(data, 0, BUFFER_SIZE)) != -1)
            outStream.write(data, 0, count);
        data = null;
        return outStream.toByteArray();
    }
    /**
     * ��byte����ת����InputStream
     *
     * @param in
     * @return
     * @throws Exception
     */
    public static InputStream byteTOInputStream(byte[] in) throws Exception {
        ByteArrayInputStream is = new ByteArrayInputStream(in);
        return is;
    }
    /**
     * ��byte����ת����String
     *
     * @param in
     * @return
     * @throws Exception
     */
    public static String byteTOString(byte[] in) {
        InputStream is = null;
        try {
            is = byteTOInputStream(in);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return InputStreamTOString(is, "UTF-8");
    }
    /**
     * ��byte����ת����String
     *
     * @param in
     * @return
     * @throws Exception
     */
    public static String getString(String in) {
        String is = null;
        try {
            is = byteTOString(StringTObyte(in));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return is;
    }
    // InputStream ת����byte[]
    public byte[] getBytes(InputStream is) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] b = new byte[BUFFER_SIZE];
        int len = 0;
        while ((len = is.read(b, 0, BUFFER_SIZE)) != -1) {
            baos.write(b, 0, len);
        }
        baos.flush();
        byte[] bytes = baos.toByteArray();
        System.out.println(new String(bytes));
        return bytes;
    }
    /**
     * ����ļ�·�������ļ�����������
     * ���ֽ�Ϊ��λ���� unicode ��
     * @return
     */
    public static FileInputStream getFileInputStream(String filepath) {
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(filepath);
        } catch (FileNotFoundException e) {
            System.out.print("������Ϣ:�ļ�������");
            e.printStackTrace();
        }
        return fileInputStream;
    }
    /**
     * ����ļ����󴴽��ļ�����������
     * ���ֽ�Ϊ��λ���� unicode ��
     * @return
     */
    public static FileInputStream getFileInputStream(File file) {
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            System.out.print("������Ϣ:�ļ�������");
            e.printStackTrace();
        }
        return fileInputStream;
    }
    /**
      * ����ļ����󴴽��ļ����������
     * ���ֽ�Ϊ��λ���� unicode ��
     * @param file
     * @param append true:�ļ���׷�ӷ�ʽ��,false:�򸲸�ԭ�ļ�������
     * @return
     */
    public static FileOutputStream getFileOutputStream(File file,boolean append) {
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(file,append);
        } catch (FileNotFoundException e) {
            System.out.print("������Ϣ:�ļ�������");
            e.printStackTrace();
        }
        return fileOutputStream;
    }
    /**
     * ����ļ�·�������ļ����������
     * ���ֽ�Ϊ��λ���� unicode ��
     * @param append true:�ļ���׷�ӷ�ʽ��,false:�򸲸�ԭ�ļ�������
     * @return
     */
    public static FileOutputStream getFileOutputStream(String filepath,boolean append) {
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(filepath,append);
        } catch (FileNotFoundException e) {
            System.out.print("������Ϣ:�ļ�������");
            e.printStackTrace();
        }
        return fileOutputStream;
    }
    public static File getFile(String filepath) {
        return new File(filepath);
    }
    public static ByteArrayOutputStream getByteArrayOutputStream() {
        return new ByteArrayOutputStream();
    }
}
src/main/java/com/hx/util/StringUtils.java
New file
@@ -0,0 +1,306 @@
package com.hx.util;
import java.io.UnsupportedEncodingException;
import java.text.MessageFormat;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 字符串工具类
 *
 * @author ThinkGem
 * @version 2013-05-22
 */
public class StringUtils {
    private static final char SEPARATOR = '_';
    private static final String CHARSET_NAME = "UTF-8";
    /**
     * 格式化字符串,替换原字符串中的{0}, {1},按顺序替换
     *
     * @param oriStr
     * @param args
     * @return
     */
    public static String format(String oriStr, Object... args) {
        return MessageFormat.format(oriStr, args);
    }
    /**
     * 转换为字节数�?
     *
     * @param str
     * @return
     */
    public static byte[] getBytes(String str) {
        if (str != null) {
            try {
                return str.getBytes(CHARSET_NAME);
            } catch (UnsupportedEncodingException e) {
                return null;
            }
        } else {
            return null;
        }
    }
    /**
     * 只取后两�?
     *
     * @param str
     * @return
     */
    public static String getLastTwoChars(String str) {
        if (null != str && str.trim().length() > 0) {
            str = str.trim();
            int len = str.length();
            if (len == 2) {
                return str;
            } else if (len > 2) {
                return str.substring(len - 2);
            }
        }
        return "";
    }
    /**
     * 只取后三�?
     *
     * @param str
     * @return
     */
    public static String getLastThreeChars(String str) {
        if (null != str && str.trim().length() > 0) {
            str = str.trim();
            int len = str.length();
            if (len == 3) {
                return str;
            } else if (len > 3) {
                return str.substring(len - 3);
            }
        }
        return "";
    }
    /**
     * 替换为手机识别的HTML,去掉样式及属�?�,保留回车�?
     *
     * @param html
     * @return
     */
    public static String replaceMobileHtml(String html) {
        if (html == null) {
            return "";
        }
        return html.replaceAll("<([a-z]+?)\\s+?.*?>", "<$1>");
    }
    /**
     * 驼峰命名法工�?
     *
     * @return toCamelCase("hello_world") == "helloWorld"
     *         toCapitalizeCamelCase("hello_world") == "HelloWorld"
     *         toUnderScoreCase("helloWorld") = "hello_world"
     */
    public static String toCamelCase(String s) {
        if (s == null) {
            return null;
        }
        s = s.toLowerCase();
        StringBuilder sb = new StringBuilder(s.length());
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == SEPARATOR) {
                upperCase = true;
            } else if (upperCase) {
                sb.append(Character.toUpperCase(c));
                upperCase = false;
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }
    /**
     * 驼峰命名法工�?
     *
     * @return toCamelCase("hello_world") == "helloWorld"
     *         toCapitalizeCamelCase("hello_world") == "HelloWorld"
     *         toUnderScoreCase("helloWorld") = "hello_world"
     */
    public static String toCapitalizeCamelCase(String s) {
        if (s == null) {
            return null;
        }
        s = toCamelCase(s);
        return s.substring(0, 1).toUpperCase() + s.substring(1);
    }
    /**
     * 驼峰命名法工�?
     *
     * @return toCamelCase("hello_world") == "helloWorld"
     *         toCapitalizeCamelCase("hello_world") == "HelloWorld"
     *         toUnderScoreCase("helloWorld") = "hello_world"
     */
    public static String toUnderScoreCase(String s) {
        if (s == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            boolean nextUpperCase = true;
            if (i < (s.length() - 1)) {
                nextUpperCase = Character.isUpperCase(s.charAt(i + 1));
            }
            if ((i > 0) && Character.isUpperCase(c)) {
                if (!upperCase || !nextUpperCase) {
                    sb.append(SEPARATOR);
                }
                upperCase = true;
            } else {
                upperCase = false;
            }
            sb.append(Character.toLowerCase(c));
        }
        return sb.toString();
    }
    /**
     * 根据规则regExpr,判断字符内容是否匹配
     * <p>
     * 利用正则表达式规则判断,待验证的字符内容是否符合要求�? <br>
     * 比如'[0-9]*'即判断是否为数字的规�?, '^[a-z0-9_-]{3,15}$'即判断是否为用户名的规则,<br>
     * '((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%]).{6,20})'即判断是否为密码的规�?,<br>
     * '^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$'即email规则,<br>
     * '([^\s]+(\.(?i)(jpg|png|gif|bmp))$)'即判断某图片文件格式,<br>
     * '^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$'即IP规则.
     *
     *
     * @param regExpr
     *            正则表达�?
     * @param content
     *            待验证的字符内容
     * @return boolean
     */
    public static boolean isMatch(String regExpr, String content) {
        if (StringUtils.isEmpty(regExpr, content))
            return false;
        Pattern pattern = Pattern.compile(regExpr);
        Matcher matcher = pattern.matcher(content);
        return matcher.matches();
    }
    /**
     * 正则判断纯数�?
     *
     * @param str
     * @return
     */
    public static boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("[0-9]*");
        Matcher isNum = pattern.matcher(str);
        if (!isNum.matches()) {
            return false;
        }
        return true;
    }
    public static boolean isEmpty(String str) {
        return null == str || str.trim().length() == 0 || "undefined".equals(str);
    }
    /**
     * 判断字符内容中是否存在一个为空的字符�?
     * <p>
     * 如果在所有的字符串内容中,只要存在某�?个字符串为空,则返回为true, 如果�?有的字符串内容中,不存在�?个空字符串,则返回为false.
     *
     * @param strings
     * @return boolean
     */
    public static boolean isEmpty(String... strings) {
        if (strings == null)
            return true;
        for (String str : strings) {
            if (StringUtils.isEmpty(str))
                return true;
        }
        return false;
    }
    public static boolean isAllEmpty(String... strings) {
        if (strings == null)
            return true;
        for (String str : strings) {
            if (!StringUtils.isEmpty(str))
                return false;
        }
        return true;
    }
    /**
     * @param strings
     *            该数组是否有�?
     * @return
     */
    public static boolean hasContent(String[] strings) {
        if (strings != null && strings.length > 0)
            return true;
        return false;
    }
    /**
     * @param params
     *            该map是否有�??
     * @return
     */
    public static boolean hasContent(Map<?, ?> params) {
        if (params != null && params.size() > 0)
            return true;
        return false;
    }
    public static boolean isNumeric2(String str) {
        if (null == str || isEmpty(str)) {
            return false;
        }
        char[] chars = str.toCharArray();
        for (char c : chars) {
            if (!Character.isDigit(c))
                return false;
        }
        return true;
    }
    public static int parseInt(String string) {
        if (null != string && isNumeric2(string)) {
            return Integer.parseInt(string);
        }
        return 0;
    }
}
src/main/java/com/hx/util/TempltUtil.java
New file
@@ -0,0 +1,150 @@
package com.hx.util;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.core.io.ClassPathResource;
import java.io.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class TempltUtil {
    public static final String PREVIEW_DOC = "/temp.docx";
    public static final String TEMP_URL = "temp";
    public static final String TEMP_NAME = "contract.tpl";
    /**
     *
     * @param tempUrl 模板所在文件夹
     * @param tempName 模板名称
     * @return
     * @throws IOException
     */
    public static Template configTemplate(String tempUrl,String tempName) throws IOException {
        Configuration config = new Configuration();
        ClassPathResource classPathResource = new ClassPathResource(tempUrl);
        config.setDirectoryForTemplateLoading(classPathResource.getFile());
        config.setObjectWrapper(new DefaultObjectWrapper());
        Template template = config.getTemplate(tempName, "UTF-8");
        return template;
    }
    /**
     *
     * @param tempUrl 模板所在文件夹
     * @param temp 模板名称
     * @param copyUrl 复制文件路径
     * @param data 模板数据map
     * return 生成路径
     */
    public static String toPreview(String tempUrl,String temp,String copyUrl, Map<?, ?> data){
        try {
        Template template = configTemplate(tempUrl,temp);
        ClassPathResource classPathResource = new ClassPathResource(tempUrl+"/"+PREVIEW_DOC);
        //生成新的模板
        File tempFile =  classPathResource.getFile();
        copyUrl = copyUrl+"/"+DateUtil.dateFormat(new Date(),"yyyyMMddHHmmss")+tempFile.getName();
        File file = new File(copyUrl);
        FileUtils.copyFile(tempFile,file);
        File file2 = new File(copyUrl);
        FileOutputStream fos = new FileOutputStream(file2);
        Writer out = new OutputStreamWriter(fos, "UTF-8");
            template.process(data, out);
            out.flush();
            out.close();
        } catch (Exception e) {
        e.printStackTrace();
        }
        return copyUrl;
    }
    /**
     *
     * @param templateUrl 模板路径目录,不包括模板名称,如 ./src/main/resources/jsonFile
     * @param templateName 模板名称,如:data.tpl
     * @param savaPath 生成文件存放目录,如 ./src/main/resources/jsonFile
     * @param name 生成的文件名称,包括后缀名称
     * @param data 模板里面内容
     * @throws Exception
     */
    public static String createDataFile(String templateUrl,String templateName,
                                      String savaPath, String name,Map<String, Object> data) throws IOException {
        String targetFile = null;
        Writer out = null;
        if(!SimpleTool.checkNotNull(templateUrl)) {
            throw new RuntimeException("templateUrl 为空");
        }
        if(!SimpleTool.checkNotNull(templateName)) {
            throw new RuntimeException("templateName 为空");
        }
        if(!SimpleTool.checkNotNull(savaPath)) {
            throw new RuntimeException("savaPath 为空");
        }
        try {
            if(!savaPath.endsWith("/")){
                savaPath = savaPath+"/";
            }
            if(!templateUrl.endsWith("/")){
                templateUrl = templateUrl +"/";
            }
            //为了解决spingBoot打包成jar获取不了文件,把文件保存到本地
            //拿到jar里面的文件流
            ClassPathResource classPathResource = new ClassPathResource(templateUrl+templateName);
            //保存模板图片路径
            String saveTempUrl = savaPath+"temp/";
            //判断是否存在了
            File temFile = new File(saveTempUrl+templateName);
            if(temFile.exists()){
                temFile = temFile.getParentFile();
            }else{
                //不存在就创建一个
                temFile = FileUtils.inputStreamToFile(classPathResource.getInputStream(),saveTempUrl,templateName);
                temFile = temFile.getParentFile();
            }
            // 反射end
            Configuration cfg = new Configuration();
            // 指定模板文件从何处加载的数据源,这里设置成一个文件目录
            cfg.setDirectoryForTemplateLoading(temFile);
            cfg.setObjectWrapper(new DefaultObjectWrapper());
            cfg.setDefaultEncoding("UTF-8");
            // 获取或创建模板
            Template template = cfg.getTemplate(templateName);
            template.setEncoding("UTF-8");
            // String targetFile = "./src/template/test.html";
            //生成路径
            targetFile = savaPath;
            File file = new File(targetFile);
            //没有找到就新建一个
            if (!file.isDirectory() && !file.exists()) {
                file.mkdirs();
            }
            targetFile += name;
            System.out.println("targetFile:"+targetFile);
            // 将模板和数据模型合并 输出到Console
            out = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(targetFile), "UTF-8"));
            template.process(data, out);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            if(SimpleTool.checkNotNull(out)){
                out.flush();
                out.close();
            }
        }
        return targetFile;
    }
}
src/main/java/com/hx/util/TengXunMapUtil.java
New file
@@ -0,0 +1,191 @@
package com.hx.util;
import net.sf.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
/**
 * 腾讯地图工具
 * @author mgchen
 *
 */
public class TengXunMapUtil {
    /**key*/
    public static final String KEY_SHOP = "NDTBZ-XH6WX-TOB4C-TZFHG-2ORS3-UCBFA";
    /**签名校验*/
    public static final String SIGN = "qI6ZmfLk0IYt7PPWThwqXMjnNjjPzSaW";
    public static final String URL_LOCATION = "http://apis.map.qq.com/ws/geocoder/v1/?address={1}&key={2}";
    public static final String URL_CITY = "http://apis.map.qq.com/ws/geocoder/v1/?location={1}&key={2}";
    /**地址转换为经纬度*/
    public static String[] getLocation(String address, String key)
    {
        try{
            String str = sendGet("https://apis.map.qq.com/ws/geocoder/v1/", "address=" + URLEncoder.encode(address, "utf-8") + "&key=" + key);
            JSONObject obj = JSONObject.fromObject(str);
            int status = obj.optInt("status", -1);
            if(status == 0)
            {
                JSONObject rObj = obj.optJSONObject("result");
                if(rObj != null)
                {
                    JSONObject lObj = rObj.optJSONObject("location");
                    if(lObj != null)
                    {
                        Double lng = lObj.optDouble("lng", 0.0);
                        Double lat = lObj.optDouble("lat", 0.0);
                        if(lng != 0.0 && lat != 0.0)
                        {
                            return new String[]{lng.toString(), lat.toString()};
                        }
                    }
                }
            }
        }catch(Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }
    /**地址转换为经纬度(签名校验)*/
    public static String[] getLocation(String address, String key,String sign) {
        try{
            sign =  MD5Util.MD5Encode("/ws/geocoder/v1?address=" + address + "&key=" + key+sign,null);
            String str = sendGet("https://apis.map.qq.com/ws/geocoder/v1", "address=" + address + "&key=" + key+"&sig="+sign);
            JSONObject obj = JSONObject.fromObject(str);
            int status = obj.optInt("status", -1);
            if(status == 0)
            {
                JSONObject rObj = obj.optJSONObject("result");
                if(rObj != null)
                {
                    JSONObject lObj = rObj.optJSONObject("location");
                    if(lObj != null)
                    {
                        Double lng = lObj.optDouble("lng", 0.0);
                        Double lat = lObj.optDouble("lat", 0.0);
                        if(lng != 0.0 && lat != 0.0)
                        {
                            return new String[]{lng.toString(), lat.toString()};
                        }
                    }
                }
            }
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 向指定URL发送GET方法的请求
     *
     * @param url
     *            发送请求的URL
     * @param param
     *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url + "?" + param;
            System.out.println("urlNameString:"+urlNameString);
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36");
            // 建立实际的连接
            connection.connect();
//            // 获取所有响应头字段
//            Map<String, List<String>> map = connection.getHeaderFields();
//            // 遍历所有的响应头字段
//            for (String key : map.keySet()) {
//                System.out.println(key + "--->" + map.get(key));/
//            }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常!" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }
    public static void main(String[] args)
    {
        System.out.println(sendGet("http://apis.map.qq.com/ws/geocoder/v1/", "address=" +"北京市海淀区彩和坊路海淀西大街74号" + "&key=" + "11"));
    }
    /**获取省/市*/
    public static String[] getAddress(String lat, String lng, String key)
    {
        try{
            String str = sendGet("http://apis.map.qq.com/ws/geocoder/v1/", "location=" + lat + "," + lng + "&key=" + key);
            JSONObject obj = JSONObject.fromObject(str);
            if(obj != null && obj.optInt("status", -1) == 0)
            {
                obj = obj.optJSONObject("result");
                if(obj != null)
                {
                    obj = obj.optJSONObject("address_component");
                    if(obj != null)
                    {
                        String nation = obj.optString("nation");
                        String province = obj.optString("province");
                        String city = obj.optString("city");
                        String area = obj.optString("district");
                        String detail = obj.optString("street") + obj.optString("street_number");
                        String[] addr = new String[]{
                                new String(nation.getBytes(), "utf-8"),
                                new String(province.getBytes(), "utf-8"),
                                new String(city.getBytes(), "utf-8"),
                                new String(area.getBytes(), "utf-8"),
                                new String(detail.getBytes(), "utf-8")
                                };
                        return addr;
                    }
                    return null;
                }
            }
        }catch(Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }
}
src/main/java/com/hx/util/ThreadPoolUtils.java
New file
@@ -0,0 +1,42 @@
package com.hx.util;
import org.springframework.stereotype.Component;
import java.util.concurrent.*;
/**
 * @PackageName com.hx.util
 * @ProjectName hx-parent
 * @Author: ChenJiaHe
 * @Date: Create in 17:12 2019/8/6
 * @Description:
 * @Copyright Copyright (c) 2019, hx01@163.com All Rights Reserved.
 */
@Component
public class ThreadPoolUtils {
    public static BlockingQueue<Runnable> queueToUse = new LinkedBlockingQueue<>(120);
    /**
     * @param poolSize
     * @param method
     * @MethodName creatExeutorService
     * @Description 创建线程池方法
     * @Auther ChenJiaHe
     * @Date 2019/8/6 17:19
     * @Since JDK 1.8
     */
    public ExecutorService creatExeutorService(int poolSize, String method, BlockingQueue<Runnable> queueToUse) {
        int coreSize = Runtime.getRuntime().availableProcessors();
        if (poolSize < coreSize) {
            coreSize = poolSize;
        }
        ThreadFactory threadFactory = r -> {
            Thread t = new Thread(r, "thread created mewthod{" + method + "}");
            t.setDaemon(true);
            return t;
        };
        final ThreadPoolExecutor executor = new ThreadPoolExecutor(coreSize, poolSize, 60, TimeUnit.SECONDS, queueToUse, threadFactory, new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }
}
src/main/java/com/hx/util/WebUtil.java
New file
@@ -0,0 +1,53 @@
package com.hx.util;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.alibaba.fastjson.JSONObject;
/**
 *
 * @author lijietian
 *
 */
public class WebUtil {
    /**
     * 返回数据给前端的方法
     *
     * @param msg 返回数据
     *
     */
    public static void AJAXdata(String msg) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletResponse response = attributes.getResponse();
        response.setContentType("text/plain");// 文本
        response.setHeader("Cache-Control", "no-store");
        response.setCharacterEncoding("utf-8");
        try {
            PrintWriter pw = response.getWriter();
            pw.write(msg);
            pw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 组成统一的格式
     *
     */
    public static String AJAXMsg(Integer status,String errorMsg,JSONObject obj) {
        JSONObject info = new JSONObject();
        info.put("status", status);
        info.put("errorMsg", errorMsg);
        info.put("datas", obj);
        return info.toJSONString();
    }
}
src/main/java/com/qq/weixin/mp/aes/AesException.java
New file
@@ -0,0 +1,59 @@
package com.qq.weixin.mp.aes;
@SuppressWarnings("serial")
public class AesException extends Exception {
    public final static int OK = 0;
    public final static int ValidateSignatureError = -40001;
    public final static int ParseXmlError = -40002;
    public final static int ComputeSignatureError = -40003;
    public final static int IllegalAesKey = -40004;
    public final static int ValidateCorpidError = -40005;
    public final static int EncryptAESError = -40006;
    public final static int DecryptAESError = -40007;
    public final static int IllegalBuffer = -40008;
    //public final static int EncodeBase64Error = -40009;
    //public final static int DecodeBase64Error = -40010;
    //public final static int GenReturnXmlError = -40011;
    private int code;
    private static String getMessage(int code) {
        switch (code) {
        case ValidateSignatureError:
            return "签名验证错误";
        case ParseXmlError:
            return "xml解析失败";
        case ComputeSignatureError:
            return "sha加密生成签名失败";
        case IllegalAesKey:
            return "SymmetricKey非法";
        case ValidateCorpidError:
            return "corpid校验失败";
        case EncryptAESError:
            return "aes加密失败";
        case DecryptAESError:
            return "aes解密失败";
        case IllegalBuffer:
            return "解密后得到的buffer非法";
//        case EncodeBase64Error:
//            return "base64加密错误";
//        case DecodeBase64Error:
//            return "base64解密错误";
//        case GenReturnXmlError:
//            return "xml生成失败";
        default:
            return null; // cannot be
        }
    }
    public int getCode() {
        return code;
    }
    AesException(int code) {
        super(getMessage(code));
        this.code = code;
    }
}
src/main/java/com/qq/weixin/mp/aes/ByteGroup.java
New file
@@ -0,0 +1,26 @@
package com.qq.weixin.mp.aes;
import java.util.ArrayList;
class ByteGroup {
    ArrayList<Byte> byteContainer = new ArrayList<Byte>();
    public byte[] toBytes() {
        byte[] bytes = new byte[byteContainer.size()];
        for (int i = 0; i < byteContainer.size(); i++) {
            bytes[i] = byteContainer.get(i);
        }
        return bytes;
    }
    public ByteGroup addBytes(byte[] bytes) {
        for (byte b : bytes) {
            byteContainer.add(b);
        }
        return this;
    }
    public int size() {
        return byteContainer.size();
    }
}
src/main/java/com/qq/weixin/mp/aes/PKCS7Encoder.java
New file
@@ -0,0 +1,67 @@
/**
 * 对企业微信发送给企业后台的消息加解密示例代码.
 *
 * @copyright Copyright (c) 1998-2014 Tencent Inc.
 */
// ------------------------------------------------------------------------
package com.qq.weixin.mp.aes;
import java.nio.charset.Charset;
import java.util.Arrays;
/**
 * 提供基于PKCS7算法的加解密接口.
 */
class PKCS7Encoder {
    static Charset CHARSET = Charset.forName("utf-8");
    static int BLOCK_SIZE = 32;
    /**
     * 获得对明文进行补位填充的字节.
     *
     * @param count 需要进行填充补位操作的明文字节个数
     * @return 补齐用的字节数组
     */
    static byte[] encode(int count) {
        // 计算需要填充的位数
        int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
        if (amountToPad == 0) {
            amountToPad = BLOCK_SIZE;
        }
        // 获得补位所用的字符
        char padChr = chr(amountToPad);
        String tmp = new String();
        for (int index = 0; index < amountToPad; index++) {
            tmp += padChr;
        }
        return tmp.getBytes(CHARSET);
    }
    /**
     * 删除解密后明文的补位字符
     *
     * @param decrypted 解密后的明文
     * @return 删除补位字符后的明文
     */
    static byte[] decode(byte[] decrypted) {
        int pad = (int) decrypted[decrypted.length - 1];
        if (pad < 1 || pad > 32) {
            pad = 0;
        }
        return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
    }
    /**
     * 将数字转化成ASCII码对应的字符,用于对明文进行补码
     *
     * @param a 需要转化的数字
     * @return 转化得到的字符
     */
    static char chr(int a) {
        byte target = (byte) (a & 0xFF);
        return (char) target;
    }
}
src/main/java/com/qq/weixin/mp/aes/SHA1.java
New file
@@ -0,0 +1,61 @@
/**
 * 对企业微信发送给企业后台的消息加解密示例代码.
 *
 * @copyright Copyright (c) 1998-2014 Tencent Inc.
 */
// ------------------------------------------------------------------------
package com.qq.weixin.mp.aes;
import java.security.MessageDigest;
import java.util.Arrays;
/**
 * SHA1 class
 *
 * 计算消息签名接口.
 */
class SHA1 {
    /**
     * 用SHA1算法生成安全签名
     * @param token 票据
     * @param timestamp 时间戳
     * @param nonce 随机字符串
     * @param encrypt 密文
     * @return 安全签名
     * @throws AesException
     */
    public static String getSHA1(String token, String timestamp, String nonce, String encrypt) throws AesException
              {
        try {
            String[] array = new String[] { token, timestamp, nonce, encrypt };
            StringBuffer sb = new StringBuffer();
            // 字符串排序
            Arrays.sort(array);
            for (int i = 0; i < 4; i++) {
                sb.append(array[i]);
            }
            String str = sb.toString();
            // SHA1签名生成
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            md.update(str.getBytes());
            byte[] digest = md.digest();
            StringBuffer hexstr = new StringBuffer();
            String shaHex = "";
            for (int i = 0; i < digest.length; i++) {
                shaHex = Integer.toHexString(digest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexstr.append(0);
                }
                hexstr.append(shaHex);
            }
            return hexstr.toString();
        } catch (Exception e) {
            e.printStackTrace();
            throw new AesException(AesException.ComputeSignatureError);
        }
    }
}
src/main/java/com/qq/weixin/mp/aes/WXBizMsgCrypt.java
New file
@@ -0,0 +1,296 @@
/**
 * 对企业微信发送给企业后台的消息加解密示例代码.
 *
 * @copyright Copyright (c) 1998-2014 Tencent Inc.
 */
// ------------------------------------------------------------------------
/**
 * 针对org.apache.commons.codec.binary.Base64,
 * 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本)
 * 官方下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi
 */
package com.qq.weixin.mp.aes;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * 提供接收和推送给企业微信消息的加解密接口(UTF8编码的字符串).
 * <ol>
 *     <li>第三方回复加密消息给企业微信</li>
 *     <li>第三方收到企业微信发送的消息,验证消息的安全性,并对消息进行解密。</li>
 * </ol>
 * 说明:异常java.security.InvalidKeyException:illegal Key Size的解决方案
 * <ol>
 *     <li>在官方网站下载JCE无限制权限策略文件(JDK7的下载地址:
 *      http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html</li>
 *     <li>下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt</li>
 *     <li>如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件</li>
 *     <li>如果安装了JDK,将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件</li>
 * </ol>
 */
public class WXBizMsgCrypt {
    //log4j日志
    private static Logger logger = LoggerFactory.getLogger(WXBizMsgCrypt.class.getName());
    static Charset CHARSET = Charset.forName("utf-8");
    Base64 base64 = new Base64();
    byte[] aesKey;
    String token;
    String receiveid;
    /**
     * 构造函数
     * @param token 企业微信后台,开发者设置的token
     * @param encodingAesKey 企业微信后台,开发者设置的EncodingAESKey
     * @param receiveid, 不同场景含义不同,详见文档
     *
     * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
     */
    public WXBizMsgCrypt(String token, String encodingAesKey, String receiveid) throws AesException {
        if (encodingAesKey.length() != 43) {
            throw new AesException(AesException.IllegalAesKey);
        }
        this.token = token;
        this.receiveid = receiveid;
        aesKey = Base64.decodeBase64(encodingAesKey + "=");
    }
    // 生成4个字节的网络字节序
    byte[] getNetworkBytesOrder(int sourceNumber) {
        byte[] orderBytes = new byte[4];
        orderBytes[3] = (byte) (sourceNumber & 0xFF);
        orderBytes[2] = (byte) (sourceNumber >> 8 & 0xFF);
        orderBytes[1] = (byte) (sourceNumber >> 16 & 0xFF);
        orderBytes[0] = (byte) (sourceNumber >> 24 & 0xFF);
        return orderBytes;
    }
    // 还原4个字节的网络字节序
    int recoverNetworkBytesOrder(byte[] orderBytes) {
        int sourceNumber = 0;
        for (int i = 0; i < 4; i++) {
            sourceNumber <<= 8;
            sourceNumber |= orderBytes[i] & 0xff;
        }
        return sourceNumber;
    }
    // 随机生成16位字符串
    String getRandomStr() {
        String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 16; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }
    /**
     * 对明文进行加密.
     *
     * @param text 需要加密的明文
     * @return 加密后base64编码的字符串
     * @throws AesException aes加密失败
     */
    String encrypt(String randomStr, String text) throws AesException {
        ByteGroup byteCollector = new ByteGroup();
        byte[] randomStrBytes = randomStr.getBytes(CHARSET);
        byte[] textBytes = text.getBytes(CHARSET);
        byte[] networkBytesOrder = getNetworkBytesOrder(textBytes.length);
        byte[] receiveidBytes = receiveid.getBytes(CHARSET);
        // randomStr + networkBytesOrder + text + receiveid
        byteCollector.addBytes(randomStrBytes);
        byteCollector.addBytes(networkBytesOrder);
        byteCollector.addBytes(textBytes);
        byteCollector.addBytes(receiveidBytes);
        // ... + pad: 使用自定义的填充方式对明文进行补位填充
        byte[] padBytes = PKCS7Encoder.encode(byteCollector.size());
        byteCollector.addBytes(padBytes);
        // 获得最终的字节流, 未加密
        byte[] unencrypted = byteCollector.toBytes();
        try {
            // 设置加密模式为AES的CBC模式
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
            IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16);
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
            // 加密
            byte[] encrypted = cipher.doFinal(unencrypted);
            // 使用BASE64对加密后的字符串进行编码
            String base64Encrypted = base64.encodeToString(encrypted);
            return base64Encrypted;
        } catch (Exception e) {
            e.printStackTrace();
            throw new AesException(AesException.EncryptAESError);
        }
    }
    /**
     * 对密文进行解密.
     *
     * @param text 需要解密的密文
     * @return 解密得到的明文
     * @throws AesException aes解密失败
     */
    String decrypt(String text) throws AesException {
        byte[] original;
        try {
            // 设置解密模式为AES的CBC模式
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            SecretKeySpec key_spec = new SecretKeySpec(aesKey, "AES");
            IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
            cipher.init(Cipher.DECRYPT_MODE, key_spec, iv);
            // 使用BASE64对密文进行解码
            byte[] encrypted = Base64.decodeBase64(text);
            // 解密
            original = cipher.doFinal(encrypted);
        } catch (Exception e) {
            logger.info("aes解密报错:",e);
            e.printStackTrace();
            throw new AesException(AesException.DecryptAESError);
        }
        String xmlContent, from_receiveid;
        try {
            // 去除补位字符
            byte[] bytes = PKCS7Encoder.decode(original);
            // 分离16位随机字符串,网络字节序和receiveid
            byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
            int xmlLength = recoverNetworkBytesOrder(networkOrder);
            xmlContent = new String(Arrays.copyOfRange(bytes, 20, 20 + xmlLength), CHARSET);
            from_receiveid = new String(Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length),
                    CHARSET);
        } catch (Exception e) {
            e.printStackTrace();
            throw new AesException(AesException.IllegalBuffer);
        }
        // receiveid不相同的情况
        if (!from_receiveid.equals(receiveid)) {
            throw new AesException(AesException.ValidateCorpidError);
        }
        return xmlContent;
    }
    /**
     * 将企业微信回复用户的消息加密打包.
     * <ol>
     *     <li>对要发送的消息进行AES-CBC加密</li>
     *     <li>生成安全签名</li>
     *     <li>将消息密文和安全签名打包成xml格式</li>
     * </ol>
     *
     * @param replyMsg 企业微信待回复用户的消息,xml格式的字符串
     * @param timeStamp 时间戳,可以自己生成,也可以用URL参数的timestamp
     * @param nonce 随机串,可以自己生成,也可以用URL参数的nonce
     *
     * @return 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串
     * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
     */
    public String EncryptMsg(String replyMsg, String timeStamp, String nonce) throws AesException {
        // 加密
        String encrypt = encrypt(getRandomStr(), replyMsg);
        // 生成安全签名
        if (timeStamp == "") {
            timeStamp = Long.toString(System.currentTimeMillis());
        }
        String signature = SHA1.getSHA1(token, timeStamp, nonce, encrypt);
        // System.out.println("发送给平台的签名是: " + signature[1].toString());
        // 生成发送的xml
        String result = XMLParse.generate(encrypt, signature, timeStamp, nonce);
        return result;
    }
    /**
     * 检验消息的真实性,并且获取解密后的明文.
     * <ol>
     *     <li>利用收到的密文生成安全签名,进行签名验证</li>
     *     <li>若验证通过,则提取xml中的加密消息</li>
     *     <li>对消息进行解密</li>
     * </ol>
     *
     * @param msgSignature 签名串,对应URL参数的msg_signature
     * @param timeStamp 时间戳,对应URL参数的timestamp
     * @param nonce 随机串,对应URL参数的nonce
     * @param postData 密文,对应POST请求的数据
     *
     * @return 解密后的原文
     * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
     */
    public String DecryptMsg(String msgSignature, String timeStamp, String nonce, String postData)
            throws AesException {
        // 密钥,公众账号的app secret
        // 提取密文
        Object[] encrypt = XMLParse.extract(postData);
        // 验证安全签名
        String signature = SHA1.getSHA1(token, timeStamp, nonce, encrypt[1].toString());
        // 和URL中的签名比较是否相等
        // System.out.println("第三方收到URL中的签名:" + msg_sign);
        // System.out.println("第三方校验签名:" + signature);
        if (!signature.equals(msgSignature)) {
            throw new AesException(AesException.ValidateSignatureError);
        }
        // 解密
        String result = decrypt(encrypt[1].toString());
        return result;
    }
    /**
     * 验证URL
     * @param msgSignature 签名串,对应URL参数的msg_signature
     * @param timeStamp 时间戳,对应URL参数的timestamp
     * @param nonce 随机串,对应URL参数的nonce
     * @param echoStr 随机串,对应URL参数的echostr
     *
     * @return 解密之后的echostr
     * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
     */
    public String VerifyURL(String msgSignature, String timeStamp, String nonce, String echoStr)
            throws AesException {
        String signature = SHA1.getSHA1(token, timeStamp, nonce, echoStr);
        if (!signature.equals(msgSignature)) {
            throw new AesException(AesException.ValidateSignatureError);
        }
        String result = decrypt(echoStr);
        return result;
    }
}
src/main/java/com/qq/weixin/mp/aes/XMLParse.java
New file
@@ -0,0 +1,106 @@
/**
 * 对企业微信发送给企业后台的消息加解密示例代码.
 *
 * @copyright Copyright (c) 1998-2014 Tencent Inc.
 */
// ------------------------------------------------------------------------
package com.qq.weixin.mp.aes;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
/**
 * XMLParse class
 *
 * 提供提取消息格式中的密文及生成回复消息格式的接口.
 */
class XMLParse {
    /**
     * 提取出xml数据包中的加密消息
     * @param xmltext 待提取的xml字符串
     * @return 提取出的加密消息字符串
     * @throws AesException
     */
    public static Object[] extract(String xmltext) throws AesException     {
        Object[] result = new Object[3];
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            String FEATURE = null;
            // This is the PRIMARY defense. If DTDs (doctypes) are disallowed, almost all XML entity attacks are prevented
            // Xerces 2 only - http://xerces.apache.org/xerces2-j/features.html#disallow-doctype-decl
            FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
            dbf.setFeature(FEATURE, true);
            // If you can't completely disable DTDs, then at least do the following:
            // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-general-entities
            // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-general-entities
            // JDK7+ - http://xml.org/sax/features/external-general-entities
            FEATURE = "http://xml.org/sax/features/external-general-entities";
            dbf.setFeature(FEATURE, false);
            // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-parameter-entities
            // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-parameter-entities
            // JDK7+ - http://xml.org/sax/features/external-parameter-entities
            FEATURE = "http://xml.org/sax/features/external-parameter-entities";
            dbf.setFeature(FEATURE, false);
            // Disable external DTDs as well
            FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
            dbf.setFeature(FEATURE, false);
            // and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks"
            dbf.setXIncludeAware(false);
            dbf.setExpandEntityReferences(false);
            // And, per Timothy Morgan: "If for some reason support for inline DOCTYPEs are a requirement, then
            // ensure the entity settings are disabled (as shown above) and beware that SSRF attacks
            // (http://cwe.mitre.org/data/definitions/918.html) and denial
            // of service attacks (such as billion laughs or decompression bombs via "jar:") are a risk."
            // remaining parser logic
            DocumentBuilder db = dbf.newDocumentBuilder();
            StringReader sr = new StringReader(xmltext);
            InputSource is = new InputSource(sr);
            Document document = db.parse(is);
            Element root = document.getDocumentElement();
            NodeList nodelist1 = root.getElementsByTagName("Encrypt");
            NodeList nodelist2 = root.getElementsByTagName("ToUserName");
            result[0] = 0;
            result[1] = nodelist1.item(0).getTextContent();
            result[2] = nodelist2.item(0).getTextContent();
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            throw new AesException(AesException.ParseXmlError);
        }
    }
    /**
     * 生成xml消息
     * @param encrypt 加密后的消息密文
     * @param signature 安全签名
     * @param timestamp 时间戳
     * @param nonce 随机字符串
     * @return 生成的xml字符串
     */
    public static String generate(String encrypt, String signature, String timestamp, String nonce) {
        String format = "<xml>\n" + "<Encrypt><![CDATA[%1$s]]></Encrypt>\n"
                + "<MsgSignature><![CDATA[%2$s]]></MsgSignature>\n"
                + "<TimeStamp>%3$s</TimeStamp>\n" + "<Nonce><![CDATA[%4$s]]></Nonce>\n" + "</xml>";
        return String.format(format, encrypt, signature, timestamp, nonce);
    }
}
src/main/main.iml
New file
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
  <component name="NewModuleRootManager" inherit-compiler-output="true">
    <exclude-output />
    <content url="file://$MODULE_DIR$">
      <sourceFolder url="file://$MODULE_DIR$/java" isTestSource="false" />
    </content>
    <orderEntry type="inheritedJdk" />
    <orderEntry type="sourceFolder" forTests="false" />
    <orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.5" level="project" />
  </component>
</module>