소스 검색

订单信息

唐tag 1 년 전
부모
커밋
cb43363294

+ 23 - 0
src/main/java/com/zswl/dataservicestarter/scheduled/OrderInfoSyncScheduled.java

@@ -0,0 +1,23 @@
+package com.zswl.dataservicestarter.scheduled;
+
+import com.zswl.dataservicestarter.utils.DateUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Configurable;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author TRX
+ * @date 2024/3/26
+ */
+@Component
+@Configurable
+@EnableScheduling
+@Slf4j
+public class OrderInfoSyncScheduled {
+    @Scheduled(fixedRate = 1000 * 5)
+    public void syncOrderInfo() {
+        log.info("同步时间: {}", DateUtils.paresTime(System.currentTimeMillis(), DateUtils.FORMAT_LONG));
+    }
+}

+ 463 - 0
src/main/java/com/zswl/dataservicestarter/utils/net/HttpClient.java

@@ -0,0 +1,463 @@
+package com.zswl.dataservicestarter.utils.net;
+
+import lombok.SneakyThrows;
+
+import javax.net.ssl.*;
+import java.io.*;
+import java.net.*;
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ * Http client
+ *
+ * @作者: @日期:2013年10月22日
+ *
+ */
+public class HttpClient {
+
+	static {
+		init();
+	}
+
+	@SneakyThrows
+	private static void init(){
+		SSLContext sslcontext = SSLContext.getInstance("SSL", "SunJSSE");//第一个参数为协议,第二个参数为提供者(可以缺省)
+		TrustManager[] tm = {new X509TrustManager(){
+
+			@Override
+			public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
+
+			}
+
+			@Override
+			public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
+
+			}
+
+			@Override
+			public X509Certificate[] getAcceptedIssuers() {
+				return new X509Certificate[0];
+			}
+		}};
+		sslcontext.init(null, tm, new SecureRandom());
+		HostnameVerifier ignoreHostnameVerifier = new HostnameVerifier() {
+			public boolean verify(String s, SSLSession sslsession) {
+				System.out.println("WARNING: Hostname is not matched for cert.");
+				return true;
+			}
+		};
+		HttpsURLConnection.setDefaultHostnameVerifier(ignoreHostnameVerifier);
+		HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());
+	}
+
+	private static final String CHARSET = "charset";
+
+	// 连接超时时间
+	private int connectTimeout = 60000;
+	// 读取超时时间
+	private int readTimeout = 60000;
+	// cookies
+	private Map<String, String> cookies = new HashMap<String, String>();
+	// 设置是否自动跳转
+	private boolean followRedirects = true;
+
+	// 监听输出管道
+	private OutputStream listenOutputStream;
+
+	// 代理IP
+	private String proxyHost;
+	// 代理端口
+	private int porxyPort;
+
+	public OutputStream getListenOutputStream() {
+		return listenOutputStream;
+	}
+
+	public HttpClient setListenOutputStream(OutputStream listenOutputStream) {
+		this.listenOutputStream = listenOutputStream;
+		return this;
+	}
+
+	public boolean isFollowRedirects() {
+		return followRedirects;
+	}
+
+	public HttpClient setFollowRedirects(boolean followRedirects) {
+		this.followRedirects = followRedirects;
+		return this;
+	}
+
+	public Map<String, String> getCookies() {
+		return cookies;
+	}
+
+	public HttpClient setCookies(Map<String, String> cookies) {
+		this.cookies = cookies;
+		return this;
+	}
+
+	public int getConnectTimeout() {
+		return connectTimeout;
+	}
+
+	public HttpClient setConnectTimeout(int connectTimeout) {
+		this.connectTimeout = connectTimeout;
+		return this;
+	}
+
+	public int getReadTimeout() {
+		return readTimeout;
+	}
+
+	public void setReadTimeout(int readTimeout) {
+		this.readTimeout = readTimeout;
+	}
+
+	public String getProxyHost() {
+		return proxyHost;
+	}
+
+	public HttpClient setProxyHost(String proxyHost) {
+		this.proxyHost = proxyHost;
+		return this;
+	}
+
+	public int getPorxyPort() {
+		return porxyPort;
+	}
+
+	public HttpClient setPorxyPort(int porxyPort) {
+		this.porxyPort = porxyPort;
+		return this;
+	}
+
+	/**
+	 * 默认的构造方法
+	 */
+	public HttpClient() {
+
+	}
+
+	/**
+	 * 请重写该方法用于显示下载进度
+	 *
+	 * @param currentPoint
+	 * @param totalPoint
+	 */
+	public void showProgress(long currentPoint, long totalPoint) {
+
+	}
+
+	/**
+	 * 使用get方式请求
+	 *
+	 * @param url
+	 * @return
+	 * @throws IOException
+	 */
+	public byte[] get(final String url) throws IOException {
+		return ReadDocuments(url, false, null).getData();
+	}
+
+	/**
+	 * 使用POST请求
+	 *
+	 * @param url
+	 * @param bin
+	 * @return
+	 * @throws IOException
+	 */
+	public byte[] post(final String url, final byte[] bin) throws IOException {
+		return ReadDocuments(url, true, bin).getData();
+	}
+
+	/**
+	 * 请求网络访问
+	 *
+	 * @param url
+	 * @return
+	 * @throws IOException
+	 */
+	public ResultBean ReadDocuments(String url) throws IOException {
+		return ReadDocuments(url, false, null);
+	}
+
+	/**
+	 *
+	 * @param url
+	 * @param isPost
+	 * @param
+	 * @return
+	 * @throws IOException
+	 */
+	public ResultBean ReadDocuments(String url, boolean isPost, byte[] postData) throws IOException {
+		return ReadDocuments(new URL(url), isPost, postData, null, null);
+	}
+
+	/**
+	 * HTTP访问网络
+	 *
+	 * @param url
+	 * @param isPost
+	 * @param postData
+	 * @param requestHead
+	 * @return
+	 * @throws IOException
+	 */
+	public ResultBean ReadDocuments(String url, boolean isPost, byte[] postData, Map<String, String> requestHead)
+			throws IOException {
+		return ReadDocuments(new URL(url), isPost, postData, requestHead, null);
+	}
+
+
+	public ResultBean ReadDocuments(final URL url, final boolean isPost, final byte[] postData,
+			Map<String, String> requestHead, Boolean onlyHead) throws IOException {
+		HttpURLConnection httpURLConnection = connect(url, isPost, requestHead);
+		if (httpURLConnection == null) {
+			return null;
+		}
+		// 写出参数
+		if (isPost && postData != null) {
+			OutputStream outputStream = httpURLConnection.getOutputStream();
+			outputStream.write(postData);
+			outputStream.flush();
+			outputStream.close();
+		}
+		// 设置响应与返回的响应头信息
+		ResultBean resultBean = readInputStream(httpURLConnection, onlyHead);
+		// 设置服务器需要设置的cookies
+		readAndSetCookies(httpURLConnection);
+		return resultBean;
+	}
+
+	/**
+	 * 创建连接管道
+	 *
+	 * @param url
+	 * @param isPost
+	 * @param requestHead
+	 * @return 返回写入的数据管道
+	 * @throws IOException
+	 */
+	protected HttpURLConnection connect(final URL url, final Boolean isPost, Map<String, String> requestHead)
+			throws IOException {
+		URLConnection uRLConnection = null;
+		if (this.proxyHost == null) {
+			uRLConnection = url.openConnection();
+		} else {
+			Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(this.proxyHost, this.porxyPort));
+			uRLConnection = url.openConnection(proxy);
+		}
+		HttpURLConnection httpURLConnection = (HttpURLConnection) uRLConnection;
+		// 设置是否自动重定向
+		httpURLConnection.setInstanceFollowRedirects(isFollowRedirects());
+		// 设置访问模式
+		httpURLConnection.setRequestMethod(isPost != null && isPost ? "POST" : "GET");
+		// 设置是否从httpUrlConnection读入,默认情况下是true;
+		httpURLConnection.setDoInput(true);
+		// http正文内,因此需要设为true, 默认情况下是false;
+		httpURLConnection.setDoOutput(true);
+		// Post 请求不能使用缓存
+		httpURLConnection.setUseCaches(false);
+		// 请求头
+		if (requestHead == null) {
+			requestHead = new HashMap<String, String>();
+		}
+		// 设置请求类型编码
+		if (requestHead.get("Content-type") == null) {
+			httpURLConnection.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
+		}
+		// 设置浏览器的版本
+		if (requestHead.get("User-Agent") == null) {
+			httpURLConnection.setRequestProperty("User-Agent", "Mozilla/5.0");
+		}
+		// 设置默认的Referer
+		if (requestHead.get("Referer") == null) {
+			httpURLConnection.setRequestProperty("Referer", url.toExternalForm());
+		}
+
+		for (String key : requestHead.keySet()) {
+			httpURLConnection.setRequestProperty(key, requestHead.get(key));
+		}
+
+		// 加载cookies
+		if (this.cookies != null && this.cookies.size() > 0)
+			httpURLConnection.setRequestProperty("Cookie", getInnerCookies());
+
+		httpURLConnection.setConnectTimeout(connectTimeout);
+		httpURLConnection.setReadTimeout(readTimeout);
+		// 开始连接连接
+		httpURLConnection.connect();
+		// 返回该创建连接后的对象
+		return httpURLConnection;
+	}
+
+	/**
+	 * 取响应的结果
+	 *
+	 * @param httpURLConnection
+	 * @return
+	 * @throws IOException
+	 */
+	protected ResultBean readInputStream(HttpURLConnection httpURLConnection, Boolean onlyHead) throws IOException {
+		// 读取响应的数据
+		InputStream inputStream = null;
+		try {
+			inputStream = httpURLConnection.getInputStream();
+		} catch (Exception e) {
+			inputStream = httpURLConnection.getErrorStream();
+		}
+		long totalByte = -1;
+		if (httpURLConnection.getHeaderField("Content-Length") != null) {
+			totalByte = Long.parseLong(httpURLConnection.getHeaderField("Content-Length"));
+		}
+		ResultBean resultBean = new ResultBean();
+		// 判断是否读取内容
+		if (onlyHead == null || onlyHead == false) {
+			byte[] resultBin = null;
+			if (inputStream != null) {
+				// 读取内容部分
+				resultBin = inputStreamToBytes(inputStream, totalByte);
+				inputStream.close();
+			}
+			resultBean.setData(resultBin);
+		}
+		// 设置响应的头信息
+		resultBean.setResponseHead(httpURLConnection.getHeaderFields());
+		// 设置响应状态code
+		resultBean.setStat(httpURLConnection.getResponseCode());
+		return resultBean;
+	}
+
+	/**
+	 * 设置当前网络访问后的cookies
+	 *
+	 * @param httpURLConnection
+	 */
+	protected void readAndSetCookies(HttpURLConnection httpURLConnection) {
+		setInnerCookies(httpURLConnection.getHeaderFields().get("Set-Cookie"));
+	}
+
+	private void setInnerCookies(List<String> cookiesStr) {
+		if (cookiesStr != null)
+			for (int i = 0; i < cookiesStr.size(); i++) {
+				String tempStr = cookiesStr.get(i);
+				tempStr = tempStr.replaceAll(";", "=");
+				String[] mapping = tempStr.split("=");
+				if (mapping.length > 1) {
+					String key = mapping[0];
+					String value = mapping[1];
+					this.cookies.put(key, value);
+				}
+			}
+	}
+
+	public String getInnerCookies() {
+		String result = "";
+		for (String key : this.cookies.keySet()) {
+			result += key + "=" + this.cookies.get(key) + "; ";
+		}
+		return result.trim();
+	}
+
+	/**
+	 *
+	 * @param inputStream
+	 * @return
+	 */
+	private byte[] inputStreamToBytes(InputStream inputStream, long totalByte) throws IOException {
+		byte[] container = new byte[102400];
+		ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
+		int b = -1;
+		while ((b = inputStream.read(container)) != -1) {
+			if (listenOutputStream != null) {
+				try {
+					listenOutputStream.write(container, 0, b);
+				} catch (Exception e) {
+					e.printStackTrace();
+				}
+			}
+			arrayOutputStream.write(container, 0, b);
+			showProgress(arrayOutputStream.size(), totalByte);
+		}
+		arrayOutputStream.flush();
+		byte[] data = arrayOutputStream.toByteArray();
+		arrayOutputStream.close();
+		return data;
+	}
+
+	/**
+	 * 返回结果集
+	 *
+	 * @author admin
+	 *
+	 */
+	public class ResultBean implements Serializable {
+		/**
+		 *
+		 */
+		private static final long serialVersionUID = 2933585102741021542L;
+
+		public ResultBean() {
+
+		}
+
+		private byte[] data;
+
+		private Map<String, List<String>> responseHead;
+
+		private int stat = 0;
+
+		public int getStat() {
+			return stat;
+		}
+
+		public void setStat(int stat) {
+			this.stat = stat;
+		}
+
+		public byte[] getData() {
+			return data;
+		}
+
+		public void setData(byte[] data) {
+			this.data = data;
+		}
+
+		public Map<String, List<String>> getResponseHead() {
+			return responseHead;
+		}
+
+		public void setResponseHead(Map<String, List<String>> responseHead) {
+			this.responseHead = responseHead;
+		}
+
+		/**
+		 * 取出字符编码,没有则返回null
+		 *
+		 * @return
+		 */
+		public String getCharset() {
+			String charset = null;
+			// 取出文字编码
+			List<String> contentTypes = this.getResponseHead().get("Content-Type");
+			if (contentTypes != null) {
+				for (String contentType : contentTypes) {
+					int at = contentType.indexOf(CHARSET + "=");
+					if (at > -1) {
+						String right = contentType.substring(at + CHARSET.length() + 1, contentType.length());
+						charset = right.trim();
+					}
+				}
+			}
+			return charset;
+		}
+	}
+
+}

