Android使用HttpUrlConnection请求服务器发送数据详解
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作为示例):
public void httpUrlConnPost(String name,String password){ HttpURLConnection urlConnection = null; URL url = null; try { url = new URL("http://192.168.1.105:8080/KYDServer/servlet/Login"); urlConnection = (HttpURLConnection) url.openConnection();//打开http连接 urlConnection.setConnectTimeout(3000);//连接的超时时间 urlConnection.setUseCaches(false);//不使用缓存 //urlConnection.setFollowRedirects(false);是static函数,作用于所有的URLConnection对象。 urlConnection.setInstanceFollowRedirects(true);//是成员函数,仅作用于当前函数,设置这个连接是否可以被重定向 urlConnection.setReadTimeout(3000);//响应的超时时间 urlConnection.setDoInput(true);//设置这个连接是否可以写入数据 urlConnection.setDoOutput(true);//设置这个连接是否可以输出数据 urlConnection.setRequestMethod("POST");//设置请求的方式 urlConnection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");//设置消息的类型 urlConnection.connect();// 连接,从上述至此的配置必须要在connect之前完成,实际上它只是建立了一个与服务器的TCP连接 JSONObject json = new JSONObject();//创建json对象 json.put("name", URLEncoder.encode(name, "UTF-8"));//使用URLEncoder.encode对特殊和不可见字符进行编码 json.put("password", URLEncoder.encode(password, "UTF-8"));//把数据put进json对象中 String jsonstr = json.toString();//把JSON对象按JSON的编码格式转换为字符串 //-------------使用字节流发送数据-------------- //OutputStream out = urlConnection.getOutputStream(); //BufferedOutputStream bos = new BufferedOutputStream(out);//缓冲字节流包装字节流 //byte[] bytes = jsonstr.getBytes("UTF-8");//把字符串转化为字节数组 //bos.write(bytes);//把这个字节数组的数据写入缓冲区中 //bos.flush();//刷新缓冲区,发送数据 //out.close(); //bos.close(); //------------字符流写入数据------------ OutputStream out = urlConnection.getOutputStream();//输出流,用来发送请求,http请求实际上直到这个函数里面才正式发送出去 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));//创建字符流对象并用高效缓冲流包装它,便获得最高的效率,发送的是字符串推荐用字符流,其它数据就用字节流 bw.write(jsonstr);//把json字符串写入缓冲区中 bw.flush();//刷新缓冲区,把数据发送出去,这步很重要 out.close(); bw.close();//使用完关闭 if(urlConnection.getResponseCode()==HttpURLConnection.HTTP_OK){//得到服务端的返回码是否连接成功 //------------字节流读取服务端返回的数据------------ //InputStream in = urlConnection.getInputStream();//用输入流接收服务端返回的回应数据 //BufferedInputStream bis = new BufferedInputStream(in);//高效缓冲流包装它,这里用的是字节流来读取数据的,当然也可以用字符流 //byte[] b = new byte[1024]; //int len = -1; //StringBuffer buffer = new StringBuffer();//用来接收数据的StringBuffer对象 //while((len=bis.read(b))!=-1){ //buffer.append(new String(b, 0, len));//把读取到的字节数组转化为字符串 //} //in.close(); //bis.close(); //Log.d("zxy", buffer.toString());//{"json":true} //JSONObject rjson = new JSONObject(buffer.toString());//把返回来的json编码格式的字符串数据转化成json对象 //------------字符流读取服务端返回的数据------------ InputStream in = urlConnection.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String str = null; StringBuffer buffer = new StringBuffer(); while((str = br.readLine())!=null){//BufferedReader特有功能,一次读取一行数据 buffer.append(str); } in.close(); br.close(); JSONObject rjson = new JSONObject(buffer.toString()); Log.d("zxy", "rjson="+rjson);//rjson={"json":true} boolean result = rjson.getBoolean("json");//从rjson对象中得到key值为"json"的数据,这里服务端返回的是一个boolean类型的数据 if(result){//判断结果是否正确 mHandler.sendEmptyMessage(USERLOGIN_SUCCESS); }else{ mHandler.sendEmptyMessage(USERLOGIN_FAILED); } }else{ mHandler.sendEmptyMessage(USERLOGIN_FAILED); } } catch (Exception e) { mHandler.sendEmptyMessage(USERLOGIN_FAILED); }finally{ urlConnection.disconnect();//使用完关闭TCP连接,释放资源 } }
服务端的代码为:(使用HttpUrlConnection,服务端是用输入流来读取客户端发过来的数据。而使用HttpClient的话,则服务端用相应的key值来获取数据)
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); System.out.println(request.getContentType());//得到客户端发送过来内容的类型,application/json;charset=UTF-8 System.out.println(request.getRemoteAddr());//得到客户端的ip地址,192.168.1.101 //------------使用字节流读取客户端发送过来的数据------------ // BufferedInputStream bis = new BufferedInputStream(request.getInputStream()); // byte[] b = new byte[1024]; // int len=-1; // StringBuffer buffer = new StringBuffer(); // while((len=bis.read(b))!=-1){ // buffer.append(new String(b, 0, len)); // } // bis.close(); // System.out.println("buffer="+buffer); // JSONObject json = JSONObject.fromObject(buffer.toString()); BufferedReader br = new BufferedReader(new InputStreamReader(//使用字符流读取客户端发过来的数据 request.getInputStream())); String line = null; StringBuffer s = new StringBuffer(); while ((line = br.readLine()) != null) { s.append(line); } br.close(); System.out.println(s.toString());//{"password":"123456","name":"admin"} JSONObject json = JSONObject.fromObject(s.toString());//转化为jSONObject对象 String name = json.getString("name");//从json对象中得到相应key的值 String password = json.getString("password"); response.setCharacterEncoding("UTF-8"); response.setContentType("application/json;charset=UTF-8"); if (name.equals("admin") && password.equals("123456")) { JSONObject rjson = new JSONObject(); rjson.put("json", true);//返回boolean类型的值 System.out.println("rjson=" + rjson); // response.getWriter().write(rjson.toString());//向客户端发送一个带有json对象内容的响应 response.getOutputStream().write(rjson.toString().getBytes("UTF-8"));//向客户端发送一个带有json对象内容的响应 } else { JSONObject rjson = new JSONObject(); rjson.put("json", false); System.out.println("rjson=" + rjson); // response.getWriter().write(rjson.toString());//向客户端发送一个带有json对象内容的响应 response.getOutputStream().write(rjson.toString().getBytes("UTF-8"));//向客户端发送一个带有json对象内容的响应 } }
二、我们再来看看用Get请求:
public void httpUrlConnGet(String name,String password){ HttpURLConnection urlConnection = null; URL url = null; try { String urlStr = "http://192.168.1.105:8080/KYDServer/servlet/Login?name="+name+"&password="+password; url = new URL(urlStr); urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.connect(); if(urlConnection.getResponseCode()==HttpURLConnection.HTTP_OK){ InputStream in = urlConnection.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String line = null; StringBuffer buffer = new StringBuffer(); while((line=br.readLine())!=null){ buffer.append(line); } in.close(); br.close(); String result = buffer.toString(); if(result.equals("ok")){ mHandler.sendEmptyMessage(USERLOGIN_SUCCESS); }else{ mHandler.sendEmptyMessage(USERLOGIN_FAILED); } }else{ mHandler.sendEmptyMessage(CONN_FIALED); } } catch (Exception e) { mHandler.sendEmptyMessage(CONN_FIALED); }finally{ urlConnection.disconnect(); } }
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正文。
转载请注明出处!!!
Android使用HttpUrlConnection请求服务器发送数据详解的更多相关文章
- Android使用HttpClient以Post、Get请求服务器发送数据的方式(普通和json)
讲这个之前,我们先来说说get和post两种请求的区别吧!!! 1. GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditPosts.jsp?name=te ...
- Android - 向服务器发送数据(GET).
在此,使用HTTP协议,通过GET请求,向服务器发送请求,这种方式适合于数据量小,数据安全性要求不高的情况下. 一,服务器端,使用Servlet. 在服务器端,定义一个HttpServlet的子类,以 ...
- 使用HttpURLConnection向服务器发送post和get请求
一.使用HttpURLConnection向服务器发送get请求 1.向服务器发送get请求 @Test publicvoid sendSms() throws Exception{ String m ...
- Android - 向服务器发送数据(POST) - HTTPClient.
该篇文章主要说明使用Apache提供的HTTPClient,通过post方式,向服务器发送数据.由于有些东西在 Android - 向服务器发送数据(GET)中提到过,就不再重复. 一,Android ...
- [android]-如何在向服务器发送request时附加已保存的cookie数据
[android]-如何在向服务器发送request时附加已保存的cookie数据 应用场景:在开发android基于手机端+服务器端的应用时,登陆->获取用户信息->获取授权用户相关业务 ...
- 使用HttpURLConnection向服务器发送post和get请求(转)
一.使用HttpURLConnection向服务器发送get请求 1.向服务器发送get请求 @Test publicvoid sendSms() throws Exception{ String m ...
- 使用post()方法以POST方式从服务器发送数据
使用post()方法以POST方式从服务器发送数据 与get()方法相比,post()方法多用于以POST方式向服务器发送数据,服务器接收到数据之后,进行处理,并将处理结果返回页面,调用格式如下: $ ...
- C语言Socket-单工通信(客户端向服务器发送数据)
服务端(server) #include <stdio.h> #include <winsock2.h> #pragma comment(lib,"ws2_32.li ...
- android bundle存放数据详解
转载自:android bundle存放数据详解 正如大家所知道,Activity之间传递数据,是将数据存放在Intent或者Bundle中 例如: 将数据存放倒Intent中传递: 将数据放到Bun ...
随机推荐
- 【实验吧】CTF_Web_天下武功唯快不破
打开链接"http://ctf5.shiyanbar.com/web/10/10.php",从页面内容未发现明显信息,查看源代码发现"please post what y ...
- Redis常用命令--Keys
Redis是一个key-value型的数据库. 所以在Redis也提供了很多操作key的命令,大概有22个. EXISTS key [key ...]:查询一个key是否存在,时间复杂度为O(1),存 ...
- Mac终端开启代理
使用shadowsocks开启代理,只支持浏览器开启代理,其他软件是不能够开启代理的,因为这个问题,自己一直无法用本地终端 git clone 一些库,网上查找方法,总结如下: 步骤一:开启shado ...
- 计蒜客NOIP模拟赛(2)D1T3 深黑幻想
[问题描述] 凡终于发愤图强,决定专心搞OI,不再玩纸牌和坑钱了!没过多久就飘飘然了,总是陷入自己进了集训队的深黑幻想之中. 样听说了之后,决定考一考凡欧拉回路怎么写.样:“我给你出一道题 ...
- 【Uva 11280 飞到弗雷德里顿】
·你可以尽情地坐飞机,但停留次数遭到限制. ·英文题,述大意: 给出一张有向图,起点是输入的第一个城市,终点是输入的最后一个城市.给出q个询问,每个询问含一个t,表示 #include&l ...
- 单纯形求解线性规划(BZOJ1061)
推荐一篇论文:http://wenku.baidu.com/view/ce5784754a7302768f99391d 我们设xi为第i个志愿者的招募次数,以样例为例,则不难列出如下的线性规划方程: ...
- SpringCloud学习之快速搭建分布式配置
一. 关于spring-cloud中的分布式配置 Spring Cloud Config为分布式系统中的外部配置提供服务器和客户端支持.使用Config Server,您可以在所有环境中管理应用程序的 ...
- c语言程序设计第四次作业——顺序结构
(一)改错题 输出三角形的面积和周长,输入三角形的三条边a.b.c,如果能构成一个三角形,输出面积area和周长perimeter(保留2位小数):否则,输出"These sides do ...
- Java锁机制了解一下
前言 回顾前面: 多线程三分钟就可以入个门了! Thread源码剖析 多线程基础必要知识点!看了学习多线程事半功倍 只有光头才能变强! 本文章主要讲的是Java多线程加锁机制,有两种: Synchro ...
- 西安电话面试:谈谈Vue数据双向绑定原理,看看你的回答能打几分
最近我参加了一次来自西安的电话面试(第二轮,技术面),是大厂还是小作坊我在这里按下不表,先来说说这次电面给我留下印象较深的几道面试题,这次先来谈谈Vue的数据双向绑定原理. 情景再现: 当我手机铃声响 ...