A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 孟凡凯老师 于 2016-5-30 19:55 编辑

【济南校区】凯哥兵法之网络编程
概述:
     在公司中Android程序基本上不可能不联网的,网络编程是每个程序员的必备技能。android系统中主要提供了两种方式来进行HTTP通信HttpURLConnection和HttpClient。   
下面简单介绍一下Get请求的使用:
httpUrlConnection的get请求:
  1. public static String httpUrlConnectionForGet(String url_str) throws Exception {
  2.     //1.创建Url对象。
  3.     URL url = new URL(url_str);
  4.     //2.通过Url获取一个HttpUrlConnection对象
  5.     HttpURLConnection openConnection = (HttpURLConnection) url.openConnection();
  6.     //3.为HttpUrlConnection对象设置请求方式,联网的超时时间
  7.     openConnection.setRequestMethod("GET");//请求方式必须大写
  8.     openConnection.setConnectTimeout(10 * 1000);//设置超时时间
  9.     //4.获取服务器的响应码,判断是否请求成功
  10.     int code = openConnection.getResponseCode();
  11.     if (code == 200) {
  12.         //5.200表示请求成功,获取流信息200 成功 206 请求部分资源成功 300 跳转  400 失败  500 服务器错
  13.         InputStream inputStream = openConnection.getInputStream();
  14.         //6.将流信息转换成字符串
  15.         result = Utils.StreamToString(inputStream);
  16.         //7.关闭资源
  17.         inputStream.close();
  18.         return result;
  19.     }
  20.     return result;
  21. }
复制代码
HttpClient的get请求:
  1. public static String httpClinetForGet(String url_str)throws Exception {
  2.         //1创建一个HttpClient的一个子类对象DefaultHttpClient
  3.         DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
  4.         //2.1 创建一个请求方式HttpUriRequest的一个子类对象HttpGet  ,get方式
  5.         HttpGet request = new HttpGet(url_str);//创建一个get方式的对象,并指定请求的地址
  6.         //2.2执行DefaultHttpClient的一个execut方法进行http请求,获取一个httpResponse对象
  7.         HttpResponse response = defaultHttpClient.execute(request);
  8.         //3.httpResponse对象获取状态码,判断
  9.         StatusLine statusLine = response.getStatusLine();//获取状态行
  10.         int code = statusLine.getStatusCode();//根据状态码获取状态行
  11.         if (code == 200) {
  12.             //4.获取服务器返回的流信息。
  13.             HttpEntity entity = response.getEntity();//获取实体信息;
  14.             InputStream inputStream = entity.getContent();//获取实体中封装的服务器流信息
  15.             result = Utils.StreamToString(inputStream);
  16.             inputStream.close();
  17.             return result;
  18.         }
  19.     return result;
  20. }
复制代码
那如果我们get请求要携带参数怎么办呢?
       Get请求的参数是通过"?"直接拼接在url地址后面不同参数之间用"&"连接的例如:
  1. String url_str = url_str+"?username="+ username+"&pwd="+ password;
复制代码
但是这样直接将参数拼接在地址栏后面有一定的弊端,携带的数据不能太大,如果要携带大数据比如上传文件或者图片的时候我们就要用到POST请求。
POST请求的使用:

HttpUrlConnection的post请求:
  1. public static String httpUrlConnectionForPost(String url_str, String username, String password) throws Exception {
  2.     //使用urlConnection执行一个post请求
  3.     URL url = new URL(url_str);
  4.     HttpURLConnection openConnection = (HttpURLConnection) url.openConnection();
  5.     openConnection.setRequestMethod("POST");
  6.     openConnection.setConnectTimeout(10 * 1000);
  7.     //向服务器传递数据时,需要对参数进行URLEncode编码
  8.     String content = "username=" + URLEncoder.encode(username, "utf-8") + "&pwd=" + URLEncoder.encode(password, "utf-8");
  9.     //post请求时需要添加几个请求头;
  10.     openConnection.setRequestProperty("Content-Length", content.length() + "");//设置请求头field:请求头的名称  newValue:值
  11.     openConnection.setRequestProperty("Cache-Control", "max-age=0");
  12.     openConnection.setRequestProperty("Origin", "http://192.168.1.100:8080");//需要访问的主机地址
  13.     openConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");//指Content-Type为表单类型
  14.     //post请求时,需要设置请求体(请求的内容)给服务器,就需要设置下面的配置
  15.     openConnection.setDoOutput(true);//告诉服务器需要传数据
  16.     //获取一个写入流,将内容写入服务器
  17.     openConnection.getOutputStream().write(content.getBytes(), 0, content.length());
  18.     if (openConnection.getResponseCode() == 200) {
  19.         InputStream inputStream = openConnection.getInputStream();
  20.         result = Utils.StreamToString(inputStream);
  21.         inputStream.close();
  22.         return result;
  23.     }
  24.     return result;
  25. }
复制代码

HttpClient的Post请求:
  1. public static String httpClientForPost(String url_str, String username, String password)throws Exception {
  2.         //1创建一个HttpClient的一个子类对象DefaultHttpClient
  3.         DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
  4.         //2.1 创建一个请求方式HttpUriRequest的一个子类对象HttpPost  ,post方式
  5.         HttpPost request = new HttpPost(url_str);//创建一个get方式的对象,并指定请求的地址
  6.         //2.2 封装请求体,以HttpEntity的方式封装
  7.         ArrayList<NameValuePair> arrayList = new ArrayList<NameValuePair>();//创建集合封装表单数据
  8.         arrayList.add(new BasicNameValuePair("username", username));//创建NameValuePair子类,封装表单的参数信息
  9.         arrayList.add(new BasicNameValuePair("pwd", password));//创建NameValuePair子类,封装表单的参数信息
  10.         UrlEncodedFormEntity entity1 = new UrlEncodedFormEntity(arrayList, "utf-8");//创建一个HttpEntity的子类对象UrlEncodedFormEntity封装数据
  11.         request.setEntity(entity1);
  12.         //2.3执行DefaultHttpClient的一个execut方法进行http请求,获取一个httpResponse对象
  13.         HttpResponse response = defaultHttpClient.execute(request);
  14.         //3.httpResponse对象获取状态码,判断
  15.         StatusLine statusLine = response.getStatusLine();//获取状态行
  16.         int code = statusLine.getStatusCode();//根据状态码获取状态行
  17.         if (code == 200) {
  18.             //4.获取服务器返回的流信息。
  19.             HttpEntity entity = response.getEntity();//获取实体信息;
  20.             InputStream inputStream = entity.getContent();//获取实体中封装的服务器流信息
  21.             result = Utils.StreamToString(inputStream);
  22.             inputStream.close();
  23.             return result;
  24.         }
  25.     return result;
  26. }
复制代码
Utils工具类的代码
  1.     public static String StreamToString(InputStream inputStream) {
  2.         String result;
  3.         try {
  4.             ByteArrayOutputStream bos = new ByteArrayOutputStream();
  5.             int len = 0;
  6.             byte[] buf = new byte[64];
  7.             while ((len = inputStream.read(buf)) != -1) {
  8.                 bos.write(buf, 0, len);
  9.                 bos.flush();
  10.             }
  11.             result = bos.toString();
  12.             bos.close();
  13.             return result;
  14.         } catch (Exception e) {
  15.             e.printStackTrace();
  16.         }
  17.         return "";
  18.     }
复制代码


关于HttpClient其它几种post上传参数的例子

