gpt4 book ai didi

spring - @ExceptionHandler 如何从 HttpServletRequest 获取原始 json post

转载 作者:行者123 更新时间:2023-12-01 16:58:38 26 4
gpt4 key购买 nike

我的休息 Controller

@RestController
public class MyController {

@RequestMapping(value = "/getrawjson", method = RequestMethod.POST)
public @ResponseBody
String search(@RequestBody Map<String, Object> json, HttpServletRequest httpServletRequest) throws PushNotiException,Exception {
return "OK";
}
}

我对无效原始 json 帖子的异常处理。我尝试使用 request.getInputStream() 但收到错误

IllegalStateException: getInputStream() has already been called for this request

@ControllerAdvice
public class MethodArgumentNotValidExceptionHandler {

@ExceptionHandler({org.springframework.http.converter.HttpMessageNotReadableException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public TrueIDResponse resolveException(HttpServletRequest request,Exception ex) throws IOException {

}
}

我想保留此异常的日志输入原始 json 数据。

有人可以帮助我吗?谢谢。

更新

正如@Sean Carrol 的建议。我按照建议尝试使用 HttpServletRequestWrapper 但仍然不起作用。

@ControllerAdvice
public class MethodArgumentNotValidExceptionHandler {



@ExceptionHandler({org.springframework.http.converter.HttpMessageNotReadableException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public TrueIDResponse resolveException(HttpServletRequest request,Exception ex) throws IOException {
MultiReadHttpServletRequest multiReadRequest = new MultiReadHttpServletRequest((HttpServletRequest) request);
InputStream inputStream = multiReadRequest.getInputStream();
String theString = IOUtils.toString(inputStream, "UTF-8");

}
}

我在 InputStream inputStream = multiReadRequest.getInputStream(); 处收到此错误线。

java.io.IOException: Stream closed

最佳答案

我可以解决这个问题,只需添加一个过滤器,拦截当前的 HttpServletRequest 并将其包装在自定义的 HttpServletRequestWrapper (MultipleReadHttpRequest)

@Component
public class CachingRequestBodyFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest currentRequest = (HttpServletRequest) servletRequest;
MultipleReadHttpRequest wrappedRequest = new MultipleReadHttpRequest(currentRequest);
chain.doFilter(wrappedRequest, servletResponse);
}
}

servlet 3.0 的 MultipleReadHttpRequest 类

public class MultiReadHttpServletRequest extends HttpServletRequestWrapper {
private ByteArrayOutputStream cachedBytes;

public MultiReadHttpServletRequest(HttpServletRequest request) {
super(request);
}

@Override
public ServletInputStream getInputStream() throws IOException {
if (cachedBytes == null)
cacheInputStream();

return new CachedServletInputStream();
}

@Override
public BufferedReader getReader() throws IOException{
return new BufferedReader(new InputStreamReader(getInputStream()));
}

private void cacheInputStream() throws IOException {
/* Cache the inputstream in order to read it multiple times. For
* convenience, I use apache.commons IOUtils
*/
cachedBytes = new ByteArrayOutputStream();
IOUtils.copy(super.getInputStream(), cachedBytes);
}

/* An inputstream which reads the cached request body */
public class CachedServletInputStream extends ServletInputStream {
private ByteArrayInputStream input;

public CachedServletInputStream() {
/* create a new input stream from the cached request body */
input = new ByteArrayInputStream(cachedBytes.toByteArray());
}

@Override
public int read() throws IOException {
return input.read();
}

@Override
public boolean isFinished() {
return input.available() == 0;
}

@Override
public boolean isReady() {
return true;
}

@Override
public void setReadListener(ReadListener listener) {
throw new RuntimeException("Not implemented");
}
}
}

关于spring - @ExceptionHandler 如何从 HttpServletRequest 获取原始 json post,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47605079/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com