Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java writeBytes空白替换为'+';_Java_Web Services_Spring Mvc_Spring Boot - Fatal编程技术网

Java writeBytes空白替换为'+';

Java writeBytes空白替换为'+';,java,web-services,spring-mvc,spring-boot,Java,Web Services,Spring Mvc,Spring Boot,当尝试使用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 co

当尝试使用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=

当您不设置
内容类型
请求头(使用
setRequestProperty()
)时,它默认为
application/x-www-form-urlcoded

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

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

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

只有在调用了
ServletRequest.getParameter
方法之一时,才会发生这种情况,因此您可能有一个
过滤器来实现这一点。如果删除了该筛选器,请求正文就不会被使用,并且
@RequestBody
参数将收到原始请求正文

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

con.setRequestProperty("Content-Type", "text/plain; charset=ISO-8859-1");
当然,如果请求主体确实是
x-www-form-urlencoded
内容,就像您的注释代码所建议的那样,那么就不应该有任何空格,而且一开始就没有问题


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

不相关,但为什么要使用
DataOutputStream
?您在哪里看到“Say+Hi=”?您能提供一个吗?我正在将从客户端收到的消息记录在spingBoot应用程序的日志文件中。分步调试后的问题来自wr.writeBytes(消息)
DataOutputStream.writeBytes()
肯定不会这样做,因为您可以通过使用它编写其他内容或阅读Javadoc轻松地为自己建立。问题可能出在
HttpURLConnection
上,虽然可能性不大,但很可能是在接收端。您需要进行进一步调试。这是接收端所做的一切记录:
code
@RequestMapping(value=“/subscribe”,method=RequestMethod.POST)public@ResponseBody String createNewUser(@RequestBody String message){log.info(message);}
HttpURLConnection
不进行此编码,也不进行此编码(显然)没有
DataOutputStream.writeBytes()
。问题在别处。@EJP你说得对,
HttpURLConnection
并没有添加
+
,而是将内容类型默认为
application/x-www-form-urlencoded
,这意味着Servlet容器或Spring框架读取内容并将其作为参数解析,然后当你请求内容时t与
@RequestBody
(与OP一样),它重建了它们,其副作用是将空格编码为
+
。如果内容类型是其他类型,Servlet容器/Spring框架不会这样做,因此我相信设置内容类型仍然是解决问题的方法。您可以将其前后颠倒。Servlet容器将+解码为空格。没有理由r要编码的服务器端。@EJP我的观点是,当“表单字段”作为参数处理,因此当方法使用
@RequestBody
注释请求完整负载时,必须根据参数重新生成。重新生成时不知道原始负载的编码不正确,因此它按照预期的编码方式对其进行编码。@Andreas您是对的,我将内容类型设置为to文本/纯文本,效果很好。非常感谢。