赵雅智_HttpURLConnection 的 get请求和post请求

用户的响应性:

Android中,应用的响应性被活动管理器(Activity Manager)和窗口管理器(Window Manager)这两个系统服务所监视。当用户触发了输入事件(如键盘输入,点击按钮等),如果应用6秒内没有响应用户的输入事件,那么,Android会认为该应用无响应,便弹出ANRApplication No Response)对话框。如下图。

 

在正常情况下,Android程序会在一条单线程里运行。如果Activity要处理一件比较耗时的工作,应该交给子线程完成,否侧会因为主线程被阻塞,后面的用户输入事件因没能在5秒内响应,导致应用出现ANR对话框。

 

HTTP协议

大多数的Android应用程序都会使用HTTP协议来发送和接收网络数据,而Android中主要提供了两种方式来进行HTTP操 作,HttpURLConnectionHttpClient。这两种方式都支持HTTPS协议、以流的形式进行上传和下载、配置超时时间、IPv6、 以及连接池等功能。

HttpURLConnection

HttpURLConnection是一种多用途、轻量极的HTTP客户端,使用它来进行HTTP操作可以适用于大多数的应用程序。虽然HttpURLConnectionAPI提供的比较简单,但是同时这也使得我们可以更加容易地去使用和扩展它。

不过在Android 2.2版本之前,HttpURLConnection一直存在着一些令人厌烦的bug。比如说对一个可读的InputStream调用close()方法时,就有可能会导致连接池失效了。那么我们通常的解决办法就是直接禁用掉连接池的功能:


通过web的完全模拟,android为我们提供了HttpURLConnection对象,我们可以向网络发送请求参数.

 

我们在请求jsp页面时,如图所示网页发送的网络请求


请求头分析

Accept:客户机通过这个头,告诉服务器,它支持哪些数据类型

Accept-Charset::客户机通过这个头,告诉服务器,它支持的编码

Accept-Encoding: 客户机通过这个头,告诉服务器,支持哪种数据压缩格式

Accept-Language: 客户机采用的是哪个语言

Host:客户机通过这个头,告诉服务器,想访问服务器哪台主机

If-Modified-Since:客户机通过这个头,告诉服务器,数据缓存的时间

Referer:客户机通过这个头,告诉服务器,客户机是从哪个页面来的(防盗链)

User-Agent: 说明客户机操作系统信息,以及浏览器信息

Cookie:客户机通过这个头,可以带点数据给服务器

Connection

响应头分析

Location:服务器通过这个头告诉浏览器去访问哪个页面,这个头通常配合302状态码使用

Content-Encoding: 服务器通过这个头告诉浏览器,回送的数据采用的压缩格式

Content-Length:  服务器通过这个头告诉浏览器,回送的数据的大小

Content-Type: 服务器通过这个头告诉浏览器,回送数据的类型

Last-Modified: 服务器通过这个头告诉浏览器,资源的最后修改时间

Refresh:服务器通过这个头告诉浏览器,定时刷新网页

Content-Disposition: attachment; filename=aaa.zip:服务器通过这个头告诉浏览器,以下载方式打开数据

ETag: W/"7777-1242234904000":缓存相关的头,为每一个资源配一个唯一的编号

 

Expires: 0  

Cache-Control: no-cache  

Pragma: no-cache   这三个头组合使用,让浏览器不要缓存数据

 

最常用的Http请求无非是getpostget请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servletpostget的不同之处在于post的参数不是放在URL字串里面,而是放在http请求的正文内。

案例

运行效果:
     

<!-- 添加网络访问权限 -->
    <uses-permission android:name="android.permission.INTERNET"/>


布局文件 activity_login.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >

    <TextView
        android:id="@+id/username"
        android:layout_width="wrap_content"
		android:layout_height="wrap_content" 
		android:textSize="20sp"
		android:layout_alignBaseline="@+id/editusername"
		android:text="@string/username"/>
    
    <EditText
        android:id="@+id/editusername"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_toRightOf="@+id/username"
        android:hint="@string/edit_username"
        />
    	
        <TextView
        android:id="@+id/password"
        android:layout_width="wrap_content"
		android:layout_height="wrap_content" 
		android:textSize="20sp"
		android:layout_below="@+id/username"
		android:layout_alignBaseline="@+id/editpass"
		android:text="@string/password"/>
    
    <EditText
        android:id="@+id/editpass"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_toRightOf="@+id/password"
        android:layout_below="@+id/editusername"
        android:hint="@string/edit_password"
        />

    <Button
        android:id="@+id/btn_login"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="80dp"
        android:layout_below="@+id/password" 
        android:layout_marginLeft="50dp"
        android:text="@string/btn_sure"
        android:onClick="login"
        />
    
    <CheckBox 
        android:id="@+id/checkbox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="50dp"
        android:layout_alignBaseline="@+id/btn_login"
        android:layout_below="@+id/editpass"
        android:layout_toRightOf="@+id/btn_login"
       	android:text="@string/checkbox"
       	/>
    
    <TextView
        android:id="@+id/tv_result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="@string/tip_result"/>
</RelativeLayout> 


String.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">lesson03</string>
    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>

    <string name="username">用户名</string>
	<string name="password">密    码</string>   
	<string name="edit_username">请输入用户名</string>
	<string name="edit_password">请输入密码</string>
 	<string name="btn_sure">确定</string>
    <string name="checkbox">是否记住密码</string>
    
    <string name="tip_result">服务器返回的数据</string>
</resources>


流转字符工具类 StreamTools.java

