Android使用HttpUrlConnection请求服务器发送数据详解

来源:互联网 发布:今天原油api数据 编辑:程序博客网 时间:2024/06/05 04:37
HttpUrlConnection是java内置的api,在java.net包下,那么,它请求网络同样也有get请求和post请求两种方式。最常用的Http请求无非是get和post,get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servlet,post与get的不同之处在于post的参数不是放在URL字串里面,而是放在http请求的正文内。

在Java中可以使用HttpURLConnection发起这两种请求,了解此类,对于了解soap,和编写servlet的自动测试代码都有很大的帮助。


一、那么我们先来看看用HttpUrlConnection怎样用Post发起请求传输json数据(这里以常用的json作为示例):

[java] view plain copy
print?
  1. public void httpUrlConnPost(String name,String password){  
  2.         HttpURLConnection urlConnection = null;  
  3.         URL url = null;  
  4.         try {  
  5.              url = new URL("http://192.168.1.105:8080/KYDServer/servlet/Login");  
  6.              urlConnection = (HttpURLConnection) url.openConnection();//打开http连接  
  7.              urlConnection.setConnectTimeout(3000);//连接的超时时间  
  8.              urlConnection.setUseCaches(false);//不使用缓存  
  9.              //urlConnection.setFollowRedirects(false);是static函数,作用于所有的URLConnection对象。  
  10.              urlConnection.setInstanceFollowRedirects(true);//是成员函数,仅作用于当前函数,设置这个连接是否可以被重定向  
  11.              urlConnection.setReadTimeout(3000);//响应的超时时间  
  12.              urlConnection.setDoInput(true);//设置这个连接是否可以写入数据  
  13.              urlConnection.setDoOutput(true);//设置这个连接是否可以输出数据  
  14.              urlConnection.setRequestMethod("POST");//设置请求的方式  
  15.              urlConnection.setRequestProperty("Content-Type""application/json;charset=UTF-8");//设置消息的类型  
  16.              urlConnection.connect();// 连接,从上述至此的配置必须要在connect之前完成,实际上它只是建立了一个与服务器的TCP连接  
  17.              JSONObject json = new JSONObject();//创建json对象  
  18.              json.put("name", URLEncoder.encode(name, "UTF-8"));//使用URLEncoder.encode对特殊和不可见字符进行编码  
  19.              json.put("password", URLEncoder.encode(password, "UTF-8"));//把数据put进json对象中  
  20.              String jsonstr = json.toString();//把JSON对象按JSON的编码格式转换为字符串  
  21.              //-------------使用字节流发送数据--------------            
  22.              //OutputStream out = urlConnection.getOutputStream();  
  23.              //BufferedOutputStream bos = new BufferedOutputStream(out);//缓冲字节流包装字节流  
  24.              //byte[] bytes = jsonstr.getBytes("UTF-8");//把字符串转化为字节数组  
  25.              //bos.write(bytes);//把这个字节数组的数据写入缓冲区中  
  26.              //bos.flush();//刷新缓冲区,发送数据  
  27.              //out.close();  
  28.              //bos.close();  
  29.              //------------字符流写入数据------------  
  30.              OutputStream out = urlConnection.getOutputStream();//输出流,用来发送请求,http请求实际上直到这个函数里面才正式发送出去  
  31.              BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));//创建字符流对象并用高效缓冲流包装它,便获得最高的效率,发送的是字符串推荐用字符流,其它数据就用字节流  
  32.              bw.write(jsonstr);//把json字符串写入缓冲区中  
  33.              bw.flush();//刷新缓冲区,把数据发送出去,这步很重要  
  34.              out.close();  
  35.              bw.close();//使用完关闭  
  36.                
  37.              if(urlConnection.getResponseCode()==HttpURLConnection.HTTP_OK){//得到服务端的返回码是否连接成功  
  38.                  //------------字节流读取服务端返回的数据------------                   
  39.                  //InputStream in = urlConnection.getInputStream();//用输入流接收服务端返回的回应数据  
  40.                  //BufferedInputStream bis = new BufferedInputStream(in);//高效缓冲流包装它,这里用的是字节流来读取数据的,当然也可以用字符流  
  41.                  //byte[] b = new byte[1024];  
  42.                  //int len = -1;  
  43.                  //StringBuffer buffer = new StringBuffer();//用来接收数据的StringBuffer对象  
  44.                  //while((len=bis.read(b))!=-1){  
  45.                  //buffer.append(new String(b, 0, len));//把读取到的字节数组转化为字符串  
  46.                  //}  
  47.                  //in.close();  
  48.                  //bis.close();  
  49.                  //Log.d("zxy", buffer.toString());//{"json":true}  
  50.                  //JSONObject rjson = new JSONObject(buffer.toString());//把返回来的json编码格式的字符串数据转化成json对象  
  51.                  //------------字符流读取服务端返回的数据------------                      
  52.                  InputStream in = urlConnection.getInputStream();  
  53.                  BufferedReader br = new BufferedReader(new InputStreamReader(in));  
  54.                  String str = null;  
  55.                  StringBuffer buffer = new StringBuffer();  
  56.                  while((str = br.readLine())!=null){//BufferedReader特有功能,一次读取一行数据  
  57.                      buffer.append(str);  
  58.                  }  
  59.                  in.close();  
  60.                  br.close();  
  61.                  JSONObject rjson = new JSONObject(buffer.toString());  
  62.                    
  63.                  Log.d("zxy""rjson="+rjson);//rjson={"json":true}  
  64.                  boolean result = rjson.getBoolean("json");//从rjson对象中得到key值为"json"的数据,这里服务端返回的是一个boolean类型的数据  
  65.                  if(result){//判断结果是否正确  
  66.                      mHandler.sendEmptyMessage(USERLOGIN_SUCCESS);  
  67.                  }else{  
  68.                      mHandler.sendEmptyMessage(USERLOGIN_FAILED);  
  69.                  }  
  70.              }else{  
  71.                  mHandler.sendEmptyMessage(USERLOGIN_FAILED);  
  72.              }  
  73.         } catch (Exception e) {  
  74.              mHandler.sendEmptyMessage(USERLOGIN_FAILED);  
  75.         }finally{  
  76.             urlConnection.disconnect();//使用完关闭TCP连接,释放资源  
  77.         }  
  78.     }  

