diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java index 3e0acb46f..11b120946 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java @@ -6,6 +6,12 @@ import okhttp3.Response; import org.apache.http.Header; import org.apache.http.client.methods.CloseableHttpResponse; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** *
  * 三种http框架的response代理类,方便提取公共方法
@@ -56,29 +62,42 @@ public class HttpResponseProxy {
       throw new WxErrorException("无法获取到文件名,Content-disposition为空");
     }
 
-    return this.extractFileNameFromContentString(contentDispositionHeader[0].getValue());
+    return extractFileNameFromContentString(contentDispositionHeader[0].getValue());
   }
 
   private String getFileName(HttpResponse response) throws WxErrorException {
     String content = response.header("Content-disposition");
-    return this.extractFileNameFromContentString(content);
+    return extractFileNameFromContentString(content);
   }
 
   private String getFileName(Response response) throws WxErrorException {
     String content = response.header("Content-disposition");
-    return this.extractFileNameFromContentString(content);
+    return extractFileNameFromContentString(content);
   }
 
-  private String extractFileNameFromContentString(String content) throws WxErrorException {
-    if (content == null || content.length() == 0) {
+  public static String extractFileNameFromContentString(String content) throws WxErrorException {
+    if (content == null || content.isEmpty()) {
       throw new WxErrorException("无法获取到文件名,content为空");
     }
 
-    int startIndex = content.indexOf("filename=\"");
-    if (startIndex != -1) {
-      startIndex += "filename=\"".length();
-      int endIndex = content.indexOf('"', startIndex);
-      return content.substring(startIndex, endIndex);
+    // 查找filename*=utf-8''开头的部分
+    Pattern pattern = Pattern.compile("filename\\*=utf-8''(.*?)($|;|\\s|,)");
+    Matcher matcher = pattern.matcher(content);
+    if (matcher.find()) {
+      String encodedFileName = matcher.group(1);
+      // 解码URL编码的文件名
+      try {
+        return URLDecoder.decode(encodedFileName, StandardCharsets.UTF_8.name());
+      } catch (UnsupportedEncodingException e) {
+        throw new RuntimeException(e);
+      }
+    }
+
+    // 查找普通filename="..."部分
+    pattern = Pattern.compile("filename=\"(.*?)\"");
+    matcher = pattern.matcher(content);
+    if (matcher.find()) {
+      return new String(matcher.group(1).getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
     }
 
     throw new WxErrorException("无法获取到文件名,header信息有问题");
diff --git a/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/http/HttpResponseProxyTest.java b/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/http/HttpResponseProxyTest.java
new file mode 100644
index 000000000..4d188b50b
--- /dev/null
+++ b/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/http/HttpResponseProxyTest.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.common.util.http;
+
+import me.chanjar.weixin.common.error.WxErrorException;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+public class HttpResponseProxyTest {
+
+  @Test
+  public void testExtractFileNameFromContentString() throws WxErrorException {
+    String content = "attachment; filename*=utf-8''%E6%B5%8B%E8%AF%95.xlsx; filename=\"��.xlsx\"";
+    String filename = HttpResponseProxy.extractFileNameFromContentString(content);
+    assertNotNull(filename);
+    assertEquals(filename, "测试.xlsx");
+  }
+
+  @Test
+  public void testExtractFileNameFromContentString_another() throws WxErrorException {
+    String content = "attachment; filename*=utf-8''%E8%90%A5%E4%B8%9A%E6%89%A7%E7%85%A7.jpg; filename=\"����.jpg\"";
+//    String content = "attachment; filename=\"����.jpg\"";
+    String filename = HttpResponseProxy.extractFileNameFromContentString(content);
+    assertNotNull(filename);
+    assertEquals(filename, "营业执照.jpg");
+  }
+}