作为主体 HttpServletRequest 始终返回 CoyoteInputStream 而不是实际主体

曼蒂思

我正在尝试编写一个方法来检查用户凭据,如果这些是正确的解析发送 JSON。它工作正常,但我无法访问 JSON。在我的代码中有一个命令InputStream inputStream = request.getInputStream();应该读取 JSON 但每次返回org.apache.catalina.connector.CoyoteInputStream@3f1e9348. 请看一下我的代码:

@POST
@Path("auth")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_HTML)
public String controller(@Context HttpServletRequest request) {


    String authorization = request.getHeader("Authorization");
    if (authorization == null) {
        authorization = request.getHeader("authorization");
    }

    String basicHeader = "basic";
    if (authorization != null && authorization.toLowerCase().startsWith(basicHeader)) {
        String base64Credentials = authorization.substring(basicHeader.length()).trim();
        String credentials = new String(Base64.getDecoder().decode(base64Credentials),
                Charset.forName("UTF-8"));
        String[] values = credentials.split(":", 2);
    }

    try {
        InputStream inputStream = request.getInputStream();
        System.out.println(inputStream);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

当我尝试使用时,request.getReader()我得到了臭名昭著的IllegalStateException: getInputStream() has already been called for this request异常。请参阅相关代码段:

if ("POST".equalsIgnoreCase(request.getMethod()))
        {
            try {
                String req = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

我使用 curl 发送POST

curl -u myusername:mypasswor -H "Content-Type: application/json"
-X POST -d '{"username":"xyz","password":"xyz"}' localhost
欧内斯特_k

您可以通过在您的方法中声明一个参数来获取您的正文内容:

public String controller(String body, @Context HttpServletRequest request) 

但是您也可以使用 JAX-RS 实现将该 JSON 反序列化为您想要的类型:

public String controller(MyExpectedType body, @Context HttpServletRequest request) 

这应该有效,因为您已经声明了预期的内容类型,假设您有一个适用的提供程序(例如 jackson-jaxrs ...)。

关于输入流错误:这可能是因为容器 JAXRS 实现已经解析了请求。

但是如果您要在正常情况下(例如在 servlet 中)处理它,您仍然需要更正读取它的方式:

getInputStream状态文档

使用 ServletInputStream 以二进制数据形式检索请求正文。可以调用此方法或 getReader() 来读取正文,而不是同时调用两者。

这意味着要在正文中获取客户端发送的内容,您需要读取流:

String body = request.getReader().lines()
                      .collect(Collectors.joining("\n"));

您还可以使用Stream基于的 API:

byte[] bytes = new byte[request.getContentLength()];
request.getInputStream().read(bytes);
String body = new String(bytes); //you may need to specify the character set

实际的输入流类是基于实现的(容器提供的),所以你不需要关心 CoyoteInputStream

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

行为主体返回 null

如何在Java中修改HttpServletRequest主体?

Elasticsearch-search_type作为主体参数

在 Invoke-RestMethod 中发送 PSCustomObject 作为主体参数

行为主体与转化

食尸鬼返回流空主体而不是json主体

constexpr函数的主体不是返回语句

春季启动@MockMvcTest MockHttpServletResponse始终返回空主体

如何将左列作为导航器,将右列作为主体?

如何处理 POST 主体 HttpServletRequest 中的 JSON

如何检测HttpServletRequest是否具有主体?

带数组的行为主体

带有方法列表的GET方法作为主体还是POST方法?

如何使用改进在api post方法中将字符串作为主体传递?

如何处理Spring WebClient获取application / octet-stream作为主体InputStream?

Spring WebClient:自动为主体计算HMAC签名并将其作为标头传递

如何在POST方法(RestTemplate)中将List <Objects>作为主体传递

如何使用CDK将帐户作为主体添加到Elasticsearch访问策略中?

如何在bash脚本中的curl中将多行json字符串作为主体发布

我如何在 spring 控制器中接收 json 作为主体?

使用 RxJS 从 JSON 获取数据尝试返回数组并将值传递给不同的行为主体

返回python字符串作为HTTP响应的主体

为什么@AuthenticationPrincipal返回Authentication而不是主体对象?

Future何时可以返回不是从Future主体内抛出的异常?

HttpServletRequest#getParts()jsp始终返回空集合

为主体的innerHTML包装div元素

行为主体行为不正常?

事件与行为主体之间的区别

嵌套订阅并需要所有值作为主体传递给API-Angular 6 RxJS