+ 95 - 0
src/main/java/com/zswl/dataservicestarter/utils/net/IPUtil.java

@@ -0,0 +1,95 @@
+package com.zswl.dataservicestarter.utils.net;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 取ip的工具
+ */
+public class IPUtil {
+
+
+    /**
+     * 可能出现用户真实ip的头
+     */
+    public final static String[] headNames = new String[]{
+            "X-FORWARDED-FOR",
+            "Proxy-Client-IP",
+            "WL-Proxy-Client-IP",
+            "HTTP_CLIENT_IP",
+            "HTTP_X_FORWARDED_FOR"
+    };
+
+
+    /**
+     * 获取远程ip
+     *
+     * @param request
+     * @return
+     */
+    public static String getRemoteIp(HttpServletRequest request) {
+        final Map<String,String> header = new HashMap();
+        Arrays.stream(headNames).forEach((name) -> {
+            header.put(name, request.getHeader(name));
+        });
+        return getRemoteIp(header, request.getRemoteAddr());
+    }
+
+
+    /**
+     * 获取远程ip
+     *
+     * @return
+     */
+    public static String getRemoteIp(Map<String,String> headers, String defaultRemoteAddr) {
+        for (String name : headNames) {
+            Object obj = headers.get(name);
+            if (obj == null || "".equals(String.valueOf(obj))) {
+                continue;
+            }
+
+            String ip = String.valueOf(obj);
+            int at = ip.indexOf(",");
+            if (at > -1) {
+                ip = ip.substring(0, at);
+            }
+            return ip;
+        }
+        return defaultRemoteAddr;
+    }
+
+
+    /**
+     * ip地址转换为十进制
+     *
+     * @return
+     */
+    public static long ipv4ToLong(String ip) {
+        String[] ips = ip.split("\\.");
+        long result = 0;
+        for (int i = 0; i < ips.length; i++) {
+            int power = 3 - i;
+            result += Integer.parseInt(ips[i]) * Math.pow(256, power);
+        }
+        return result;
+    }
+
+
+    /**
+     * long 转换为 ip
+     *
+     * @param i
+     * @return
+     */
+    public static String longToIpv4(long i) {
+        return ((i >> 24) & 0xFF) +
+                "." + ((i >> 16) & 0xFF) +
+                "." + ((i >> 8) & 0xFF) +
+                "." + (i & 0xFF);
+
+    }
+
+
+}

