Java 使用Jakarta HttpClient模拟POST网络请求
我尝试模拟由封闭源代码应用程序发送的网络请求。以下 是否从封闭源应用程序捕获网络请求快照:Java 使用Jakarta HttpClient模拟POST网络请求,java,Java,我尝试模拟由封闭源代码应用程序发送的网络请求。以下 是否从封闭源应用程序捕获网络请求快照: - Http: Request, POST /%5bvUpJYKw4QvGRMBmhATUxRwv4JrU9aDnwNEuangVyy6OuHxi2YiY=%5dImage Command: POST - URI: /%5bvUpJYKw4QvGRMBmhATUxRwv4JrU9aDnwNEuangVyy6OuHxi2YiY=%5dImage? Location: /%5bvUpJY
- Http: Request, POST /%5bvUpJYKw4QvGRMBmhATUxRwv4JrU9aDnwNEuangVyy6OuHxi2YiY=%5dImage
Command: POST
- URI: /%5bvUpJYKw4QvGRMBmhATUxRwv4JrU9aDnwNEuangVyy6OuHxi2YiY=%5dImage?
Location: /%5bvUpJYKw4QvGRMBmhATUxRwv4JrU9aDnwNEuangVyy6OuHxi2YiY=%5dImage
ProtocolVersion: HTTP/1.1
- ContentType: application/x-www-form-urlencoded
MediaType: application/x-www-form-urlencoded
Cache-Control: no-cache
Pragma: no-cache
UserAgent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_06
Host: www.xxx.com:20000
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
ContentLength: 164
HeaderEnd: CRLF
- payload: HttpContentType = application/x-www-form-urlencoded
[SORT]: 0,1,0,10,5,0,KL,0
[FIELD]: 33,38,51,58,68,88,78,98,99,101,56,57,69,70,71,72,89,90,91,92,59,60,61,62,79,80,81,82
[LIST]: 1155.KL,1295.KL,7191.KL,0097.KL,2267.KL
我使用httpclient模拟上述请求
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
try {
// TODO code application logic here
HttpClient httpClient = new HttpClient();
httpClient.getParams().setParameter(HttpMethodParams.USER_AGENT, "Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_06");
PostMethod post = new PostMethod("http://www.xxx.com:20000/%5bvUpJYKw4QvGRMBmhATUxRwv4JrU9aDnwNEuangVyy6OuHxi2YiY=%5dImage?");
NameValuePair[] data = {
new NameValuePair("SORT", "0,1,0,10,5,0,KL,0"),
new NameValuePair("FIELD", "33,38,51,58,68,88,78,98,99,101,56,57,69,70,71,72,89,90,91,92,59,60,61,62,79,80,81,82"),
new NameValuePair("LIST", "1155.KL,1295.KL,7191.KL,0097.KL,2267.KL")
};
post.setRequestBody(data);
httpClient.executeMethod(post);
System.out.println(post.getResponseBodyAsString());
}
catch (Exception exp) {
exp.printStackTrace();
}
}
然而,服务器端并没有响应。我尝试捕获自己的网络请求快照:
- Http: Request, POST /%5bvUpJYKw4QvGRMBmhATUxRwv4JrU9aDnwNEuangVyy6OuHxi2YiY=%5dImage
Command: POST
- URI: /%5bvUpJYKw4QvGRMBmhATUxRwv4JrU9aDnwNEuangVyy6OuHxi2YiY=%5dImage
Location: /%5bvUpJYKw4QvGRMBmhATUxRwv4JrU9aDnwNEuangVyy6OuHxi2YiY=%5dImage
ProtocolVersion: HTTP/1.1
UserAgent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_06
Host: www.xxx.com:20000
ContentLength: 234
- ContentType: application/x-www-form-urlencoded
MediaType: application/x-www-form-urlencoded
HeaderEnd: CRLF
- payload: HttpContentType = application/x-www-form-urlencoded
SORT: 0%2C1%2C0%2C10%2C5%2C0%2CKL%2C0
FIELD: 33%2C38%2C51%2C58%2C68%2C88%2C78%2C98%2C99%2C101%2C56%2C57%2C69%2C70%2C71%2C72%2C89%2C90%2C91%2C92%2C59%2C60%2C61%2C62%2C79%2C80%2C81%2C82
LIST: 1155.KL%2C1295.KL%2C7191.KL%2C0097.KL%2C2267.KL
似乎有两种主要的不同:
(1) URI
(2) 有效载荷
我的httpclient代码中有没有遗漏什么
经过几次实验,我意识到,httpclient对我的负载执行URL编码。它明确地转变为
1155.KL,1295.KL,7191.KL,0097.KL,2267.KL
到
1155.KL%2C1295.KL%2C7191.KL%2C0097.KL%2C2267.KL
为了避免这种情况,我编写了一个测试代码。下面的测试代码有效
try {
Socket socket = new Socket("www.xxx.com", 20000);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
final String body = "[SORT]=0,1,0,10,5,0,KL,0&[FIELD]=33,38,51,58,68,88,78,98,99,101,56,57,69,70,71,72,89,90,91,92,59,60,61,62,79,80,81,82&[LIST]=1155.KL,1295.KL,7191.KL,0097.KL,2267.KL";
final int length = body.length();
final String s = "POST /%5bvUpJYKw4QvGRMBmhATUxRwv4JrU9aDnwNEuangVyy6OuHxi2YiY=%5dImage? HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nCache-Control: no-cache\r\nPragma: no-cache\r\nUser-Agent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_06\r\nHost: www.xxx.com:20000\r\nAccept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\nConnection: keep-alive\r\nContent-Length: "+length+"\r\n\r\n" + body;
out.println(s);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true) {
String ss = in.readLine();
if (ss == null) break;
System.out.println(ss);
}
}
catch (Exception exp) {
}
以下是捕获的快照:
Frame: Number = 16, Captured Frame Length = 597, MediaType = ETHERNET
+ Ethernet: Etype = Internet IP (IPv4),DestinationAddress:[7C-04-20-00-01-00],SourceAddress:[01-00-01-00-00-00]
+ Ipv4: Src = 10.176.181.55, Dest = 202.75.55.23, Next Protocol = TCP, Packet ID = 956, Total IP Length = 583
+ Tcp: Flags=...AP..., SrcPort=49253, DstPort=20000, PayloadLen=543, Seq=3920474750 - 3920475293, Ack=3537289604, Win=4380 (scale factor 0x2) = 17520
- Http: Request, POST /%5bvUpJYKw4QvGRMBmhATUxRwv4JrU9aDnwNEuangVyy6OuHxi2YiY=%5dImage
Command: POST
+ URI: /%5bvUpJYKw4QvGRMBmhATUxRwv4JrU9aDnwNEuangVyy6OuHxi2YiY=%5dImage?
ProtocolVersion: HTTP/1.1
+ ContentType: application/x-www-form-urlencoded
Cache-Control: no-cache
Pragma: no-cache
UserAgent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_06
Host: n2ntbfd03.asiaebroker.com:20000
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
ContentLength: 164
HeaderEnd: CRLF
- payload: HttpContentType = application/x-www-form-urlencoded
[SORT]: 0,1,0,10,5,0,KL,0
[FIELD]: 33,38,51,58,68,88,78,98,99,101,56,57,69,70,71,72,89,90,91,92,59,60,61,62,79,80,81,82
[LIST]: 1155.KL,1295.KL,7191.KL,0097.KL,2267.KL
您是如何创建快照的?参数名称周围的括号是什么意思?同一个参数是否有多个值,而不是一个用逗号分隔的值,或者参数名称是否应该用括号括起来?您还缺少标题: 接受 缓存控制 布拉格马 仅Accept头就足以让服务器做出有意义的响应。对于httpclient 4,请尝试以下操作:
httpclient.addRequestInterceptor(new HttpRequestInterceptor() {
public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException {
request.setHeader("Pragma","no-cache");
request.setHeader("Cache-Control","no-cache");
request.setHeader("Accept","text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2");
}
});
或者类似于httpclient 3.x的内容:
method.setRequestHeader("Pragma","no-cache");
method.setRequestHeader("Cache-Control","no-cache");
method.setRequestHeader("Accept","text/html, image/gif, image/jpeg, *; q=.2, */*;
根据捕获排序与[排序]中参数名称的显示方式判断。我怀疑服务器希望您发送带有多个表单控件的数组,如 排序=0&SORT=1&SORT=0 他们可能将此作为一种安全措施,因为这不能用HTML实现 编辑:您需要像这样传递参数
NameValuePair[] data = {
new NameValuePair("SORT", "0"),
new NameValuePair("SORT", "1"),
...
new NameValuePair("FIELD", "33"),
...
};
很抱歉我正在使用HttpClient 3.1您能捕获原始请求吗?可能快照中出现的列表如下所示:SORT=0&SORT=1&SORT=0。。。但是您用于捕获请求的软件正在对列表进行漂亮的打印。现在真正的问题是,如何避免HttpClient对我的负载执行URL编码?请尝试捕获原始请求,以便我们可以查看列表是如何发布的。Fiddler是免费的,但只在windows上工作。查尔斯有30天的免费试用期。@Yan。您永远不希望在没有URL编码的情况下发送有效负载。它总是被编码的。你的捕获程序为你解码并组合了它。请参阅我编辑的答案。这是“选择多个值”的发布方式。否。这不管用。服务器希望看到原始“[SORT]=0,1,0,10,5,0,KL,0&[FIELD]=33,…”。但是HttpClient将始终执行URL编码。我使用原始TCP套接字对数据进行测试,没有编码,效果非常好。但是,我需要使用HttpClient,因为它支持NTLM。服务器当时不使用HTTP。只需组成你自己的身体和回应。setBody()。请参阅了解解决方案