diff --git a/hutool-core/src/main/java/cn/hutool/core/io/FileUtil.java b/hutool-core/src/main/java/cn/hutool/core/io/FileUtil.java
index 7b7fda581..219831fdf 100755
--- a/hutool-core/src/main/java/cn/hutool/core/io/FileUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/io/FileUtil.java
@@ -23,6 +23,7 @@ import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.CharsetUtil;
+import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.SystemUtil;
import java.io.BufferedInputStream;
@@ -3144,6 +3145,17 @@ public class FileUtil extends PathUtil {
return file;
}
+ /**
+ * 根据文件扩展名获得MimeType
+ *
+ * @param filePath 文件路径或文件名
+ * @param defaultValue 当获取MimeType为null时的默认值
+ * @return MimeType
+ */
+ public static String getMimeType(final String filePath, final String defaultValue) {
+ return ObjUtil.defaultIfNull(getMimeType(filePath), defaultValue);
+ }
+
/**
* 根据文件扩展名获得MimeType
*
diff --git a/hutool-http/src/main/java/cn/hutool/http/HttpUtil.java b/hutool-http/src/main/java/cn/hutool/http/HttpUtil.java
index 9fd7e52fb..6b97ecb01 100755
--- a/hutool-http/src/main/java/cn/hutool/http/HttpUtil.java
+++ b/hutool-http/src/main/java/cn/hutool/http/HttpUtil.java
@@ -1,28 +1,17 @@
package cn.hutool.http;
import cn.hutool.core.codec.BaseN.Base64;
-import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.io.IoUtil;
import cn.hutool.core.net.url.UrlQueryUtil;
-import cn.hutool.core.regex.ReUtil;
import cn.hutool.core.text.StrUtil;
-import cn.hutool.core.util.CharsetUtil;
-import cn.hutool.core.util.ObjUtil;
import cn.hutool.http.client.ClientConfig;
import cn.hutool.http.client.Request;
import cn.hutool.http.client.Response;
-import cn.hutool.http.client.cookie.GlobalCookieManager;
import cn.hutool.http.client.engine.ClientEngineFactory;
-import cn.hutool.http.meta.ContentType;
import cn.hutool.http.meta.Method;
import cn.hutool.http.server.SimpleServer;
-import java.io.InputStream;
-import java.net.CookieManager;
-import java.net.HttpURLConnection;
import java.nio.charset.Charset;
import java.util.Map;
-import java.util.regex.Pattern;
/**
* Http请求工具类
@@ -31,15 +20,6 @@ import java.util.regex.Pattern;
*/
public class HttpUtil {
- /**
- * 正则:Content-Type中的编码信息
- */
- public static final Pattern CHARSET_PATTERN = Pattern.compile("charset\\s*=\\s*([a-z0-9-]*)", Pattern.CASE_INSENSITIVE);
- /**
- * 正则:匹配meta标签的编码信息
- */
- public static final Pattern META_CHARSET_PATTERN = Pattern.compile("]*?charset\\s*=\\s*['\"]?([a-z0-9-]*)", Pattern.CASE_INSENSITIVE);
-
/**
* 检测是否https
*
@@ -215,143 +195,6 @@ public class HttpUtil {
return urlBuilder.toString();
}
- /**
- * 从Http连接的头信息中获得字符集
- * 从ContentType中获取
- *
- * @param conn HTTP连接对象
- * @return 字符集
- */
- public static Charset getCharset(final HttpURLConnection conn) {
- if (conn == null) {
- return null;
- }
- return getCharset(conn.getContentType());
- }
-
- /**
- * 从Http连接的头信息中获得字符集
- * 从ContentType中获取
- *
- * @param contentType Content-Type
- * @return 字符集
- * @since 5.2.6
- */
- public static Charset getCharset(final String contentType) {
- return CharsetUtil.parse(getCharsetName(contentType), null);
- }
-
- /**
- * 从Http连接的头信息中获得字符集
- * 从ContentType中获取
- *
- * @param contentType Content-Type
- * @return 字符集
- * @since 5.2.6
- */
- public static String getCharsetName(final String contentType) {
- if (StrUtil.isBlank(contentType)) {
- return null;
- }
- return ReUtil.get(CHARSET_PATTERN, contentType, 1);
- }
-
- /**
- * 从流中读取内容
- * 首先尝试使用charset编码读取内容(如果为空默认UTF-8),如果isGetCharsetFromContent为true,则通过正则在正文中获取编码信息,转换为指定编码;
- *
- * @param in 输入流
- * @param charset 字符集
- * @param isGetCharsetFromContent 是否从返回内容中获得编码信息
- * @return 内容
- */
- public static String getString(final InputStream in, final Charset charset, final boolean isGetCharsetFromContent) {
- final byte[] contentBytes = IoUtil.readBytes(in);
- return getString(contentBytes, charset, isGetCharsetFromContent);
- }
-
- /**
- * 从流中读取内容
- * 首先尝试使用charset编码读取内容(如果为空默认UTF-8),如果isGetCharsetFromContent为true,则通过正则在正文中获取编码信息,转换为指定编码;
- *
- * @param contentBytes 内容byte数组
- * @param charset 字符集
- * @param isGetCharsetFromContent 是否从返回内容中获得编码信息
- * @return 内容
- */
- public static String getString(final byte[] contentBytes, Charset charset, final boolean isGetCharsetFromContent) {
- if (null == contentBytes) {
- return null;
- }
-
- if (null == charset) {
- charset = CharsetUtil.UTF_8;
- }
- String content = new String(contentBytes, charset);
- if (isGetCharsetFromContent) {
- final String charsetInContentStr = ReUtil.get(META_CHARSET_PATTERN, content, 1);
- if (StrUtil.isNotBlank(charsetInContentStr)) {
- Charset charsetInContent = null;
- try {
- charsetInContent = Charset.forName(charsetInContentStr);
- } catch (final Exception e) {
- if (StrUtil.containsIgnoreCase(charsetInContentStr, "utf-8") || StrUtil.containsIgnoreCase(charsetInContentStr, "utf8")) {
- charsetInContent = CharsetUtil.UTF_8;
- } else if (StrUtil.containsIgnoreCase(charsetInContentStr, "gbk")) {
- charsetInContent = CharsetUtil.GBK;
- }
- // ignore
- }
- if (null != charsetInContent && false == charset.equals(charsetInContent)) {
- content = new String(contentBytes, charsetInContent);
- }
- }
- }
- return content;
- }
-
- /**
- * 根据文件扩展名获得MimeType
- *
- * @param filePath 文件路径或文件名
- * @param defaultValue 当获取MimeType为null时的默认值
- * @return MimeType
- * @see FileUtil#getMimeType(String)
- * @since 4.6.5
- */
- public static String getMimeType(final String filePath, final String defaultValue) {
- return ObjUtil.defaultIfNull(getMimeType(filePath), defaultValue);
- }
-
- /**
- * 根据文件扩展名获得MimeType
- *
- * @param filePath 文件路径或文件名
- * @return MimeType
- * @see FileUtil#getMimeType(String)
- */
- public static String getMimeType(final String filePath) {
- return FileUtil.getMimeType(filePath);
- }
-
- /**
- * 从请求参数的body中判断请求的Content-Type类型,支持的类型有:
- *
- *
- * 1. application/json - * 1. application/xml - *- * - * @param body 请求参数体 - * @return Content-Type类型,如果无法判断返回null - * @see ContentType#get(String) - * @since 3.2.0 - */ - public static String getContentTypeByRequestBody(final String body) { - final ContentType contentType = ContentType.get(body); - return (null == contentType) ? null : contentType.toString(); - } - /** * 创建简易的Http服务器 * @@ -379,14 +222,4 @@ public class HttpUtil { final String data = username.concat(":").concat(password); return "Basic " + Base64.encode(data, charset); } - - /** - * 关闭Cookie - * - * @see GlobalCookieManager#setCookieManager(CookieManager) - * @since 5.6.5 - */ - public static void closeCookie() { - GlobalCookieManager.setCookieManager(null); - } } diff --git a/hutool-http/src/main/java/cn/hutool/http/client/Response.java b/hutool-http/src/main/java/cn/hutool/http/client/Response.java index 39586c476..991857ff7 100755 --- a/hutool-http/src/main/java/cn/hutool/http/client/Response.java +++ b/hutool-http/src/main/java/cn/hutool/http/client/Response.java @@ -3,8 +3,9 @@ package cn.hutool.http.client; import cn.hutool.core.convert.Convert; import cn.hutool.core.text.StrUtil; import cn.hutool.http.HttpException; -import cn.hutool.http.HttpUtil; import cn.hutool.http.client.body.ResponseBody; +import cn.hutool.http.html.HtmlUtil; +import cn.hutool.http.meta.ContentTypeUtil; import cn.hutool.http.meta.Header; import java.io.Closeable; @@ -51,7 +52,7 @@ public interface Response extends Closeable { * @return 字符集 */ default Charset charset() { - return HttpUtil.getCharset(header(Header.CONTENT_TYPE)); + return ContentTypeUtil.getCharset(header(Header.CONTENT_TYPE)); } /** @@ -78,7 +79,7 @@ public interface Response extends Closeable { * @throws HttpException 包装IO异常 */ default String bodyStr() throws HttpException { - return HttpUtil.getString(bodyBytes(), charset(), true); + return HtmlUtil.getString(bodyBytes(), charset(), true); } /** diff --git a/hutool-http/src/main/java/cn/hutool/http/client/body/MultipartOutputStream.java b/hutool-http/src/main/java/cn/hutool/http/client/body/MultipartOutputStream.java index 795a84ab0..ceb99425f 100644 --- a/hutool-http/src/main/java/cn/hutool/http/client/body/MultipartOutputStream.java +++ b/hutool-http/src/main/java/cn/hutool/http/client/body/MultipartOutputStream.java @@ -1,16 +1,16 @@ package cn.hutool.http.client.body; import cn.hutool.core.convert.Convert; +import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IoUtil; +import cn.hutool.core.io.resource.HttpResource; import cn.hutool.core.io.resource.MultiResource; import cn.hutool.core.io.resource.Resource; import cn.hutool.core.io.resource.StringResource; import cn.hutool.core.text.StrUtil; -import cn.hutool.http.meta.ContentType; import cn.hutool.http.HttpGlobalConfig; -import cn.hutool.core.io.resource.HttpResource; -import cn.hutool.http.HttpUtil; +import cn.hutool.http.meta.ContentType; import java.io.IOException; import java.io.OutputStream; @@ -159,7 +159,7 @@ public class MultipartOutputStream extends OutputStream { } else if (StrUtil.isNotEmpty(fileName)) { // 根据name的扩展名指定互联网媒体类型,默认二进制流数据 write(StrUtil.format(CONTENT_TYPE_FILE_TEMPLATE, - HttpUtil.getMimeType(fileName, ContentType.OCTET_STREAM.getValue()))); + FileUtil.getMimeType(fileName, ContentType.OCTET_STREAM.getValue()))); } // 内容 diff --git a/hutool-http/src/main/java/cn/hutool/http/client/body/StringBody.java b/hutool-http/src/main/java/cn/hutool/http/client/body/StringBody.java index c83ab718e..bf3d38f52 100755 --- a/hutool-http/src/main/java/cn/hutool/http/client/body/StringBody.java +++ b/hutool-http/src/main/java/cn/hutool/http/client/body/StringBody.java @@ -2,7 +2,7 @@ package cn.hutool.http.client.body; import cn.hutool.core.io.resource.HttpResource; import cn.hutool.core.io.resource.StringResource; -import cn.hutool.http.HttpUtil; +import cn.hutool.http.meta.ContentTypeUtil; import java.nio.charset.Charset; @@ -20,7 +20,7 @@ public class StringBody extends ResourceBody { * @param charset 自定义编码 */ public StringBody(final String body, final Charset charset) { - this(body, HttpUtil.getContentTypeByRequestBody(body), charset); + this(body, ContentTypeUtil.getContentTypeByRequestBody(body), charset); } /** diff --git a/hutool-http/src/main/java/cn/hutool/http/client/cookie/GlobalCookieManager.java b/hutool-http/src/main/java/cn/hutool/http/client/cookie/GlobalCookieManager.java index 9b53a5014..d48de5e7c 100644 --- a/hutool-http/src/main/java/cn/hutool/http/client/cookie/GlobalCookieManager.java +++ b/hutool-http/src/main/java/cn/hutool/http/client/cookie/GlobalCookieManager.java @@ -28,6 +28,16 @@ public class GlobalCookieManager { cookieManager = new CookieManager(new ThreadLocalCookieStore(), CookiePolicy.ACCEPT_ALL); } + /** + * 关闭Cookie + * + * @see GlobalCookieManager#setCookieManager(CookieManager) + * @since 5.6.5 + */ + public static void closeCookie() { + setCookieManager(null); + } + /** * 自定义{@link CookieManager} * diff --git a/hutool-http/src/main/java/cn/hutool/http/html/HtmlUtil.java b/hutool-http/src/main/java/cn/hutool/http/html/HtmlUtil.java index 2c1e70de6..f381c4c97 100755 --- a/hutool-http/src/main/java/cn/hutool/http/html/HtmlUtil.java +++ b/hutool-http/src/main/java/cn/hutool/http/html/HtmlUtil.java @@ -1,10 +1,14 @@ package cn.hutool.http.html; +import cn.hutool.core.io.IoUtil; import cn.hutool.core.regex.ReUtil; import cn.hutool.core.text.StrUtil; import cn.hutool.core.text.escape.EscapeUtil; +import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.XmlUtil; +import java.io.InputStream; +import java.nio.charset.Charset; import java.util.regex.Pattern; /** @@ -26,6 +30,10 @@ public class HtmlUtil { * script标签正则 */ public static final Pattern RE_SCRIPT = Pattern.compile("<[\\s]*?script[^>]*?>.*?<[\\s]*?\\/[\\s]*?script[\\s]*?>", Pattern.CASE_INSENSITIVE); + /** + * 正则:匹配meta标签的编码信息 + */ + public static final Pattern META_CHARSET_PATTERN = Pattern.compile("]*?charset\\s*=\\s*['\"]?([a-z0-9-]*)", Pattern.CASE_INSENSITIVE); private static final char[][] TEXT = new char[256][]; @@ -222,4 +230,58 @@ public class HtmlUtil { public static String filter(final String htmlContent) { return new HTMLFilter().filter(htmlContent); } + + /** + * 从流中读取内容
+ * 1. application/json + * 1. application/xml + *+ * + * @param body 请求参数体 + * @return Content-Type类型,如果无法判断返回null + * @see ContentType#get(String) + * @since 3.2.0 + */ + public static String getContentTypeByRequestBody(final String body) { + final ContentType contentType = ContentType.get(body); + return (null == contentType) ? null : contentType.toString(); + } +} diff --git a/hutool-http/src/main/java/cn/hutool/http/server/HttpServerRequest.java b/hutool-http/src/main/java/cn/hutool/http/server/HttpServerRequest.java index 12deeb661..ef1f0b892 100644 --- a/hutool-http/src/main/java/cn/hutool/http/server/HttpServerRequest.java +++ b/hutool-http/src/main/java/cn/hutool/http/server/HttpServerRequest.java @@ -13,8 +13,8 @@ import cn.hutool.core.text.StrUtil; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.ObjUtil; +import cn.hutool.http.meta.ContentTypeUtil; import cn.hutool.http.meta.Header; -import cn.hutool.http.HttpUtil; import cn.hutool.http.meta.Method; import cn.hutool.http.useragent.UserAgent; import cn.hutool.http.useragent.UserAgentUtil; @@ -171,7 +171,7 @@ public class HttpServerRequest extends HttpServerBase { public Charset getCharset() { if(null == this.charsetCache){ final String contentType = getContentType(); - this.charsetCache = ObjUtil.defaultIfNull(HttpUtil.getCharset(contentType), DEFAULT_CHARSET); + this.charsetCache = ObjUtil.defaultIfNull(ContentTypeUtil.getCharset(contentType), DEFAULT_CHARSET); } return this.charsetCache; diff --git a/hutool-http/src/main/java/cn/hutool/http/server/HttpServerResponse.java b/hutool-http/src/main/java/cn/hutool/http/server/HttpServerResponse.java index a3250f3aa..ff04da7ac 100644 --- a/hutool-http/src/main/java/cn/hutool/http/server/HttpServerResponse.java +++ b/hutool-http/src/main/java/cn/hutool/http/server/HttpServerResponse.java @@ -4,12 +4,11 @@ import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IoUtil; import cn.hutool.core.net.url.URLEncoder; -import cn.hutool.core.util.ObjUtil; import cn.hutool.core.text.StrUtil; +import cn.hutool.core.util.ObjUtil; import cn.hutool.http.meta.ContentType; import cn.hutool.http.meta.Header; import cn.hutool.http.meta.HttpStatus; -import cn.hutool.http.HttpUtil; import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; @@ -391,7 +390,7 @@ public class HttpServerResponse extends HttpServerBase { if(StrUtil.isBlank(fileName)){ fileName = file.getName(); } - final String contentType = ObjUtil.defaultIfNull(HttpUtil.getMimeType(fileName), "application/octet-stream"); + final String contentType = FileUtil.getMimeType(fileName, ContentType.OCTET_STREAM.getValue()); BufferedInputStream in = null; try { in = FileUtil.getInputStream(file); diff --git a/hutool-http/src/test/java/cn/hutool/http/HtmlUtilTest.java b/hutool-http/src/test/java/cn/hutool/http/HtmlUtilTest.java index 1f2c14bc8..7242ba526 100644 --- a/hutool-http/src/test/java/cn/hutool/http/HtmlUtilTest.java +++ b/hutool-http/src/test/java/cn/hutool/http/HtmlUtilTest.java @@ -1,6 +1,8 @@ package cn.hutool.http; +import cn.hutool.core.regex.ReUtil; import cn.hutool.http.html.HtmlUtil; +import cn.hutool.http.meta.ContentTypeUtil; import org.junit.Assert; import org.junit.Test; @@ -182,4 +184,19 @@ public class HtmlUtilTest { final String result = HtmlUtil.removeAllHtmlAttr(html, "div"); Assert.assertEquals("", result); } + + @Test + public void getCharsetTest() { + String charsetName = ReUtil.get(ContentTypeUtil.CHARSET_PATTERN, "Charset=UTF-8;fq=0.9", 1); + Assert.assertEquals("UTF-8", charsetName); + + charsetName = ReUtil.get(HtmlUtil.META_CHARSET_PATTERN, "