服务端的代码为:(使用HttpUrlConnection,服务端是用输入流来读取客户端发过来的数据。而使用HttpClient的话,则服务端用相应的key值来获取数据)

[java] view plain copy
print?
  1. public void doPost(HttpServletRequest request,  
  2.             HttpServletResponse response) throws ServletException, IOException {  
  3.         request.setCharacterEncoding("UTF-8");  
  4.         System.out.println(request.getContentType());//得到客户端发送过来内容的类型,application/json;charset=UTF-8  
  5.         System.out.println(request.getRemoteAddr());//得到客户端的ip地址,192.168.1.101  
  6.         //------------使用字节流读取客户端发送过来的数据------------  
  7.         // BufferedInputStream bis = new BufferedInputStream(request.getInputStream());  
  8.         // byte[] b = new byte[1024];  
  9.         // int len=-1;  
  10.         // StringBuffer buffer = new StringBuffer();  
  11.         // while((len=bis.read(b))!=-1){  
  12.         // buffer.append(new String(b, 0, len));  
  13.         // }  
  14.         // bis.close();  
  15.         // System.out.println("buffer="+buffer);  
  16.         // JSONObject json = JSONObject.fromObject(buffer.toString());  
  17.   
  18.         BufferedReader br = new BufferedReader(new InputStreamReader(//使用字符流读取客户端发过来的数据  
  19.                 request.getInputStream()));  
  20.         String line = null;  
  21.         StringBuffer s = new StringBuffer();  
  22.         while ((line = br.readLine()) != null) {  
  23.             s.append(line);  
  24.         }  
  25.         br.close();  
  26.         System.out.println(s.toString());//{"password":"123456","name":"admin"}  
  27.         JSONObject json = JSONObject.fromObject(s.toString());//转化为jSONObject对象  
  28.   
  29.         String name = json.getString("name");//从json对象中得到相应key的值  
  30.         String password = json.getString("password");  
  31.           
  32.         response.setCharacterEncoding("UTF-8");  
  33.         response.setContentType("application/json;charset=UTF-8");  
  34.         if (name.equals("admin") && password.equals("123456")) {  
  35.             JSONObject rjson = new JSONObject();  
  36.             rjson.put("json"true);//返回boolean类型的值  
  37.             System.out.println("rjson=" + rjson);  
  38.             // response.getWriter().write(rjson.toString());//向客户端发送一个带有json对象内容的响应  
  39.             response.getOutputStream().write(rjson.toString().getBytes("UTF-8"));//向客户端发送一个带有json对象内容的响应  
  40.         } else {  
  41.             JSONObject rjson = new JSONObject();  
  42.             rjson.put("json"false);  
  43.             System.out.println("rjson=" + rjson);  
  44.             // response.getWriter().write(rjson.toString());//向客户端发送一个带有json对象内容的响应  
  45.             response.getOutputStream().write(rjson.toString().getBytes("UTF-8"));//向客户端发送一个带有json对象内容的响应  
  46.         }  
  47.     }  

