本帖最后由 孟凡凯老师 于 2016-5-30 19:55 编辑
【济南校区】凯哥兵法之网络编程 概述: 在公司中Android程序基本上不可能不联网的,网络编程是每个程序员的必备技能。android系统中主要提供了两种方式来进行HTTP通信HttpURLConnection和HttpClient。
下面简单介绍一下Get请求的使用: httpUrlConnection的get请求: - public static String httpUrlConnectionForGet(String url_str) throws Exception {
- //1.创建Url对象。
- URL url = new URL(url_str);
- //2.通过Url获取一个HttpUrlConnection对象
- HttpURLConnection openConnection = (HttpURLConnection) url.openConnection();
- //3.为HttpUrlConnection对象设置请求方式,联网的超时时间
- openConnection.setRequestMethod("GET");//请求方式必须大写
- openConnection.setConnectTimeout(10 * 1000);//设置超时时间
- //4.获取服务器的响应码,判断是否请求成功
- int code = openConnection.getResponseCode();
- if (code == 200) {
- //5.200表示请求成功,获取流信息200 成功 206 请求部分资源成功 300 跳转 400 失败 500 服务器错
- InputStream inputStream = openConnection.getInputStream();
- //6.将流信息转换成字符串
- result = Utils.StreamToString(inputStream);
- //7.关闭资源
- inputStream.close();
- return result;
- }
- return result;
- }
复制代码 HttpClient的get请求:- public static String httpClinetForGet(String url_str)throws Exception {
- //1创建一个HttpClient的一个子类对象DefaultHttpClient
- DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
- //2.1 创建一个请求方式HttpUriRequest的一个子类对象HttpGet ,get方式
- HttpGet request = new HttpGet(url_str);//创建一个get方式的对象,并指定请求的地址
- //2.2执行DefaultHttpClient的一个execut方法进行http请求,获取一个httpResponse对象
- HttpResponse response = defaultHttpClient.execute(request);
- //3.httpResponse对象获取状态码,判断
- StatusLine statusLine = response.getStatusLine();//获取状态行
- int code = statusLine.getStatusCode();//根据状态码获取状态行
- if (code == 200) {
- //4.获取服务器返回的流信息。
- HttpEntity entity = response.getEntity();//获取实体信息;
- InputStream inputStream = entity.getContent();//获取实体中封装的服务器流信息
- result = Utils.StreamToString(inputStream);
- inputStream.close();
- return result;
- }
- return result;
- }
复制代码那如果我们get请求要携带参数怎么办呢? Get请求的参数是通过"?"直接拼接在url地址后面不同参数之间用"&"连接的例如: - String url_str = url_str+"?username="+ username+"&pwd="+ password;
复制代码但是这样直接将参数拼接在地址栏后面有一定的弊端,携带的数据不能太大,如果要携带大数据比如上传文件或者图片的时候我们就要用到POST请求。 POST请求的使用:
HttpUrlConnection的post请求: - public static String httpUrlConnectionForPost(String url_str, String username, String password) throws Exception {
- //使用urlConnection执行一个post请求
- URL url = new URL(url_str);
- HttpURLConnection openConnection = (HttpURLConnection) url.openConnection();
- openConnection.setRequestMethod("POST");
- openConnection.setConnectTimeout(10 * 1000);
- //向服务器传递数据时,需要对参数进行URLEncode编码
- String content = "username=" + URLEncoder.encode(username, "utf-8") + "&pwd=" + URLEncoder.encode(password, "utf-8");
- //post请求时需要添加几个请求头;
- openConnection.setRequestProperty("Content-Length", content.length() + "");//设置请求头field:请求头的名称 newValue:值
- openConnection.setRequestProperty("Cache-Control", "max-age=0");
- openConnection.setRequestProperty("Origin", "http://192.168.1.100:8080");//需要访问的主机地址
- openConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");//指Content-Type为表单类型
- //post请求时,需要设置请求体(请求的内容)给服务器,就需要设置下面的配置
- openConnection.setDoOutput(true);//告诉服务器需要传数据
- //获取一个写入流,将内容写入服务器
- openConnection.getOutputStream().write(content.getBytes(), 0, content.length());
- if (openConnection.getResponseCode() == 200) {
- InputStream inputStream = openConnection.getInputStream();
- result = Utils.StreamToString(inputStream);
- inputStream.close();
- return result;
- }
- return result;
- }
复制代码
HttpClient的Post请求: - public static String httpClientForPost(String url_str, String username, String password)throws Exception {
- //1创建一个HttpClient的一个子类对象DefaultHttpClient
- DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
- //2.1 创建一个请求方式HttpUriRequest的一个子类对象HttpPost ,post方式
- HttpPost request = new HttpPost(url_str);//创建一个get方式的对象,并指定请求的地址
- //2.2 封装请求体,以HttpEntity的方式封装
- ArrayList<NameValuePair> arrayList = new ArrayList<NameValuePair>();//创建集合封装表单数据
- arrayList.add(new BasicNameValuePair("username", username));//创建NameValuePair子类,封装表单的参数信息
- arrayList.add(new BasicNameValuePair("pwd", password));//创建NameValuePair子类,封装表单的参数信息
- UrlEncodedFormEntity entity1 = new UrlEncodedFormEntity(arrayList, "utf-8");//创建一个HttpEntity的子类对象UrlEncodedFormEntity封装数据
- request.setEntity(entity1);
- //2.3执行DefaultHttpClient的一个execut方法进行http请求,获取一个httpResponse对象
- HttpResponse response = defaultHttpClient.execute(request);
- //3.httpResponse对象获取状态码,判断
- StatusLine statusLine = response.getStatusLine();//获取状态行
- int code = statusLine.getStatusCode();//根据状态码获取状态行
- if (code == 200) {
- //4.获取服务器返回的流信息。
- HttpEntity entity = response.getEntity();//获取实体信息;
- InputStream inputStream = entity.getContent();//获取实体中封装的服务器流信息
- result = Utils.StreamToString(inputStream);
- inputStream.close();
- return result;
- }
- return result;
- }
复制代码 Utils工具类的代码- public static String StreamToString(InputStream inputStream) {
- String result;
- try {
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- int len = 0;
- byte[] buf = new byte[64];
- while ((len = inputStream.read(buf)) != -1) {
- bos.write(buf, 0, len);
- bos.flush();
- }
- result = bos.toString();
- bos.close();
- return result;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return "";
- }
复制代码
关于HttpClient其它几种post上传参数的例子
1.Key-Value - DefaultHttpClient httpClient = new DefaultHttpClient();
- HttpPost post = new HttpPost(url);
- //设置数据
- // 设置post请求的参数
- List<BasicNameValuePair> parameters = new ArrayList<BasicNameValuePair>();
- // 遍历map,拿到具体的参数
- for (Map.Entry<String, String> info : paramsMap.entrySet()) {
- String key = info.getKey();// 参数的key
- String value = info.getValue();// 参与具体的value
- BasicNameValuePair basicNameValuePair = new BasicNameValuePair(key, value);
- parameters.add(basicNameValuePair);
- }
- HttpEntity reqEntity = new UrlEncodedFormEntity(parameters);
- post.setEntity(reqEntity);
- HttpResponse response = httpClient.execute(post);
- if (response.getStatusLine().getStatusCode() == 200) {
- HttpEntity resEntity = response.getEntity();
- String result = EntityUtils.toString(resEntity);
- System.out.println("result:" + result);
- }
复制代码
2.jsonString key-value缺点是结构单一,一直put参数 jsonString结构可以无限嵌套,拼写方便 - Student student = new Student("zhangsan", 18, 1);
- Gson gson = new Gson();
- String jsonString = gson.toJson(student);
- DefaultHttpClient httpClient = new DefaultHttpClient();
- HttpPost post = new HttpPost("http://httpbin.org/post");
- // 设置post请求的参数-->jsonString
- HttpEntity reqEntity = new StringEntity(jsonString);
- post.setEntity(reqEntity);
- HttpResponse response = httpClient.execute(post);
- if (response.getStatusLine().getStatusCode() == 200) {
- HttpEntity resEntity = response.getEntity();
- String result = EntityUtils.toString(resEntity);
- System.out.println("result:" + result);
- }
复制代码
3.file文件上传 朋友圈上传图片,意见反馈,晒图 FileEntiy惯性思维,根据上面所学用FileEntiy传文件 httpmime.jar:文件上传用这个jar包 用MultipartEntity这个Entity上传图片 key-value形式上传图片 - File file = new File("文件在手机sd卡中的路径");
- try {
- DefaultHttpClient httpClient = new DefaultHttpClient();
- ttpPost post = new HttpPost("http://httpbin.org/post");
- // 设置post请求的参数-->file
- MultipartEntity reqEntity = new MultipartEntity();
- FileBody fileBody = new FileBody(file);
- reqEntity.addPart("actimg", fileBody);
- post.setEntity(reqEntity);
- HttpResponse response = httpClient.execute(post);
- if (response.getStatusLine().getStatusCode() == 200) {
- HttpEntity resEntity = response.getEntity();
- String result = EntityUtils.toString(resEntity);
- System.out.println("result:" + result);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
复制代码
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。可以抓包,可以模拟数据发送。
|