有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

web服务Java writeBytes空白被“+”替换

当尝试使用HttpURLConnection执行post请求时,消息中的空格被替换为“+”并在字符串末尾添加“=”。 我正在使用JDK 1.8.091,以下是我的代码:

public void sendPost(String message) throws Exception {
String url = "http://localhost:8081/subscribe";

        URL obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();

        //add reuqest header
        con.setRequestMethod("POST");
        /*String urlParameters = "sn=C02G8416DRJM&cn=&locale=&caller=&num=12345";*/

        // Send post request
        con.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(con.getOutputStream());
        wr.writeBytes(message);
        wr.flush();
        wr.close();
}

sendPost(“sayhi”)会在服务器端给出:Say+Hi=


共 (1) 个答案

  1. # 1 楼答案

    当您不设置Content-Type请求头(使用setRequestProperty())时,它默认为application/x-www-form-urlencoded

    当POST请求的内容类型为application/x-www-form-urlencoded时,可以使用ServletRequest.getParameter方法从请求正文中提取参数。这消耗请求主体,因此对getInputStream()getReader()的任何后续调用都将返回null

    当您的Spring处理程序方法请求带有@RequestBody注释的请求主体,并且主体已经被使用时,Spring将根据参数重建主体,以提供方法参数(基本上是伪造的)。当Spring从解析的参数重建请求主体时,它将按照application/x-www-form-urlencoded内容类型的要求对它们进行URL编码。此编码将空格转换为+

    带有Say Hi的原始请求正文被解析为带有值""的参数"Say Hi"(没有=的参数具有空值)。当按照application/x-www-form-urlencoded重新构建时,参数被编码为Say+Hi=,这就是您看到的

    只有在调用了其中一个ServletRequest.getParameter方法时才会发生这种情况,因此您可能有一个Filter方法来执行此操作。如果删除了该过滤器,请求主体就不会被使用,@RequestBody参数将接收原始请求主体

    另一种防止问题的方法是将请求正文作为text/plain内容类型发送,因为这似乎是您想要的方式,即请求正文实际上不是x-www-form-urlencoded

    con.setRequestProperty("Content-Type", "text/plain; charset=ISO-8859-1");
    

    当然,如果请求主体真正x-www-form-urlencoded内容,就像您的注释代码所建议的那样,那么就不应该有任何空格,而且一开始就没有问题

    重述:您的问题是,您在帖子正文中发送任意文本,但您没有设置内容类型,因此它默认为application/x-www-form-urlencoded,并且您的内容不符合该内容类型的规范,即您的请求格式错误,行为不可预测