1.Key-Value

  1. DefaultHttpClient httpClient = new DefaultHttpClient();
  2. HttpPost post = new HttpPost(url);  
  3. //设置数据
  4. // 设置post请求的参数
  5. List<BasicNameValuePair> parameters = new ArrayList<BasicNameValuePair>();
  6. // 遍历map,拿到具体的参数
  7. for (Map.Entry<String, String> info : paramsMap.entrySet()) {
  8.      String key = info.getKey();// 参数的key
  9.      String value = info.getValue();// 参与具体的value
  10.      BasicNameValuePair basicNameValuePair = new BasicNameValuePair(key, value);
  11.      parameters.add(basicNameValuePair);
  12.    }
  13.      HttpEntity reqEntity = new UrlEncodedFormEntity(parameters);
  14. post.setEntity(reqEntity);  
  15. HttpResponse response = httpClient.execute(post);
  16. if (response.getStatusLine().getStatusCode() == 200) {   
  17.      HttpEntity resEntity = response.getEntity();            
  18.      String result = EntityUtils.toString(resEntity);
  19.      System.out.println("result:" + result);
  20. }
复制代码


2.jsonString
key-value缺点是结构单一,一直put参数
jsonString结构可以无限嵌套,拼写方便

  1. Student student = new Student("zhangsan", 18, 1);
  2. Gson gson = new Gson();
  3. String jsonString = gson.toJson(student);
  4. DefaultHttpClient httpClient = new DefaultHttpClient();
  5. HttpPost post = new HttpPost("http://httpbin.org/post");
  6. // 设置post请求的参数-->jsonString
  7. HttpEntity reqEntity = new StringEntity(jsonString);
  8. post.setEntity(reqEntity);
  9. HttpResponse response = httpClient.execute(post);
  10. if (response.getStatusLine().getStatusCode() == 200) {
  11.         HttpEntity resEntity = response.getEntity();
  12.         String result = EntityUtils.toString(resEntity);
  13.         System.out.println("result:" + result);
  14. }
复制代码

3.file文件上传
朋友圈上传图片,意见反馈,晒图
FileEntiy惯性思维,根据上面所学用FileEntiy传文件
httpmime.jar:文件上传用这个jar包
用MultipartEntity这个Entity上传图片
key-value形式上传图片

  1. File file = new File("文件在手机sd卡中的路径");
  2. try {
  3. DefaultHttpClient httpClient = new DefaultHttpClient();
  4. ttpPost post = new HttpPost("http://httpbin.org/post");
  5. // 设置post请求的参数-->file
  6. MultipartEntity reqEntity = new MultipartEntity();
  7. FileBody fileBody = new FileBody(file);
  8. reqEntity.addPart("actimg", fileBody);
  9. post.setEntity(reqEntity);
  10. HttpResponse response = httpClient.execute(post);
  11. if (response.getStatusLine().getStatusCode() == 200) {
  12.         HttpEntity resEntity = response.getEntity();
  13.         String result = EntityUtils.toString(resEntity);
  14.         System.out.println("result:" + result);
  15. }
  16. } catch (Exception e) {
  17.         e.printStackTrace();
  18. }
复制代码

4.Content-Type种类
上传数据多种类型。那么服务器怎么知道上传数据的形式
可以人员之间约定,但这样不规范。如果不认识服务器的人员就没发预定
那么我们就用到了Content-Type,为javaWeb当中的知识

1、 服务端需要返回一段普通文本给客户端,Content-Type="text/plain"
2 、服务端需要返回一段HTML代码给客户端 ,Content-Type="text/html"
3 、服务端需要返回一段XML代码给客户端 ,Content-Type="text/xml"
4 、服务端需要返回一个file给
5 、服务端需要返回一段json串给客户端

application/x-www-form-urlencoded:表单,key-value
mutipart/form-data:二进制,file
text/plain:普通文本,默认类型
application/json:json数据,***注意有好多服务器默认是json,但要手动加上
手动加一个application/json。
有可能一次copy一个网络请求代码就能通了。
但有的服务器默认text/plain。你传json过去了,就会报json解析异常
有的大公司就判断Content-Type类型,如果类型不对就报错
模拟请求工具
chrom浏览器postman插件。火狐浏览器:restclient插件。
不想在浏览器上用,可以用feddler。可以抓包,可以模拟数据发送。


0 个回复

您需要登录后才可以回帖 登录 | 加入黑马