如何发送一个HTTP POST请求
如何发送一个HTTP POST请求你可以想象,发送一个HTTP POST请求的处理过程其实与发送一个GET请求非常地类似。我们将修改一个现有命令,添加少量的新的命令,并添加一个来自通用连接框架的附加的对象和一个附加的StringBuffer对象把POST请求体重的内容发送到服务器中。剩下的命令将保持不变。
复制我们刚才创建的sendHttpGet()方法,把它粘贴进同一个类文件,改名为sendHttpPost()。 现在,我们将修改这个新方法来发送一个HTTP POST请求到服务器。 在方法的顶部添加两个新的变量说明。 声明一个类型为DataOutputStream的变量和另一个String类型的变量。 我们将使用DataOutputStream对象把存在于字符串变量中的POST请求体发送到服务器中。
DataOutputStream dos = null; String requestBody = null; |
修改connector.open()命令包含另一个参数,指出连接将允许客户端可以通过连接在服务器上读和写。
hcon = ( HttpConnection ) Connector.open( url, Connector.READ_WRITE ); |
设置HttpConnection对象使用的请求方法为POST(默认的方法是GET)。
hcon.setRequestMethod( HttpConnection.POST ); |
得到一个用于现有的HTTP连接的DataOutputStream对象。
dos = hc.openDataOutputStream(); |
声明一个字节数组并通过检索一个来自requestBody字符串的字节数组初始化。 然后把DataOutputStream的缓冲写入字节数组内。
byte[] byteRequest = requestBody.getBytes(); for( int i = 0; i < byteRequest.length; i++ ) { dos.writeByte(byteRequest[i]); }//结束for( int i = 0; i < byteRequest.length; i++ ) dos.flush(); //包含本句,在某些设被上将可能会产生不可预期的结果 |
调用flush ()方法的意图是发送已经写入的数据到DataOutputStream的服务器的缓冲区中。 在某些电话上,这个操作工作正常,在其他的电话上,它导致HTTP请求的Transfer - Encoding被设置为" chunked ",有一些随机字符被放到请求本身的前面和后面。那又怎样处理这个问题呢?这个方法调用实际上是根本不需要的。在接下来的一行中,服务器连接打开(通过openInputStream ()),将自动输入缓冲区。因此,你最好不要调用缓冲区的flush()方法。这个方法其余的部分保持不变,除了DataOutputStream对象必须在finally{}语句块中关闭。
} finally { if ( hc != null ) hc.close(); if ( dis != null ) dis.close(); if ( dos != null ) dis.close(); }//结束 try/finally |
这就是所有的程序代码!并请参见本文后附带的程序代码。
随着可以使用国际互联网络和支持网络的无线设备日益的增多普及,Java和J2ME的重要性也在不断的变大。因为HTTP协议是当前仅有的,被所有的遵从MIDP规范的设备支持的网络协议,它也是用于开发无线网络应用程序的最好的候选者。
在本文中,我们探究了无线网络编程的基本结构和几个核心问题,我们看了如何调用两个最常用的HTTP请求方法:GET和POST。J2ME仍然在它的发展初期,并且无线设备也即将得到大面积的普及。所以,所有有志投身于无线网络编程中的开发者们将得到大展拳脚的好机会。
附录:
/* * HttpMidlet.java */ import javax.microedition.midlet.*; import javax.microedition.lcdui.*; import javax.microedition.io.*; import java.io.*; public class HttpMidlet extends MIDlet implements CommandListener { //使用默认的URL。用户可以从图形用户接口改变这个值 private static String defaultURL = "http://localhost:8080/test/servlet/EchoServlet"; // 主MIDP 显示 private Display myDisplay = null; // 输入URL的图形用户接口组件 private Form requestScreen; private TextField requestField; // 用于提交请求的图形用户接口组件 private List list; private String[] menuItems; // 用于显示服务器响应的图形用户接口组件 private Form resultScreen; private StringItem resultField; //用于requestScreen的"send"按钮 Command sendCommand; // 用于requestScreen的"exit"按钮 Command exitCommand; // 用于requestScreen的"back"按钮 Command backCommand; public HttpMidlet(){ // 初始化图形用户接口组件 myDisplay = Display.getDisplay( this ); sendCommand = new Command( "SEND", Command.OK, 1 ); exitCommand = new Command( "EXIT", Command.OK, 1 ); backCommand = new Command( "BACK", Command.OK, 1 ); //显示请求的URL requestScreen = new Form( "Type in a URL:" ); requestField = new TextField( null, defaultURL, 100, TextField.URL ); requestScreen.append( requestField ); requestScreen.addCommand( sendCommand ); requestScreen.addCommand( exitCommand ); requestScreen.setCommandListener( this ); // 选择想要的HTTP请求方法 menuItems = new String[] {"GET Request", "POST Request"}; list = new List( "Select an HTTP method:", List.IMPLICIT, menuItems, null ); list.setCommandListener( this ); // 先是从服务器上收到的信息 resultScreen = new Form( "Server Response:" ); resultScreen.addCommand( backCommand ); resultScreen.setCommandListener( this ); }//结束HttpMidlet() public void startApp() { myDisplay.setCurrent( requestScreen ); }//结束 startApp() public void commandAction( Command com, Displayable disp ) { // 当用户点击"send"按钮 if ( com == sendCommand ) { myDisplay.setCurrent( list ); } else if ( com == backCommand ) { requestField.setString( defaultURL ); myDisplay.setCurrent( requestScreen ); } else if ( com == exitCommand ) { destroyApp( true ); notifyDestroyed(); }//结束 if ( com == sendCommand ) if ( disp == list && com == List.SELECT_COMMAND ) { String result; if ( list.getSelectedIndex() == 0 ) // 发送一个 GET 请求到服务器 result = sendHttpGet( requestField.getString() ); else // 发送一个 POST 请求到服务器 result = sendHttpPost( requestField.getString() ); resultField = new StringItem( null, result ); resultScreen.append( resultField ); myDisplay.setCurrent( resultScreen ); }//结束if ( dis == list && com == List.SELECT_COMMAND ) }//结束 commandAction( Command, Displayable ) private String sendHttpGet( String url ) { HttpConnection hcon = null; DataInputStream dis = null; StringBuffer responseMessage = new StringBuffer(); try { //使用READ权限的标准的 HttpConnection hcon = ( HttpConnection )Connector.open( url ); //从HttpConnection取得一个 DataInputStream dis = new DataInputStream( hcon.openInputStream() ); // 从服务器上取回响应 int ch; while ( ( ch = dis.read() ) != -1 ) { responseMessage.append( (char) ch ); }//结束while ( ( ch = dis.read() ) != -1 ) } catch( Exception e ) { e.printStackTrace(); responseMessage.append( "ERROR" ); } finally { try { if ( hcon != null ) hcon.close(); if ( dis != null ) dis.close(); } catch ( IOException ioe ) { ioe.printStackTrace(); }//结束try/catch }//结束try/catch/finally return responseMessage.toString(); }//结束sendHttpGet( String ) private String sendHttpPost( String url ) { HttpConnection hcon = null; DataInputStream dis = null; DataOutputStream dos = null; StringBuffer responseMessage = new StringBuffer(); // 请求体 String requeststring = "This is a POST."; try { // 使用读写权限的 HttpConnection hcon = ( HttpConnection )Connector.open( url, Connector.READ_WRITE ); //设置请求方法为POST hcon.setRequestMethod( HttpConnection.POST ); // 取得发送请求字符串的DataOutputStream dos = hcon.openDataOutputStream(); byte[] request_body = requeststring.getBytes(); // 发送请求字符串到服务器 for( int i = 0; i < request_body.length; i++ ) { dos.writeByte( request_body[i] ); }//结束 for( int i = 0; i < request_body.length; i++ ) // 取得做为接收服务器响应的DataInputStream dis = new DataInputStream( hcon.openInputStream() ); // 从服务器上取回响应 int ch; while( ( ch = dis.read() ) != -1 ) { responseMessage.append( (char)ch ); }//结束while( ( ch = dis.read() ) != -1 ) { } catch( Exception e ) { e.printStackTrace(); responseMessage.append( "ERROR" ); } finally { // 释放输入输出流和HTTP连接 try { if( hcon != null ) hcon.close(); if( dis != null ) dis.close(); if( dos != null ) dos.close(); } catch ( IOException ioe ) { ioe.printStackTrace(); }//结束try/catch }//结束try/catch/finally return responseMessage.toString(); }//结束sendHttpPost( String ) public void pauseApp() { }//结束pauseApp() public void destroyApp( boolean unconditional ) { myDisplay = null; requestScreen = null; requestField = null; resultScreen = null; resultField = null; }//结束 destroyApp( boolean ) }//结束HttpMidlet |