package com.example.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class StreamTools {
/**
 * 把流轉換成字符串
 * @param is
 * @return
 */
	public static String streamToStr(InputStream is){
		
		try {
			// 字节的输出流
			ByteArrayOutputStream os = new ByteArrayOutputStream();
			// 定义读取长度
			int len = 0;
			// 定义缓冲区
			byte buffer[] = new byte[1024];
			// 从输入流中读取,并写入os对象中
			while ((len = is.read(buffer)) != -1) {
				os.write(buffer, 0, len);
			}
			// 关闭流
			is.close();
			os.close();
			// 写到字节流
			return new String(os.toByteArray());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}
}


Activity类 LoginActivity.java

 

package com.example.android_http;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.example.util.StreamTools;

public class LoginActivity extends Activity {
	private EditText et_username;
	private EditText et_password;

	private TextView tv_result;
	private final int CHANGETEXTVIEW = 1;
	
	//消息处理者
	private Handler handler = new Handler(){
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			int what = msg.what;//标识
			switch (what) {
			case CHANGETEXTVIEW://这个消息就改变TextView控件的操作
				String result = (String) msg.obj;//附带的对象
				tv_result.setText(result);//改变控件内容
				Toast.makeText(LoginActivity.this, result, Toast.LENGTH_LONG).show();
				break;

			default:
				break;
			}
		}
		
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_login);
		findView();

	}


	/**
	 * 查找控件
	 */
	public void findView() {
		et_password = (EditText) findViewById(R.id.editpass);
		et_username = (EditText) findViewById(R.id.editusername);
		tv_result = (TextView) findViewById(R.id.tv_result);
	}

	/**
	 * 登陆按钮操作
	 * @param v
	 */
	public void login(View v) {
		// 获取点击控件的id
		int id = v.getId();
		// 根据id进行判断
		switch (id) {
		case R.id.btn_login:// 进行登录操作
			// 获取用户名密码
			final String userName = et_username.getText().toString();
			final String userPass = et_password.getText().toString();

			// 判断是否为空
			if (TextUtils.isEmpty(userName) || TextUtils.isEmpty(userPass)) {
				Toast.makeText(getApplicationContext(), "用户名或者密码不能为空", 0)
						.show();
			} else {
				Toast.makeText(getApplicationContext(), "发送请求道服务器", 0)
				.show();
				// 访问网络 (需要一个网络的权限) <uses-permission android:name="android.permission.INTERNET"/>
				// 访问网络(耗时的操作) 避免阻塞主线程(UI) 需要开启新的子线程来处理
				new Thread() {
					public void run() {
						//调用get或者post请求
						postOper(userName, userPass);
					};
				}.start();

			}
			break;

		default:
			break;
		}
	}
 
	
	public void postOper(String userName,String userPass){
		try {
			// 请求地址
			String spec = "http://172.16.237.144:8080/Login/LoginServlet";
			// 根据地址创建URL对象(网络访问url)
			URL url = new URL(spec);
			// 采用http协议打开的连接对象
			HttpURLConnection urlConnection = (HttpURLConnection) url
					.openConnection();
			urlConnection.setRequestMethod("POST");// 以get方式发起请求
			urlConnection.setReadTimeout(5000);// 设置超时
			urlConnection.setConnectTimeout(5000);// 设置连接超时
			
			//传递的数据
			String data = "username"+userName+"&userpass"+userPass;
			
			//设置请求头
			urlConnection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
			//设置请求头
			urlConnection.setRequestProperty("Connection","keep-alive");
			//设置请求头
			urlConnection.setRequestProperty("Content-Length",String.valueOf(data.getBytes().length));
		
			//设置请求头
			urlConnection.setRequestProperty("User-Agent","	Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0");
			
			//post 流的方式写入
			urlConnection.setDoInput(true);//发送post请求必须设置允许输入
			urlConnection.setDoOutput(true);//发送post请求必须设置允许输出
			
			OutputStream os = urlConnection.getOutputStream();
			os.write(data.getBytes());
			os.flush();
			// 获取相应的 code 400 200 505 302
			if (urlConnection.getResponseCode() == 200) {
				// 得到网络返回的输入流
				InputStream is = urlConnection.getInputStream();
				//通过工具类处理
				String result = StreamTools.streamToStr(is);
				
				Message msg = new Message();
				msg.what = CHANGETEXTVIEW;//消息的唯一标志
				msg.obj = result;//改变的内容通过object传过去
				handler.sendMessage(msg);//发送消息
				System.out.println("返回的数据是:" + result);
				
			} else {
				System.out.println("请求url失败");
			}

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * 通过get方式发送请求
	 * @param userName
	 * @param userPass
	 */
	public void getOper(String userName,String userPass){
		try {
			// 请求地址
			String spec = "http://172.16.237.144:8080/Login/LoginServlet?username="
					+ userName + "&userpass=" + userPass;
			// 根据地址创建URL对象(网络访问url)
			URL url = new URL(spec);
			// 采用http协议打开的连接对象
			HttpURLConnection urlConnection = (HttpURLConnection) url
					.openConnection();
			urlConnection.setRequestMethod("GET");// 以get方式发起请求
			urlConnection.setReadTimeout(5000);// 设置超时
			urlConnection.setConnectTimeout(5000);// 设置连接超时
			urlConnection
					.setRequestProperty("User-Agent",
							"Mozilla/5.0 (Windows NT 6.3; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0");
			// 获取相应的 code 400 200 505 302
			if (urlConnection.getResponseCode() == 200) {
				// 得到网络返回的输入流
				InputStream is = urlConnection.getInputStream();
				//通过工具类处理
				String result = StreamTools.streamToStr(is);
				
				Message msg = new Message();
				msg.what = CHANGETEXTVIEW;//消息的唯一标志
				msg.obj = result;//改变的内容通过object传过去
				
				handler.sendMessage(msg);//发送消息
				
				System.out.println("返回的数据是:" + result);
			} else {
				System.out.println("请求url失败");
			}

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值