pull/3/head
tanghc 4 years ago
parent 3f9365f5d5
commit 2270c50886
  1. 12
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/param/ApiArgumentResolver.java
  2. 53
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/param/ByteArrayStreamWrapper.java
  3. 106
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/param/MyServletRequestWrapper.java
  4. 7
      sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1001_BaseController.java

@ -13,6 +13,7 @@ import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
@ -25,6 +26,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ServletRequestMetho
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.InputStream;
import java.io.OutputStream;
@ -117,6 +119,10 @@ public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver {
, NativeWebRequest nativeWebRequest
, WebDataBinderFactory webDataBinderFactory
) throws Exception {
nativeWebRequest = new SopServletWebRequest(
(HttpServletRequest) nativeWebRequest.getNativeRequest(),
(HttpServletResponse) nativeWebRequest.getNativeResponse()
);
if (openApiParams.contains(methodParameter)) {
Object paramObj = this.getParamObject(methodParameter, nativeWebRequest);
if (paramObj != null) {
@ -221,4 +227,10 @@ public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver {
public void setParamValidator(ParamValidator paramValidator) {
this.paramValidator = paramValidator;
}
private static final class SopServletWebRequest extends ServletWebRequest {
public SopServletWebRequest(HttpServletRequest request, HttpServletResponse response) {
super(new MyServletRequestWrapper(request), response);
}
}
}

@ -0,0 +1,53 @@
package com.gitee.sop.servercommon.param;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import java.io.IOException;
/**
* byte数组流包装
*
* @author tanghc
*/
public class ByteArrayStreamWrapper extends ServletInputStream {
private byte[] data;
private int idx = 0;
/**
* Creates a new <code>ByteArrayStreamWrapper</code> instance.
*
* @param data a <code>byte[]</code> value
*/
public ByteArrayStreamWrapper(byte[] data) {
if (data == null) {
data = new byte[0];
}
this.data = data;
}
@Override
public int read() throws IOException {
if (idx == data.length) {
return -1;
}
// I have to AND the byte with 0xff in order to ensure that it is returned as an unsigned integer
// the lack of this was causing a weird bug when manually unzipping gzipped request bodies
return data[idx++] & 0xff;
}
@Override
public boolean isFinished() {
return true;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
}
}

@ -0,0 +1,106 @@
package com.gitee.sop.servercommon.param;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;
/**
* 包装HttpServletRequest
*/
@Slf4j
public class MyServletRequestWrapper extends HttpServletRequestWrapper {
private final byte[] body;
private final Map<String, String[]> parameterMap;
public MyServletRequestWrapper(HttpServletRequest request) {
super(request);
// 先缓存请求参数,不然获取不到,原因:
// 调用getInputStream方法时,usingInputStream会变成true
// 之后再调用request.getParameterMap(),就一直返回空map
// 因此要先调用request.getParameterMap()缓存起来
// 详见org.apache.catalina.connector.Request.parseParameters()中
// if (usingInputStream || usingReader) {
// success = true;
// return;
// }
parameterMap = request.getParameterMap();
try {
body = IOUtils.toByteArray(super.getInputStream());
} catch (IOException e) {
log.error("cache body error, url:{}",request.getRequestURI(), e);
throw new RuntimeException("cache body error", e);
}
}
@Override
public Map<String, String[]> getParameterMap() {
return parameterMap;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() throws IOException {
return new ByteArrayStreamWrapper(body);
}
/**
* byte数组流包装
*
* @author tanghc
*/
public static class ByteArrayStreamWrapper extends ServletInputStream {
private byte[] data;
private int idx = 0;
/**
* Creates a new <code>ByteArrayStreamWrapper</code> instance.
*
* @param data a <code>byte[]</code> value
*/
public ByteArrayStreamWrapper(byte[] data) {
if (data == null) {
data = new byte[0];
}
this.data = data;
}
@Override
public int read() throws IOException {
if (idx == data.length) {
return -1;
}
// I have to AND the byte with 0xff in order to ensure that it is returned as an unsigned integer
// the lack of this was causing a weird bug when manually unzipping gzipped request bodies
return data[idx++] & 0xff;
}
@Override
public boolean isFinished() {
return true;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
}
}
}

@ -12,7 +12,9 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.nio.charset.StandardCharsets;
@ -83,9 +85,10 @@ public class Example1001_BaseController {
// 忽略验证
@ApiOperation(value = "忽略签名验证", notes = "忽略签名验证")
@Open(value = "story.get.ignore", ignoreValidate = true)
@RequestMapping("/get/ignore/v1")
public StoryResult getStory21(StoryParam story) {
@RequestMapping(value = "/get/ignore/v1", method = {RequestMethod.GET, RequestMethod.POST})
public StoryResult getStory21(@RequestBody StoryParam story) {
StoryResult result = new StoryResult();
result.setId((long) story.getId());
result.setName(story.getName() + ", ignoreValidate = true");
return result;
}

Loading…
Cancel
Save