+ 580 - 0
src/main/java/com/zswl/dataservicestarter/utils/net/apache/BeanUtil.java

@@ -0,0 +1,580 @@
+package com.zswl.dataservicestarter.utils.net.apache;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.SneakyThrows;
+import org.springframework.beans.BeanWrapper;
+import org.springframework.beans.BeanWrapperImpl;
+import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.*;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static java.util.Locale.ENGLISH;
+
+/**
+ * Bean工具
+ */
+public class BeanUtil {
+
+    //默认的基础类型的实例化初始值
+    private static final Map<Class, Object> BaseType = new HashMap() {
+        {
+            put(int.class, 0);
+            put(long.class, 0l);
+            put(short.class, 0);
+            put(byte.class, 0);
+            put(float.class, 0f);
+            put(double.class, 0d);
+            put(boolean.class, false);
+            put(char.class, "");
+
+            put(Integer.class, 0);
+            put(Long.class, 0l);
+            put(Short.class, 0);
+            put(Byte.class, 0);
+            put(Float.class, 0f);
+            put(Double.class, 0d);
+            put(Boolean.class, false);
+
+            put(BigDecimal.class, 0);
+        }
+    };
+
+    // 参数名发现
+    private final static LocalVariableTableParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
+
+    /**
+     * javaBean转map
+     *
+     * @param obj
+     * @return
+     * @throws Exception
+     */
+    public static Map<String, Object> bean2Map(Object obj) {
+        Map<String, Object> map = new HashMap<>();
+        if (obj == null) {
+            return map;
+        }
+        try {
+            // 获取javaBean的BeanInfo对象
+            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass(), Object.class);
+            // 获取属性描述器
+            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
+            for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
+                // 获取属性名
+                String key = propertyDescriptor.getName();
+                // 获取该属性的值
+                Method readMethod = propertyDescriptor.getReadMethod();
+                // 通过反射来调用javaBean定义的getName()方法
+                Object value = readMethod.invoke(obj);
+                map.put(key, value);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return map;
+    }
+
+
+    /**
+     * 读取一个bean的类型
+     *
+     * @return
+     */
+    @SneakyThrows
+    public static Map<String, Class> readBeanType(Class<?> cls) {
+        Map<String, Class> ret = new HashMap<>();
+        // 获取javaBean的BeanInfo对象
+        BeanInfo beanInfo = Introspector.getBeanInfo(cls, Object.class);
+        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
+        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
+            ret.put(propertyDescriptor.getName(), propertyDescriptor.getPropertyType());
+        }
+        return ret;
+    }
+
+
+    /**
+     * 通过map设置bean对象
+     *
+     * @param obj
+     * @param map
+     */
+    @SneakyThrows
+    public static void setBean(final Object obj, final Map<String, Object> map) {
+        // 获取javaBean的BeanInfo对象
+        BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass(), Object.class);
+        // 获取属性描述器
+        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
+        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
+            // 获取属性名
+            String key = propertyDescriptor.getName();
+            if (!map.containsKey(key)) {
+                continue;
+            }
+
+
+            // 兼容 @Accessors(chain = true)
+            // 获取该属性的值
+            Method writeMethod = propertyDescriptor.getWriteMethod();
+
+            //如果为空则通过反射取出来
+            if (writeMethod == null) {
+                writeMethod = obj.getClass().getMethod(toMethodName(propertyDescriptor.getName()), propertyDescriptor.getPropertyType());
+            }
+
+            // 通过反射来调用javaBean定义的getName()方法
+            if (writeMethod == null) {
+                continue;
+            }
+
+            //调用方法
+            final Class propertyType = propertyDescriptor.getPropertyType();
+            Object sourceObj = map.get(key);
+            if (sourceObj == null) {
+                continue;
+            }
+
+            //递归类型 ( 当value 为 map)
+            if (propertyType != sourceObj.getClass() && sourceObj instanceof Map) {
+                Object ret = newClass(propertyType);
+                setBean(ret, (Map) sourceObj);
+                writeMethod.invoke(obj, ret);
+            } else if (sourceObj instanceof Collection || sourceObj.getClass().isArray()) {
+                writeMethod.invoke(obj, toTypeFromCollectionObject(propertyType, sourceObj));
+            } else {
+                writeMethod.invoke(obj, sourceObj);
+            }
+        }
+    }
+
+    /**
+     * 转换到目标类型
+     *
+     * @param <T>
+     * @return
+     */
+    private static <T> T toTypeFromCollectionObject(Class<T> targetCls, Object sourceObj) {
+
+        //处理集合类型
+        List items = null;
+        if (sourceObj instanceof Collection) {
+            items = (List) ((Collection) sourceObj).stream().collect(Collectors.toList());
+        } else if (targetCls.isArray()) {
+            items = Arrays.stream((Object[]) sourceObj).collect(Collectors.toList());
+        } else {
+            items = new ArrayList();
+        }
+
+
+        //目标类型
+        if (targetCls.isArray()) {
+            Object ret = Array.newInstance(targetCls.getComponentType(), items.size());
+            for (int i = 0; i < items.size(); i++) {
+                Array.set(ret, i, items.get(i));
+            }
+            return (T) ret;
+        }
+
+
+        if (targetCls == List.class) {
+            return (T) new ArrayList(items);
+        }
+        if (targetCls == Set.class) {
+            return (T) new HashSet<>(items);
+        }
+        if (targetCls == Vector.class) {
+            return (T) new Vector<>(items);
+        }
+//        sourceObj instanceof Map sourceObj instanceof Collections || sourceObj.getClass().isArray()
+
+        return null;
+    }
+
+    /**
+     * 转换到方法名
+     *
+     * @param name
+     * @return
+     */
+    private static String toMethodName(String name) {
+        return "set" + name.substring(0, 1).toUpperCase(ENGLISH) + name.substring(1);
+    }
+
+    /**
+     * Bean转到Map
+     *
+     * @param obj
+     * @return
+     */
+    public static Map<String, Object> toMap(Object obj) {
+        Map<String, Object> m = new HashMap<>();
+        setMap(m, obj);
+        return m;
+    }
+
+
+    @SneakyThrows
+    public static <T> T getBeanValue(Object obj, String name) {
+        // 获取javaBean的BeanInfo对象
+        BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass(), Object.class);
+        // 获取属性描述器
+        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
+        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
+            // 获取属性名
+            String key = propertyDescriptor.getName();
+            if (key.equals(name)) {
+                Method readMethod = propertyDescriptor.getReadMethod();
+                return (T) readMethod.invoke(obj, name);
+            }
+        }
+        return null;
+    }
+
+
+    /**
+     * bean转到Map
+     *
+     * @param map
+     * @param obj
+     */
+    @SneakyThrows
+    public static void setMap(final Map<String, Object> map, final Object obj) {
+        //如果对象为Map,直接拷贝到目标Map中
+        if (obj instanceof Map) {
+            map.putAll((Map) obj);
+            return;
+        }
+        // 获取javaBean的BeanInfo对象
+        BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass(), Object.class);
+        // 获取属性描述器
+        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
+        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
+            // 获取属性名
+            String key = propertyDescriptor.getName();
+            Method readMethod = propertyDescriptor.getReadMethod();
+            map.put(key, readMethod.invoke(obj));
+        }
+    }
+
+
+    /**
+     * 获取bean对象中为null的属性名
+     *
+     * @param source
+     * @return
+     */
+    public static void getNullPropertyNames(Object source, Set<String> sets) {
+        final BeanWrapper src = new BeanWrapperImpl(source);
+        PropertyDescriptor[] pds = src.getPropertyDescriptors();
+        for (PropertyDescriptor pd : pds) {
+            Object srcValue = src.getPropertyValue(pd.getName());
+            if (srcValue == null) sets.add(pd.getName());
+        }
+    }
+
+
+    /**
+     * 构建Bean对象
+     *
+     * @param cls
+     * @param componentType
+     * @param <T>
+     * @return
+     */
+    @SneakyThrows
+    private static <T> T buildBean(final Class<T> cls, final Class componentType, int currentDepth,
+                                   int maxDepthCount) {
+        //集合对象
+        Object items = null;
+        //单独的属性
+        Object item = null;
+        //处理数组与集合
+        if (cls.isArray()) {
+            items = Array.newInstance(componentType, 1);
+            item = newClass(componentType);
+            Array.set(items, 0, item);
+        } else if (Collection.class.isAssignableFrom(cls)) {
+            item = newClass(componentType);
+            if (cls == Collection.class) {
+                List list = new ArrayList();
+                list.add(item);
+                items = list;
+            } else {
+                //取出ofMethod 的方法
+                Method ofMethod = cls.getDeclaredMethod("of", Object.class);
+                if (ofMethod != null) {
+                    ofMethod.setAccessible(true);
+                    items = ofMethod.invoke(null, item);
+                }
+            }
+        } else if (Map.class.isAssignableFrom(cls)) {
+            items = new HashMap<>();
+        } else {
+            item = newClass(cls);
+        }
+
+        //深度执行 , 过滤基础类型与字符串类型
+        if (item != null && !(item instanceof String) && currentDepth < maxDepthCount && item.getClass() != Object.class && !item.getClass().isEnum()) {
+            depthSetBean(item, ++currentDepth, maxDepthCount);
+        }
+        //集合对象不为空则返回集合对象,否则返回单个的对象
+        return (T) (items != null ? items : item);
+    }
+
+
+    /**
+     * 获取方法上的参数名
+     *
+     * @param method
+     * @return
+     */
+    public static String[] getParameterNames(Method method) {
+        return parameterNameDiscoverer.getParameterNames(method);
+    }
+
+    /**
+     * 取方法名上的参数名,优先遵循是 RequestParam 注解
+     *
+     * @param method
+     * @param index
+     * @return
+     */
+    public static String getMethodParamName(Method method, final int index) {
+        String[] paramNames = getParameterNames(method);
+        //读取参数名,优先读取注解上的参数名
+        String paramName = null;
+        Annotation[] parameterAnnotations = method.getParameterAnnotations()[index];
+        for (Annotation parameterAnnotation : parameterAnnotations) {
+            if (parameterAnnotation instanceof RequestParam) {
+                RequestParam requestParam = (RequestParam) parameterAnnotation;
+                return requestParam.value();
+            }
+        }
+        if (paramName == null) {
+            paramName = paramNames[index];
+        }
+
+        return paramName;
+    }
+
+    /**
+     * 设置BeanMap的项
+     *
+     * @param ret
+     * @param spaceName
+     * @param itemKey
+     * @param fieldCommentText
+     * @param value
+     */
+    private static void setBeanMapItem(final Map<String, BeanValueInfo> ret, final String spaceName,
+                                       final String itemKey, String fieldCommentText, Object value) {
+        String key = getItemKeyName(spaceName, itemKey);
+        if (StringUtils.hasText(key)) {
+            ret.put(key, new BeanValueInfo(key, fieldCommentText, value));
+        }
+    }
+
+    /**
+     * 获取项目的key
+     *
+     * @param spaceName
+     * @param itemKey
+     * @return
+     */
+    private static String getItemKeyName(String spaceName, String itemKey) {
+        String ret = StringUtils.hasText(spaceName) && StringUtils.hasText(itemKey) ? spaceName + "." + itemKey : itemKey;
+        if (ret.indexOf(".") < 0) {
+            return ret;
+        }
+        //根据spring controller的规则,如果有多级对象,则去掉首个
+        String[] items = ret.split("\\.");
+        if (items.length > 1) {
+            String[] newItems = new String[items.length - 1];
+            System.arraycopy(items, 1, newItems, 0, newItems.length);
+            ret = TextUtil.join(newItems, ".");
+        }
+        return ret;
+    }
+
+
+    /**
+     * 参数信息
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class BeanValueInfo {
+
+        //名称
+        private String name;
+
+        //类型
+        private String commentText;
+
+        //值
+        private Object value;
+
+//        //方法
+//        private String commentText;
+//
+//        //参数注释
+//        private Map<String,String> paramCommentText;
+
+    }
+
+
+    /**
+     * 构建bean,支持深度遍历构建
+     *
+     * @param cls
+     * @param <T>
+     * @return
+     */
+    public static <T> T buildBean(Class<T> cls, int maxDepthCount) {
+        return buildBean(cls, cls.getComponentType(), 0, maxDepthCount);
+    }
+
+
+    /**
+     * 通过属性构建bean对象
+     *
+     * @param field
+     * @param <T>
+     * @return
+     */
+    private static <T> T buildBean(Field field, int currentDepth, int maxDepthCount) {
+        Class type = field.getType();
+        Class[] cls = getGenericType(field);
+        Object ret = buildBean(type, (cls != null && cls.length > 0) ? cls[0] : type.getComponentType(), currentDepth, maxDepthCount);
+        return ret == null ? null : (T) ret;
+    }
+
+
+    /**
+     * 实例化对象
+     *
+     * @param cls
+     */
+    @SneakyThrows
+    public static <T> T newClass(Class<T> cls) {
+        //基础类型,则直接返回null
+        Object val = BaseType.get(cls);
+        if (val != null) {
+            return (T) val;
+        }
+        //枚举类
+        if (cls.isEnum()) {
+            return (T) cls.getFields()[0].get(null);
+        }
+
+        // 数组与集合
+        if (cls.isArray()) {
+            return (T) Array.newInstance(cls, 0);
+        } else if (cls == List.class) {
+            return (T) new ArrayList();
+        } else if (cls == Set.class) {
+            return (T) new HashSet<>();
+        } else if (cls == Map.class) {
+            return (T) new HashMap<>();
+        }
+
+
+        Constructor<?> newConstructor = null;
+        //遍历出所有的构造方法
+        for (Constructor<?> constructor : cls.getDeclaredConstructors()) {
+            if (constructor.getParameterCount() == 0) {
+                newConstructor = constructor;
+                break;
+            }
+        }
+        Assert.notNull(newConstructor, "未找到可用的构造方法 : " + cls);
+        return (T) newConstructor.newInstance();
+    }
+
+
+    /**
+     * 获取枚举类的class
+     *
+     * @param field
+     * @return
+     */
+    public static Class[] getGenericType(Field field) {
+        Type genericType = field.getGenericType();
+        if (null == genericType) {
+            return null;
+        }
+        if (genericType instanceof ParameterizedType) {
+            ParameterizedType pt = (ParameterizedType) genericType;
+            // 得到泛型里的class类型对象
+            return Arrays.stream(pt.getActualTypeArguments()).map((it) -> {
+                return (Class) it;
+            }).collect(Collectors.toList()).toArray(new Class[0]);
+        }
+        return null;
+    }
+
+    /**
+     * 深度设置Bean的默认值,调用Set方法进行赋值
+     *
+     * @param item
+     */
+    @SneakyThrows
+    private static <T> void depthSetBean(Object item, int currentDepth, int maxDepthCount) {
+        // 获取javaBean的BeanInfo对象
+        BeanInfo beanInfo = Introspector.getBeanInfo(item.getClass(), Object.class);
+        // 获取属性描述器
+        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
+        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
+            String name = propertyDescriptor.getName();
+            //属性
+            Field field = getField(item.getClass(), name);
+            if (field == null) {
+                continue;
+            }
+            // 根据类型进行构建Bean
+            Object val = buildBean(field, currentDepth, maxDepthCount);
+            if (val != null) {
+                // 获取该属性的值
+                Method readMethod = propertyDescriptor.getWriteMethod();
+                // 通过反射来调用javaBean定义的getName()方法
+                readMethod.invoke(item, val);
+            }
+        }
+    }
+
+
+    /**
+     * 获取class的属性
+     *
+     * @param cls
+     * @param fieldName
+     * @return
+     */
+    @SneakyThrows
+    private static Field getField(Class cls, String fieldName) {
+        for (Field field : cls.getDeclaredFields()) {
+            if (field.getName().equals(fieldName)) {
+                field.setAccessible(true);
+                return field;
+            }
+        }
+        Field field = null;
+        if (cls.getSuperclass() != null) {
+            field = getField(cls.getSuperclass(), fieldName);
+        }
+        return field;
+    }
+
+}

