From c9a180abce0117b926a1e10aa8a1edc13ea71e23 Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 7 Jan 2021 17:43:19 +0800 Subject: [PATCH] fix bug for #1358 --- CHANGELOG.md | 1 + .../http/server/HttpServerResponse.java | 73 ++++++++++++++++--- .../hutool/http/server/SimpleServerTest.java | 6 +- .../java/cn/hutool/json/JSONUtilTest.java | 9 +++ 4 files changed, 76 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d44a4d0e..78f6d9d03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ ### Bug修复 * 【core 】 修复CsvReader读取双引号未转义问题(issur#I2BMP1@Gitee) * 【json 】 JSONUtil.parse修复config无效问题(issur#1363@Github) +* 【http 】 修复SimpleServer返回响应内容Content-Lenth不正确的问题(issur#1358@Github) ------------------------------------------------------------------------------------------------------------- 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 848250d15..fe19c206f 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 @@ -46,7 +46,7 @@ public class HttpServerResponse extends HttpServerBase { } /** - * 发送HTTP状态码 + * 发送HTTP状态码,Content-Length为0不定长度,会输出Transfer-encoding: chunked * * @param httpStatusCode HTTP状态码,见HttpStatus * @return this @@ -64,6 +64,17 @@ public class HttpServerResponse extends HttpServerBase { return send(HttpStatus.HTTP_OK); } + /** + * 发送成功状态码 + * + * @param bodyLength 响应体长度,默认0表示不定长度,会输出Transfer-encoding: chunked + * @return this + * @since 5.5.7 + */ + public HttpServerResponse sendOk(int bodyLength) { + return send(HttpStatus.HTTP_OK, bodyLength); + } + /** * 发送404错误页 * @@ -91,7 +102,7 @@ public class HttpServerResponse extends HttpServerBase { * 发送HTTP状态码 * * @param httpStatusCode HTTP状态码,见HttpStatus - * @param bodyLength 响应体长度,默认0 + * @param bodyLength 响应体长度,默认0表示不定长度,会输出Transfer-encoding: chunked * @return this */ public HttpServerResponse send(int httpStatusCode, long bodyLength) { @@ -290,7 +301,8 @@ public class HttpServerResponse extends HttpServerBase { * @return this */ public HttpServerResponse write(byte[] data) { - return write(new ByteArrayInputStream(data)); + final ByteArrayInputStream in = new ByteArrayInputStream(data); + return write(in, in.available()); } /** @@ -302,8 +314,21 @@ public class HttpServerResponse extends HttpServerBase { * @since 5.2.6 */ public HttpServerResponse write(InputStream in, String contentType) { + return write(in, 0, contentType); + } + + /** + * 返回数据给客户端 + * + * @param in 需要返回客户端的内容 + * @param length 内容长度,默认0表示不定长度,会输出Transfer-encoding: chunked + * @param contentType 返回的类型 + * @return this + * @since 5.2.7 + */ + public HttpServerResponse write(InputStream in, int length, String contentType) { setContentType(contentType); - return write(in); + return write(in, length); } /** @@ -313,9 +338,23 @@ public class HttpServerResponse extends HttpServerBase { * @return this */ public HttpServerResponse write(InputStream in) { + return write(in, 0); + } + + /** + * 写出数据到客户端 + * + * @param in 数据流 + * @param length 指定响应内容长度,默认0表示不定长度,会输出Transfer-encoding: chunked + * @return this + */ + public HttpServerResponse write(InputStream in, int length) { + if (false == isSendCode) { + sendOk(Math.max(0, length)); + } OutputStream out = null; try { - out = getOut(); + out = this.httpExchange.getResponseBody(); IoUtil.copy(in, out); } finally { IoUtil.close(out); @@ -332,12 +371,16 @@ public class HttpServerResponse extends HttpServerBase { * @since 5.2.6 */ public HttpServerResponse write(File file) { + final long fileSize = file.length(); + if(fileSize > Integer.MAX_VALUE){ + throw new IllegalArgumentException("File size is too bigger than " + Integer.MAX_VALUE); + } final String fileName = file.getName(); final String contentType = ObjectUtil.defaultIfNull(HttpUtil.getMimeType(fileName), "application/octet-stream"); BufferedInputStream in = null; try { in = FileUtil.getInputStream(file); - write(in, contentType, fileName); + write(in, (int)fileSize, contentType, fileName); } finally { IoUtil.close(in); } @@ -352,13 +395,25 @@ public class HttpServerResponse extends HttpServerBase { * @param fileName 文件名 * @since 5.2.6 */ - public void write(InputStream in, String contentType, String fileName) { + public void write(InputStream in, String contentType, String fileName) { + write(in, 0, contentType, fileName); + } + + /** + * 返回文件数据给客户端(文件下载) + * + * @param in 需要返回客户端的内容 + * @param contentType 返回的类型 + * @param fileName 文件名 + * @since 5.2.7 + */ + public HttpServerResponse write(InputStream in, int length, String contentType, String fileName) { final Charset charset = ObjectUtil.defaultIfNull(this.charset, DEFAULT_CHARSET); - if(false == contentType.startsWith("text/")){ + if (false == contentType.startsWith("text/")) { // 非文本类型数据直接走下载 setHeader(Header.CONTENT_DISPOSITION, StrUtil.format("attachment;filename={}", URLUtil.encode(fileName, charset))); } - write(in, contentType); + return write(in, length, contentType); } } diff --git a/hutool-http/src/test/java/cn/hutool/http/server/SimpleServerTest.java b/hutool-http/src/test/java/cn/hutool/http/server/SimpleServerTest.java index fc06d0db8..a16c96a1a 100644 --- a/hutool-http/src/test/java/cn/hutool/http/server/SimpleServerTest.java +++ b/hutool-http/src/test/java/cn/hutool/http/server/SimpleServerTest.java @@ -45,10 +45,8 @@ public class SimpleServerTest { response.write(request.getMultipart().getParamMap().toString(), ContentType.TEXT_PLAIN.toString()); } ) - .addAction("test/zeroStr", (req, res)->{ - res.addHeader("Content-Length", "0".length() + ""); - res.write("0"); - }) + // 测试输出响应内容是否能正常返回Content-Length头信息 + .addAction("test/zeroStr", (req, res)-> res.write("0")) .start(); } } diff --git a/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java b/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java index 4d599d1c0..9dcd583cc 100644 --- a/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java +++ b/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java @@ -10,6 +10,7 @@ import cn.hutool.json.test.bean.UserC; import org.junit.Assert; import org.junit.Test; +import java.math.BigInteger; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -163,6 +164,14 @@ public class JSONUtilTest { Assert.assertEquals("12.00", jsonObject.getBigDecimal("test").setScale(2).toString()); } + @Test + public void doubleTest2() { + String json = "{\"test\": 12.00}"; + final JSONObject jsonObject = JSONUtil.parseObj(json); + jsonObject.set("test2", new BigInteger("12")); + Console.log(jsonObject); + } + @Test public void parseObjTest() { // 测试转义