java.lang.IllegalStateException: STREAMED

最近突然发现程序中大量的报java.lang.IllegalStateException: STREAMED异常,抛出异常的地方调用了如下代码

    public static String getBody(HttpServletRequest req) {
        try {
            return StringUtils.bufferToString(req.getReader());
        } catch (IOException e) {
            log.warn("Exception reading request body: ", e);
            return "";
        }
    }

上网搜了一下,在Servlet的API文档中发现如下描述:

 public java.io.BufferedReader getReader()
    ...
    ...
Throws:
    java.lang.IllegalStateException - if getInputStream() method has been called on this request

 public ServletInputStream getInputStream()
    ...
    ...
    Throws:
    java.lang.IllegalStateException - if the getReader() method has already been called for this request

看来是某个地方已经调用了getInputStream,此处再调用导致异常抛出,那就也改用getInputStream方法好了,对getBody方法修改如下:

    public static String getBody(HttpServletRequest req) {
        try(InputStream inputStream = req.getInputStream()) {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
            return StringUtils.bufferToString(bufferedReader);
        } catch (IOException e) {
            log.error("exception while reading body from request.", e);
        }

        return "";
    }

改完之后果然异常再也没有发生过,但是有新的问题:getBody总是得到空字符串,明明body体里是有内容的,再搜,果然有说法,getInputStream和getReader方法只能调用一次,调用过之后,数据就失效了,所以再读就只能得到空。
还是得回头找在哪调用过getInputStream呢?
在Filter中找到了下面的调用:

    String key = request.getParameter("xxx");

在网上搜到了getParameter的源码解析,跟踪代码确认,实现是org.eclipse.jetty.server.Request中的getParameter方法,跟踪调用到如下方法:

    public void extractFormParameters(MultiMap<String> params) {
        ......
        InputStream in = this.getInputStream();
        ......

此处调用了getInputStream方法导致后续问题的发生。
此处是为了获取url中的参数,改用getQueryString绕过去,但实际上网上也有很多的解决办法,包括写Wrapper对body进行缓存,如解决 request中getReader()和getInputStream()只能调用一次

参考:

  1. ServletRequest.getReader
  2. HttpServletRequest.getParameter()源码分析
  3. 解决 request中getReader()和getInputStream()只能调用一次
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
java.lang.IllegalStateException: No properties是一个异常,表示在代码中找不到配置属性。这个异常通常发生在使用Spring Boot时,没有正确配置@ConfigurationProperties注解的情况下。 解决这个问题的方法是确保在需要配置属性的类上添加@ConfigurationProperties注解,并在属性的getter和setter方法上添加@Value注解。这样Spring Boot就能正确地读取和注入配置属性。 以下是一个示例代码,演示了如何解决java.lang.IllegalStateException: No properties异常: ```java import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties(prefix = "myapp") public class MyAppProperties { private String property1; private int property2; public String getProperty1() { return property1; } public void setProperty1(String property1) { this.property1 = property1; } public int getProperty2() { return property2; } public void setProperty2(int property2) { this.property2 = property2; } } ``` 在上面的示例中,我们创建了一个名为MyAppProperties的类,并在类上添加了@ConfigurationProperties注解,并指定了属性的前缀为"myapp"。然后,我们定义了两个属性property1和property2,并为它们分别提供了getter和setter方法。 通过这样的配置,Spring Boot就能正确地读取和注入配置属性,避免了java.lang.IllegalStateException: No properties异常的发生。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值