修复请求体超过256KB无法请求问题

pull/3/head
tanghc 4 years ago
parent f86e569c03
commit 4d6693aca2
  1. 8
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/ServerWebExchangeUtil.java
  2. 42
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/codec/MessageReaderFactory.java
  3. 6
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/EnvironmentKeys.java
  4. 11
      sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1001_BaseController.java
  5. 11
      sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/LargeTextParam.java
  6. 3
      sop-gateway/src/main/resources/META-INF/gateway.properties
  7. 2
      sop-test/src/main/java/com/gitee/sop/test/HttpTool.java
  8. 3
      sop-test/src/main/resources/large_data.txt
  9. 7
      sop-test/src/test/java/com/gitee/sop/test/AlipayClientPostTest.java
  10. 20
      sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java
  11. 10
      sop-test/src/test/java/com/gitee/sop/test/DownloadTest.java
  12. 65
      sop-test/src/test/java/com/gitee/sop/test/LargeBodyPostTest.java
  13. 8
      sop-test/src/test/java/com/gitee/sop/test/SpringmvcDemoPostTest.java
  14. 8
      sop-test/src/test/java/com/gitee/sop/test/ThrowExceptionDemoTest.java

@ -3,6 +3,7 @@ package com.gitee.sop.gatewaycommon.gateway;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.gitee.sop.gatewaycommon.bean.SopConstants; import com.gitee.sop.gatewaycommon.bean.SopConstants;
import com.gitee.sop.gatewaycommon.gateway.codec.MessageReaderFactory;
import com.gitee.sop.gatewaycommon.gateway.common.FileUploadHttpServletRequest; import com.gitee.sop.gatewaycommon.gateway.common.FileUploadHttpServletRequest;
import com.gitee.sop.gatewaycommon.gateway.common.RequestContentDataExtractor; import com.gitee.sop.gatewaycommon.gateway.common.RequestContentDataExtractor;
import com.gitee.sop.gatewaycommon.gateway.common.SopServerHttpRequestDecorator; import com.gitee.sop.gatewaycommon.gateway.common.SopServerHttpRequestDecorator;
@ -22,7 +23,6 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver; import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.reactive.function.server.HandlerStrategies;
import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain; import org.springframework.web.server.WebFilterChain;
@ -48,11 +48,7 @@ public class ServerWebExchangeUtil {
private static final FormHttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter(); private static final FormHttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter();
private static final List<HttpMessageReader<?>> messageReaders; private static final List<HttpMessageReader<?>> messageReaders = MessageReaderFactory.build();
static {
messageReaders = HandlerStrategies.withDefaults().messageReaders();
}
/** /**
* 重定向 * 重定向

@ -0,0 +1,42 @@
package com.gitee.sop.gatewaycommon.gateway.codec;
import com.gitee.sop.gatewaycommon.manager.EnvironmentKeys;
import org.springframework.core.codec.AbstractDataBufferDecoder;
import org.springframework.http.codec.HttpMessageReader;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.reactive.function.server.HandlerStrategies;
import java.lang.reflect.Method;
import java.util.List;
/**
* @author tanghc
*/
public class MessageReaderFactory {
public static final String METHOD_SET_MAX_IN_MEMORY_SIZE = "setMaxInMemorySize";
public static final String METHOD_GET_DECODER = "getDecoder";
public static List<HttpMessageReader<?>> build() {
String maxInMemorySizeValueStr = EnvironmentKeys.MAX_IN_MEMORY_SIZE.getValue();
int maxInMemorySizeValue = Integer.parseInt(maxInMemorySizeValueStr);
List<HttpMessageReader<?>> messageReaders = HandlerStrategies.withDefaults().messageReaders();
// 设置POST缓存大小
for (HttpMessageReader<?> httpMessageReader : messageReaders) {
Method[] methods = ReflectionUtils.getDeclaredMethods(httpMessageReader.getClass());
for (Method method : methods) {
String methodName = method.getName();
if (METHOD_SET_MAX_IN_MEMORY_SIZE.equals(methodName)) {
ReflectionUtils.invokeMethod(method, httpMessageReader, maxInMemorySizeValue);
} else if (METHOD_GET_DECODER.equals(methodName)) {
Object decoder = ReflectionUtils.invokeMethod(method, httpMessageReader);
if (decoder instanceof AbstractDataBufferDecoder) {
AbstractDataBufferDecoder<?> bufferDecoder = (AbstractDataBufferDecoder<?>) decoder;
bufferDecoder.setMaxInMemorySize(maxInMemorySizeValue);
}
}
}
}
return messageReaders;
}
}

@ -30,6 +30,12 @@ public enum EnvironmentKeys {
*/ */
PRE_DOMAIN("pre.domain"), PRE_DOMAIN("pre.domain"),
/**
* post请求body缓存大小
*/
MAX_IN_MEMORY_SIZE("spring.codec.max-in-memory-size", "262144")
; ;
private final String key; private final String key;

@ -2,6 +2,7 @@ package com.gitee.sop.storyweb.controller;
import com.gitee.sop.servercommon.annotation.Open; import com.gitee.sop.servercommon.annotation.Open;
import com.gitee.sop.storyweb.controller.param.CategoryParam; import com.gitee.sop.storyweb.controller.param.CategoryParam;
import com.gitee.sop.storyweb.controller.param.LargeTextParam;
import com.gitee.sop.storyweb.controller.param.StoryParam; import com.gitee.sop.storyweb.controller.param.StoryParam;
import com.gitee.sop.storyweb.controller.result.CategoryResult; import com.gitee.sop.storyweb.controller.result.CategoryResult;
import com.gitee.sop.storyweb.controller.result.StoryResult; import com.gitee.sop.storyweb.controller.result.StoryResult;
@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.nio.charset.StandardCharsets;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -69,6 +71,15 @@ public class Example1001_BaseController {
return result; return result;
} }
@Open(value = "story.get.large")
@RequestMapping("/get/large/v1")
public StoryResult getStoryLarge(LargeTextParam param) {
StoryResult result = new StoryResult();
int length = param.getContent().getBytes(StandardCharsets.UTF_8).length;
result.setName("length:" + length);
return result;
}
// 返回数组结果 // 返回数组结果
@ApiOperation(value = "返回数组结果", notes = "返回数组结果") @ApiOperation(value = "返回数组结果", notes = "返回数组结果")
@Open("story.list") @Open("story.list")

@ -0,0 +1,11 @@
package com.gitee.sop.storyweb.controller.param;
import lombok.Data;
/**
* @author tanghc
*/
@Data
public class LargeTextParam {
private String content;
}

@ -26,6 +26,9 @@ spring.cloud.gateway.discovery.locator.enabled=true
mybatis.fill.com.gitee.fastmybatis.core.support.DateFillInsert=gmt_create mybatis.fill.com.gitee.fastmybatis.core.support.DateFillInsert=gmt_create
mybatis.fill.com.gitee.fastmybatis.core.support.DateFillUpdate=gmt_modified mybatis.fill.com.gitee.fastmybatis.core.support.DateFillUpdate=gmt_modified
# POST请求最大缓存512KB
spring.codec.max-in-memory-size=524288
# 文件上传配置 # 文件上传配置
spring.servlet.multipart.enabled=true spring.servlet.multipart.enabled=true
# 这里设置大一点没关系,真实大小由upload.max-file-size控制 # 这里设置大一点没关系,真实大小由upload.max-file-size控制

@ -501,7 +501,7 @@ public class HttpTool {
if (file.isDirectory()) { if (file.isDirectory()) {
throw new IOException("File '" + file + "' exists but is a directory"); throw new IOException("File '" + file + "' exists but is a directory");
} }
if (file.canRead() == false) { if (!file.canRead()) {
throw new IOException("File '" + file + "' cannot be read"); throw new IOException("File '" + file + "' cannot be read");
} }
} else { } else {

File diff suppressed because one or more lines are too long

@ -52,16 +52,15 @@ public class AlipayClientPostTest extends TestBase {
bizContent.put("name", "葫芦娃"); bizContent.put("name", "葫芦娃");
params.put("biz_content", JSON.toJSONString(bizContent)); params.put("biz_content", JSON.toJSONString(bizContent));
String content = AlipaySignature.getSignContent(params);
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
params.put("sign", sign);
System.out.println("----------- 请求信息 -----------"); System.out.println("----------- 请求信息 -----------");
System.out.println("请求参数:" + buildParamQuery(params)); System.out.println("请求参数:" + buildParamQuery(params));
System.out.println("商户秘钥:" + privateKey); System.out.println("商户秘钥:" + privateKey);
String content = AlipaySignature.getSignContent(params);
System.out.println("待签名内容:" + content); System.out.println("待签名内容:" + content);
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
System.out.println("签名(sign):" + sign); System.out.println("签名(sign):" + sign);
params.put("sign", sign);
System.out.println("URL参数:" + buildUrlQuery(params)); System.out.println("URL参数:" + buildUrlQuery(params));
System.out.println("----------- 返回结果 -----------"); System.out.println("----------- 返回结果 -----------");

@ -2,8 +2,10 @@ package com.gitee.sop.test;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -204,6 +206,24 @@ public class AllInOneTest extends TestBase {
client.execute(requestBuilder); client.execute(requestBuilder);
} }
/**
* 测试post提交大文本内容
* @throws IOException
*/
public void testLargeBody() throws IOException {
String root = System.getProperty("user.dir");
// 这个文件有600KB的数据
File file = new File(root + "/src/main/resources/large_data.txt");
String fileContent = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
Client.RequestBuilder requestBuilder = new Client.RequestBuilder()
.method("story.get.large")
.version("1.0")
.bizContent(new BizContent().add("content", fileContent))
.httpMethod(HttpTool.HTTPMethod.POST);
client.execute(requestBuilder);
}
/** /**
* 下载文件 * 下载文件
*/ */

@ -29,7 +29,7 @@ public class DownloadTest extends TestBase {
// 公共请求参数 // 公共请求参数
Map<String, String> params = new HashMap<String, String>(); Map<String, String> params = new HashMap<String, String>();
params.put("app_id", appId); params.put("app_id", appId);
params.put("method", "story.download"); params.put("method", "file.download");
params.put("format", "json"); params.put("format", "json");
params.put("charset", "utf-8"); params.put("charset", "utf-8");
params.put("sign_type", "RSA2"); params.put("sign_type", "RSA2");
@ -42,16 +42,16 @@ public class DownloadTest extends TestBase {
bizContent.put("name", "葫芦娃"); bizContent.put("name", "葫芦娃");
params.put("biz_content", JSON.toJSONString(bizContent)); params.put("biz_content", JSON.toJSONString(bizContent));
String content = AlipaySignature.getSignContent(params);
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
params.put("sign", sign);
System.out.println("----------- 请求信息 -----------"); System.out.println("----------- 请求信息 -----------");
System.out.println("请求参数:" + buildParamQuery(params)); System.out.println("请求参数:" + buildParamQuery(params));
System.out.println("商户秘钥:" + privateKey); System.out.println("商户秘钥:" + privateKey);
String content = AlipaySignature.getSignContent(params);
System.out.println("待签名内容:" + content); System.out.println("待签名内容:" + content);
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
System.out.println("签名(sign):" + sign); System.out.println("签名(sign):" + sign);
System.out.println("URL参数:" + buildUrlQuery(params));
params.put("sign", sign);
System.out.println("----------- 返回结果 -----------"); System.out.println("----------- 返回结果 -----------");
InputStream fileInputStream = download(url, params); InputStream fileInputStream = download(url, params);

@ -0,0 +1,65 @@
package com.gitee.sop.test;
import com.alibaba.fastjson.JSON;
import com.gitee.sop.test.alipay.AlipaySignature;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* 模仿支付宝客户端请求接口
*/
public class LargeBodyPostTest extends TestBase {
String url = "http://localhost:8081";
String appId = "2019032617262200001";
// 平台提供的私钥
String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ=";
// 测试大容量报文
@Test
public void testGet() throws Exception {
// 公共请求参数
Map<String, String> params = new HashMap<String, String>();
params.put("app_id", appId);
params.put("method", "story.get.large");
params.put("format", "json");
params.put("charset", "utf-8");
params.put("sign_type", "RSA2");
params.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
params.put("version", "1.0");
// 业务参数
Map<String, String> bizContent = new HashMap<>();
bizContent.put("id", "1");
String root = System.getProperty("user.dir");
File file = new File(root + "/src/main/resources/large_data.txt");
String fileContent = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
bizContent.put("content", fileContent);
params.put("biz_content", JSON.toJSONString(bizContent));
String content = AlipaySignature.getSignContent(params);
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
params.put("sign", sign);
System.out.println("----------- 请求信息 -----------");
System.out.println("请求参数:" + buildParamQuery(params));
System.out.println("商户秘钥:" + privateKey);
System.out.println("待签名内容:" + content);
System.out.println("签名(sign):" + sign);
System.out.println("URL参数:" + buildUrlQuery(params));
System.out.println("----------- 返回结果 -----------");
String responseData = post(url, params);// 发送请求
System.out.println(responseData);
}
}

@ -38,16 +38,16 @@ public class SpringmvcDemoPostTest extends TestBase {
bizContent.put("goods_name", "iphone6"); bizContent.put("goods_name", "iphone6");
params.put("biz_content", JSON.toJSONString(bizContent)); params.put("biz_content", JSON.toJSONString(bizContent));
String content = AlipaySignature.getSignContent(params);
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
params.put("sign", sign);
System.out.println("----------- 请求信息 -----------"); System.out.println("----------- 请求信息 -----------");
System.out.println("请求参数:" + buildParamQuery(params)); System.out.println("请求参数:" + buildParamQuery(params));
System.out.println("商户秘钥:" + privateKey); System.out.println("商户秘钥:" + privateKey);
String content = AlipaySignature.getSignContent(params);
System.out.println("待签名内容:" + content); System.out.println("待签名内容:" + content);
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
System.out.println("签名(sign):" + sign); System.out.println("签名(sign):" + sign);
System.out.println("URL参数:" + buildUrlQuery(params));
params.put("sign", sign);
System.out.println("----------- 返回结果 -----------"); System.out.println("----------- 返回结果 -----------");
String responseData = post(url, params);// 发送请求 String responseData = post(url, params);// 发送请求

@ -39,16 +39,16 @@ public class ThrowExceptionDemoTest extends TestBase {
bizContent.put("goods_comment", "1111"); bizContent.put("goods_comment", "1111");
params.put("biz_content", JSON.toJSONString(bizContent)); params.put("biz_content", JSON.toJSONString(bizContent));
String content = AlipaySignature.getSignContent(params);
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
params.put("sign", sign);
System.out.println("----------- 请求信息 -----------"); System.out.println("----------- 请求信息 -----------");
System.out.println("请求参数:" + buildParamQuery(params)); System.out.println("请求参数:" + buildParamQuery(params));
System.out.println("商户秘钥:" + privateKey); System.out.println("商户秘钥:" + privateKey);
String content = AlipaySignature.getSignContent(params);
System.out.println("待签名内容:" + content); System.out.println("待签名内容:" + content);
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
System.out.println("签名(sign):" + sign); System.out.println("签名(sign):" + sign);
System.out.println("URL参数:" + buildUrlQuery(params));
params.put("sign", sign);
System.out.println("----------- 返回结果 -----------"); System.out.println("----------- 返回结果 -----------");
String responseData = post(url, params);// 发送请求 String responseData = post(url, params);// 发送请求

Loading…
Cancel
Save