当前位置: 首页 > 知识库问答 >
问题:

@ExceptionHandler如何从HttpServletRequest获取原始json帖子

林念
2023-03-14

我的Rest控制器

@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 帖子。我尝试使用请求。

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的建议。我尝试按照建议使用HttpServletRequest estWrapper,但它仍然不起作用。

@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:溪流关闭

共有1个答案

娄利
2023-03-14

我可以解决这个问题,只需添加一个过滤器,拦截当前的HttpServletRequest并将其包装在自定义的HttpServletRequest estWrapper(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");
        }
    }
}
 类似资料:
  • 问题内容: 根据php手册或php:// input都不能与POST请求一起使用。 “ php:// input允许您读取原始的POST数据。它是内存占用较少的替代方法,并且不需要任何特殊的php.ini指令。php:// input不适用于。” 如何获取表格的原始数据? 问题答案: 直接回答:你不能那样做。只要PHP看到multipart / form-data Content- Type,它就

  • 问题内容: 是否可以从ServletContext获取HttpServletRequest? 问题答案: 是否可以从ServletContext获取HttpServletRequest? 没有。 该代表的应用程序。该应用程序可以涵盖许多会话和请求。但是您无法通过来获取“当前正在运行”的请求或会话。有关servlet和作用域如何工作的详细信息,可以在以下相关答案中找到:servlet如何工作?实例化

  • 问题内容: 有没有办法从获取原始/原始JSON值? 问题: 现在是,但是我需要原始字符串。 有没有办法获得这个原始价值?另外,我无法更改创建方式(例如更改设置),因为它作为参数传递给我的课程… (参考:原始的NJsonSchema问题) 问题答案: 您无法获取原始字符串,无法识别日期字符串并将其转换为自身内部的结构。如果您这样做,则可以看到以下内容: 但是,您可以通过执行以下操作以ISO 8601

  • 问题内容: 我正在尝试从文件夹中包含在项目中的原始文件获取。但是无论如何,我都会得到一个。 该文件是一个文件,也尝试过使用,也不起作用。使用DOES 播放两个文件都可以。 的回报: 我的代码: 错误: 问题答案: 尝试这种方法,用作您的inputStream。沿着这个地方: 返回一个InputStream 编辑:如果您使用上述方法,请删除这些代码 希望这有帮助,祝你好运!^^

  • 我能够通过IMAP连接到Gmail并进行解析,但是在电子邮件正文中,我获得了Gmail特定的内容,例如

  • 问题内容: 我正在HTTP POST到URL http:// laptop:8080 / apollo / services / rpc?cmd = execute 与POST数据 Http请求的为 如何从获取POST数据? 如果我枚举请求参数,则只能看到一个参数“ cmd”,而看不到POST数据。 问题答案: 通常,你可以以相同的方式在Servlet中获取GET和POST参数: 但仅当POST数