diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java index 29c27fecd..a9092e2fd 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java @@ -1,14 +1,11 @@ package com.github.binarywang.wxpay.config; import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.util.ResourcesUtils; import com.github.binarywang.wxpay.v3.WxPayV3HttpClientBuilder; import com.github.binarywang.wxpay.v3.auth.*; import com.github.binarywang.wxpay.v3.util.PemUtils; -import jodd.util.ResourcesUtil; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.SneakyThrows; -import lombok.ToString; +import lombok.*; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RegExUtils; import org.apache.commons.lang3.StringUtils; @@ -239,10 +236,10 @@ public class WxPayConfig { * @author doger.wang **/ public CloseableHttpClient initApiV3HttpClient() throws WxPayException { - String privateKeyPath = this.getPrivateKeyPath(); - String privateCertPath = this.getPrivateCertPath(); - String serialNo = this.getCertSerialNo(); - String apiV3Key = this.getApiV3Key(); + val privateKeyPath = this.getPrivateKeyPath(); + val privateCertPath = this.getPrivateCertPath(); + val serialNo = this.getCertSerialNo(); + val apiV3Key = this.getApiV3Key(); if (StringUtils.isBlank(privateKeyPath)) { throw new WxPayException("请确保privateKeyPath已设置"); } @@ -301,7 +298,7 @@ public class WxPayConfig { path = "/" + path; } try { - inputStream = ResourcesUtil.getResourceAsStream(path); + inputStream = ResourcesUtils.getResourceAsStream(path); if (inputStream == null) { throw new WxPayException(fileNotFoundMsg); } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/ResourcesUtils.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/ResourcesUtils.java new file mode 100644 index 000000000..3a9e78855 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/ResourcesUtils.java @@ -0,0 +1,120 @@ +package com.github.binarywang.wxpay.util; + +import jodd.io.IOUtil; +import jodd.util.ClassUtil; +import lombok.val; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; + +/** + * 基于jodd.util.ResourcesUtil改造实现 + * @author jodd + */ +public class ResourcesUtils { + + /** + * Retrieves given resource as URL. + * @see #getResourceUrl(String, ClassLoader) + */ + public static URL getResourceUrl(final String resourceName) { + return getResourceUrl(resourceName, null); + } + + /** + * Retrieves given resource as URL. Resource is always absolute and may + * starts with a slash character. + *

+ * Resource will be loaded using class loaders in the following order: + *

+ */ + public static URL getResourceUrl(String resourceName, final ClassLoader classLoader) { + + if (resourceName.startsWith("/")) { + resourceName = resourceName.substring(1); + } + + URL resourceUrl; + + // try #1 - using provided class loader + if (classLoader != null) { + resourceUrl = classLoader.getResource(resourceName); + if (resourceUrl != null) { + return resourceUrl; + } + } + + // try #2 - using thread class loader + final ClassLoader currentThreadClassLoader = Thread.currentThread().getContextClassLoader(); + if ((currentThreadClassLoader != null) && (currentThreadClassLoader != classLoader)) { + resourceUrl = currentThreadClassLoader.getResource(resourceName); + if (resourceUrl != null) { + return resourceUrl; + } + } + + // try #3 - using caller classloader, similar as Class.forName() + val callerClass = ClassUtil.getCallerClass(2); + val callerClassLoader = callerClass.getClassLoader(); + + if ((callerClassLoader != classLoader) && (callerClassLoader != currentThreadClassLoader)) { + resourceUrl = callerClassLoader.getResource(resourceName); + return resourceUrl; + } + + return null; + } + + public static String getResourceAsString(final String resourceName) throws IOException { + final InputStream inputStream = getResourceAsStream(resourceName); + try { + final char[] data = IOUtil.readChars(inputStream); + return new String(data); + } + finally { + IOUtil.close(inputStream); + } + } + + /** + * Opens a resource of the specified name for reading. + * @see #getResourceAsStream(String, ClassLoader) + */ + public static InputStream getResourceAsStream(final String resourceName) throws IOException { + return getResourceAsStream(resourceName, null); + } + + /** + * Opens a resource of the specified name for reading. + * @see #getResourceUrl(String, ClassLoader) + */ + public static InputStream getResourceAsStream(final String resourceName, final ClassLoader callingClass) throws IOException { + final URL url = getResourceUrl(resourceName, callingClass); + if (url != null) { + return url.openStream(); + } + return null; + } + + /** + * Opens a resource of the specified name for reading. Controls caching, + * that is important when the same jar is reloaded using custom classloader. + */ + public static InputStream getResourceAsStream(final String resourceName, final ClassLoader callingClass, + final boolean useCache) throws IOException { + final URL url = getResourceUrl(resourceName, callingClass); + if (url != null) { + final URLConnection urlConnection = url.openConnection(); + urlConnection.setUseCaches(useCache); + return urlConnection.getInputStream(); + } + return null; + } + +}