From a8c2c738d3518d8f2d52f24fd97d384fd04e0678 Mon Sep 17 00:00:00 2001 From: datagear Date: Thu, 3 Sep 2020 15:05:51 +0800 Subject: [PATCH] =?UTF-8?q?[analysis]=E5=AE=8C=E5=96=84HttpDataSet?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../support/AbstractCsvFileDataSet.java | 6 +- .../support/AbstractJsonFileDataSet.java | 6 +- .../analysis/support/HttpDataSet.java | 134 ++++++-- .../support/html/HtmlChartPluginLoader.java | 2 +- .../analysis/support/HttpDataSetTest.java | 294 ++++++++++++++++-- .../main/java/org/datagear/util/IOUtil.java | 31 +- 6 files changed, 404 insertions(+), 69 deletions(-) diff --git a/datagear-analysis/src/main/java/org/datagear/analysis/support/AbstractCsvFileDataSet.java b/datagear-analysis/src/main/java/org/datagear/analysis/support/AbstractCsvFileDataSet.java index 58b5ad26..060ab139 100644 --- a/datagear-analysis/src/main/java/org/datagear/analysis/support/AbstractCsvFileDataSet.java +++ b/datagear-analysis/src/main/java/org/datagear/analysis/support/AbstractCsvFileDataSet.java @@ -26,10 +26,8 @@ import org.datagear.util.IOUtil; */ public abstract class AbstractCsvFileDataSet extends AbstractCsvDataSet { - public static final String DEFAULT_ENCODING = "UTF-8"; - /** 文件编码 */ - private String encoding = DEFAULT_ENCODING; + private String encoding = IOUtil.CHARSET_UTF_8; public AbstractCsvFileDataSet() { @@ -60,7 +58,7 @@ public abstract class AbstractCsvFileDataSet extends AbstractCsvDataSet protected TemplateResolvedSource getCsvReader(Map paramValues) throws Throwable { File file = getCsvFile(paramValues); - return new TemplateResolvedSource(IOUtil.getReader(file, this.encoding)); + return new TemplateResolvedSource<>(IOUtil.getReader(file, this.encoding)); } /** diff --git a/datagear-analysis/src/main/java/org/datagear/analysis/support/AbstractJsonFileDataSet.java b/datagear-analysis/src/main/java/org/datagear/analysis/support/AbstractJsonFileDataSet.java index 0a29b992..cf849c21 100644 --- a/datagear-analysis/src/main/java/org/datagear/analysis/support/AbstractJsonFileDataSet.java +++ b/datagear-analysis/src/main/java/org/datagear/analysis/support/AbstractJsonFileDataSet.java @@ -27,10 +27,8 @@ import org.datagear.util.IOUtil; */ public abstract class AbstractJsonFileDataSet extends AbstractJsonDataSet { - public static final String DEFAULT_ENCODING = "UTF-8"; - /** 文件编码 */ - private String encoding = DEFAULT_ENCODING; + private String encoding = IOUtil.CHARSET_UTF_8; public AbstractJsonFileDataSet() { @@ -61,7 +59,7 @@ public abstract class AbstractJsonFileDataSet extends AbstractJsonDataSet protected TemplateResolvedSource getJsonReader(Map paramValues) throws Throwable { File file = getJsonFile(paramValues); - return new TemplateResolvedSource(IOUtil.getReader(file, this.encoding)); + return new TemplateResolvedSource<>(IOUtil.getReader(file, this.encoding)); } /** diff --git a/datagear-analysis/src/main/java/org/datagear/analysis/support/HttpDataSet.java b/datagear-analysis/src/main/java/org/datagear/analysis/support/HttpDataSet.java index 6bc7b770..6d69f010 100644 --- a/datagear-analysis/src/main/java/org/datagear/analysis/support/HttpDataSet.java +++ b/datagear-analysis/src/main/java/org/datagear/analysis/support/HttpDataSet.java @@ -8,7 +8,6 @@ package org.datagear.analysis.support; import java.io.IOException; -import java.io.InputStreamReader; import java.io.Reader; import java.io.Serializable; import java.nio.charset.Charset; @@ -45,13 +44,15 @@ import org.datagear.analysis.DataSetResult; import org.datagear.analysis.ResolvedDataSetResult; import org.datagear.util.IOUtil; import org.datagear.util.StringUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.fasterxml.jackson.databind.ObjectMapper; /** * HTTP数据集。 *

- * 此类的{@linkplain #getUri()}、{@linkplain #getRequestContent()}支持Freemarker模板语言。 + * 此类的{@linkplain #getUri()}、{@linkplain #getHeaderContent()}、{@linkplain #getRequestContent()}支持Freemarker模板语言。 *

* * @author datagear@163.com @@ -59,6 +60,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; */ public class HttpDataSet extends AbstractResolvableDataSet { + protected static final Logger LOGGER = LoggerFactory.getLogger(HttpDataSet.class); + public static final String HTTP_METHOD_GET = "GET"; public static final String HTTP_METHOD_POST = "POST"; @@ -94,13 +97,15 @@ public class HttpDataSet extends AbstractResolvableDataSet /** 请求方法 */ private String httpMethod = HTTP_METHOD_GET; - /** 请求头 */ - @SuppressWarnings("unchecked") - private List headers = Collections.EMPTY_LIST; + /** 请求头JSON文本 */ + private String headerContent = ""; /** 请求内容类型 */ private String requestContentType = CONTENT_TYPE_FORM; + /** 请求内容编码 */ + private String requestContentCharset = IOUtil.CHARSET_UTF_8; + /** 请求内容JSON文本 */ private String requestContent = ""; @@ -169,14 +174,30 @@ public class HttpDataSet extends AbstractResolvableDataSet this.httpMethod = httpMethod; } - public List getHeaders() + public String getHeaderContent() { - return headers; + return headerContent; } - public void setHeaders(List headers) + /** + * 设置请求头JSON文本,格式为: + *
+	 * [
+	 *   {name: "...", value: "..."},
+	 *   {name: "...", value: "..."},
+	 *   ...
+	 * ]
+	 * 
+ *
+ *

+ * 请求头JSON文本支持Freemarker模板语言。 + *

+ * + * @param headerContent + */ + public void setHeaderContent(String headerContent) { - this.headers = headers; + this.headerContent = headerContent; } public String getRequestContentType() @@ -194,6 +215,24 @@ public class HttpDataSet extends AbstractResolvableDataSet this.requestContentType = requestContentType; } + public String getRequestContentCharset() + { + return requestContentCharset; + } + + /** + * 设置请求内容编码。 + *

+ * 默认请求内容编码为{@code UTF-8}。 + *

+ * + * @param requestContentCharset + */ + public void setRequestContentCharset(String requestContentCharset) + { + this.requestContentCharset = requestContentCharset; + } + public String getRequestContent() { return requestContent; @@ -263,11 +302,12 @@ public class HttpDataSet extends AbstractResolvableDataSet try { String uri = resolveTemplateUri(paramValues); + String headerContent = resolveTemplateHeaderContent(paramValues); String requestContent = resolveTemplateRequestContent(paramValues); ClassicHttpRequest request = createHttpRequest(uri); - setHttpHeaders(request, getHeaders()); + setHttpHeaders(request, headerContent); setHttpEntity(request, requestContent); JsonResponseHandler responseHandler = new JsonResponseHandler(); @@ -275,8 +315,11 @@ public class HttpDataSet extends AbstractResolvableDataSet ResolvedDataSetResult result = this.httpClient.execute(request, responseHandler); - String templateResult = "URI:\n" + uri + "\n-----------------------------------------\n" - + "Request content:\n" + requestContent; + String templateResult = "URI:" + System.lineSeparator() + uri // + + System.lineSeparator() + "-----------------------------------------" + System.lineSeparator() // + + "Headers:" + System.lineSeparator() + headerContent // + + System.lineSeparator() + "-----------------------------------------" + System.lineSeparator() // + + "Request content:" + System.lineSeparator() + requestContent; return new TemplateResolvedDataSetResult(result.getResult(), result.getProperties(), templateResult); } @@ -294,12 +337,14 @@ public class HttpDataSet extends AbstractResolvableDataSet } } - protected void setHttpHeaders(ClassicHttpRequest request, List headers) throws Throwable + protected void setHttpHeaders(ClassicHttpRequest request, String headerContent) throws Throwable { - if (headers == null || headers.isEmpty()) + if (StringUtil.isEmpty(headerContent)) return; - for (HttpHeader header : headers) + List headers = toNameValuePairs(headerContent); + + for (NameValuePair header : headers) request.setHeader(header.getName(), header.getValue()); } @@ -307,8 +352,8 @@ public class HttpDataSet extends AbstractResolvableDataSet { if (CONTENT_TYPE_FORM.equals(this.requestContentType)) { - List params = toRequestParams(requestContent); - request.setEntity(new UrlEncodedFormEntity(params)); + List params = toNameValuePairs(requestContent); + request.setEntity(new UrlEncodedFormEntity(params, Charset.forName(this.requestContentCharset))); } else if (CONTENT_TYPE_JSON.equals(this.requestContentType)) { @@ -324,6 +369,11 @@ public class HttpDataSet extends AbstractResolvableDataSet return resolveAsFmkTemplate(this.uri, paramValues); } + protected String resolveTemplateHeaderContent(Map paramValues) throws Throwable + { + return resolveAsFmkTemplate(this.headerContent, paramValues); + } + protected String resolveTemplateRequestContent(Map paramValues) throws Throwable { return resolveAsFmkTemplate(this.requestContent, paramValues); @@ -354,24 +404,24 @@ public class HttpDataSet extends AbstractResolvableDataSet /** * 将指定JSON字符串转换为名/值列表。 * - * @param requestContent + * @param jsonArrayContent * 可能为{@code null}、{@code ""} - * @return 空列表表示无名/值参数 + * @return 空列表表示无名/值 * @throws Throwable */ @SuppressWarnings("unchecked") - protected List toRequestParams(String requestContent) throws Throwable + protected List toNameValuePairs(String jsonArrayContent) throws Throwable { - if (StringUtil.isEmpty(requestContent)) + if (StringUtil.isEmpty(jsonArrayContent)) return Collections.EMPTY_LIST; - Object jsonObj = getObjectMapperNonStardand().readValue(requestContent, Object.class); + Object jsonObj = getObjectMapperNonStardand().readValue(jsonArrayContent, Object.class); if (jsonObj == null) return Collections.EMPTY_LIST; if (!(jsonObj instanceof Collection)) - throw new DataSetException("The request content must be JSON array"); + throw new DataSetException("The content must be JSON array"); Collection collection = (Collection) jsonObj; @@ -398,8 +448,8 @@ public class HttpDataSet extends AbstractResolvableDataSet } if (name == null) - throw new DataSetException("The request content " + idx - + "-th element must be JSON object : {name: \"...\", value: \"...\"}"); + throw new DataSetException( + "The content " + idx + "-th element must be JSON object : {name: \"...\", value: \"...\"}"); nameValuePairs.add(new BasicNameValuePair(name, value)); @@ -547,14 +597,8 @@ public class HttpDataSet extends AbstractResolvableDataSet reader = IOUtil.getReader(""); else { - String contentTypeStr = entity.getContentType(); - - ContentType contentType = ContentType.APPLICATION_JSON; - if (!StringUtil.isEmpty(contentTypeStr)) - contentType = ContentType.parse(contentTypeStr); - Charset charset = contentType.getCharset(); - - reader = new InputStreamReader(entity.getContent(), charset); + Charset contentCharset = resolveCharset(entity, ContentType.APPLICATION_JSON.getCharset()); + reader = IOUtil.getReader(entity.getContent(), contentCharset); } if (this.properties == null || this.properties.isEmpty()) @@ -569,6 +613,30 @@ public class HttpDataSet extends AbstractResolvableDataSet return new ResolvedDataSetResult(result, this.properties); } } + + protected Charset resolveCharset(HttpEntity entity, Charset defaultCharset) + { + Charset contentCharset = null; + + String contentTypeStr = entity.getContentType(); + + if (!StringUtil.isEmpty(contentTypeStr)) + { + try + { + ContentType contentType = ContentType.parse(contentTypeStr); + contentCharset = contentType.getCharset(); + } + catch (Throwable t) + { + LOGGER.warn("Default charset [" + defaultCharset + "] will be used because parse error", t); + + contentCharset = defaultCharset; + } + } + + return (contentCharset != null ? contentCharset : defaultCharset); + } } protected static class HttpResponseJsonDataSet extends AbstractJsonDataSet diff --git a/datagear-analysis/src/main/java/org/datagear/analysis/support/html/HtmlChartPluginLoader.java b/datagear-analysis/src/main/java/org/datagear/analysis/support/html/HtmlChartPluginLoader.java index a3297310..2fac4c2b 100644 --- a/datagear-analysis/src/main/java/org/datagear/analysis/support/html/HtmlChartPluginLoader.java +++ b/datagear-analysis/src/main/java/org/datagear/analysis/support/html/HtmlChartPluginLoader.java @@ -81,7 +81,7 @@ public class HtmlChartPluginLoader private JsonChartPluginPropertiesResolver jsonChartPluginPropertiesResolver = new JsonChartPluginPropertiesResolver(); /** 文件编码 */ - private String encoding = "UTF-8"; + private String encoding = IOUtil.CHARSET_UTF_8; public HtmlChartPluginLoader() { diff --git a/datagear-analysis/src/test/java/org/datagear/analysis/support/HttpDataSetTest.java b/datagear-analysis/src/test/java/org/datagear/analysis/support/HttpDataSetTest.java index d28831e9..3f72e084 100644 --- a/datagear-analysis/src/test/java/org/datagear/analysis/support/HttpDataSetTest.java +++ b/datagear-analysis/src/test/java/org/datagear/analysis/support/HttpDataSetTest.java @@ -5,11 +5,13 @@ package org.datagear.analysis.support; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; -import java.util.Collections; +import java.net.URLDecoder; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -19,6 +21,7 @@ import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.core5.http.ClassicHttpRequest; import org.apache.hc.core5.http.ClassicHttpResponse; import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.Header; import org.apache.hc.core5.http.HttpEntity; import org.apache.hc.core5.http.HttpException; import org.apache.hc.core5.http.impl.bootstrap.HttpServer; @@ -26,9 +29,9 @@ import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap; import org.apache.hc.core5.http.io.HttpRequestHandler; import org.apache.hc.core5.http.io.entity.StringEntity; import org.apache.hc.core5.http.protocol.HttpContext; +import org.datagear.analysis.DataSetParam; import org.datagear.analysis.DataSetProperty; import org.datagear.util.IOUtil; -import org.datagear.util.StringUtil; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -43,7 +46,11 @@ public class HttpDataSetTest { protected static final int PORT = 50402; - protected static final String PARAM_0 = "param0"; + protected static final String SERVER = "http://localhost:" + PORT; + + protected static final String PARAM_NAME_0 = "param0"; + + protected static final String PARAM_NAME_1 = "param1"; protected static HttpServer server; @@ -52,22 +59,68 @@ public class HttpDataSetTest @BeforeClass public static void initTestHttpServer() throws Throwable { - server = ServerBootstrap.bootstrap() - .setListenerPort(PORT).register("/test0", new HttpRequestHandler() + server = ServerBootstrap.bootstrap().setListenerPort(PORT) + // + .register("/testSimple", new HttpRequestHandler() + { + @Override + public void handle(ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context) + throws HttpException, IOException + { + StringEntity responseEntity = new StringEntity( + "[{name: 'aaa', value: 11}, {name: '名称b', value: 22}]", ContentType.APPLICATION_JSON); + response.setEntity(responseEntity); + } + }) + // + .register("/testParam", new HttpRequestHandler() { @Override public void handle(ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context) throws HttpException, IOException { Map params = parseRequestParams(request); - String pv = params.get(PARAM_0); + String p0 = params.get(PARAM_NAME_0); + String p1 = params.get(PARAM_NAME_1); - StringEntity responseEntity = new StringEntity( - "[{name: 'aaa', value: 11}, {name: '" + pv + "', value: 22}]", + StringEntity responseEntity = new StringEntity("[{name: '" + PARAM_NAME_0 + "', value: '" + p0 + + "'}, {name: '" + PARAM_NAME_1 + "', value: '" + p1 + "'}]", ContentType.APPLICATION_JSON); response.setEntity(responseEntity); } - }).create(); + }) + // + .register("/testJson", new HttpRequestHandler() + { + @Override + public void handle(ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context) + throws HttpException, IOException + { + String reqJson = getRequestStringContent(request); + + StringEntity responseEntity = new StringEntity(reqJson, ContentType.APPLICATION_JSON); + response.setEntity(responseEntity); + } + }) + // + .register("/testHeader", new HttpRequestHandler() + { + @Override + public void handle(ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context) + throws HttpException, IOException + { + Header h0 = request.getHeader(PARAM_NAME_0); + Header h1 = request.getHeader(PARAM_NAME_1); + + StringEntity responseEntity = new StringEntity( + "[{name: '" + PARAM_NAME_0 + "', value: '" + h0.getValue() + "'}, {name: '" + + PARAM_NAME_1 + "', value: '" + h1.getValue() + "'}]", + ContentType.APPLICATION_JSON); + response.setEntity(responseEntity); + } + }) + // + .create(); server.start(); @@ -82,21 +135,29 @@ public class HttpDataSetTest } @Test - public void resolveTest_CONTENT_TYPE_FORM() throws Throwable + public void resolveTest_onlyUri() throws Throwable { - String pv = "ppp0"; + List params = Arrays.asList(new DataSetParam("param", DataSetParam.DataType.NUMBER, true)); - HttpDataSet dataSet = new HttpDataSet("a", "a", httpClient, "http://localhost:" + PORT + "/test0"); - dataSet.setRequestContent("[ { name: '" + PARAM_0 + "', value: '" + pv + "' }, { name: 'p1', value: 'b' } ]"); + HttpDataSet dataSet = new HttpDataSet(HttpDataSet.class.getName(), HttpDataSet.class.getName(), httpClient, + SERVER + "/testSimple?param=${param}"); - TemplateResolvedDataSetResult result = dataSet.resolve(Collections.emptyMap()); + dataSet.setParams(params); + + Map paramValues = new HashMap<>(); + paramValues.put("param", "pv"); + + TemplateResolvedDataSetResult result = dataSet.resolve(paramValues); List properties = result.getProperties(); @SuppressWarnings("unchecked") List> data = (List>) result.getResult().getData(); + String templateResult = result.getTemplateResult(); { assertEquals(2, properties.size()); + assertTrue(templateResult.contains("param=pv")); + { DataSetProperty property = properties.get(0); assertEquals("name", property.getName()); @@ -123,30 +184,219 @@ public class HttpDataSetTest { Map row = data.get(1); - assertEquals(pv, row.get("name")); + assertEquals("名称b", row.get("name")); assertEquals(22, ((Number) row.get("value")).intValue()); } } } + @Test + public void resolveTest_rqeuestContent_CONTENT_TYPE_FORM() throws Throwable + { + String pv0 = "p0"; + String pv1 = "参数值1"; + + List params = Arrays.asList(new DataSetParam("param", DataSetParam.DataType.NUMBER, true)); + + HttpDataSet dataSet = new HttpDataSet(HttpDataSet.class.getName(), HttpDataSet.class.getName(), httpClient, + SERVER + "/testParam"); + dataSet.setRequestContent("[ { name: '" + PARAM_NAME_0 + "', value: '" + pv0 + "' }, { name: '" + PARAM_NAME_1 + + "', value: '${param}' } ]"); + dataSet.setParams(params); + + Map paramValues = new HashMap<>(); + paramValues.put("param", pv1); + + TemplateResolvedDataSetResult result = dataSet.resolve(paramValues); + List properties = result.getProperties(); + @SuppressWarnings("unchecked") + List> data = (List>) result.getResult().getData(); + String templateResult = result.getTemplateResult(); + + { + assertEquals(2, properties.size()); + + assertTrue(templateResult.contains("value: '" + pv1 + "'")); + + { + DataSetProperty property = properties.get(0); + assertEquals("name", property.getName()); + assertEquals(DataSetProperty.DataType.STRING, property.getType()); + } + + { + DataSetProperty property = properties.get(1); + assertEquals("value", property.getName()); + assertEquals(DataSetProperty.DataType.STRING, property.getType()); + } + } + + { + assertEquals(2, data.size()); + + { + Map row = data.get(0); + + assertEquals(PARAM_NAME_0, row.get("name")); + assertEquals(pv0, row.get("value")); + } + + { + Map row = data.get(1); + + assertEquals(PARAM_NAME_1, row.get("name")); + assertEquals(pv1, row.get("value")); + } + } + } + + @Test + public void resolveTest_rqeuestContent_CONTENT_TYPE_JSON() throws Throwable + { + String pv0 = "p0"; + String pv1 = "参数值1"; + + List params = Arrays.asList(new DataSetParam("param", DataSetParam.DataType.NUMBER, true)); + + HttpDataSet dataSet = new HttpDataSet(HttpDataSet.class.getName(), HttpDataSet.class.getName(), httpClient, + SERVER + "/testJson"); + dataSet.setRequestContentType(HttpDataSet.CONTENT_TYPE_JSON); + dataSet.setRequestContent("[ { name: '" + PARAM_NAME_0 + "', value: '" + pv0 + "' }, { name: '" + PARAM_NAME_1 + + "', value: '${param}' } ]"); + dataSet.setParams(params); + + Map paramValues = new HashMap<>(); + paramValues.put("param", pv1); + + TemplateResolvedDataSetResult result = dataSet.resolve(paramValues); + List properties = result.getProperties(); + @SuppressWarnings("unchecked") + List> data = (List>) result.getResult().getData(); + String templateResult = result.getTemplateResult(); + + { + assertEquals(2, properties.size()); + + assertTrue(templateResult.contains("value: '" + pv1 + "'")); + + { + DataSetProperty property = properties.get(0); + assertEquals("name", property.getName()); + assertEquals(DataSetProperty.DataType.STRING, property.getType()); + } + + { + DataSetProperty property = properties.get(1); + assertEquals("value", property.getName()); + assertEquals(DataSetProperty.DataType.STRING, property.getType()); + } + } + + { + assertEquals(2, data.size()); + + { + Map row = data.get(0); + + assertEquals(PARAM_NAME_0, row.get("name")); + assertEquals(pv0, row.get("value")); + } + + { + Map row = data.get(1); + + assertEquals(PARAM_NAME_1, row.get("name")); + assertEquals(pv1, row.get("value")); + } + } + } + + @Test + public void resolveTest_headerContent() throws Throwable + { + String pv0 = "p0"; + String pv1 = "p1"; + + List params = Arrays.asList(new DataSetParam("param", DataSetParam.DataType.NUMBER, true)); + + HttpDataSet dataSet = new HttpDataSet(HttpDataSet.class.getName(), HttpDataSet.class.getName(), httpClient, + SERVER + "/testHeader"); + dataSet.setRequestContentType(HttpDataSet.CONTENT_TYPE_JSON); + dataSet.setHeaderContent("[ { name: '" + PARAM_NAME_0 + "', value: '" + pv0 + "' }, { name: '" + PARAM_NAME_1 + + "', value: '${param}' } ]"); + dataSet.setParams(params); + + Map paramValues = new HashMap<>(); + paramValues.put("param", pv1); + + TemplateResolvedDataSetResult result = dataSet.resolve(paramValues); + List properties = result.getProperties(); + @SuppressWarnings("unchecked") + List> data = (List>) result.getResult().getData(); + String templateResult = result.getTemplateResult(); + + { + assertEquals(2, properties.size()); + + assertTrue(templateResult.contains("value: '" + pv1 + "'")); + + { + DataSetProperty property = properties.get(0); + assertEquals("name", property.getName()); + assertEquals(DataSetProperty.DataType.STRING, property.getType()); + } + + { + DataSetProperty property = properties.get(1); + assertEquals("value", property.getName()); + assertEquals(DataSetProperty.DataType.STRING, property.getType()); + } + } + + { + assertEquals(2, data.size()); + + { + Map row = data.get(0); + + assertEquals(PARAM_NAME_0, row.get("name")); + assertEquals(pv0, row.get("value")); + } + + { + Map row = data.get(1); + + assertEquals(PARAM_NAME_1, row.get("name")); + assertEquals(pv1, row.get("value")); + } + } + } + protected static Map parseRequestParams(ClassicHttpRequest request) throws IOException { - Map map = new HashMap(); + Map map = new HashMap<>(); - HttpEntity entity = request.getEntity(); - String encoding = entity.getContentEncoding(); - Reader reader = new InputStreamReader(entity.getContent(), - (StringUtil.isEmpty(encoding) ? "iso-8859-1" : encoding)); - String content = IOUtil.readString(reader, false); + String content = getRequestStringContent(request); String[] strss = content.split("&"); for (String strs : strss) { String[] pv = strs.split("="); - map.put(pv[0], pv[1]); + map.put(pv[0], URLDecoder.decode(pv[1], IOUtil.CHARSET_UTF_8)); } return map; } + + protected static String getRequestStringContent(ClassicHttpRequest request) throws IOException + { + HttpEntity entity = request.getEntity(); + String contentTypeStr = entity.getContentType(); + ContentType contentType = ContentType.parse(contentTypeStr); + Reader reader = new InputStreamReader(entity.getContent(), contentType.getCharset()); + String content = IOUtil.readString(reader, false); + + return content; + } } diff --git a/datagear-util/src/main/java/org/datagear/util/IOUtil.java b/datagear-util/src/main/java/org/datagear/util/IOUtil.java index 58827ea0..b43fc3c7 100644 --- a/datagear-util/src/main/java/org/datagear/util/IOUtil.java +++ b/datagear-util/src/main/java/org/datagear/util/IOUtil.java @@ -37,6 +37,10 @@ import java.util.zip.ZipOutputStream; */ public class IOUtil { + public static final String CHARSET_UTF_8 = "UTF-8"; + + public static final String CHARSET_ISO_8859_1 = "ISO-8859-1"; + private IOUtil() { throw new UnsupportedOperationException(); @@ -337,24 +341,41 @@ public class IOUtil */ public static BufferedReader getReader(File file) throws FileNotFoundException, UnsupportedEncodingException { - return getReader(getInputStream(file), null); + return getReader(getInputStream(file), (String) null); } /** * 获取输入流。 * * @param in - * @param encoding + * @param charset * 允许为{@code null} * @return * @throws UnsupportedEncodingException */ - public static BufferedReader getReader(InputStream in, String encoding) throws UnsupportedEncodingException + public static BufferedReader getReader(InputStream in, String charset) throws UnsupportedEncodingException { - if (StringUtil.isEmpty(encoding)) + if (StringUtil.isEmpty(charset)) return new BufferedReader(new InputStreamReader(in)); else - return new BufferedReader(new InputStreamReader(in, encoding)); + return new BufferedReader(new InputStreamReader(in, charset)); + } + + /** + * 获取输入流。 + * + * @param in + * @param charset + * 允许为{@code null} + * @return + * @throws UnsupportedEncodingException + */ + public static BufferedReader getReader(InputStream in, Charset charset) throws UnsupportedEncodingException + { + if (charset == null) + return new BufferedReader(new InputStreamReader(in)); + else + return new BufferedReader(new InputStreamReader(in, charset)); } /**