尝试使用JSoup复制成功的POST请求——发送到服务器的数据未被解码

3

HTTP请求头:

Host: www.mysite.com
Content-Type: application/x-www-form-urlencoded
Cookie: bbuserid=XXX; bbpassword=YYY; bbsessionhash=ZZZ
Content-Length: 252

HTTP 请求正文:

message=%E4%F6%F5%FC%E4%F6%F5%FC%E4%F6%F5%FC%E4%F6%F5%FC&securitytoken=XXX&do=postreply&t=483553

工作正常!服务器上发布的数据被解码到另一端,用户看到的是原始消息,其中包含äöõüäöõüäöõüäöõü

现在让我们尝试使用JSoup实现这个确切的例子:

//request body 
Map<String, String> datamap = new HashMap<String, String>();
datamap.put(Session.SESSION_SECURITYTOKEN,"XXX");
datamap.put("message", URLEncoder.encode(finalText, "ISO-8859-1"));
datamap.put("do", "postreply");
datamap.put("t", "483553");

//make a post
Jsoup.connect(url)
.header("Content-Type","application/x-www-form-urlencoded")
.timeout(10000)
.cookie(Session.COOKIE_HASH_KEY,session.bbsessionhash)
.cookie(Session.COOKIE_PASSWORD_KEY,session.bbpassword)
.cookie(Session.COOKIE_USERID_KEY,session.bbuserid)
.data(datamap).post();

我的消息已经发布,但服务器没有对其进行解码。因此,当用户查看消息时,他/她会看到:%E4%F6%F5%FC%E4%F6%F5%FC%E4%F6%F5%FC%E4%F6%F5%FC 注意:我是从Android进行POST请求,并将数据发布到vBulletin论坛软件(回复主题)。
问题:当我使用JSoup发送消息时,服务器将其视为普通文本而不是编码文本。如何让服务器理解消息参数包含编码文本而不是普通文本?

2
我不熟悉Jsoup,但我想它是在data方法中对其参数进行编码。因此,在值上使用URLEncoder.encode会使数据被编码两次。 - McDowell
移除 URLEncoder.encode 会将纯文本添加到消息参数中,我失去了需要编码的特定字符。工作的 POST 请求以某种方式告诉服务器,该消息已编码并且您(服务器)必须对其进行解码。但是当我尝试复制它时,服务器将消息视为纯文本。有什么想法,如何使服务器理解消息参数包含编码文本而不是纯文本? - Indrek Kõue
1个回答

4

Jsoup默认使用UTF-8对查询字符串进行URL编码。当前API版本中,您无法更改它而不重新构建源代码(在org.jsoup.helper.HttpConnection类中使用了org.jsoup.helper.DataUtil#defaultCharset常量)。最好的方法是发布问题报告,请求预先设置字符集的能力。

在此之前,您可以使用HttpClientURLConnection,这些工具允许更精细地控制发送HTTP请求。最后,您可以将其响应作为InputStream提供给Jsoup#parse()方法。


更新:如果目标网站支持,您可以尝试在Content-Type请求头中明确指定客户端使用的字符集:

.header("Content-Type","application/x-www-form-urlencoded;charset=UTF-8")

请注意,您不应该自己使用URLEncoder#encode()方法;让Jsoup处理即可。

那么我的理解是,JSoup会自动将每个HTTP POST请求体编码为UTF-8,而且无法更改(除非编辑JSoup源代码并重新编译jar包)? - Indrek Kõue
没错。Jsoup是一个相对较新的API,需要更多的调优来更好地满足实际应用需求。我们欢迎新的问题和功能请求。还可以参考它的Connection javadoc的最后一段:http://jsoup.org/apidocs/org/jsoup/Connection.html 至于选择UTF-8的原因,那很可能是因为Jsoup被设计成HTML5解析器,而HTML5规定了UTF-8作为默认字符集。从这个角度来看,你的目标网站可以说是“过时”的。 - BalusC
1
请查看答案更新;如果目标网站支持,这将起作用,但如果目标网站没有遵守(那么实际上就是目标网站自己的问题),请不要感到惊讶。 - BalusC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接