commit 9b77b796cf394c1156d15f2651fb4191e8b15199 Author: mengyxu Date: Wed Aug 4 17:41:00 2021 +0800 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4ba0aaf --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +/.classpath +/.project +/.settings +/bin/ +/logs +/target/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..8c930d9 --- /dev/null +++ b/pom.xml @@ -0,0 +1,87 @@ + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.0.2.RELEASE + + com.mengyxu.core + mengyxu_core + 0.0.1 + mengyxu_core + mengyxu-core + jar + + + UTF-8 + UTF-8 + 1.3.2 + 1.2.17 + 1.2.46 + 4.0.1 + 2.0.0 + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + ${mybatis-spring-boot.version} + + + + org.projectlombok + lombok + + + + com.alibaba + fastjson + ${fastjson.version} + + + + org.apache.httpcomponents + httpclient + + + + org.apache.poi + poi-ooxml + ${apache.poi.version} + + + + org.dom4j + dom4j + ${dom4j.version} + + + + + \ No newline at end of file diff --git a/src/main/java/com/mengyxu/core/exception/ControllerExceptionHandler.java b/src/main/java/com/mengyxu/core/exception/ControllerExceptionHandler.java new file mode 100644 index 0000000..c346118 --- /dev/null +++ b/src/main/java/com/mengyxu/core/exception/ControllerExceptionHandler.java @@ -0,0 +1,63 @@ +package com.mengyxu.core.exception; + +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; + +import org.springframework.dao.DuplicateKeyException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; + +import com.mengyxu.core.pojo.com.AjaxResponse; + +import lombok.extern.log4j.Log4j2; + +/** All rights reserved + * author:mengyxu + * date:2019年6月4日 + */ + +@Log4j2 +@ControllerAdvice +public class ControllerExceptionHandler { + + @ResponseBody + @ExceptionHandler(CoreException.class) + public AjaxResponse handlerSprtException(CoreException e) { + log.warn(e.getMessage()); + return new AjaxResponse(false, e.getMessage()); + } + + @ResponseBody + @ExceptionHandler(DuplicateKeyException.class) + public AjaxResponse handlerDuplicateKeyException(DuplicateKeyException e) { + return new AjaxResponse(false, "数据已存在,请勿重复添加"); + } + + @ResponseBody + @ExceptionHandler(SQLException.class) + public AjaxResponse handlerSqlException(SQLException e) { + log.warn(e.getMessage()); + return new AjaxResponse(false, "数据库访问出错!"); + } + + @ResponseBody + @ExceptionHandler(NullPointerException.class) + public AjaxResponse handlerNullPointerException(NullPointerException e) { + log.warn(e.getMessage()); + return new AjaxResponse(false, "操作失败,缺少必要参数!"); + } + + @ResponseBody + @ExceptionHandler(Exception.class) + public Map handlerException(Exception e) { + log.error("请求失败!",e); + Map map = new HashMap<>(); + map.put("success", false); + map.put("message", "操作失败,参数错误!"); + map.put("error", e.getMessage()); + return map; + } + +} diff --git a/src/main/java/com/mengyxu/core/exception/CoreException.java b/src/main/java/com/mengyxu/core/exception/CoreException.java new file mode 100644 index 0000000..47943f4 --- /dev/null +++ b/src/main/java/com/mengyxu/core/exception/CoreException.java @@ -0,0 +1,34 @@ +package com.mengyxu.core.exception; + +import lombok.Getter; + +@Getter +public class CoreException extends Exception{ + private static final long serialVersionUID = 1L; + + private String errCode; + private String errDesc; + + + public CoreException(Throwable e){ + super(e); + } + + public CoreException(String msg){ + super(msg); + } + + public CoreException(String msg, Throwable e){ + super(msg, e); + } + + public CoreException(String code, String msg){ + this(msg); + this.errCode = code; + } + + public CoreException(String code, String msg, Throwable e){ + this(msg, e); + this.errCode = code; + } +} diff --git a/src/main/java/com/mengyxu/core/golbal/GlobalBuffer.java b/src/main/java/com/mengyxu/core/golbal/GlobalBuffer.java new file mode 100644 index 0000000..9c8ce3c --- /dev/null +++ b/src/main/java/com/mengyxu/core/golbal/GlobalBuffer.java @@ -0,0 +1,78 @@ +package com.mengyxu.core.golbal; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import com.mengyxu.core.exception.CoreException; +import com.mengyxu.core.pojo.com.Cache; +import com.mengyxu.core.utils.DateUtil; +import com.mengyxu.core.utils.StringUtil; + +import lombok.extern.log4j.Log4j2; + +/** All rights reserved + * author:mengyxu + * date:2019年9月19日 + */ + +@Log4j2 +@EnableScheduling +@Component +public class GlobalBuffer { + private static final Map CACHES_MAP = new HashMap<>(); + private static int KEY_PREFIX_SEQ = 0; + + @Scheduled(cron = "${quartz.cron.clean.global:0 */10 * * * ?}") + public void job() { + log.info("清理已过期失效的缓存"); + GlobalBuffer.cleanCache(); + } + + + public static Map getBuffer(){ + return CACHES_MAP; + } + + public static synchronized String getSeq() { + return StringUtil.lpad(KEY_PREFIX_SEQ++ + "", "0", 10); + } + + public static void addCache(String key,Cache cache) { + CACHES_MAP.put(key, cache); + } + + public static Cache getCache(String key) { + Cache cache = CACHES_MAP.get(key); + if(Cache.isEmpty(cache)) { + CACHES_MAP.remove(key); + return null; + } + return cache; + } + + public static void removeCache(String key) { + CACHES_MAP.remove(key); + } + + public static synchronized void cleanCache() { + Iterator> iter = CACHES_MAP.entrySet().iterator(); + while (iter.hasNext()){ + Cache cache = iter.next().getValue(); + if(cache == null || cache.getValue() == null) { + iter.remove(); + } + } + } + + public static void setLoseTime(String key, String loseTime) throws CoreException { + Long time = DateUtil.parse(loseTime, DateUtil.FORMAT19_LINE_YYYYMMDDHHMMSS).getTime(); + Cache.setLoseTime(getCache(key), time); + } + +} diff --git a/src/main/java/com/mengyxu/core/golbal/GlobalConstant.java b/src/main/java/com/mengyxu/core/golbal/GlobalConstant.java new file mode 100644 index 0000000..d7ef0a5 --- /dev/null +++ b/src/main/java/com/mengyxu/core/golbal/GlobalConstant.java @@ -0,0 +1,44 @@ +package com.mengyxu.core.golbal; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import org.springframework.boot.system.ApplicationHome; +import org.springframework.util.DigestUtils; + +public class GlobalConstant { + + public static final String RESOURCES_ROOT_PATH; + public static final String JAR_RESOURCES_PATH; + public static final String JAR_DOWNLOAD_PATH; + public static final String FILE_DOWNLOAD_PATH; + + public static final String DEFAULT_PASSWORD = DigestUtils.md5DigestAsHex("888888".getBytes()); + public static final String CODE_KEY_PREFIX = "login-code-"; + public static final String TIKEN_KEY_PREFIX = "login-token-"; + public static final String LOGIN_COOKIE_NAME = "UMLoginToken"; + + + public static final String ENCODING_UTF8 = "UTF-8"; + + public static final Map YYS_TYPES = new HashMap<>(); + static{ + RESOURCES_ROOT_PATH = GlobalConstant.class.getClassLoader().getResource("").getPath(); + FILE_DOWNLOAD_PATH = RESOURCES_ROOT_PATH + "/file/"; + + ApplicationHome h = new ApplicationHome(GlobalConstant.class); + File jarF = h.getSource(); + JAR_RESOURCES_PATH = jarF.getParentFile().toString(); + JAR_DOWNLOAD_PATH = JAR_RESOURCES_PATH + "/file/"; + + YYS_TYPES.put(0, "移动"); + YYS_TYPES.put(1, "联通"); + YYS_TYPES.put(2, "电信"); + } + + private GlobalConstant(){ + //Add a private constructor to hide the implicit public one. + } + +} diff --git a/src/main/java/com/mengyxu/core/http/HttpResult.java b/src/main/java/com/mengyxu/core/http/HttpResult.java new file mode 100644 index 0000000..56b8eb8 --- /dev/null +++ b/src/main/java/com/mengyxu/core/http/HttpResult.java @@ -0,0 +1,27 @@ +package com.mengyxu.core.http; + +import lombok.Getter; +import lombok.Setter; + +/** All rights reserved + * author:mengyxu + * date:2019年5月25日 + */ + +@Setter +@Getter +public class HttpResult { + + // 响应的状态码 + private int code; + + // 响应的响应体 + private String body; + + public HttpResult(int code, String body) { + super(); + this.code = code; + this.body = body; + } + +} diff --git a/src/main/java/com/mengyxu/core/http/HttpService.java b/src/main/java/com/mengyxu/core/http/HttpService.java new file mode 100644 index 0000000..d8be755 --- /dev/null +++ b/src/main/java/com/mengyxu/core/http/HttpService.java @@ -0,0 +1,235 @@ +package com.mengyxu.core.http; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.http.NameValuePair; +import org.apache.http.client.CookieStore; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.BasicCookieStore; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.impl.cookie.BasicClientCookie; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import lombok.extern.log4j.Log4j2; + +/** All rights reserved + * author:mengyxu + * date:2019年5月25日 + */ + +@Log4j2 +@SuppressWarnings("all") +public class HttpService { + private static final String ENCODING_UTF8 = "UTF-8"; + + private static final PoolingHttpClientConnectionManager cm; + + private static final RequestConfig config; + + private static CookieStore cookieStore = new BasicCookieStore(); + + static{ + cm = new PoolingHttpClientConnectionManager(); + cm.setMaxTotal(200); + cm.setDefaultMaxPerRoute(20); + + config = RequestConfig.custom().setConnectTimeout(100000) + .setConnectionRequestTimeout(50000).setSocketTimeout(100000) + .setStaleConnectionCheckEnabled(true).build(); + } + + /** + * 设置请求所携带cookie + * @param cookies + */ + public static void setCookies(Map cookies) { + cookieStore = new BasicCookieStore(); + if(cookies != null) { + for (String key : cookies.keySet()) { + String value = cookies.get(key); + BasicClientCookie clientCookie = new BasicClientCookie(key, value); + clientCookie.setVersion(0); + clientCookie.setSecure(false); + clientCookie.setDomain("."); + clientCookie.setPath("/"); + cookieStore.addCookie(clientCookie); + } + } + } + + /** + * 带参数的get请求 + * + * @param url + * @param map + * @return + */ + public static HttpResult doGet(String url, Map param) { + try { + // 1.创建URIBuilder + URIBuilder uriBuilder = new URIBuilder(url); + + // 2.设置请求参数 + if (param != null) { + // 遍历请求参数 + for (Map.Entry entry : param.entrySet()) { + // 封装请求参数 + uriBuilder.setParameter(entry.getKey(), entry.getValue().toString()); + } + } + + // 3.创建请求对象httpGet + HttpGet httpGet = new HttpGet(uriBuilder.build()); + httpGet.setConfig(config); + // 4.使用httpClient发起请求 + CloseableHttpResponse response = HttpClients.custom().setDefaultCookieStore(cookieStore).setConnectionManager(cm).build() + .execute(httpGet); + + // 5.解析返回结果,封装返回对象httpResult + return getResult(response); + } catch (Exception e) { + log.error("http request failed",e); + return new HttpResult(500, "http request failed"); + } + } + + /** + * 不带参数的get + * + * @param url + * @return + */ + public static HttpResult doGet(String url) { + return doGet(url, null); + } + + + /** + * 带参数的post请求 + * + * @param url + * @param map + * @return + * @ + */ + public static HttpResult doPost(String url, Map param) { + try { + // 1. 声明httppost + HttpPost httpPost = new HttpPost(url); + httpPost.setHeader("Accept", "application/json"); + httpPost.setHeader("Content-Type", "application/json"); + String charSet = "UTF-8"; + + // 2.封装请求参数,请求数据是表单 + if (param != null) { + // 声明封装表单数据的容器 + List parameters = new ArrayList(); + for (Map.Entry entry : param.entrySet()) { + // 封装请求参数到容器中 + parameters.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString())); + } + + // 创建表单的Entity对象 + UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters, ENCODING_UTF8); + + // 3. 把封装好的表单实体对象设置到HttpPost对象 + httpPost.setEntity(entity); + } + + // 4. 使用Httpclient发起请求 + CloseableHttpResponse response = HttpClients.custom().setDefaultCookieStore(cookieStore).setConnectionManager(cm).build() + .execute(httpPost); + + return getResult(response); + } catch (Exception e) { + log.error("http request failed",e); + return new HttpResult(500, "http request failed"); + } + } + + /** + * json格式参数的post请求 + * + * @param url 请求地址 + * @param params json格式参数 + * @return + * @ + */ + public static HttpResult postWithJson(String url, String params, Map headers) { + try { + // 1. 声明httppost + HttpPost httpPost = new HttpPost(url); + httpPost.setHeader("Accept", "application/json"); + httpPost.setHeader("Content-Type", "application/json"); + String charSet = "UTF-8"; + StringEntity entity = new StringEntity(params, charSet); + httpPost.setEntity(entity); + + //设置http请求头 + if(headers != null) { + for (String key : headers.keySet()) { + httpPost.setHeader(key, headers.get(key)); + } + } + + // 4. 使用Httpclient发起请求 + CloseableHttpResponse response = HttpClients.custom().setConnectionManager(cm).build().execute(httpPost); + + // 5. 解析返回数据,封装HttpResult + return getResult(response); + } catch (Exception e) { + log.error("http request failed",e); + return new HttpResult(500, "http request failed"); + } + } + + private static HttpResult getResult(CloseableHttpResponse response) throws IOException { + // 状态码 + int code = response.getStatusLine().getStatusCode(); + + // 响应体内容 + String body = null; + if (response.getEntity() != null) { + body = EntityUtils.toString(response.getEntity(), ENCODING_UTF8); + } + + return new HttpResult(code, body); + } + + /** + * 不带参数的post请求 + * + * @param url + * @return + */ + public static HttpResult doPost(String url) { + return doPost(url, null); + } + + public static void doPostAsync(final String url, final Map param){ + new Thread(new Runnable() { + @Override + public void run() { + try { + doPost(url, param); + } catch (Exception e) { + e.printStackTrace(); + } + } + }).start(); + } + +} diff --git a/src/main/java/com/mengyxu/core/pojo/BufferResult.java b/src/main/java/com/mengyxu/core/pojo/BufferResult.java new file mode 100644 index 0000000..c5d724d --- /dev/null +++ b/src/main/java/com/mengyxu/core/pojo/BufferResult.java @@ -0,0 +1,43 @@ +package com.mengyxu.core.pojo; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import com.mengyxu.core.pojo.com.Cache; + +import lombok.Data; + +/** All rights reserved + * author:mengyxu + * date:2019年12月13日 + */ + +@Data +@SuppressWarnings("all") +public class BufferResult { + + private String key; + private boolean effective; + private String loseTime; + private Object value; + + public BufferResult(String key, Cache cache) { + this.key = key; + this.effective = !Cache.isEmpty(cache); + this.loseTime = cache.getLoseTime(); + this.value = cache.getValue(); + if(value instanceof Map) { + Map map = (Map) value; + Set keySet = map.keySet(); + if(!keySet.isEmpty() && keySet.toArray()[0] instanceof Integer) { + Map newMap = new HashMap<>(); + for (Object mapKey : keySet) { + newMap.put(mapKey.toString(), map.get(mapKey)); + } + this.value = newMap; + } + } + } + +} diff --git a/src/main/java/com/mengyxu/core/pojo/base/BaseCountBean.java b/src/main/java/com/mengyxu/core/pojo/base/BaseCountBean.java new file mode 100644 index 0000000..1aadeeb --- /dev/null +++ b/src/main/java/com/mengyxu/core/pojo/base/BaseCountBean.java @@ -0,0 +1,18 @@ +package com.mengyxu.core.pojo.base; + +import lombok.Getter; +import lombok.Setter; + +/** All rights reserved + * author:mengyxu + * date:2019年5月10日 + */ + +@Setter +@Getter +public class BaseCountBean { + + private long total; + private long disTotal; + +} diff --git a/src/main/java/com/mengyxu/core/pojo/base/BasePageParam.java b/src/main/java/com/mengyxu/core/pojo/base/BasePageParam.java new file mode 100644 index 0000000..4a30b14 --- /dev/null +++ b/src/main/java/com/mengyxu/core/pojo/base/BasePageParam.java @@ -0,0 +1,23 @@ +package com.mengyxu.core.pojo.base; + +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Getter; +import lombok.Setter; + +/** All rights reserved + * author:mengyxu + * date:2019年10月17日 + */ + +@Setter +@Getter +public class BasePageParam extends BasePojo { + + @JSONField(serialize=false) + private Integer page; + @JSONField(serialize=false) + private Integer size; + @JSONField(serialize=false) + private Integer limitStart; + +} diff --git a/src/main/java/com/mengyxu/core/pojo/base/BasePeriod.java b/src/main/java/com/mengyxu/core/pojo/base/BasePeriod.java new file mode 100644 index 0000000..69994e5 --- /dev/null +++ b/src/main/java/com/mengyxu/core/pojo/base/BasePeriod.java @@ -0,0 +1,18 @@ +package com.mengyxu.core.pojo.base; + +import lombok.Getter; +import lombok.Setter; + +/** All rights reserved + * author:mengyxu + * date:2019年12月24日 + */ + +@Setter +@Getter +public class BasePeriod extends BasePageParam { + + private String startTime; + private String endTime; + +} diff --git a/src/main/java/com/mengyxu/core/pojo/base/BasePojo.java b/src/main/java/com/mengyxu/core/pojo/base/BasePojo.java new file mode 100644 index 0000000..15b6faa --- /dev/null +++ b/src/main/java/com/mengyxu/core/pojo/base/BasePojo.java @@ -0,0 +1,27 @@ +package com.mengyxu.core.pojo.base; + +import java.util.Date; + +import com.mengyxu.core.utils.DateUtil; +import com.mengyxu.core.utils.StringUtil; + +import lombok.Data; + +/** All rights reserved + * author:mengyxu + * date:2019年9月20日 + */ + +@Data +public class BasePojo { + + private String time; + + public String getTime() { + if(!StringUtil.isEmpty(time)) { + return time; + } + return DateUtil.format(new Date(), DateUtil.FORMAT19_LINE_YYYYMMDDHHMMSS); + } + +} diff --git a/src/main/java/com/mengyxu/core/pojo/base/BaseTree.java b/src/main/java/com/mengyxu/core/pojo/base/BaseTree.java new file mode 100644 index 0000000..d34b56f --- /dev/null +++ b/src/main/java/com/mengyxu/core/pojo/base/BaseTree.java @@ -0,0 +1,23 @@ +package com.mengyxu.core.pojo.base; + +import java.util.List; + +import lombok.Getter; +import lombok.Setter; + +/** All rights reserved + * author:mengyxu + * date:2019年10月17日 + */ + +@Setter +@Getter +public abstract class BaseTree { + + private String id;//编号 + private String name;//名称 + private String desc;//说明 + + private List children; + +} diff --git a/src/main/java/com/mengyxu/core/pojo/com/AjaxResponse.java b/src/main/java/com/mengyxu/core/pojo/com/AjaxResponse.java new file mode 100644 index 0000000..231aecb --- /dev/null +++ b/src/main/java/com/mengyxu/core/pojo/com/AjaxResponse.java @@ -0,0 +1,31 @@ +package com.mengyxu.core.pojo.com; + +import lombok.Data; + +/** All rights reserved + * author:mengyxu + * date:2019年6月26日 + */ + +@Data +public class AjaxResponse { + private boolean success; + private String message; + private Object data; + + public AjaxResponse(boolean success, String message) { + this.success = success; + this.message = message; + } + + public AjaxResponse() { + super(); + } + + public AjaxResponse(boolean success, String message, Object data) { + this.success = success; + this.message = message; + this.data = data; + } + +} diff --git a/src/main/java/com/mengyxu/core/pojo/com/Cache.java b/src/main/java/com/mengyxu/core/pojo/com/Cache.java new file mode 100644 index 0000000..be58187 --- /dev/null +++ b/src/main/java/com/mengyxu/core/pojo/com/Cache.java @@ -0,0 +1,57 @@ +package com.mengyxu.core.pojo.com; + +import java.util.Date; + +import com.mengyxu.core.utils.DateUtil; + +/** All rights reserved + * author:mengyxu + * date:2019年6月26日 + */ + +@SuppressWarnings("unchecked") +public class Cache { + + private Object value; + private Long timeout; + private Long loseTime; + + public Cache(T value) { + this.value = value; + } + + public Cache(T value, long timeout) { + this.value = value; + this.timeout = timeout; + this.loseTime = System.currentTimeMillis() + timeout*1000; + } + + public T getValue() { + if(loseTime != null && System.currentTimeMillis() > loseTime) { + return null; + } + return (T)value; + } + + public String getLoseTime() { + if(loseTime == null) { + return "永不失效"; + } + return DateUtil.format(new Date(loseTime), DateUtil.FORMAT19_LINE_YYYYMMDDHHMMSS); + } + + public void refresh() { + if(timeout != null) { + this.loseTime = System.currentTimeMillis() + timeout*1000; + } + } + + public static boolean isEmpty(Cache cache) { + return cache == null || cache.getValue() == null; + } + + public static void setLoseTime(Cache cache,Long loseTime) { + cache.loseTime = loseTime; + } + +} diff --git a/src/main/java/com/mengyxu/core/pojo/com/Entry.java b/src/main/java/com/mengyxu/core/pojo/com/Entry.java new file mode 100644 index 0000000..cb8a072 --- /dev/null +++ b/src/main/java/com/mengyxu/core/pojo/com/Entry.java @@ -0,0 +1,17 @@ +package com.mengyxu.core.pojo.com; + +import java.io.Serializable; + +import lombok.Data; + +/** All rights reserved + * author:mengyxu + * date:2019年6月26日 + */ + +@Data +public class Entry implements Serializable{ + private static final long serialVersionUID = 8389699482773678138L; + private K key; + private V value; +} diff --git a/src/main/java/com/mengyxu/core/pojo/com/PageResult.java b/src/main/java/com/mengyxu/core/pojo/com/PageResult.java new file mode 100644 index 0000000..fc6410a --- /dev/null +++ b/src/main/java/com/mengyxu/core/pojo/com/PageResult.java @@ -0,0 +1,19 @@ +package com.mengyxu.core.pojo.com; + +import java.util.List; + +import lombok.Getter; +import lombok.Setter; + +/** All rights reserved + * author:mengyxu + * date:2019年6月26日 + */ + +@Setter +@Getter +public class PageResult{ + private List rows; // 每页记录集合 + private String status; + private Long total; +} \ No newline at end of file diff --git a/src/main/java/com/mengyxu/core/pojo/com/VueTreeSlt.java b/src/main/java/com/mengyxu/core/pojo/com/VueTreeSlt.java new file mode 100644 index 0000000..d7feab3 --- /dev/null +++ b/src/main/java/com/mengyxu/core/pojo/com/VueTreeSlt.java @@ -0,0 +1,30 @@ +package com.mengyxu.core.pojo.com; + +import java.util.List; + +import com.mengyxu.core.pojo.base.BaseTree; + +import lombok.Getter; +import lombok.Setter; + +/** All rights reserved + * author:mengyxu + * date:2019年6月26日 + */ + +@Setter +@Getter +public class VueTreeSlt extends BaseTree { + + private String label; + private Integer level; + + public List getChildren(){ + List children = super.getChildren(); + if(children == null || children.isEmpty()) { + return null; + } + return children; + } + +} diff --git a/src/main/java/com/mengyxu/core/pojo/special/XmlTag.java b/src/main/java/com/mengyxu/core/pojo/special/XmlTag.java new file mode 100644 index 0000000..de0ecea --- /dev/null +++ b/src/main/java/com/mengyxu/core/pojo/special/XmlTag.java @@ -0,0 +1,24 @@ +package com.mengyxu.core.pojo.special; + +import java.util.List; +import java.util.Map; + +import lombok.Getter; +import lombok.Setter; + +/** All rights reserved + * author:mengyxu + * date:2020年5月8日 + */ + +@Setter +@Getter +public class XmlTag { + + private String name; + private Map attrs; + private String value; + private List nodes; + private boolean editable; + +} diff --git a/src/main/java/com/mengyxu/core/promise/ExcelParser.java b/src/main/java/com/mengyxu/core/promise/ExcelParser.java new file mode 100644 index 0000000..062a9c7 --- /dev/null +++ b/src/main/java/com/mengyxu/core/promise/ExcelParser.java @@ -0,0 +1,18 @@ +package com.mengyxu.core.promise; + +import java.util.List; + +import com.mengyxu.core.exception.CoreException; + +/** All rights reserved + * author:mengyxu + * date:2019年11月22日 + */ + +public interface ExcelParser { + + public List parseToArray(T obj); + + public List parseToObj(List list, Object param) throws CoreException; + +} diff --git a/src/main/java/com/mengyxu/core/utils/Base64Util.java b/src/main/java/com/mengyxu/core/utils/Base64Util.java new file mode 100644 index 0000000..bcfaa8c --- /dev/null +++ b/src/main/java/com/mengyxu/core/utils/Base64Util.java @@ -0,0 +1,63 @@ +package com.mengyxu.core.utils; + +import java.io.UnsupportedEncodingException; +import java.util.Base64; + +import com.mengyxu.core.exception.CoreException; +import com.mengyxu.core.golbal.GlobalConstant; + +/** All rights reserved + * author:mengyxu + * date:2019年5月25日 + */ + +public class Base64Util { + + /** + * 解密 + * @return + * @throws CoreException + */ + public static String decodeToString(String str) throws CoreException { + return decodeToString(str, GlobalConstant.ENCODING_UTF8); + } + + public static byte[] decode(String str) { + return Base64.getDecoder().decode(str); + } + + public static String decodeToString(String str, String encoding) throws CoreException{ + try { + byte[] decode = decode(str); + return new String(decode, encoding); + } catch (UnsupportedEncodingException e) { + throw new CoreException("Unsupport encoding [" + encoding +"]", e); + }catch (IllegalArgumentException e) { + throw new CoreException("It's not the Base64 encoding string."); + } + + } + + /** + * 加密 + * @return + * @throws CoreException + */ + public static String encode(String str) throws CoreException { + return encode(str.getBytes()); + } + + public static String encode(byte[] bytes) { + return Base64.getEncoder().encodeToString(bytes); + } + + public static String encode(String str, String encoding) throws CoreException { + try { + return encode(str.getBytes(encoding)); + } catch (UnsupportedEncodingException e) { + throw new CoreException("Unsupport encoding [" + encoding +"]", e); + } + } + + private Base64Util(){} +} diff --git a/src/main/java/com/mengyxu/core/utils/ByteUtil.java b/src/main/java/com/mengyxu/core/utils/ByteUtil.java new file mode 100644 index 0000000..e4ce8eb --- /dev/null +++ b/src/main/java/com/mengyxu/core/utils/ByteUtil.java @@ -0,0 +1,316 @@ +package com.mengyxu.core.utils; + + +/** All rights reserved + * author:mengyxu + * date:2020年1月6日 + */ + +public class ByteUtil { + /** + * 转换short为byte + * + * @param b + * @param s + * 需要转换的short + * @param index + */ + public static void putShort(byte b[], short s, int index) { + b[index + 1] = (byte) (s >> 8); + b[index + 0] = (byte) (s >> 0); + } + + /** + * 转换无符号short为byte + * + * @param b + * @param i 需要转换的short + * @param index + */ + public static void putUnsignedShort(byte b[], int i, int index) { + short s = (short) i; + b[index + 1] = (byte) (s >> 0); + b[index + 0] = (byte) (s >> 8); + } + /** + * 通过byte数组取到short + * + * @param b + * @param index + * 第几位开始取 + * @return + */ + public static short getShort(byte[] b, int index) { + return (short) (((b[index + 1] << 8) | b[index + 0] & 0xff)); + } + + /** + * 通过byte数组取到无符号short + * + * @param b + * @param index 第几位开始取 + * @return + */ + public static int getUnsignedShort(byte[] b, int index) { + short s = (short) ((b[index + 0] << 8) | b[index + 1] & 0xff); + return Short.toUnsignedInt(s); + } + + /** + * 转换int为byte数组 + * + * @param bb + * @param x + * @param index + */ + public static void putInt(byte[] bb, int x, int index) { + bb[index + 3] = (byte) (x >> 24); + bb[index + 2] = (byte) (x >> 16); + bb[index + 1] = (byte) (x >> 8); + bb[index + 0] = (byte) (x >> 0); + } + + /** + * 转换无符号int为byte数组 + * + * @param bb + * @param l + * @param index + */ + public static void putUnsignedInt(byte[] bb, long l, int index) { + int x = (int) l; + bb[index + 0] = (byte) (x >> 24); + bb[index + 1] = (byte) (x >> 16); + bb[index + 2] = (byte) (x >> 8); + bb[index + 3] = (byte) (x >> 0); + } + /** + * 通过byte数组取到int + * + * @param bb + * @param index + * 第几位开始 + * @return + */ + public static int getInt(byte[] bb, int index) { + return (int) ((((bb[index + 3] & 0xff) << 24) | ((bb[index + 2] & 0xff) << 16) | ((bb[index + 1] & 0xff) << 8) + | ((bb[index + 0] & 0xff) << 0))); + } + + /** + * 通过byte数组取到无符号int + * + * @param bb + * @param index 第几位开始 + * @return + */ + public static long getUnsignedInt(byte[] bb, int index) { + int i = (int) ((((bb[index + 0] & 0xff) << 24) | ((bb[index + 1] & 0xff) << 16) | ((bb[index + 2] & 0xff) << 8) + | ((bb[index + 3] & 0xff) << 0))); + return Integer.toUnsignedLong(i); + } + /** + * 转换long型为byte数组 + * + * @param bb + * @param x + * @param index + */ + public static void putLong(byte[] bb, long x, int index) { + bb[index + 7] = (byte) (x >> 56); + bb[index + 6] = (byte) (x >> 48); + bb[index + 5] = (byte) (x >> 40); + bb[index + 4] = (byte) (x >> 32); + bb[index + 3] = (byte) (x >> 24); + bb[index + 2] = (byte) (x >> 16); + bb[index + 1] = (byte) (x >> 8); + bb[index + 0] = (byte) (x >> 0); + } + public static void putLongNet(byte[] bb, long x, int index) { + bb[index + 0] = (byte) (x >> 56); + bb[index + 1] = (byte) (x >> 48); + bb[index + 2] = (byte) (x >> 40); + bb[index + 3] = (byte) (x >> 32); + bb[index + 4] = (byte) (x >> 24); + bb[index + 5] = (byte) (x >> 16); + bb[index + 6] = (byte) (x >> 8); + bb[index + 7] = (byte) (x >> 0); + } + /** + * 通过byte数组取到long + * + * @param bb + * @param index + * @return + */ + public static long getLong(byte[] bb, int index) { + return ((((long) bb[index + 7] & 0xff) << 56) | (((long) bb[index + 6] & 0xff) << 48) + | (((long) bb[index + 5] & 0xff) << 40) | (((long) bb[index + 4] & 0xff) << 32) + | (((long) bb[index + 3] & 0xff) << 24) | (((long) bb[index + 2] & 0xff) << 16) + | (((long) bb[index + 1] & 0xff) << 8) | (((long) bb[index + 0] & 0xff) << 0)); + } + public static long getLongNet(byte[] bb, int index) { + return ((((long) bb[index + 0] & 0xff) << 56) | (((long) bb[index + 1] & 0xff) << 48) + | (((long) bb[index + 2] & 0xff) << 40) | (((long) bb[index + 3] & 0xff) << 32) + | (((long) bb[index + 4] & 0xff) << 24) | (((long) bb[index + 5] & 0xff) << 16) + | (((long) bb[index + 6] & 0xff) << 8) | (((long) bb[index + 7] & 0xff) << 0)); + } + /** + * 字符到字节转换 + * + * @param ch + * @return + */ + public static void putChar(byte[] bb, char ch, int index) { + int temp = (int) ch; + // byte[] b = new byte[2]; + for (int i = 0; i < 2; i ++ ) { + bb[index + i] = new Integer(temp & 0xff).byteValue(); // 将最高位保存在最低位 + temp = temp >> 8; // 向右移8位 + } + } + public static void putCharNet(byte[] bb, char ch, int index) { + int temp = (int) ch; + // byte[] b = new byte[2]; + for (int i = 1; i >=0; i -- ) { + bb[index + i] = new Integer(temp & 0xff).byteValue(); // 将最高位保存在最低位 + temp = temp >> 8; // 向右移8位 + } + } + /** + * 字节到字符转换 + * + * @param b + * @return + */ + public static char getChar(byte[] b, int index) { + int s = 0; + if (b[index + 1] > 0) + s += b[index + 1]; + else + s += 256 + b[index + 0]; + s *= 256; + if (b[index + 0] > 0) + s += b[index + 1]; + else + s += 256 + b[index + 0]; + char ch = (char) s; + return ch; + } + + /** + * float转换byte + * + * @param bb + * @param x + * @param index + */ + public static void putFloat(byte[] bb, float x, int index) { + // byte[] b = new byte[4]; + int l = Float.floatToIntBits(x); + for (int i = 0; i < 4; i++) { + bb[index + i] = new Integer(l).byteValue(); + l = l >> 8; + } + } + + /** + * 通过byte数组取得float + * + * @param bb + * @param index + * @return + */ + public static float getFloat(byte[] b, int index) { + int l; + l = b[index + 0]; + l &= 0xff; + l |= ((long) b[index + 1] << 8); + l &= 0xffff; + l |= ((long) b[index + 2] << 16); + l &= 0xffffff; + l |= ((long) b[index + 3] << 24); + return Float.intBitsToFloat(l); + } + + /** + * double转换byte + * + * @param bb + * @param x + * @param index + */ + public static void putDouble(byte[] bb, double x, int index) { + // byte[] b = new byte[8]; + long l = Double.doubleToLongBits(x); + for (int i = 0; i < 4; i++) { + bb[index + i] = new Long(l).byteValue(); + l = l >> 8; + } + } + + /** + * 通过byte数组取得float + * + * @param bb + * @param index + * @return + */ + public static double getDouble(byte[] b, int index) { + long l; + l = b[0]; + l &= 0xff; + l |= ((long) b[1] << 8); + l &= 0xffff; + l |= ((long) b[2] << 16); + l &= 0xffffff; + l |= ((long) b[3] << 24); + l &= 0xffffffffl; + l |= ((long) b[4] << 32); + l &= 0xffffffffffl; + l |= ((long) b[5] << 40); + l &= 0xffffffffffffl; + l |= ((long) b[6] << 48); + l &= 0xffffffffffffffl; + l |= ((long) b[7] << 56); + return Double.longBitsToDouble(l); + } + + /** + * IPV4地址转换无符号byte数组 + * + * @param b + * @param ip + * @param index + */ + public static void putIpv4(byte[] b, String ip, int index) { + if (StringUtil.isEmpty(ip)) { + return; + } + String[] arr = ip.split("\\."); + if (arr.length != 4) { + return; + } + for (int i = 0; i < arr.length; i++) { + short s = Short.parseShort(arr[i]); + b[i + index] = (byte) s; + } + } + + /** + * 通过无符号byte数组取得IPV4地址 + * + * @param b + * @param index + * @return + */ + public static String getIpv4(byte[] b, int index) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < 4; i++) { + int s = Byte.toUnsignedInt(b[index + i]); + sb.append(s).append("."); + } + return sb.substring(0, sb.length() - 1); + } + +} \ No newline at end of file diff --git a/src/main/java/com/mengyxu/core/utils/DateUtil.java b/src/main/java/com/mengyxu/core/utils/DateUtil.java new file mode 100644 index 0000000..598e741 --- /dev/null +++ b/src/main/java/com/mengyxu/core/utils/DateUtil.java @@ -0,0 +1,234 @@ +package com.mengyxu.core.utils; + +import java.text.DateFormat; +import java.text.MessageFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; + +import com.mengyxu.core.exception.CoreException; + +/** All rights reserved + * author:mengyxu + * date:2019年5月17日 + */ + +public class DateUtil { + public static final String FORMAT10_LINE_DDMMYYYY = "dd-MM-yyyy"; + public static final String FORMAT10_LINE_MMDDYYYY = "MM-dd-yyyy"; + public static final String FORMAT10_LINE_YYYYMMDD = "yyyy-MM-dd"; + + public static final String FORMAT10_SLASH_DDMMYYYY = "dd/MM/yyyy"; + public static final String FORMAT10_SLASH_MMDDYYYY = "MM/dd/yyyy"; + public static final String FORMAT10_SLASH_YYYYMMDD = "yyyy/MM/dd"; + + public static final String FORMAT19_LINE_YYYYMMDDHHMMSS = "yyyy-MM-dd HH:mm:ss"; + + public static final String FORMAT8_DDMMYYYY = "ddMMyyyy"; + public static final String FORMAT8_MMDDYYYY = "MMddyyyy"; + public static final String FORMAT8_YYYYMMDD = "yyyyMMdd"; + + public static final String FORMAT3_YYM = "yy年M月"; + public static final String FORMAT2_MD = "M月d日"; + public static final String FORMAT2_DH = "d日H时"; + + public static final String FORMAT10_YYYYMMDDHH = "yyyyMMddHH"; + + public static final String FORMAT6_YYYYMM = "yyyyMM"; + public static final String FORMAT8_YYYYMM = "yyyy年MM月"; + + public static final String FORMAT14_YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; + public static final String FORMAT_GMT_8 = "EEE MMM dd yyyy HH:mm:ss 'GMT+0800(中国标准时间)'"; + + public static final String FORMAT20_LINE_YYYYMMDDTHHMMSS = "yyyy-MM-dd'T'HH:mm:ss"; + + + private DateUtil(){ + //Add a private constructor to hide the implicit public one. + } + + /** + *

+ * Convert a date string from srcPattern to destPattern。 + *

+ * @param dateStr + * @param srcPattern + * @param destPattern + * @return + * @throws CoreException + */ + public static String convert(String dateStr, String srcPattern, String destPattern) throws CoreException{ + if (dateStr == null){ + return null; + } + + Date date = parse(dateStr, srcPattern); + return format(date, destPattern); + } + + /** + * Format a date with specific String pattern. + * @param date + * @param pattern + * @return + */ + public static String format(Date date, String pattern){ + DateFormat formatter = new SimpleDateFormat(pattern); + + return formatter.format(date); + } + + + /** + * Format a date with specific String pattern. + * @param date + * @param pattern + * @Param locale + * @return + */ + public static String format(Date date, String pattern, Locale locale){ + DateFormat formatter = new SimpleDateFormat(pattern, locale); + + return formatter.format(date); + } + + /** + * Parse a string to a date with pattern. + * @param src + * @param pattern + * @return + * @throws CoreException + */ + public static Date parse(String src, String pattern) throws CoreException{ + DateFormat formatter = new SimpleDateFormat(pattern); + try { + return formatter.parse(src); + } catch (ParseException e) { + String message = "Connect convert to date. Unexpected pattern [{0}] for value [{1}]."; + throw new CoreException(MessageFormat.format(message, pattern, src), e); + } + } + + public static int compare(String src, String dest, String pattern) throws CoreException{ + Date srcDate = parse(src, pattern); + Date destDate = parse(dest, pattern); + + return srcDate.compareTo(destDate); + } + + public static long diff(String src, String dest, String pattern) throws CoreException{ + Date srcDate = parse(src, pattern); + Date destDate = parse(dest, pattern); + + return (destDate.getTime()-srcDate.getTime())/(1000*60*60*24); + } + + + public static int diff(Date srcDate, Date destDate) throws CoreException{ + Calendar src = Calendar.getInstance(); + src.setTime(srcDate); + + Calendar dest = Calendar.getInstance(); + dest.setTime(destDate); + + if (src.get(Calendar.YEAR) == dest.get(Calendar.YEAR)){ + return dest.get(Calendar.DAY_OF_YEAR) - src.get(Calendar.DAY_OF_YEAR); + } else { + int srcYear = src.get(Calendar.YEAR); + + Calendar tmp = Calendar.getInstance(); + tmp.setTimeInMillis(dest.getTimeInMillis()); + tmp.set(Calendar.YEAR, srcYear); + + int diff = tmp.get(Calendar.DAY_OF_YEAR) - src.get(Calendar.DAY_OF_YEAR); + diff += (destDate.getTime()-tmp.getTimeInMillis())/(1000*60*60*24L); + + return diff; + } + } + + /** + * Return today with pattern. + * + * @return + */ + public static String today(String pattern) { + return format(new Date(), pattern); + } + + public static Date dayAdd(int offset) { + return dayAdd(new Date(), offset); + } + public static Date dayAdd(Date date, int offset) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + offset); + return calendar.getTime(); + } + public static String dayAdd(String pattern, int offset){ + Date date = dayAdd(offset); + return format(date, pattern); + } + public static String dayAdd(String src, String pattern, int offset) throws CoreException { + Date date = dayAdd(parse(src, pattern), offset); + return format(date, pattern); + } + + public static Date hourAdd(Date date, int offset){ + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + offset); + return calendar.getTime(); + } + public static Date hourAdd(int offset){ + return hourAdd(new Date(), offset); + } + public static String hourAdd(String pattern, int offset){ + Date date = hourAdd(offset); + return format(date, pattern); + } + public static String hourAdd(String src, String pattern, int offset) throws CoreException { + Date date = hourAdd(parse(src, pattern), offset); + return format(date, pattern); + } + + public static Date monthAdd(Date date, int offset){ + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + offset); + calendar.set(Calendar.DAY_OF_MONTH, calendar.getMinimum(Calendar.DATE)); + return calendar.getTime(); + } + public static Date monthAdd(int offset){ + return monthAdd(new Date(), offset); + } + public static String monthAdd(String pattern, int offset) { + Date date = monthAdd(offset); + return format(date, pattern); + } + public static String monthAdd(String src, String pattern, int offset) throws CoreException { + Date date = monthAdd(parse(src, pattern), offset); + return format(date, pattern); + } + + public static String getFirstDay(Date month, String destPattern){ + Calendar calendar = Calendar.getInstance(); + calendar.setTime(month); + calendar.set(Calendar.DAY_OF_MONTH, calendar.getMinimum(Calendar.DATE)); + return format(calendar.getTime(), destPattern); + } + public static String getFirstDay(String month, String srcPattern, String destPattern) throws CoreException{ + return getFirstDay(parse(month, srcPattern),destPattern); + } + public static String getLastDay(Date month, String pattern){ + Calendar calendar = Calendar.getInstance(); + calendar.setTime(month); + calendar.set(Calendar.DAY_OF_MONTH, calendar.getMaximum(Calendar.DATE)); + return format(calendar.getTime(), pattern); + } + public static String getLastDay(String month, String srcPattern, String destPattern) throws CoreException{ + return getLastDay(parse(month, srcPattern),destPattern); + } +} diff --git a/src/main/java/com/mengyxu/core/utils/ExcelUtil.java b/src/main/java/com/mengyxu/core/utils/ExcelUtil.java new file mode 100644 index 0000000..bc7606a --- /dev/null +++ b/src/main/java/com/mengyxu/core/utils/ExcelUtil.java @@ -0,0 +1,173 @@ +package com.mengyxu.core.utils; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.springframework.web.multipart.MultipartFile; + +import com.mengyxu.core.exception.CoreException; +import com.mengyxu.core.promise.ExcelParser; + +import lombok.extern.log4j.Log4j2; + +/** All rights reserved + * author:mengyxu + * date:2019年11月22日 + */ + +@Log4j2 +@SuppressWarnings("all") +public class ExcelUtil { + + + /** + * 将数据转换为Excel表格,并将Excel表格转为字节数组返回 + * @param template 模版路径 + * @param data 源数据 + * @param parser 数据转换工具 + * @return + * @throws CoreException + */ + public static byte[] parseToExcelByteArray(String template, List data, ExcelParser parser) throws CoreException { + Workbook book = parserToExcel(template, data, parser); + try( + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ) { + book.write(bos); + return bos.toByteArray(); + } catch (IOException e) { + log.error("将Excel转为字节数组失败",e); + throw new CoreException("将Excel转为字节数组失败"); + } + } + + /** + * 将数据转换为Excel表格并返回 + * @param template 模版路径 + * @param data 源数据 + * @param parser 数据转换工具 + * @return + * @throws CoreException + */ + public static Workbook parserToExcel(String template, List data, ExcelParser parser) { + Workbook book = loadTemplate(template); + Sheet sheet = book.getSheetAt(0); + int index = 1; + for (Object obj : data) { + List result = parser.parseToArray(obj); + for (String[] arr : result) { + Row row = sheet.createRow(index++); + for (int i = 0; i < arr.length; i++) { + row.createCell(i).setCellValue(arr[i]); + } + } + } + return book; + } + + private static HSSFWorkbook loadTemplate(String template) { + File file = new File(template); + if(file.exists()) { + try { + return new HSSFWorkbook(new POIFSFileSystem(new FileInputStream(file))); + } catch (IOException e) { + log.warn("读取Excel模版失败:"+template,e); + } + } + return new HSSFWorkbook(); + } + + public static List readExcelAsBeanList(MultipartFile file, ExcelParser parser) throws CoreException{ + return readExcelAsBeanList(file, parser, null); + } + + public static List readExcelAsBeanList(MultipartFile file, ExcelParser parser, Object param) throws CoreException{ + List list = readExcel(file); + return parser.parseToObj(list,param); + } + + public static List readExcel(MultipartFile file) throws CoreException{ + Workbook book = loadExcel(file); + Sheet sheet = book.getSheetAt(0); + if(sheet == null || sheet.getLastRowNum() < 1) { + return null; + } + int rowLen = sheet.getLastRowNum(); + List list = new ArrayList<>(); + for (int i = 1; i <= rowLen; i++) { + Row row = sheet.getRow(i); + if(row == null) { + continue; + } + short cellLen = row.getLastCellNum(); + if(cellLen <= 0) { + continue; + } + String[] arr = new String[cellLen]; + for (int j = 0; j < cellLen; j++) { + Cell cell = row.getCell(j); + if(cell != null) { + cell.setCellType(CellType.STRING); + arr[j] = cell.getStringCellValue(); + } + } + if(StringUtil.isAllEmpty(arr)) { + continue; + } + list.add(arr); + } + return list; + } + + public static Workbook loadExcel(MultipartFile file) throws CoreException{ + Workbook book = null; + try { + InputStream is = file.getInputStream(); + String name = file.getOriginalFilename(); + if(isExcel2003(name)) { + book = new HSSFWorkbook(is); + }else if(isExcel2007(name)){ + book = new XSSFWorkbook(is); + } + } catch (Exception e) { + log.error("读取Excel失败",e); + throw new CoreException("导入失败,读取文件出错!",e); + } + if(book == null) { + throw new CoreException("导入失败,不支持的文件类型!"); + } + return book; + } + + /*** + * + * @param 判断文件类型是不是2003版本 + * @return + */ + public static boolean isExcel2003(String filePath) { + return filePath.matches("^.+\\.(?i)(xls)$"); + } + + /** + * + * @param 判断文件类型是不是2007版本 + * @return + */ + public static boolean isExcel2007(String filePath) { + return filePath.matches("^.+\\.(?i)(xlsx)$"); + } + +} diff --git a/src/main/java/com/mengyxu/core/utils/FileUtil.java b/src/main/java/com/mengyxu/core/utils/FileUtil.java new file mode 100644 index 0000000..bc588ba --- /dev/null +++ b/src/main/java/com/mengyxu/core/utils/FileUtil.java @@ -0,0 +1,448 @@ +package com.mengyxu.core.utils; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.BufferedWriter; +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.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.nio.file.Files; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import com.mengyxu.core.exception.CoreException; +import com.mengyxu.core.golbal.GlobalConstant; + +import lombok.extern.log4j.Log4j2; + +/** All rights reserved + * author:mengyxu + * date:2019年11月22日 + */ + +@Log4j2 +public class FileUtil { + private static final long MAX_SIZE_READ_CONTENT = 10 * 1024L * 1024L; + public static final String ZIP = "zip"; + public static final String RAR = "rar"; + + public static BufferedReader readFile(String filePath) { + File file = new File(filePath); + return readFile(file); + } + + public static BufferedReader readFile(File file) { + try { + if (file.exists()){ + return new BufferedReader(new InputStreamReader((new FileInputStream(file)), "UTF-8")); + } + } catch (IOException e) { + log.error("Read file error.", e); + } + return null; + } + + public static byte[] read(String filePath) { + File file = new File(filePath); + return read(file); + } + + public static byte[] read(File file) { + if (file.exists()){ + try( + InputStream in = new FileInputStream(file); + ) { + byte[] body = new byte[in.available()]; + in.read(body); + return body; + } catch (IOException e) { + log.error("Read file error.", e); + } + } + return null; + } + + /** + * Read file and return content in string; + * @param file + * @return + * @throws CoreException + */ + public static String readFileToString(File file) throws CoreException{ + if (file.exists() && file.length() > MAX_SIZE_READ_CONTENT) { + throw new CoreException(MessageFormat.format("File [{0}] is larger than 10M!", file.getAbsolutePath())); + } + + StringBuilder builder = new StringBuilder(); + String line = null; + + try( + BufferedReader reader = readFile(file); + ){ + if (reader == null){ + log.error(MessageFormat.format("Read file [{0}] failed! ", file.getAbsolutePath())); + return null; + } + while ((line = reader.readLine()) != null){ + builder.append(line); + } + } catch (IOException e) { + log.error(MessageFormat.format("Read file [{0}] failed! ", file.getAbsolutePath())); + return null; + } + + return builder.toString(); + } + + /** + * @see readFileToString + * @param filePath + * @return + * @throws CoreException + */ + public static String readFileToString(String filePath) throws CoreException{ + return readFileToString(new File(filePath)); + } + + public static Scanner scannerFile(String filePath) { + File file = new File(filePath); + + return scannerFile(file); + } + + public static Scanner scannerFile(File file) { + try { + if (file.exists()){ + return new Scanner((new FileInputStream(file)), "UTF-8"); + } + } catch (IOException e) { + log.error("Scanner file error.", e); + } + + return null; + } + + /** + * Loop and return the file list for the root path. + * @param root + * @return + */ + public static List listFiles(File root) { + List fileList = new ArrayList<>(); + File[] configs = root.listFiles(); + if (configs != null) { + for (File f : configs) { + addFileList(fileList, f); + } + } + return fileList; + } + + private static void addFileList(List results, File file) { + if (file.isFile()) { + results.add(file); + + } else if (file.isDirectory()) { + results.addAll(listFiles(file)); + } else { + log.error("Skip " + file + " is not a valid file."); + } + } + + public static boolean mkdir(String dirPath){ + File dir = new File(dirPath); + + if (!dir.exists()) { + return dir.mkdirs(); + } + + return true; + } + + /** + * Write a file with BufferedOutputStream. + * No close method called in this method for parameter 'os'. + * The caller should be close it itself. + * @param file + * @param os + * @throws CoreException + */ + public static void write(File file, OutputStream os) throws CoreException{ + BufferedOutputStream bos = new BufferedOutputStream(os); + + try ( + BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); + ) { + byte[] buffered = new byte[1024 * 256]; + int len = 0; + int count = 0; + while((len = bis.read(buffered)) != -1){ + bos.write(buffered, 0, len); + + if (++count % 100 == 0){ + bos.flush(); + } + } + bos.flush(); + } catch (Exception e) { + throw new CoreException(e.getMessage(), e); + } + } + + + /** + * Write the content line by line to the file. + * @param filePath + * @param contentList + * @return + * @throws CoreException + */ + public static File writeToFile(String fullFileName, List contentList) throws CoreException{ + if (contentList == null || contentList.isEmpty()){ + return null; + } + + return writeToFile(fullFileName, contentList.toArray(new String[]{})); + } + + + /** + * Write the content line by line to the file. + * @param filePath + * @param contentList + * @return + * @throws CoreException + */ + public static File writeToFile(String fullFileName, String... lines) throws CoreException{ + if (lines == null || lines.length == 0){ + return null; + } + + File newFile = new File(fullFileName); + File parent = newFile.getParentFile(); + if(!parent.exists()){ + parent.mkdirs(); + } + + try ( + //It will be auto closed at the end with try-with-resources structure. + BufferedWriter bufferedWriter = new BufferedWriter( + new OutputStreamWriter(new FileOutputStream(newFile, true), GlobalConstant.ENCODING_UTF8)); + ){ + for (String content : lines) { + bufferedWriter.write(content); + bufferedWriter.newLine(); + } + bufferedWriter.flush(); + } catch (IOException e) { + log.error("FileUtil.writeToFile(): IOException:"+e.getMessage()); + throw new CoreException("FileUtil.writeForExistFile(): IOException:",e); + } + + return newFile; + } + + /** + * Write the content of inputStream to the file. + * @param filePath + * @param inputStream + * @return + * @throws CoreException + */ + public static void writeToFile(String fullFileName, InputStream is) throws CoreException{ + File newFile = new File(fullFileName); + File parent = newFile.getParentFile(); + if(!parent.exists()){ + parent.mkdirs(); + } + try ( + FileOutputStream fos = new FileOutputStream(newFile); + ){ + byte[] buffered = new byte[1024 * 256]; + int len = 0; + int count = 0; + while((len = is.read(buffered)) != -1){ + fos.write(buffered, 0, len); + + if (++count % 100 == 0){ + fos.flush(); + } + } + fos.flush(); + } catch (IOException e) { + log.error("FileUtil.writeToFile(): IOException:"+e.getMessage()); + throw new CoreException("FileUtil.writeForExistFile(): IOException:",e); + } + } + + /** + * Remove suffix for a file name. + * @param fileName + * @return + */ + public static String removeSuffix(String fileName){ + String dest = fileName; + + if (fileName.lastIndexOf('.') > 0){ + dest = fileName.substring(0, fileName.lastIndexOf('.')); + } + + return dest; + } + + /** + * Copy a file to b file. + * @param src + * @param dest + * @return True for successfully. False for failed or empty parameter. + * @throws CoreException + */ + public static boolean copy(File src, File dest) throws CoreException{ + if (src == null || dest == null){ + return false; + } + + try ( + OutputStream os = new FileOutputStream(dest); + ){ + write(src, os); + } catch (IOException e) { + String msg = MessageFormat.format("Cannot copy file from [{0}] to [{1}]", src.getAbsolutePath(), dest.getAbsolutePath()); + throw new CoreException(msg); + } + + return true; + } + + private FileUtil(){ + //A private constructor to hide the implicit public one. + } + public static void decompression(File srcFile, File dstFile) throws CoreException{ + String fileType = getTypeByStream(srcFile); + if(ZIP.equals(fileType)){ + unzip(srcFile,dstFile); + } + } + public static void unzip(File srcFile, File dstFile) throws CoreException { + if (srcFile.exists()) { + if (!dstFile.getParentFile().exists()) { + // 创建文件父目录 + dstFile.getParentFile().mkdirs(); + } + + try ( + ZipInputStream zis = new ZipInputStream(new FileInputStream(srcFile)); + BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dstFile)); + ){ + ZipEntry entry = null; + while ((entry = zis.getNextEntry()) != null && !entry.isDirectory()) { + // 写入文件 + int read = 0; + byte[] buffer = new byte[1024 * 10]; + while ((read = zis.read(buffer, 0, buffer.length)) != -1) { + bos.write(buffer, 0, read); + } + bos.flush(); + } + zis.closeEntry(); + } catch (IOException e) { + throw new CoreException(e); + } + } + } + /** + * 根据文件流读取文件真实类型 + * + * @param is + * @return + * @throws FileNotFoundException + */ + public static String getTypeByStream(File f) throws CoreException { + byte[] b = new byte[4]; + try (FileInputStream is = new FileInputStream(f);) { + is.read(b, 0, b.length); + } catch (IOException e) { + throw new CoreException(e); + } + + String hexString = bytesToHexString(b); + + if (hexString == null){ + throw new CoreException("Unknown file type."); + } + + String type = hexString.toUpperCase(); + if (type.contains("52617221")) { + return RAR; + } else if (type.contains("504B0304")) { + return ZIP; + } + return type; + } + /** + * byte数组转换成16进制字符串 + * + * @param src + * @return + */ + public static String bytesToHexString(byte[] src) { + StringBuilder stringBuilder = new StringBuilder(); + if (src == null || src.length <= 0) { + return null; + } + for (int i = 0; i < src.length; i++) { + int v = src[i] & 0xFF; + String hv = Integer.toHexString(v); + if (hv.length() < 2) { + stringBuilder.append(0); + } + stringBuilder.append(hv); + } + return stringBuilder.toString(); + } + + /** + * + * @param files + * @return + */ + public static boolean deleteFiles(File...files){ + if (files == null || files.length == 0){ + log.warn("No parameter [files] provided!"); + return false; + } + + boolean deleteResult = true; + for (File file : files) { + if (file != null) { + try { + Files.deleteIfExists(file.toPath()); + } catch (IOException e) { + log.warn(">(o_o)<~ Cannot delete temporary file: " + file.getAbsolutePath()); + deleteResult = false; + } + } + } + + return deleteResult; + } + + public static boolean isAvailableDir(String filePath){ + return isAvailableDir(new File(filePath)); + } + + public static boolean isAvailableDir(File dirFile){ + return dirFile.exists() && dirFile.isDirectory(); + } +} diff --git a/src/main/java/com/mengyxu/core/utils/IDNumUtil.java b/src/main/java/com/mengyxu/core/utils/IDNumUtil.java new file mode 100644 index 0000000..bd6c34a --- /dev/null +++ b/src/main/java/com/mengyxu/core/utils/IDNumUtil.java @@ -0,0 +1,190 @@ +package com.mengyxu.core.utils; + +/** All rights reserved + * author:mengyxu + * date:2019年5月25日 + */ + +public class IDNumUtil { + + /** + * 18位二代身份证号码的正则表达式 + */ + private static final String REGEX_ID_NO_18 = "^" + + "\\d{6}" // 6位地区码 + + "(18|19|([23]\\d))\\d{2}" // 年YYYY + + "((0[1-9])|(10|11|12))" // 月MM + + "(([0-2][1-9])|10|20|30|31)" // 日DD + + "\\d{3}" // 3位顺序码 + + "[0-9Xx]" // 校验码 + + "$"; + + /** + * 17位二代身份证本体码的正则表达式 + */ + private static final String REGEX_MASTER_NUMBER = "^" + + "\\d{6}" // 6位地区码 + + "(18|19|([23]\\d))\\d{2}" // 年YYYY + + "((0[1-9])|(10|11|12))" // 月MM + + "(([0-2][1-9])|10|20|30|31)" // 日DD + + "\\d{3}" // 3位顺序码 + + "$"; + + /** + * 15位一代身份证号码的正则表达式 + */ + private static final String REGEX_ID_NO_15 = "^" + + "\\d{6}" // 6位地区码 + + "\\d{2}" // 年YYYY + + "((0[1-9])|(10|11|12))" // 月MM + + "(([0-2][1-9])|10|20|30|31)" // 日DD + + "\\d{3}"// 3位顺序码 + + "$"; + + private IDNumUtil() { + //Add a private constructor to hide the implicit public one. + } + + /** + * 校验身份证号码,适用于18位的二代身份证号码 + * @param IDNo18 身份证号码 + * @return true - 校验通过
+ * false - 校验不通过 + */ + public static boolean checkIDNo(String IDNo18) { + // 校验身份证号码的长度 + if (!checkStrLength(IDNo18, 18)) { + return false; + } + // 匹配身份证号码的正则表达式 + if (!regexMatch(IDNo18, REGEX_ID_NO_18)) { + return false; + } + // 校验身份证号码的验证码 + return validateCheckNumber(IDNo18); + } + + /** + * 校验字符串长度 + * + * @param inputString 字符串 + * @param len 预期长度 + * @return true - 校验通过
+ * false - 校验不通过 + */ + private static boolean checkStrLength(String inputString, int len) { + if (inputString == null || inputString.length() != len) { + return false; + } + return true; + } + + /** + * 匹配正则表达式 + * + * @param inputString 字符串 + * @param regex 正则表达式 + * @return true - 校验通过
+ * false - 校验不通过 + */ + private static boolean regexMatch(String inputString, String regex) { + return inputString.matches(regex); + } + + /** + * 校验码校验,适用于18位的二代身份证号码 + * + * @param IDNo18 身份证号码 + * @return true - 校验通过
+ * false - 校验不通过 + */ + private static boolean validateCheckNumber(String IDNo18) { + // 加权因子 + int[] W = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 }; + char[] IDNoArray = IDNo18.toCharArray(); + int sum = 0; + for (int i = 0; i < W.length; i++) { + sum += Integer.parseInt(String.valueOf(IDNoArray[i])) * W[i]; + } + // 校验位是X,则表示10 + if (IDNoArray[17] == 'X' || IDNoArray[17] == 'x') { + sum += 10; + } else { + sum += Integer.parseInt(String.valueOf(IDNoArray[17])); + } + // 如果除11模1,则校验通过 + return sum % 11 == 1; + } + + /** + * 计算身份证号码的校验码 + * + * @param masterNumber 本体码 + * @return 身份证号码 + * @throws IllegalArgumentException + * 如果本体码为空或长度不为17位或不满足本体码组成规则 + * 6位地址码+ + * 出生年月日YYYYMMDD+3位顺序码 + */ + public static String computeIDNoCheckNumber(String masterNumber) { + // 校验本体码的长度 + if (!checkStrLength(masterNumber, 17)) { + throw new IllegalArgumentException(); + } + // 匹配本体码的正则表达式 + if (!regexMatch(masterNumber, REGEX_MASTER_NUMBER)) { + throw new IllegalArgumentException(); + } + // 计算校验码 + String checkNumber = computeCheckNumber(masterNumber); + // 返回本体码+校验码=完整的身份证号码 + return masterNumber + checkNumber; + } + + /** + * 计算校验码,适用于18位的二代身份证号码 + * + * @param masterNumber 本体码 + * @return 校验码 + */ + private static String computeCheckNumber(String masterNumber) { + // 加权因子 + int[] W = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 }; + char[] masterNumberArray = masterNumber.toCharArray(); + int sum = 0; + for (int i = 0; i < W.length; i++) { + sum += Integer.parseInt(String.valueOf(masterNumberArray[i])) * W[i]; + } + // 根据同余定理得到的校验码数组 + String[] checkNumberArray = { "1", "0", "X", "9", "8", "7", "6", "5", "4", + "3", "2" }; + // 得到校验码 + String checkNumber = checkNumberArray[sum % 11]; + // 返回校验码 + return checkNumber; + } + + /** + * 15位一代身份证号码升级18位二代身份证号码 + * + * @param IDNo15 15位的一代身份证号码 + * @return 18位的二代身份证号码 + */ + public static String updateIDNo15to18(String IDNo15) { + // 校验身份证号码的长度 + if (!checkStrLength(IDNo15, 15)) { + throw new IllegalArgumentException(); + } + // 匹配身份证号码的正则表达式 + if (!regexMatch(IDNo15, REGEX_ID_NO_15)) { + throw new IllegalArgumentException(); + } + // 得到本体码,因一代身份证皆为19XX年生人,年份中增加19,组成4位 + String masterNumber = IDNo15.substring(0, 6) + "19" + IDNo15.substring(6); + // 计算校验码 + String checkNumber = computeCheckNumber(masterNumber); + // 返回本体码+校验码=完整的身份证号码 + return masterNumber + checkNumber; + } + +} diff --git a/src/main/java/com/mengyxu/core/utils/JsonUtil.java b/src/main/java/com/mengyxu/core/utils/JsonUtil.java new file mode 100644 index 0000000..7bc9d0c --- /dev/null +++ b/src/main/java/com/mengyxu/core/utils/JsonUtil.java @@ -0,0 +1,54 @@ +package com.mengyxu.core.utils; + +import java.util.List; +import java.util.Map; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +/** All rights reserved + * author:mengyxu + * date:2019年5月25日 + * + * 处理json数据的工具类 + */ + +public class JsonUtil { + + private JsonUtil(){ + //Add a private constructor to hide the implicit public one. + } + + public static Map toStringMap(String jsonStr){ + return JSON.parseObject(jsonStr,new TypeReference>(){} ); + } + + public static List> toStirngMapList(String jsonStr){ + return JSON.parseObject(jsonStr, new TypeReference>>(){}); + } + + public static Map>> toMapStirngMapList(String jsonStr){ + return JSON.parseObject(jsonStr, new TypeReference>>>(){}); + } + + public static List toStringList(String jsonStr){ + return JSON.parseObject(jsonStr, new TypeReference>(){}); + } + + public static List toIntegerList(String jsonStr){ + return JSON.parseObject(jsonStr, new TypeReference>(){}); + } + + public static List toEntityList(Class clazz, String jsonStr){ + return JSON.parseArray(jsonStr, clazz); + } + + public static T toEntity(Class clazz, String jsonStr){ + return JSON.parseObject(jsonStr, clazz); + } + + public static Map toEntiryMap(String jsonStr){ + return JSON.parseObject(jsonStr, new TypeReference>(){}); + } + +} diff --git a/src/main/java/com/mengyxu/core/utils/LocationUtil.java b/src/main/java/com/mengyxu/core/utils/LocationUtil.java new file mode 100644 index 0000000..aa42a9a --- /dev/null +++ b/src/main/java/com/mengyxu/core/utils/LocationUtil.java @@ -0,0 +1,159 @@ +package com.mengyxu.core.utils; + +import java.math.BigDecimal; + +/** All rights reserved + * author:mengyxu + * date:2020年6月10日 + * + * 百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换的工具 + */ +public class LocationUtil { + + static int B_DIV_SCALE = 15; + static BigDecimal x_pi = new BigDecimal("3.14159265358979324").multiply(new BigDecimal("3000")).divide(new BigDecimal("180"), B_DIV_SCALE, BigDecimal.ROUND_HALF_UP); + // π + static BigDecimal pi = new BigDecimal("3.1415926535897932384626"); + // 长半轴 + static BigDecimal a = new BigDecimal("6378245"); + // 扁率 + static BigDecimal ee = new BigDecimal("0.00669342162296594323"); + static BigDecimal b_1 = new BigDecimal("-1"); + static BigDecimal b_2 = new BigDecimal("10"); + static BigDecimal b_3 = new BigDecimal("2"); + static BigDecimal b_4 = new BigDecimal("105"); + static BigDecimal b_5 = new BigDecimal("3"); + static BigDecimal b_6 = new BigDecimal("35"); + static BigDecimal b_7 = new BigDecimal("160"); + static BigDecimal b_8 = new BigDecimal("1"); + static BigDecimal b_9 = new BigDecimal("150"); + static BigDecimal b_10 = new BigDecimal("180"); + + static BigDecimal b_11 = new BigDecimal("0.00002"); + static BigDecimal b_12 = new BigDecimal("0.000003"); + static BigDecimal b_13 = new BigDecimal("0.0065"); + static BigDecimal b_14 = new BigDecimal("0.006"); + + /** + * WGS坐标转百度坐标系(BD-09) + * + * @param lng WGS84坐标系的经度 + * @param lat WGS84坐标系的纬度 + * @return 百度坐标数组 + */ + public static double[] wgs84tobd09(double lng, double lat) { + double[] gcj = wgs84togcj02(lng, lat); + double[] bd09 = gcj02tobd09(gcj[0], gcj[1]); + return bd09; + } + public static String[] wgs84tobd09(String lng, String lat) { + double lon = Double.parseDouble(lng); + double lt = Double.parseDouble(lat); + double[] arr = wgs84tobd09(lon, lt); + return new String[] {arr[0] + "", arr[1] + ""}; + } + + /** + * 火星坐标系(GCJ-02)转百度坐标系(BD-09) + * + * @param lng 火星坐标经度 + * @param lat 火星坐标纬度 + * @return 百度坐标数组 + * @see 谷歌、高德——>百度 + */ + public static double[] gcj02tobd09(double lng, double lat) { + BigDecimal b_lng = new BigDecimal(lng); + BigDecimal b_lat = new BigDecimal(lat); + BigDecimal z = new BigDecimal(Math.sqrt(b_lng.multiply(b_lng).add(b_lat.multiply(b_lat)).doubleValue())).add(b_11.multiply(new BigDecimal(Math.sin(b_lat.multiply(x_pi).doubleValue())))); + BigDecimal theta = new BigDecimal(Math.atan2(b_lat.doubleValue(), b_lng.doubleValue())).add(b_12.multiply(new BigDecimal(Math.cos(b_lng.multiply(x_pi).doubleValue())))); + BigDecimal bd_lng = z.multiply(new BigDecimal(Math.cos(theta.doubleValue()))).add(b_13); +// z * Math.cos(theta) + 0.0065; + BigDecimal bd_lat = z.multiply(new BigDecimal(Math.sin(theta.doubleValue()))).add(b_14); + return new double[]{bd_lng.doubleValue(), bd_lat.doubleValue()}; + } + + /** + * WGS84转GCJ02(火星坐标系) + * + * @param lng WGS84坐标系的经度 + * @param lat WGS84坐标系的纬度 + * @return 火星坐标数组 + */ + public static double[] wgs84togcj02(double lng, double lat) { + BigDecimal b_lng = new BigDecimal(lng + ""); + BigDecimal b_lat = new BigDecimal(lat + ""); + if (out_of_china(b_lng, b_lat)) { + return new double[]{b_lng.doubleValue(), b_lat.doubleValue()}; + } + BigDecimal dlat = transformlat(b_lng.subtract(b_4), b_lat.subtract(b_6)); + BigDecimal dlng = transformlng(b_lng.subtract(b_4), b_lat.subtract(b_6)); + BigDecimal radlat = b_lat.divide(b_10, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(pi); + BigDecimal magic = new BigDecimal(Math.sin(radlat.doubleValue())); + magic = b_8.subtract(ee.multiply(magic).multiply(magic)); + BigDecimal sqrtmagic = new BigDecimal(Math.sqrt(magic.doubleValue())); + dlat = (dlat.multiply(b_10)).divide((a.multiply(b_8.subtract(ee))).divide((magic.multiply(sqrtmagic)), B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(pi), B_DIV_SCALE, BigDecimal.ROUND_HALF_UP); + dlng = (dlng.multiply(b_10)).divide((a.divide(sqrtmagic, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(Math.cos(radlat.doubleValue())).multiply(pi))), B_DIV_SCALE, BigDecimal.ROUND_HALF_UP); + BigDecimal mglat = b_lat.add(dlat); + BigDecimal mglng = b_lng.add(dlng); + return new double[]{mglng.doubleValue(), mglat.doubleValue()}; + } + + /** + * 纬度转换 + * + * @param lng + * @param lat + * @return + */ + private static BigDecimal transformlat(BigDecimal lng, BigDecimal lat) { + BigDecimal bet = b_1.multiply(b_2).multiply(b_2) + .add(b_3.multiply(lng)) + .add(b_5.multiply(lat)) + .add(b_3.divide(b_2, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(lat).multiply(lat)) + .add(b_8.divide(b_2, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(lng).multiply(lat)) + .add(b_3.divide(b_2, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(Math.sqrt(Math.abs(lng.doubleValue()))))); + bet = bet.add((b_3.multiply(b_2).multiply(new BigDecimal(Math.sin(b_3.multiply(b_5).multiply(lng).multiply(pi).doubleValue()))) + .add(b_3.multiply(b_2).multiply(new BigDecimal(Math.sin(b_3.multiply(lng).multiply(pi).doubleValue()))))).multiply(b_3).divide(b_5, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP)); + bet = bet.add((b_3.multiply(b_2).multiply(new BigDecimal(Math.sin(lat.multiply(pi).doubleValue()))) + .add(b_3.multiply(b_3).multiply(b_2).multiply(new BigDecimal(Math.sin(lat.divide(b_5, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(pi).doubleValue()))))).multiply(b_3).divide(b_5, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP)); + bet = bet.add((b_7.multiply(new BigDecimal(Math.sin(lat.divide(b_5.multiply(b_3).multiply(b_3), B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(pi).doubleValue()))) + .add(b_7.multiply(b_3).multiply(new BigDecimal(Math.sin(lat.multiply(pi).divide(b_5.multiply(b_2), B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue()))))).multiply(b_3).divide(b_5, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP)); + return bet; + } + + /** + * 经度转换 + * + * @param lng + * @param lat + * @return + */ + private static BigDecimal transformlng(BigDecimal lng, BigDecimal lat) { + BigDecimal bet = b_2.multiply(b_2).multiply(b_5).add(lng).add(b_3.multiply(lat)).add(b_8.divide(b_2, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(lng).multiply(lng)) + .add(b_8.divide(b_2, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(lng).multiply(lat)).add(b_8.divide(b_2, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(Math.sqrt(Math.abs(lng.doubleValue()))))); + bet = bet.add((b_3.multiply(b_2).multiply(new BigDecimal(Math.sin(b_3.multiply(b_5).multiply(lng).multiply(pi).doubleValue()))) + .add(b_3.multiply(b_2).multiply(new BigDecimal(Math.sin(b_3.multiply(lng).multiply(pi).doubleValue()))))).multiply(b_3).divide(b_5, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP)); + bet = bet.add((b_3.multiply(b_2).multiply(new BigDecimal(Math.sin(lng.multiply(pi).doubleValue()))) + .add(b_3.multiply(b_3).multiply(b_2).multiply(new BigDecimal(Math.sin(lng.divide(b_5, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(pi).doubleValue()))))).multiply(b_3).divide(b_5, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP)); + bet = bet.add((b_9.multiply(new BigDecimal(Math.sin(lng.divide(b_3.multiply(b_3).multiply(b_5), B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(pi).doubleValue()))) + .add(b_9.multiply(b_3).multiply(new BigDecimal(Math.sin(lng.divide(b_5.multiply(b_2), B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(pi).doubleValue())))).multiply(b_3).divide(b_5, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP))); + return bet; + } + + /** + * 判断是否在国内,不在国内不做偏移 + * + * @param lng + * @param lat + * @return + */ + private static boolean out_of_china(BigDecimal lng, BigDecimal lat) { + if (lng.compareTo(new BigDecimal("73.66")) < 0 || lng.compareTo(new BigDecimal("135.05")) > 0) { + return true; + } else if (lat.compareTo(new BigDecimal("3.86")) < 0 || lat.compareTo(new BigDecimal("53.55")) > 0) { + return true; + } + return false; + } + +} \ No newline at end of file diff --git a/src/main/java/com/mengyxu/core/utils/MsgUtil.java b/src/main/java/com/mengyxu/core/utils/MsgUtil.java new file mode 100644 index 0000000..a908fbc --- /dev/null +++ b/src/main/java/com/mengyxu/core/utils/MsgUtil.java @@ -0,0 +1,20 @@ +package com.mengyxu.core.utils; + +import com.mengyxu.core.exception.CoreException; + +/** All rights reserved + * author:mengyxu + * date:2019年5月27日 + */ + +public class MsgUtil { + + private MsgUtil(){ + //Add a private constructor to hide the implicit public one. + } + + public static String sendMessageCode(String phoneNum) throws CoreException{ + return StringUtil.getStringNum(6); + } + +} diff --git a/src/main/java/com/mengyxu/core/utils/RSAUtil.java b/src/main/java/com/mengyxu/core/utils/RSAUtil.java new file mode 100644 index 0000000..4df2c72 --- /dev/null +++ b/src/main/java/com/mengyxu/core/utils/RSAUtil.java @@ -0,0 +1,290 @@ +package com.mengyxu.core.utils; + +import java.security.Key; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Signature; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.HashMap; +import java.util.Map; + +import javax.crypto.Cipher; + +import lombok.extern.log4j.Log4j2; + +/** All rights reserved + * author:mengyxu + * date:2020年6月10日 + */ + +@Log4j2 +public class RSAUtil { + /** + * 定义加密方式 + */ + private final static String KEY_RSA = "RSA"; + /** + * 定义签名算法 + */ + private final static String KEY_RSA_SIGNATURE = "MD5withRSA"; + + /** + * 定义公钥算法 + */ + private final static String KEY_RSA_PUBLICKEY = "RSAPublicKey"; + + /** + * 定义私钥算法 + */ + private final static String KEY_RSA_PRIVATEKEY = "RSAPrivateKey"; + + /** + * 用私钥对信息生成数字签名 + * @param data 加密数据 + * @param privateKey 私钥 + * @return + */ + public static String sign(byte[] data, String privateKey) { + String str = ""; + try { + //转码16进制字符串 + byte[] bytes = StringToByteKey(privateKey); + // 构造PKCS8EncodedKeySpec对象 + X509EncodedKeySpec pkcs = new X509EncodedKeySpec(bytes); + // 指定的加密算法 + KeyFactory factory = KeyFactory.getInstance(KEY_RSA); + // 取私钥对象 + PrivateKey key = factory.generatePrivate(pkcs); + // 用私钥对信息生成数字签名 + Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE); + signature.initSign(key); + signature.update(data); + str = byteToStringKey(signature.sign()); + } catch (Exception e) { + log.error("Sign failed", e); + } + return str; + } + + /** + * 校验数字签名 + * @param data 加密数据 + * @param publicKey 公钥 + * @param sign 数字签名 + * @return 校验成功返回true,失败返回false + */ + public static boolean verify(byte[] data, String publicKey, String sign) { + boolean flag = false; + try { + // 解密由base64编码的公钥 + byte[] bytes = StringToByteKey(publicKey); + // 构造X509EncodedKeySpec对象 + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes); + // 指定的加密算法 + KeyFactory factory = KeyFactory.getInstance(KEY_RSA); + // 取公钥对象 + PublicKey key = factory.generatePublic(keySpec); + // 用公钥验证数字签名 + Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE); + signature.initVerify(key); + signature.update(data); + flag = signature.verify(StringToByteKey(sign)); + } catch (Exception e) { + log.error("Verify failed", e); + } + return flag; + } + + /** + * 公钥解密 + * @param data 加密数据 + * @param key 公钥 + * @return + */ + public static String decryptByPublicKey(String data, String key) { + try { + //解码公钥 + byte[] pubKey = Base64Util.decode(key); + // 取得公钥 + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubKey); + KeyFactory factory = KeyFactory.getInstance(KEY_RSA); + PublicKey publicKey = factory.generatePublic(keySpec); + // 对数据解密 + Cipher cipher = Cipher.getInstance(factory.getAlgorithm()); + cipher.init(Cipher.DECRYPT_MODE, publicKey); + byte[] result = cipher.doFinal(Base64Util.decode(data)); + if(result != null) { + return new String(result); + } + } catch (Exception e) { + log.error("decryptByPublicKey fail-",e); + } + return null; + } + + /** + * 公钥加密 + * @param data 待加密数据 + * @param key 公钥 + * @return + */ + public static String encryptByPublicKey(String data, String key) { + try { + byte[] pubKey = Base64Util.decode(key); + // 取得公钥 + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubKey); + KeyFactory factory = KeyFactory.getInstance(KEY_RSA); + PublicKey publicKey = factory.generatePublic(keySpec); + // 对数据加密 + Cipher cipher = Cipher.getInstance(factory.getAlgorithm()); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + byte[] result = cipher.doFinal(data.getBytes()); + if(result != null) { + return Base64Util.encode(result); + } + } catch (Exception e) { + log.error("encryptByPublicKey failed-",e); + } + return null; + } + + /** + * 私钥解密 + * @param data 加密数据 + * @param key 私钥 + * @return + */ + public static byte[] decryptByPrivateKey(byte[] data, String key) { + byte[] result = null; + try { + // 对私钥解密 + byte[] bytes = StringToByteKey(key); + // 取得私钥 + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes); + KeyFactory factory = KeyFactory.getInstance(KEY_RSA); + PrivateKey privateKey = factory.generatePrivate(keySpec); + // 对数据解密 + Cipher cipher = Cipher.getInstance(factory.getAlgorithm()); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + result = cipher.doFinal(data); + } catch (Exception e) { + log.error("decryptByPrivateKey failed", e); + } + return result; + } + + /** + * 私钥加密 + * @param data 待加密数据 + * @param key 私钥 + * @return + */ + public static byte[] encryptByPrivateKey(byte[] data, String key) { + byte[] result = null; + try { + byte[] bytes = StringToByteKey(key); + // 取得私钥 + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes); + KeyFactory factory = KeyFactory.getInstance(KEY_RSA); + PrivateKey privateKey = factory.generatePrivate(keySpec); + // 对数据加密 + Cipher cipher = Cipher.getInstance(factory.getAlgorithm()); + cipher.init(Cipher.ENCRYPT_MODE, privateKey); + result = cipher.doFinal(data); + } catch (Exception e) { + log.error("encryptByPrivateKey failed", e); + } + return result; + } + + /** + * 初始化密钥 + * @return + */ + public static Map init() { + Map map = null; + try { + KeyPairGenerator generator = KeyPairGenerator.getInstance(KEY_RSA); + generator.initialize(1024); + KeyPair keyPair = generator.generateKeyPair(); + // 公钥 + RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); + // 私钥 + RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); + // 将密钥封装为map + map = new HashMap<>(); + map.put(KEY_RSA_PUBLICKEY, publicKey); + map.put(KEY_RSA_PRIVATEKEY, privateKey); + } catch (NoSuchAlgorithmException e) { + log.error("Exception occurred!", e); + } + return map; + } + + /** + * 获取公钥 + * @param map + * @return + */ + public static String getPublicKey(Map map) { + String str = ""; + try { + Key key = (Key) map.get(KEY_RSA_PUBLICKEY); + str = byteToStringKey(key.getEncoded()); + } catch (Exception e) { + log.error("getPublicKey failed", e); + } + return str; + } + + /** + * 获取私钥 + * @param map + * @return + */ + public static String getPrivateKey(Map map) { + String str = ""; + try { + Key key = (Key) map.get(KEY_RSA_PRIVATEKEY); + str = byteToStringKey(key.getEncoded()); + } catch (Exception e) { + log.error("getPrivateKey failed", e); + } + return str; + } + + public static String byteToStringKey(byte[] key) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < key.length; i++) { + if ((key[i] & 0xff) < 0x10) { + sb.append("0"); + } + sb.append(Integer.toHexString(0xFF & key[i])); + } + return sb.toString().toUpperCase(); + } + + public static byte[] StringToByteKey(String key) { + key = key.toUpperCase(); + byte[] arr = new byte[key.length() / 2]; + int k = 0; + for (int i = 0; i < arr.length; i++) {//因为是16进制,最多只会占用4位,转换成字节需要两个16进制的字符,高位在先 + byte high = (byte) (Character.digit(key.charAt(k), 16) & 0xff); + byte low = (byte) (Character.digit(key.charAt(k + 1), 16) & 0xff); + arr[i] = (byte) (high << 4 | low); + k += 2; + } + return arr; + } + + private RSAUtil(){ + //Do nothing. + } +} \ No newline at end of file diff --git a/src/main/java/com/mengyxu/core/utils/ShellUtil.java b/src/main/java/com/mengyxu/core/utils/ShellUtil.java new file mode 100644 index 0000000..7d99743 --- /dev/null +++ b/src/main/java/com/mengyxu/core/utils/ShellUtil.java @@ -0,0 +1,81 @@ +package com.mengyxu.core.utils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; + +import com.mengyxu.core.exception.CoreException; +import com.mengyxu.core.golbal.GlobalConstant; + +import lombok.extern.log4j.Log4j2; + +/** + * Ownership belongs to the company author:mengyxu date:2021年1月20日 + */ + +@Log4j2 +public class ShellUtil { + public static final boolean IS_LINUX; + + static { + IS_LINUX = "linux".equals(System.getProperty("os.name").toLowerCase()); + } + + public static int executeShellCmd(String cmd) throws CoreException { + try { + log.info("ShellUtil runtime exec commond----------------->" + cmd); + Process process = null; + if(IS_LINUX) { + process = Runtime.getRuntime().exec(new String[] {"/bin/sh", "-c", cmd}); + }else { + process = Runtime.getRuntime().exec(cmd); + } + + if (process != null) { + final InputStream input = process.getInputStream(); + logInputStream(cmd, input); + + process.waitFor(); + log.info("process result:" + process.exitValue());// 0代表成功,其他代表失败,返回未终止的子进程的数量 + process.destroy(); + return process.exitValue(); + } + } catch (Exception e) { + log.error("Execute shell error log", e); + return -1; + } + // end + return 0; + } + + /** + * In order to log input stream + * + * @param in + * @throws UnsupportedEncodingException + */ + public static void logInputStream(String shells, InputStream in) throws UnsupportedEncodingException { + + StringBuilder builder = new StringBuilder(); + builder.append("Shell [").append(shells).append(" return log: "); + String str = null; + try (final BufferedReader inBr = new BufferedReader(new InputStreamReader(in, GlobalConstant.ENCODING_UTF8));) { + while ((str = inBr.readLine()) != null) { + builder.append(str); + builder.append("\n"); + } + } catch (IOException e) { + log.error("Read log inputstream failed!", e); + } + + // Log to file. + log.info(builder.toString()); + } + + private ShellUtil() { + // Not allow to create instance. + } + +} diff --git a/src/main/java/com/mengyxu/core/utils/SpringContextUtil.java b/src/main/java/com/mengyxu/core/utils/SpringContextUtil.java new file mode 100644 index 0000000..20b9ae1 --- /dev/null +++ b/src/main/java/com/mengyxu/core/utils/SpringContextUtil.java @@ -0,0 +1,37 @@ +package com.mengyxu.core.utils; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +/** All rights reserved + * author:mengyxu + * date:2019年6月26日 + */ + +@Component(value="springContextUtil") +public class SpringContextUtil implements ApplicationContextAware{ + private static ApplicationContext appContext; + + @Override + public void setApplicationContext(ApplicationContext context) + throws BeansException { + SpringContextUtil.appContext = context; + } + + @SuppressWarnings("unchecked") + public static T getBeanByName(String beanName){ + if(beanName == null){ + return null; + } + return (T) appContext.getBean(beanName); + } + + public static T getBeanByClass(Class clazz){ + if(clazz == null){ + return null; + } + return (T) appContext.getBean(clazz); + } +} diff --git a/src/main/java/com/mengyxu/core/utils/StringUtil.java b/src/main/java/com/mengyxu/core/utils/StringUtil.java new file mode 100644 index 0000000..8ea9415 --- /dev/null +++ b/src/main/java/com/mengyxu/core/utils/StringUtil.java @@ -0,0 +1,406 @@ +package com.mengyxu.core.utils; + +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.regex.Pattern; + +import com.mengyxu.core.exception.CoreException; + +/** All rights reserved + * author:mengyxu + * date:2019年6月26日 + */ + +public class StringUtil { + private static final char[] HEX_DIGITS_L = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', + 'c', 'd', 'e', 'f' }; + private static final char[] HEX_DIGITS_U = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', + 'C', 'D', 'E', 'F' }; + private static final String DEFAULT_ENCODING = "UTF-8"; + public static final String EMPTY_STRING = ""; + private static final String ARGUMENT_PREFIX = "{"; + private static final String ARGUMENT_SUFFIX = "}"; + private static final Pattern COMPRESS_PATTERN = Pattern.compile("(\\r|\\n|\\r\\n)\\s*"); + + private StringUtil() { + // Add a private constructor to hide the implicit public one. + } + + public static String compress(String src) { + return COMPRESS_PATTERN.matcher(src).replaceAll(EMPTY_STRING); + } + + /** + * Concatenate all the parameters to one string. + * + * @param src + * @param args -- random length parameters. + * @return + */ + public static String concate(String src, String... args) { + StringBuilder builder = new StringBuilder().append(src); + + if (args != null) { + for (String arg : args) { + builder.append(arg); + } + } + + return builder.toString(); + } + + public static String splice(String delimiter, String... args) { + StringBuilder builder = new StringBuilder(); + + if (args != null) { + for (String arg : args) { + builder.append(arg == null ? "" : arg).append(delimiter); + } + } + String s = builder.toString(); + return s.substring(0, s.lastIndexOf(delimiter)); + } + + public static String toString(String[] array) { + if (array == null) { + return null; + } + + StringBuilder builder = new StringBuilder(); + + builder.append("{"); + for (String element : array) { + builder.append("'").append(element).append("',"); + } + + builder.deleteCharAt(builder.length() - 1).append("}"); + + return builder.toString(); + } + + public static boolean isEmpty(String value) { + return value == null || value.trim().isEmpty(); + } + + public static String md5(String src, boolean lowercase) throws CoreException { + return md5(src, null, lowercase); + } + + /** + * 32位小写 MD5 编码 + * + * @param s + * @param encoding + * @return + * @throws RrsException + */ + public static String md5(String s, String expectedEncoding, boolean lowercase) throws CoreException { + String encoding = DEFAULT_ENCODING; + + if (expectedEncoding != null) { + encoding = expectedEncoding; + } + + // 用来将字节转换成 16 进制表示的字符 + char[] hexDigits; + if (lowercase) { + hexDigits = HEX_DIGITS_L; + } else { + hexDigits = HEX_DIGITS_U; + } + + String result = null; + + if (s != null) { + try { + // 返回实现指定摘要算法的 MessageDigest 对象 + MessageDigest md = MessageDigest.getInstance("MD5"); + + // 使用encoding编码将originstr字符串编码并保存到source字节数组 + byte[] source = s.getBytes(encoding); + + // 使用指定的 byte 数组更新摘要 + md.update(source); + + // 通过执行诸如填充之类的最终操作完成哈希计算,结果是一个128位的长整数 + byte[] tmp = md.digest(); + + // 用16进制数表示需要32位 + char[] ss = new char[32]; + + for (int i = 0, j = 0; i < 16; i++) { + // j表示转换结果中对应的字符位置 + // 从第一个字节开始,对 MD5 的每一个字节 + // 转换成 16 进制字符 + byte b = tmp[i]; + + // 取字节中高 4 位的数字转换 + // 无符号右移运算符>>> ,它总是在左边补0 + // 0x代表它后面的是十六进制的数字. f转换成十进制就是15 + ss[j++] = hexDigits[b >>> 4 & 0xf]; + + // 取字节中低 4 位的数字转换 + ss[j++] = hexDigits[b & 0xf]; + } + result = new String(ss);// 结果转换成字符串用于返回 + } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { + // 当请求特定的加密算法而它在该环境中不可用时抛出此异常 + throw new CoreException("md5(String) - s=" + s, e); //$NON-NLS-1$ + } + } + + return result; + } + + public static String[] split(String s, String delimiter) { + return split(s, delimiter, 10); + } + + public static String[] split(String s, String delimiter, int initCapacity) { + List list = new ArrayList<>(initCapacity); + + int index = -1; + int offset = 0; + s = s.replace("\\N", ""); + while ((index = s.indexOf(delimiter, index + 1)) != -1) { + String ss = s.substring(offset, index); + list.add(ss); + offset = index + 1; + } + list.add(s.substring(offset)); + + return list.toArray(new String[0]); + } + + public static String getStringNum(int length) { + Random r = new Random(); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < length; i++) { + sb.append(r.nextInt(10)); + } + return sb.toString(); + } + + public static String getStringHex(int length) { + Random r = new Random(); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < length; i++) { + sb.append(HEX_DIGITS_L[r.nextInt(16)]); + } + return sb.toString(); + } + + /** + * Pack the reminding left space with filler and return a fixed length string. + * Return itself if length of source string is larger or equals to the fixed + * length. 左补齐 + * + * @param src + * @param filler + * @param totalLength + * @return + */ + public static String lpad(String src, String filler, int totalLength) { + // Check length + int len = src.length(); + + // Return itself if larger or equals to the totalLength + if (len >= totalLength) { + return src; + } + + // To pack left space with filler. + StringBuilder builder = new StringBuilder(totalLength); + for (int i = len; i < totalLength; i++) { + builder.append(filler); + } + + // fill the resource string and return it. + return builder.append(src).toString(); + } + + /** + * + * Pack the reminding right space with filler and return a fixed length string. + * Return itself if length of source string is larger or equals to the fixed + * length. 右补齐 + * + * @param src + * @param filler + * @param totalLength + * @return + */ + public static String rpad(String src, String filler, int totalLength) { + int len = src.length(); + if (len >= totalLength) { + return src; + } + StringBuilder builder = new StringBuilder(src); + for (int i = len; i < totalLength; i++) { + builder.append(filler); + } + return builder.toString(); + } + + public static String subString(String str, int length) { + return str.substring(0, str.length() > length ? length : str.length()); + } + + public static String subString(String str, int start, int length) { + if (str == null) { + return null; + } + int len = str.length(); + if (len <= start) { + return null; + } + if (len < start + length) { + return str.substring(start, len - 1); + } + return str.substring(start, start + length); + } + + public static String right(String str, int length) { + if (str == null) { + return str; + } + int len = str.length(); + if (len <= length) { + return str; + } + return str.substring(len - length); + } + + // 字符串转换unicode + public static String stringToUnicode(String string) { + StringBuffer unicode = new StringBuffer(); + for (int i = 0; i < string.length(); i++) { + char c = string.charAt(i); // 取出每一个字符 + unicode.append("\\u" + Integer.toHexString(c));// 转换为unicode + } + return unicode.toString(); + } + + // unicode 转字符串 + public static String unicodeToString(String unicode) { + StringBuffer string = new StringBuffer(); + String[] hex = unicode.split("\\\\u"); + for (int i = 1; i < hex.length; i++) { + int data = Integer.parseInt(hex[i], 16);// 转换出每一个代码点 + string.append((char) data);// 追加成string + } + return string.toString(); + } + + /** + * Inject the arguments into a string and return. + * + * @param src + * @param args + * @return + */ + public static String injectJsonStringArgument(String src, String... args) { + StringBuilder builder = new StringBuilder(); + + int start = 0; + int end = 0; + int i = 0; + while ((start = src.indexOf(ARGUMENT_PREFIX + i + ARGUMENT_SUFFIX, end)) >= 0) { + builder.append(src.substring(end, start)); + + end = src.indexOf(ARGUMENT_SUFFIX, start); + + if (end > start) { + int index = Integer.valueOf(src.substring(start + 1, end)); + builder.append(args[index]); + + // Move to next + end += 1; + } else { + break; + } + i++; + } + + builder.append(src.substring(end)); + + return builder.toString(); + } + + public static boolean isNumeric(String value) { + return isInteger(value) || isDouble(value); + } + + public static boolean isInteger(String value) { + try { + Integer.parseInt(value); + return true; + } catch (NumberFormatException e) { + return false; + } + } + + public static boolean isDouble(String value) { + boolean flag = false; + + try { + if (value.contains(".")) { + flag = Double.isNaN(Double.parseDouble(value)); + } + } catch (NumberFormatException e) { + flag = false; + } + + return flag; + } + + public static boolean equals(String src, String dest) { + if (src == null && dest == null) { + return true; + } + return src != null && src.equals(dest); + } + + public static boolean isEmpty(String... values) { + for (String value : values) { + if (isEmpty(value)) { + return true; + } + } + return false; + } + + public static boolean isAllEmpty(String... values) { + for (String value : values) { + if (!isEmpty(value)) { + return false; + } + } + return true; + } + + public static int length(String str) { + if (isEmpty(str)) { + return 0; + } + return str.length(); + } + + public static boolean isBlank(final CharSequence cs) { + int strLen; + if (cs == null || (strLen = cs.length()) == 0) { + return true; + } + for (int i = 0; i < strLen; i++) { + if (!Character.isWhitespace(cs.charAt(i))) { + return false; + } + } + return true; + } + +} diff --git a/src/main/java/com/mengyxu/core/utils/XmlUtil.java b/src/main/java/com/mengyxu/core/utils/XmlUtil.java new file mode 100644 index 0000000..a17d560 --- /dev/null +++ b/src/main/java/com/mengyxu/core/utils/XmlUtil.java @@ -0,0 +1,137 @@ +package com.mengyxu.core.utils; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.dom4j.Attribute; +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; + +import com.mengyxu.core.exception.CoreException; +import com.mengyxu.core.pojo.special.XmlTag; + +/** All rights reserved + * author:mengyxu + * date:2020年6月28日 + */ + +public class XmlUtil { + private static final String XML_HEADER = ""; + private static final String SEPARATOR = System.getProperty("line.separator"); + + public static XmlTag readFileAsTag(File file) throws CoreException{ + SAXReader reader = new SAXReader(); + Document document; + try { + document = reader.read(file); + Element node = document.getRootElement(); + return parsToTag(node); + } catch (DocumentException e) { + throw new CoreException("解析XML文件失败"); + } + } + + private static XmlTag parsToTag(Element node) { + XmlTag tag = new XmlTag(); + tag.setName(node.getName()); + List list = node.attributes(); + if (list != null && !list.isEmpty()) { + Map attrs = new HashMap<>(); + for (Attribute attr : list) { + attrs.put(attr.getName(), attr.getValue()); + } + tag.setAttrs(attrs); + } + Iterator iter = node.elementIterator(); + if(iter.hasNext()) { + List nodes = new ArrayList<>(); + while (iter.hasNext()){ + nodes.add(parsToTag(iter.next())); + } + tag.setNodes(nodes); + }else { + tag.setValue(node.getStringValue()); + } + return tag; + } + + public static String formatTagAsXml(XmlTag tag) { + return XML_HEADER + toXml(tag, 0); + } + + private static String toXml(XmlTag tag, int idx) { + StringBuffer sb = new StringBuffer(); + apendTab(idx, sb); + sb.append("<").append(tag.getName()); + Map attrs = tag.getAttrs(); + String flag = null; + if(attrs != null && !attrs.isEmpty()) { + for (String key : attrs.keySet()) { + String val = attrs.get(key); + if(key.equals("type")) { + flag = val; + } + sb.append(" ").append(key).append("=\"") + .append(val).append("\""); + } + } + sb.append(">"); + List nodes = tag.getNodes(); + if(nodes != null && !nodes.isEmpty()) { + for (XmlTag node : nodes) { + sb.append(toXml(node, idx+1)); + } + apendTab(idx, sb); + }else { + String value = tag.getValue(); + if("isdn".equals(flag)) { + sb.append(format("19" + value)); + }else if("imsi".equals(flag)) { + sb.append(format(value)); + }else { + sb.append(value); + } + } + sb.append(""); + return sb.toString(); + } + + private static void apendTab(int idx, StringBuffer sb) { + sb.append(SEPARATOR); + for (int i = 0; i < idx; i++) { + sb.append(" "); + } + } + + private static String format(String str) { + int len = str.length(); + if(len%2 != 0) { + str += "F"; + } + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < str.length()/2; i++) { + sb.append(str.charAt(i*2+1)).append(str.charAt(i*2)).append(" "); + } + return sb.substring(0, sb.length()-1); + } + + public static String parse(String str) { + if(StringUtil.isEmpty(str)) { + return ""; + } + str = str.trim().replace(" ", ""); + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < str.length()/2; i++) { + sb.append(str.charAt(i*2+1)).append(str.charAt(i*2)); + } + return sb.substring(0, sb.length()-1).replace("F", ""); + } + + +} diff --git a/src/test/java/com/mengyxu/core/test/Base64Tester.java b/src/test/java/com/mengyxu/core/test/Base64Tester.java new file mode 100644 index 0000000..0ebc5b9 --- /dev/null +++ b/src/test/java/com/mengyxu/core/test/Base64Tester.java @@ -0,0 +1,22 @@ +package com.mengyxu.core.test; + +import org.junit.Test; + +import com.mengyxu.core.exception.CoreException; +import com.mengyxu.core.utils.Base64Util; +import com.mengyxu.core.utils.RSAUtil; + +/** All rights reserved + * author:mengyxu + * date:2019年6月26日 + */ +public class Base64Tester { + + @Test + public void decode() throws CoreException { + String s = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A"; + byte[] b = Base64Util.decode(s); + System.out.println(RSAUtil.byteToStringKey(b)); + } + +} diff --git a/src/test/java/com/mengyxu/core/test/LocationUtilTester.java b/src/test/java/com/mengyxu/core/test/LocationUtilTester.java new file mode 100644 index 0000000..959b3c4 --- /dev/null +++ b/src/test/java/com/mengyxu/core/test/LocationUtilTester.java @@ -0,0 +1,36 @@ +package com.mengyxu.core.test; + +import java.util.Arrays; + +import org.junit.Test; + +import com.mengyxu.core.utils.LocationUtil; + +/** All rights reserved + * author:mengyxu + * date:2020年7月9日 + */ + +public class LocationUtilTester { + + @Test + public void test1() { + long start = System.currentTimeMillis(); + String x = "114.06444999999997"; + String y = "22.507108"; + String[] arr = LocationUtil.wgs84tobd09(x, y); + System.out.println(Arrays.toString(arr)); + System.out.println(System.currentTimeMillis() - start); + } + + @Test + public void test2() { + long start = System.currentTimeMillis(); + String x = "120"; + String y = "24"; + String[] arr = LocationUtil.wgs84tobd09(x, y); + System.out.println(Arrays.toString(arr)); + System.out.println(System.currentTimeMillis() - start); + } + +} diff --git a/src/test/java/com/mengyxu/core/test/RSAUtilTester.java b/src/test/java/com/mengyxu/core/test/RSAUtilTester.java new file mode 100644 index 0000000..3aeffcc --- /dev/null +++ b/src/test/java/com/mengyxu/core/test/RSAUtilTester.java @@ -0,0 +1,137 @@ +package com.mengyxu.core.test; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.math.BigInteger; +import java.security.KeyFactory; +import java.security.PublicKey; +import java.security.spec.RSAPublicKeySpec; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.Cipher; + +import org.junit.Test; + +import com.mengyxu.core.exception.CoreException; +import com.mengyxu.core.utils.Base64Util; +import com.mengyxu.core.utils.RSAUtil; +import com.mengyxu.core.utils.StringUtil; + +/** All rights reserved + * author:mengyxu + * date:2020年6月11日 + */ + +public class RSAUtilTester { + public static final String a = "138128429165014960214288316246915564109957848967973935739058724552651480736930647934382755460619033465620384391387196627089864034424350665139841418169631846827850418205510584071030219835341930960684577738773846628024223162766742868530563861053134130417499539521288428945157726371402147367583657263208271059771"; + + //字符串进行加密填充的名称 + public static final String PADDING = "RSA/NONE/NoPadding"; + //字符串持有安全提供者的名称 + public static final String PROVIDER = "BC"; + + @Test + public void stringToByteKey() throws CoreException { + String key = "0008000001000100BEC07F26C1D87D7E022D3E82A4F8A0E83E2079206D728EFF0123194DFD6627655ACA16FA16EB076A09B85902E19727B1D8CCE91F998DD5EFB5D26CCE9B4BB1A0D2708B59EFA1217305BA8838960B1862198F2847C0182D5CA8F38D95949A3AD07E576713405C82DB06F89744D80660D562C8B13BE56E048DA0EC7934550653B6AFA2BB7ACDD893E595303E826AAE62095FD8280304BF5EE00DDE4DB3D5D20BFBEFA6C7D527D87E1F6BEA415E143F400A79AC1F24077AC205E433C730977AAC85A4BA2138AAA4B64C95AE14357204A6A6F708DF60290A94358358AF416EFB97E585EBC368E0F6BB189B0368861E1F8D1C62D53A9CF4A2BC4308883B87455FF72F"; + byte[] arr = RSAUtil.StringToByteKey(key); + for (byte b : arr) { + System.out.println(b); + } + } + + @Test + public void byteToStringKey() throws IOException { + File file = new File("D:/pubkey.Rsapub"); + FileInputStream fis = new FileInputStream(file); + byte[] arr = new byte[fis.available()]; + fis.read(arr); + fis.close(); + String key = RSAUtil.byteToStringKey(arr); + System.out.println(key); + } + + @Test + public void encryptByPublicKey() throws IOException { + String key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvsB/JsHYfX4CLT6CpPig6D4geSBtco7/ASMZTf1mJ2Vayhb6FusHagm4WQLhlyex2MzpH5mN1e+10mzOm0uxoNJwi1nvoSFzBbqIOJYLGGIZjyhHwBgtXKjzjZWUmjrQfldnE0BcgtsG+JdE2AZg1WLIsTvlbgSNoOx5NFUGU7avort6zdiT5ZUwPoJqrmIJX9goAwS/XuAN3k2z1dIL+++mx9Un2H4fa+pBXhQ/QAp5rB8kB3rCBeQzxzCXeqyFpLohOKqktkyVrhQ1cgSmpvcI32ApCpQ1g1ivQW77l+WF68No4Pa7GJsDaIYeH40cYtU6nPSivEMIiDuHRV/3LwIDAQAB"; + String data = "123456789"; + String result = RSAUtil.encryptByPublicKey(data, key); + System.out.println(result); + } + + @Test + public void dcryptByPublicKey() throws IOException { + String key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvsB/JsHYfX4CLT6CpPig6D4geSBtco7/ASMZTf1mJ2Vayhb6FusHagm4WQLhlyex2MzpH5mN1e+10mzOm0uxoNJwi1nvoSFzBbqIOJYLGGIZjyhHwBgtXKjzjZWUmjrQfldnE0BcgtsG+JdE2AZg1WLIsTvlbgSNoOx5NFUGU7avort6zdiT5ZUwPoJqrmIJX9goAwS/XuAN3k2z1dIL+++mx9Un2H4fa+pBXhQ/QAp5rB8kB3rCBeQzxzCXeqyFpLohOKqktkyVrhQ1cgSmpvcI32ApCpQ1g1ivQW77l+WF68No4Pa7GJsDaIYeH40cYtU6nPSivEMIiDuHRV/3LwIDAQAB"; + String data = "rBmtPB1ip3Z9nEaUHt2PCaC47CLD/N+SU3CQSMYUSlujTzzw2pJorSXQiRo3nm3gmQjQiPC0JWjhyRzXw1D1TDHr0aRlFv3GuvO2YUkWivxGh4bPArOT7VLEzerjWJ4N9fqPlGi9ZgMbEDhhiONBJ9ipX8t+w2ymTPpcngHRUZQM2vNk/CMgh1F5caYqsqW28XmI5unL3FYGR0U8GK6XfQs/O8doLxXHZ1XSCymjTOMeZ8uhkY/I66pGFS5wjz+m0ZqjcTDwE9UHYGPVNfIx3sgHZ8YyIr/kYxC94dGXp19sTIQBp14QK0pwD6m7xPIQcMOsoZsCVKbqJF/CCjdfgg=="; + String result = RSAUtil.decryptByPublicKey(data, key); + System.out.println(result); + } + + @Test + public void encryptByPublicKey1() throws Exception { + + File file = new File("D:/pubkey.der"); + FileInputStream fis = new FileInputStream(file); + byte[] arr = new byte[fis.available()]; + System.out.println(arr.length); + fis.read(arr); + fis.close(); + byte[] arr1 = new byte[4]; + byte[] arr2 = new byte[256]; + for (int i = 0; i < 4; i++) { + arr1[i] = arr[7-i]; + } + for (int i = 0; i < 256; i++) { + arr2[i] = arr[i+8]; + } + String data = "123456789"; + KeyFactory kf = KeyFactory.getInstance("RSA"); + BigInteger modulus = new BigInteger(arr1); + BigInteger publicExponent = new BigInteger(arr2).abs(); + System.out.println(modulus); + System.out.println(publicExponent); + RSAPublicKeySpec keySpec = new RSAPublicKeySpec(publicExponent, modulus); +// X509EncodedKeySpec keySpec = new X509EncodedKeySpec(arr); + PublicKey publicKey = kf.generatePublic(keySpec); + Cipher cipher = Cipher.getInstance(kf.getAlgorithm()); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + byte[] result = cipher.doFinal(data.getBytes()); + for (byte b : result) { + System.out.println(b); + } +// System.out.println(Base64Util.encode(result)); + } + + @Test + public void test() throws Exception { + //读取pem证书 + BufferedReader br = new BufferedReader(new FileReader("D:/pub2.pem")); + String s = br.readLine(); + StringBuffer publickey = new StringBuffer(); + while (!StringUtil.isEmpty(s)) { + if(s.charAt(0) != '-') + publickey.append(s); + s = br.readLine(); + } + br.close(); + byte[] keybyte = Base64Util.decode(publickey.toString()); + KeyFactory kf = KeyFactory.getInstance("RSA"); + + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keybyte); + + PublicKey publicKey = kf.generatePublic(keySpec); + Cipher cipher = Cipher.getInstance(kf.getAlgorithm()); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + byte[] result = cipher.doFinal("123456789".getBytes()); + System.out.println(Base64Util.encode(result)); + FileOutputStream fos = new FileOutputStream(new File("D:/pub2.bin")); + fos.write(result); + fos.flush(); + fos.close(); + } + + +} diff --git a/src/test/java/com/mengyxu/core/test/Tester.java b/src/test/java/com/mengyxu/core/test/Tester.java new file mode 100644 index 0000000..0159956 --- /dev/null +++ b/src/test/java/com/mengyxu/core/test/Tester.java @@ -0,0 +1,76 @@ +package com.mengyxu.core.test; + +import java.io.ByteArrayOutputStream; +import java.math.BigInteger; +import java.security.KeyFactory; +import java.security.PublicKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.RSAPublicKeySpec; +import java.util.Base64; + +import javax.crypto.Cipher; + +import org.junit.Test; + +import com.mengyxu.core.exception.CoreException; +import com.mengyxu.core.utils.Base64Util; + +/** All rights reserved + * author:mengyxu + * date:2020年6月11日 + */ + +public class Tester { + public static final String a = "138128429165014960214288316246915564109957848967973935739058724552651480736930647934382755460619033465620384391387196627089864034424350665139841418169631846827850418205510584071030219835341930960684577738773846628024223162766742868530563861053134130417499539521288428945157726371402147367583657263208271059771"; + public static final String b = "65537"; + + @Test + public void test() throws Exception{ + + RSAPublicKey res = a(a, b); + //待加密内容 + String text = "我是一个小test"; + //加密后内容 + String en_text = a(res, text); + System.out.println(en_text); + } + + @Test + public void test1() throws CoreException { + String s = "MTIzNDU2Nzg5"; + System.out.println(Base64Util.decodeToString(s)); + } + + public static RSAPublicKey a(String str, String str2) { + try { + return (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(new BigInteger(str), new BigInteger(str2))); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public static String a(PublicKey publicKey, String str) throws Exception { + Cipher instance = Cipher.getInstance("RSA"); + instance.init(1, publicKey); + byte[] bytes = str.getBytes("UTF-8"); + int length = bytes.length; + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + int i = 0; + int i2 = 0; + while (true) { + int i3 = length - i; + if (i3 > 0) { + byte[] doFinal = i3 > 117 ? instance.doFinal(bytes, i, 117) : instance.doFinal(bytes, i, i3); + byteArrayOutputStream.write(doFinal, 0, doFinal.length); + i2++; + i = i2 * 117; + } else { + byte[] byteArray = byteArrayOutputStream.toByteArray(); + byteArrayOutputStream.close(); + return Base64.getEncoder().encodeToString(byteArray); + } + } + } + +}