使用Delphi的TIdHttp控件发起一个POST请求很简单,定义一个TStringList实例,往上面添加参数就行:
procedure TForm1.Button1Click(Sender: TObject);
var
HttpClient: TIdHttp;
ParamList: TStringList;
begin
HttpClient := TIdHttp.Create();
ParamList := TStringList.Create;
ParamList.Add('user=pan');
ShowMessage(HttpClient.Post('http://192.168.0.105:8080/Servlets/Submit', ParamList));
end;
运行代码,使用WireShark抓包工具看到这个POST请求发出来了,Content-Type是application/x-www-form-urlencoded,这种类型的意思是将参数打包成key-value的形式。
然后来看看服务端的Java代码:
public class Submit extends HttpServlet {
...
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("Hello Servlet, " + request.getParameter("user") + "!");
}
}
客户端收到Post的响应,就会把“Hello Servlet, pan!”这段文字显示出来了。
补充:
当post的参数值带中文时,会被编码为UTF8格式,例如POST方法的WIRESHARK抓包:
再看200 OK消息的抓包:
此时不能直接使用TIdHTTP.Post方法返回的字符串,而是要对其正确解码,否则读到的是乱码:
procedure TForm1.Button1Click(Sender: TObject); var HttpClient: TIdHttp; ParamList: TStringList; SS: TStringStream; begin SS := TStringStream.Create('', TEncoding.UTF8); HttpClient := TIdHttp.Create(); ParamList := TStringList.Create; ParamList.Add('action=测 试'); ParamList.Add('user=用 户'); HttpClient.Post('http://192.168.0.102:8080/HelloServlet/Submit', ParamList, SS); ShowMessage(SS.DataString); end;解决乱码问题的方法在于我们通过TStringStream将返回的字符流按UTF8解码。
补充2:当POST方法中有两个相同的参数名时,例如:
procedure TForm1.Button1Click(Sender: TObject); var HttpClient: TIdHttp; ParamList: TStringList; SS: TStringStream; begin SS := TStringStream.Create('', TEncoding.UTF8); HttpClient := TIdHttp.Create(); ParamList := TStringList.Create; ParamList.Add('action=测 试'); ParamList.Add('user=用 户1'); ParamList.Add('user=用 户2'); HttpClient.Post('http://192.168.0.100:8080/HelloServlet/Submit', ParamList, SS); ShowMessage(SS.DataString); end;
此时在服务器端如果仍然使用getParameter方法,则只能返回第一个值“用 户1”,需要使用getParameterValues方法:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub // response.getWriter().println("Hello Servlet, " + request.getParameter("user") + "!"); String[] user = request.getParameterValues("user"); response.getWriter().println("Hello Servlet, " + user[0] + " and " + user[1] + "!"); }
此时客户端收到:
因此同名参数的两个值都读出来了。