二、我们再来看看用Get请求:

[java] view plain copy
print?
  1. public void httpUrlConnGet(String name,String password){  
  2.         HttpURLConnection urlConnection = null;  
  3.         URL url = null;  
  4.         try {  
  5.             String urlStr = "http://192.168.1.105:8080/KYDServer/servlet/Login?name="+name+"&password="+password;  
  6.             url = new URL(urlStr);  
  7.             urlConnection = (HttpURLConnection) url.openConnection();  
  8.             urlConnection.connect();  
  9.             if(urlConnection.getResponseCode()==HttpURLConnection.HTTP_OK){  
  10.                 InputStream in = urlConnection.getInputStream();  
  11.                 BufferedReader br = new BufferedReader(new InputStreamReader(in));  
  12.                 String line = null;  
  13.                 StringBuffer buffer = new StringBuffer();  
  14.                 while((line=br.readLine())!=null){  
  15.                     buffer.append(line);  
  16.                 }  
  17.                 in.close();  
  18.                 br.close();  
  19.                 String result = buffer.toString();  
  20.                 if(result.equals("ok")){  
  21.                     mHandler.sendEmptyMessage(USERLOGIN_SUCCESS);  
  22.                 }else{  
  23.                     mHandler.sendEmptyMessage(USERLOGIN_FAILED);  
  24.                 }  
  25.             }else{  
  26.                 mHandler.sendEmptyMessage(CONN_FIALED);  
  27.             }  
  28.         } catch (Exception e) {  
  29.             mHandler.sendEmptyMessage(CONN_FIALED);  
  30.         }finally{  
  31.             urlConnection.disconnect();  
  32.         }  
  33.     }  
Get请求的服务端代码我就不写啦,但是服务端是用key值来获取数据的哦,这个和post的方式不同。

所以总结一下:

  • 使用HttpUrlConnection请求服务器的话:

用Get请求:客户端的数据是放在url中的,通过url来传给服务器。服务端接收客户端发来的数据是用对应的key值的,服务端返回数据给客户端是用response.getWriter().write()或response.getOutputStream().write()来返回的,客户端接收服务端返回来的数据是用urlConnection.getInputStream()输入流来读取的。

用Post请求:客户端的数据是放在正文中的,即是通过urlConnection.getOutputStream()输出流来发送给服务器的。服务端接收客户端发来的数据是用request.getInputStream()输入流来读取的,服务端返回数据给客户端是用response.getWriter().write()或response.getOutputStream().write()来返回的客户端接收服务端返回来的数据是用urlConnection.getInputStream()输入流来读取的。【注】:使用HttpUrlConnection客户端的发送和接收数据都是用流操作的。

  • 使用HttpClient请求服务器的话:

用Get请求:客户端的数据是放在url中的,通过url传给服务器。服务端接收客户端发来的数据是用对应的key值的,服务端返回数据给客户端是用response.getWriter().write()或response.getOutputStream().write()来返回的,客户端接收服务端返回来的数据是用

response.getEntity()来接收。

用Post请求:客户端的数据是放在List<NameValuePair>parameters集合中,通过post.setEntity(new UrlEncodedFormEntity(parameters, "UTF-8"))发送给服务器。服务端接收客户端发来的数据是用对应的key值的,服务端返回数据给客户端是用response.getWriter().write()或response.getOutputStream().write()来返回的客户端接收服务端返回来的数据是用

response.getEntity()来接收。


HttpURLConnection.connect()函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。无论是post还是get,http请求实际上直到HttpURLConnection.getInputStream()这个函数里面才正式发送出去。

在HttpUrlConnection
中,顺序是重中之重,对urlConnection对象的一切配置(那一堆set函数)都必须要在connect()函数执行之前完成。

http请求实际上由两部分组成,一个是http头,所有关于此次http请求的配置都在http头里面定义,另一个是正文content。在connect()函数里面,会根据HttpURLConnection对象的配置值生成http头,因此在调用connect函数之前,就必须把所有的配置准备好。
紧接着http头的是http请求的正文,正文的内容通过outputStream写入,实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络,而是在流关闭后,根据输入的内容生成http正文。


转载请注明出处!!!

 
2 0