Java调用Python的x-www-form-urlencoded接口实现
本文介绍如何使用Java向Python后端服务发送x-www-form-urlencoded格式的POST请求,适用于Tornado等Python框架搭建的接口。
添加Maven依赖
首先在项目中添加Apache Commons HttpClient依赖:
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
核心实现代码
package com.example.util;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.NameValuePair;
/**
* HTTP POST请求工具类
*/
public class HttpRequestUtil {
/**
* 发送POST请求并获取响应结果
* @param requestUrl 请求地址
* @param content 请求参数内容
* @return 服务端返回的响应字符串
*/
public String doRequest(String requestUrl, String content) {
String response = "请求失败";
try {
response = executePost(requestUrl, content);
} catch (Exception e) {
e.printStackTrace();
}
return decodeUnicode(response);
}
/**
* 执行POST请求
* @param requestUrl 请求URL地址
* @param content POST请求体参数
* @return 响应内容
* @throws Exception 请求过程中的异常
*/
private String executePost(String requestUrl, String content) throws Exception {
PostMethod postRequest = new PostMethod(requestUrl);
// 设置请求头Content-Type为x-www-form-urlencoded
postRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
// 构建请求参数数组,注意不能传NULL,需要传空字符串
NameValuePair[] params = new NameValuePair[2];
params[0] = new NameValuePair("type", "text");
params[1] = new NameValuePair("content", content);
postRequest.setRequestBody(params);
HttpClient httpClient = new HttpClient();
httpClient.executeMethod(postRequest);
String result = postRequest.getResponseBodyAsString();
postRequest.releaseConnection();
return result;
}
/**
* 解码Unicode字符串,将Unicode编码转换为中文
* 处理Python接口返回的中文乱码问题
* @param theString 包含Unicode编码的字符串
* @return 解码后的正常字符串
*/
public static String decodeUnicode(String theString) {
char aChar;
int len = theString.length();
StringBuffer outBuffer = new StringBuffer(len);
for (int x = 0; x < len;) {
aChar = theString.charAt(x++);
if (aChar == '\\') {
aChar = theString.charAt(x++);
if (aChar == 'u') {
// 读取四位十六进制数
int value = 0;
for (int i = 0; i < 4; i++) {
aChar = theString.charAt(x++);
switch (aChar) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
value = (value << 4) + aChar - '0';
break;
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
value = (value << 4) + 10 + aChar - 'a';
break;
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
value = (value << 4) + 10 + aChar - 'A';
break;
default:
throw new IllegalArgumentException("Malformed \\uxxxx encoding.");
}
}
outBuffer.append((char) value);
} else {
if (aChar == 't') {
aChar = '\t';
} else if (aChar == 'r') {
aChar = '\r';
} else if (aChar == 'n') {
aChar = '\n';
} else if (aChar == 'f') {
aChar = '\f';
}
outBuffer.append(aChar);
}
} else {
outBuffer.append(aChar);
}
}
return outBuffer.toString();
}
}
使用示例
public class Main {
public static void main(String[] args) {
HttpRequestUtil util = new HttpRequestUtil();
String result = util.doRequest("http://your-python-server/api/endpoint", "测试内容");
System.out.println("响应结果:" + result);
}
}
关键点说明
- Content-Type设置:必须设置为application/x-www-form-urlencoded,这是Python Tornado等框架默认支持的表单提交格式
- 参数传递:NameValuePair数组不能传null,需要传空字符串
- 连接释放:调用releaseConnection()释放HTTP连接资源
- 字符编码:请求和响应都建议指定utf-8编码,避免中文乱码
- Unicode解码:Python返回的中文字符可能是Unicode编码格式,需要解码处理