+ 261 - 0
src/main/java/com/zswl/dataservicestarter/utils/net/apache/HttpClientUtil.java

@@ -0,0 +1,261 @@
+package com.zswl.dataservicestarter.utils.net.apache;
+
+import lombok.Cleanup;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.Header;
+import org.apache.http.client.config.RequestConfig;
+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.methods.HttpRequestBase;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.TrustStrategy;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.ssl.SSLContexts;
+import org.springframework.cglib.beans.BeanMap;
+import org.springframework.util.StreamUtils;
+
+import javax.net.ssl.SSLContext;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.*;
+
+@Slf4j
+public class HttpClientUtil {
+
+    /**
+     * 网络请求
+     *
+     * @param httpModel
+     * @return
+     * @throws IOException
+     */
+    public static ResponseModel request(HttpModel httpModel) throws IOException {
+        Map<String, Set<Object>> headers = new HashMap<>();
+        @Cleanup ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        Integer code = request(httpModel, byteArrayOutputStream, headers);
+        byte[] content = byteArrayOutputStream.toByteArray();
+        Object body = getBody(headers, content);
+        return ResponseModel.builder().headers(headers).body(body).code(code).build();
+    }
+
+
+    /**
+     * 构建响应
+     *
+     * @return
+     */
+    public static Map<String, Object> buildResponse(Map<String, Set<Object>> headers, Object body) {
+        return new HashMap<String, Object>() {{
+            put("headers", headers);
+            put("body", body);
+        }};
+    }
+
+
+    /**
+     * 网络请求
+     *
+     * @param httpModel
+     * @param outputStream
+     * @return
+     */
+    @SneakyThrows
+    public static Integer request(HttpModel httpModel, OutputStream outputStream, Map<String, Set<Object>> headers) throws IOException {
+        //构建超时参数
+        RequestConfig.Builder builder = RequestConfig.custom();
+        if (httpModel.getTimeOut() != null) {
+            builder.setSocketTimeout(httpModel.getTimeOut());
+        }
+        RequestConfig requestConfig = builder.build();
+
+        //忽略ssl
+        SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustStrategy() {
+            @Override
+            public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
+                return true;
+            }
+        }).build();
+        CloseableHttpClient httpclient = HttpClients.custom().setDefaultRequestConfig(requestConfig).setSSLContext(sslContext).setSSLHostnameVerifier(new NoopHostnameVerifier()).build();
+
+//        CloseableHttpClient httpclient = HttpClients.createDefault();
+        HttpRequestBase requestBase = null;
+        String[] urls = httpModel.getUrl().split("://");
+
+        String url = urls[0] + "://" + UrlEncodeUtil.encode(urls[1]);
+
+        //请求类型的判断
+        if (httpModel.getMethod() == MethodType.Get || httpModel.getMethod() == null) {
+            requestBase = new HttpGet(url);
+        } else if (httpModel.getMethod() == MethodType.Post || httpModel.getMethod() == MethodType.Json) {
+            HttpPost httpPost = new HttpPost(url);
+            httpPost.setEntity(buildHttpEntity(httpModel));
+            requestBase = httpPost;
+        }
+
+        //设置请求头
+        if (httpModel.getHeader() != null) {
+            for (Map.Entry<String, Object> entry : httpModel.getHeader().entrySet()) {
+                requestBase.setHeader(entry.getKey(), String.valueOf(entry.getValue()));
+            }
+        }
+
+
+        //开始请求
+        CloseableHttpResponse response = httpclient.execute(requestBase);
+
+        if (headers != null) {
+            for (Header header : response.getAllHeaders()) {
+                Set<Object> val = headers.get(header.getName());
+                if (val == null) {
+                    val = new HashSet<>();
+                    headers.put(header.getName(), val);
+                }
+                val.add(header.getValue());
+            }
+        }
+
+        //转发数据流
+        @Cleanup InputStream inputStream = response.getEntity().getContent();
+        int size = StreamUtils.copy(inputStream, outputStream);
+        log.info("requestUrl : " + httpModel.getUrl() + " , responseSize : " + size);
+        return response.getStatusLine().getStatusCode();
+    }
+
+
+    /**
+     * 获取body部分
+     *
+     * @param headers
+     * @param content
+     * @return
+     */
+    public static Object getBody(Map<String, Set<Object>> headers, byte[] content) {
+        Set<Object> contentTypeHeader = headers.get("Content-Type");
+
+        Object ret = null;
+
+        String contentType = null;
+        String charset = null;
+        if (contentTypeHeader != null && contentTypeHeader.size() > 0) {
+            String val = String.valueOf(contentTypeHeader.toArray(new Object[0])[0]);
+            String[] tmp = val.split(";");
+            if (tmp.length > 0) {
+                contentType = tmp[0];
+            }
+            if (tmp.length > 1) {
+                charset = tmp[1];
+            }
+        }
+
+        //获取字符编码
+        if (charset != null) {
+            String[] charsetArr = charset.split("=");
+            if (charset.length() > 0) {
+                charset = charsetArr[1];
+            }
+        }
+
+
+        try {
+            String contentStr = new String(content, charset == null ? "UTF-8" : charset);
+            if ("application/json".equals(contentType)) {
+//                ret = JsonUtil.toObject(contentStr, Object.class);
+                ret = contentStr;
+            } else {
+                ret = contentStr;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+
+        return ret;
+    }
+
+
+    /**
+     * 创建数据
+     *
+     * @param httpModel
+     * @return
+     */
+    private static StringEntity buildHttpEntity(HttpModel httpModel) {
+        String body = null;
+        String mimeType = null;
+        if (httpModel.getMethod() == MethodType.Post) {
+            mimeType = "application/x-www-form-urlencoded";
+            if (httpModel.getBody() == null) {
+                body = "";
+            } else if (httpModel.getBody() instanceof String) {
+                body = String.valueOf(httpModel.getBody());
+            } else {
+                //支持对象和map
+                StringBuffer sb = new StringBuffer();
+                Map<String, Object> bean = null;
+                if (httpModel.getBody() instanceof Map) {
+                    bean = (Map<String, Object>) httpModel.getBody();
+                } else {
+                    bean = BeanMap.create(body);
+                }
+                bean.entrySet().forEach((entry) -> {
+                    sb.append(UrlEncodeUtil.encode(entry.getKey()) + "=" + UrlEncodeUtil.encode(String.valueOf(entry.getValue())) + "&");
+                });
+                body = sb.toString();
+            }
+        } else if (httpModel.getMethod() == MethodType.Json) {
+            mimeType = "application/json";
+            body = httpModel.getBody() == null ? "{}" : JsonUtil.toJson(httpModel.getBody());
+        }
+        return new StringEntity(body, ContentType.create(mimeType, httpModel.getCharset()));
+    }
+
+
+    /**
+     * 创建post信息
+     *
+     * @param m
+     * @return
+     */
+    public static String buildPostInfo(Map<String, Object> m) {
+        final StringBuilder sb = new StringBuilder();
+        m.entrySet().forEach((it) -> {
+            Object val = it.getValue();
+            List<String> values;
+            if (val instanceof Collection) {
+                values = new ArrayList<String>((Collection<String>) val);
+            } else if (val.getClass().isArray()) {
+                values = Arrays.asList((String[]) val);
+            } else {
+                values = new ArrayList<String>() {{
+                    add(String.valueOf(it.getValue()));
+                }};
+            }
+            appendFormInfo(sb, it.getKey(), values);
+        });
+        return sb.toString();
+    }
+
+    /**
+     * 构建表单信息
+     *
+     * @param sb
+     * @param key
+     * @param values
+     */
+    private static void appendFormInfo(StringBuilder sb, String key, List<String> values) {
+        for (String value : values) {
+            sb.append(key + "=" + value + "&");
+        }
+    }
+
+
+}

+ 60 - 0
src/main/java/com/zswl/dataservicestarter/utils/net/apache/HttpModel.java

@@ -0,0 +1,60 @@
+package com.zswl.dataservicestarter.utils.net.apache;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+
+import java.util.Map;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+@Validated
+public class HttpModel {
+
+
+    /**
+     * Url地址
+     */
+    private String url;
+
+    private String apiName = "";
+
+    public String getUrl() {
+        return url + apiName;
+    }
+
+
+    /**
+     * 网络请求方式
+     */
+    private MethodType method = MethodType.Post;
+
+
+    /**
+     * 请求头
+     */
+    private Map<String, Object> header;
+
+
+    /**
+     * 请求体,仅为post生效
+     */
+    private Object body;
+
+
+    /**
+     * 请求编码
+     */
+    private String charset;
+
+
+    /**
+     * 超时
+     */
+    private Integer timeOut;
+
+}

+ 75 - 0
src/main/java/com/zswl/dataservicestarter/utils/net/apache/JsonUtil.java

@@ -0,0 +1,75 @@
+package com.zswl.dataservicestarter.utils.net.apache;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectWriter;
+import org.springframework.util.StreamUtils;
+
+import java.io.InputStream;
+
+public class JsonUtil {
+    private static ObjectMapper objectMapper = new ObjectMapper();
+
+    /**
+     * 转换到json字符串
+     *
+     * @param object
+     * @return
+     * @throws Exception
+     */
+    public static String toJson(Object object, boolean format) {
+        try {
+            ObjectWriter objectWriter;
+            if (format) {
+                return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
+            } else {
+                return objectMapper.writeValueAsString(object);
+            }
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
+    /**
+     * 转换到json字符串
+     *
+     * @param object
+     * @return
+     */
+    public static String toJson(Object object) {
+        return toJson(object, false);
+    }
+
+
+    /**
+     * 转换为对象
+     *
+     * @param json
+     * @param cls
+     * @return
+     * @throws Exception
+     */
+    public static <T> T toObject(String json, Class<T> cls) throws Exception {
+        return objectMapper.readValue(json, cls);
+    }
+
+    /**
+     * 载入文件到对象
+     *
+     * @param configName
+     * @param cls
+     * @return
+     * @throws Exception
+     */
+    public static <T> T loadToObject(String configName, Class<T> cls) throws Exception {
+        T t = null;
+        InputStream inputStream = JsonUtil.class.getClassLoader().getResourceAsStream(configName);
+        byte[] bin = StreamUtils.copyToByteArray(inputStream);
+        String json = new String(bin, "UTF-8");
+        t = toObject(json, cls);
+        inputStream.close();
+        return t;
+    }
+}

+ 10 - 0
src/main/java/com/zswl/dataservicestarter/utils/net/apache/MethodType.java

@@ -0,0 +1,10 @@
+package com.zswl.dataservicestarter.utils.net.apache;
+
+/**
+ * 方法类型
+ */
+public enum MethodType {
+    Post,
+    Get,
+    Json
+}

+ 40 - 0
src/main/java/com/zswl/dataservicestarter/utils/net/apache/ResponseModel.java

@@ -0,0 +1,40 @@
+package com.zswl.dataservicestarter.utils.net.apache;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Map;
+import java.util.Set;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class ResponseModel {
+
+    /**
+     * 响应编码
+     */
+    private int code;
+
+    public boolean isSuccess() {
+        if (code == 200) {
+            return true;
+        }
+        return false;
+    }
+
+
+    /**
+     * header
+     */
+    private Map<String, Set<Object>> headers;
+
+    /**
+     * body
+     */
+    private Object body;
+
+}

+ 68 - 0
src/main/java/com/zswl/dataservicestarter/utils/net/apache/TextUtil.java

@@ -0,0 +1,68 @@
+package com.zswl.dataservicestarter.utils.net.apache;
+
+/**
+ * 字符串工具集合
+ *
+ * @author 练书锋
+ */
+public class TextUtil {
+
+    /**
+     * 字符串
+     *
+     * @param source
+     * @param startText
+     * @param endText
+     * @return
+     */
+    public static String subText(String source, String startText, String endText, int offSet) {
+        int start = source.indexOf(startText, offSet) + 1;
+        if (start == -1) {
+            return null;
+        }
+        int end = source.indexOf(endText, start + offSet + startText.length() - 1);
+        if (end == -1) {
+            end = source.length();
+        }
+        return source.substring(start + startText.length() - 1, end);
+    }
+
+    /**
+     * 合并字符串数组到字符串,以关键词间隔
+     *
+     * @param arr
+     * @param keyword
+     * @return
+     */
+    public static String join(String[] arr, String keyword) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < arr.length - 1; i++) {
+            sb.append(arr[i]);
+            sb.append(keyword);
+        }
+        if (arr.length > 0) {
+            sb.append(arr[arr.length - 1]);
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * 填充文本
+     *
+     * @param fillText
+     * @param size
+     * @param source
+     * @return
+     */
+    public static String fill(char fillText, int size, Object source) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(String.valueOf(source));
+        while (sb.length() < size) {
+            sb.insert(0, fillText);
+        }
+        return sb.toString();
+    }
+
+
+}

+ 48 - 0
src/main/java/com/zswl/dataservicestarter/utils/net/apache/UrlEncodeUtil.java

@@ -0,0 +1,48 @@
+package com.zswl.dataservicestarter.utils.net.apache;
+
+import lombok.SneakyThrows;
+
+import java.net.URLEncoder;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * URL编码工具
+ */
+public class UrlEncodeUtil {
+
+    private final static String[] NotEncodeCharset = new String[]{
+            ":", "/", "\\", "&", "?", "="
+    };
+    private final static Set<Integer> NotEncodeAscii = Collections.synchronizedSet(new HashSet<>());
+
+    static {
+        for (String s : NotEncodeCharset) {
+            try {
+                NotEncodeAscii.add((int) s.getBytes("UTF-8")[0]);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    @SneakyThrows
+    public static String encode(String url) {
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < url.length(); i++) {
+            String str = url.substring(i, i + 1);
+            int ascii = (int) str.getBytes("UTF-8")[0];
+            // 0 - 9  , A - Z , a = z , ( NotEncodeCharset  )
+            if ((ascii >= 48 && ascii <= 57) || (ascii >= 65 && ascii <= 90) || (ascii >= 97 && ascii <= 122) || (NotEncodeAscii.contains(ascii))) {
+                sb.append(str);
+            } else {
+                sb.append(URLEncoder.encode(str, "UTF-8"));
+            }
+        }
+
+        return sb.toString();
+    }
+
+
+}