JAVA中使用UTF-8进行Http POST请求

9

我的J2EE应用程序可以从JSP页面接收POST请求,这一点没有问题。

但是,如果我使用另一个Java应用程序发送POST请求,则接收到的参数不是UTF-8字符串。

以下是我的代码:

URL url = new URL("http://localhost:8080/ITUNLPWebInterface/SimpleApi");
HttpURLConnection cox = (HttpURLConnection) url.openConnection();

cox.setDoInput(true);
cox.setDoOutput(true);
cox.setRequestMethod("POST");
cox.setRequestProperty("Accept-Charset", "UTF-8");
cox.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
cox.setRequestProperty("charset", "UTF-8");

DataOutputStream dos = new DataOutputStream(cox.getOutputStream());
String query = "tool=ner&input=şaşaşa";
dos.writeBytes(query);
dos.close();

我做错了什么吗?

谢谢您的回复。


你尝试将 application/x-www-form-urlencoded; charset=utf-8 更改为 application/x-www-form-urlencoded - Rong Nguyen
同样,服务器无法看到参数... - tom
6个回答

14

这个工作!!!

package com.erenerdogan.utils;

import com.erenerdogan.webservice.ServiceInterface;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;

/**
 *
 * @author erenerdogan
 */
public class WebService 
{
private String server;

    public WebService(String server) {
        this.server = server;
    }

private HttpPost createPostRequest(String method, Map<String, String> paramPairs){
    // Creating HTTP Post
    HttpPost httpPost = new HttpPost(server + "/" + method);
    // Building post parameters
    List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(paramPairs.size());
    for (String key : paramPairs.keySet()){
        nameValuePair.add(new BasicNameValuePair(key, paramPairs.get(key)));
            System.out.println("Key : "+ key + " - Value : "+ paramPairs.get(key) );
    }

    // Url Encoding the POST parameters
    try {
        httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair,"UTF-8"));
    } catch (UnsupportedEncodingException e) {
        // writing error to Log
        e.printStackTrace();
    }
    return httpPost;
}

public String callServer(String method, Map<String, String> paramPairs) throws ClientProtocolException, IOException{

    // Creating HTTP client
    HttpClient httpClient = new DefaultHttpClient();

    HttpParams httpParameters = httpClient.getParams();
    HttpConnectionParams.setConnectionTimeout(httpParameters, 10 * 1000);
    HttpConnectionParams.setSoTimeout(httpParameters, 3 * 1000);
    HttpResponse httpResponse = httpClient.execute(createPostRequest(method, paramPairs));
    HttpEntity httpEntity = httpResponse.getEntity();
    String xml = EntityUtils.toString(httpEntity);

    return xml;
}
}

最重要的一行是 httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair,"UTF-8"));,这对我很有效。 - Sourav Kanta

6

DataOutputStream.writeBytes(String)的文档说明如下:

将字符串作为字节序列写入底层输出流。将按顺序写入字符串中的每个字符,通过舍弃其高8位。如果未抛出异常,则计数器会递增s的长度。

改用cox.getOutputStream().write(query.getBytes("UTF-8"));

此处DataOutputStream是多余的。


DataOutputStream 类中的 writeBytes(String) 方法不适用于参数 (byte[])。所以我认为我们不能使用这种方式,对吧? - tom
谢谢您的回复,我刚刚尝试了一下,但仍然是“?”而不是特殊字符。 - tom
你的源文件使用哪种编码保存的?并且你是否在javac中指定了它? - Christoffer Hammarström
好的,我找到了这个错误。为了让我的请求在Firefox(直接请求)中工作,我必须使用ISO-8859-1接收,然后转换为UTF-8。现在它可以工作了,但是从URI地址栏获取Firefox GET请求就不行了。至少... - tom

2

试试这个

HttpClient client = new DefaultHttpClient();
HttpPost port = new HttpPost("http://localhost:8080/ITUNLPWebInterface/SimpleApi");

List<NameValuePair> parameters = new ArrayList<NameValuePair>(3);
parameters.add(new BasicNameValuePair("tool", "ner"));
parameters.add(new BasicNameValuePair("input", "şaşaşa"));
//post.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
post.setEntity(new UrlEncodedFormEntity(params, "ISO-8859-3")); //try this one

HttpResponse resp = client.execute(post);

https://en.wikipedia.org/wiki/ISO/IEC_8859-3 似乎支持您的特殊字符 ş


好的,我已经做了,结果一样,在服务器上我得到的是'?'而不是特殊字符。 - tom
在我的测试用例中它可以工作,你能否发布你的结果和读取这些参数的类?这样我可以更好地帮助你。 - Emanuele
尝试其他两件事情... 尝试将ISO-8859-3添加为字符集, 并尝试编辑post.setEntity(new UrlEncodedFormEntity(params, "ISO-8859-3")); - Emanuele
我刚试了一下,还是“?”。我要疯了。 顺便说一下,因为是土耳其语,所以它是ISO-8859-9。 - tom
请提供您的服务器代码或一些测试用例以重现您的行为。 - Emanuele

2

对我很有效:

connection = (HttpURLConnection) url.openConnection();
...
byte[] data = message.getBytes("UTF-8");
...
DataOutputStream wr = new DataOutputStream(
connection.getOutputStream());
wr.write(data);
wr.close();

0

基于 HttpClient 的例子 "FluentRequests.java":

Content content = Request.Post("http://localhost:8080/ITUNLPWebInterface/SimpleApi")
        .body(new UrlEncodedFormEntity(
                Form.form()
                .add("tool", "ner")
                .add("input", "şaşaşa")
                .build(), "UTF-8"))
        .execute().returnContent();
System.out.println(content);

0

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