我的休息控制器
@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()
@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
答案 0 :(得分:-1)
我可以解决这个问题,只需添加一个过滤器,拦截当前的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");
}
}
}