您的位置:首页 > 理论基础 > 计算机网络

Android的Http网络通信

2015-08-25 21:03 417 查看
在Android中针对HTTP进行网络通信有两种:一是HttpURLConnection;二是Apache HTTP客户端。HTTP通信中使用最多的就是Get和Post,Get请求可以获取静态页面,也可以把参数放在URL字符串后面,传递给服务器。Post与Get的不同之处在于Post的参数不是放在URL字符串里面,而是放在http请求数据中。

1、HttpURLConnection接口

HttpURLConnection是Java的标准类,继承自URLConnection类,URLConnection与HttpURLConnection都是抽象类,无法直接实例化对象。其对象主要通过URL的openConnection方法获得,创建一个HttpURLConnection连接的代码如下:

URL url;
			url = new URL("http://www.baidu.com");
			HttpURLConnection urlConn = (HttpURLConnection)url.openConnection();
openConnection方法只创建URLConnection或者HttpURLConnection实例,但并不进行真正的连接操作。并且,每次openConnection都将创建一个新的实例。因此,在连接之前我们可以对其一些属性进行设置,比如超时时间等。下面是对HttpURLConnection实例的属性设置:

//设置输入(输出)流
			 urlConn.setDoInput(true);
			 urlConn.setDoOutput(true);
			 //设置请求方式为get
			 urlConn.setRequestMethod("GET");
			 //设置不使用缓存
			 urlConn.setUseCaches(false);

下面我们通过一个程序分别以get和post方式向服务提交用户名和登录密码,服务比较android端传送过的数据后,返回是否登录成功的结果,界面效果如下:



public class MainActivity extends Activity {
	private EditText etUsername;
	private EditText etPassword;
	private Button  btnGet;
	private Button btnPost;
	private TextView tvresult;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		etUsername = (EditText) findViewById(R.id.username);
		etPassword = (EditText) findViewById(R.id.password);
		btnGet = (Button) findViewById(R.id.btnGet);
		btnPost = (Button) findViewById(R.id.btnPost);
		tvresult = (TextView)findViewById(R.id.tvresult);
		btnGet.setOnClickListener(getListener);
		btnPost.setOnClickListener(postListener);
	}

以Get方式传递参数,需要将参数拼接到url后面。我们首先声明请求的URL,通过该地址创建URL对象,通过URL对象打开连接,获得HttpURLConnection对象。调用HttpURLConnection对象的getResponseCode方法判断是否请求成功,如果成功获得输入流,则读入登录反馈信息。

private OnClickListener getListener = new OnClickListener() {	
		@Override
		public void onClick(View v) {
			String urlStr = "http://192.168.0.100:8080/myweb/servlet/LoginAction?";
			String param = "username="+etUsername.getText().toString()+"&password="+etPassword.getText().toString();
			urlStr += param;
			try {
				//实例化URL
				URL url = new URL(urlStr);
				//获得HttpsURLConnection实例
				HttpURLConnection conn = (HttpURLConnection)url.openConnection();
				//如果请求成功
				if(conn.getResponseCode() == HttpURLConnection.HTTP_OK){
					//获得输入流
					InputStream in = conn.getInputStream();
					//数组缓存
					byte []b = new byte[in.available()];
					//读数据到缓存
					in.read(b);
					//转换为字符串
					String msg = new String (b);
					Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();
					//显示结果
					tvresult.setText(msg);
					//关闭输入流
					in.close();
				}
				//断开连接
				conn.disconnect();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	};
由于HttpURLConnection默认使用Get方式,所以如果我们要使用Post方式,则需要调用setRequestMethod进行设置。然后将我们要传递的参数内容通过writeBytes方法写入数据流。

private OnClickListener postListener = new OnClickListener() {	
		@Override
		public void onClick(View v) {
			String urlStr = "http://192.168.0.100:8080/myweb/servlet/LoginAction";
			String param = "username="+etUsername.getText().toString()+"&password="+etPassword.getText().toString();

			try {
				//实例化URL
				URL url = new URL(urlStr);
				//获得HttpsURLConnection实例
				HttpURLConnection conn = (HttpURLConnection)url.openConnection();
				//因为是POST请求,要设置输出流,输入流
				conn.setDoOutput(true);
				conn.setDoInput(true);
				//设置以POST方式
				conn.setRequestMethod("POST");
				//post请求不能使用缓存
				conn.setUseCaches(false);
				conn.connect();
				//获取输出流对象
				DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
				//将要传送的内容写入流中
				dos.writeBytes(param);
				//刷新、关闭
				dos.flush();
				dos.close();
				BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
				//获取数据
				String msg = reader.readLine();
				reader.close();
				//关闭http连接
				conn.disconnect();
				Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();
				//显示结果
				tvresult.setText(msg);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	};
在服务器端创建LoginAction,响应请求并返回登录结果。该Servlet只做简单判断,没有连接后台数据库。

public class LoginAction extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//从请求中获取用户名和密码
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		//设置内容类型
		response.setContentType("text/html");
		//设置字符编码
		response.setCharacterEncoding("utf-8");
		//获得打印输出流
		PrintWriter out = response.getWriter();
		String msg = "Get方式请求";
		if(username!=null&&username.equals("admin")&&
		   password!=null&&password.equals("123456")){
			msg += "登录成功";
		}else{
			msg += "登录失败";
		}
		//返回信息给客户端
		out.print(msg);
		//刷新输出流
		out.flush();
		//关闭输出流
		out.close();
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//从请求中获取用户名和密码
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		//设置内容类型
		response.setContentType("text/html");
		//设置字符编码
		response.setCharacterEncoding("utf-8");
		//获得打印输出流
		PrintWriter out = response.getWriter();
		String msg = "Post方式请求";
		if(username!=null&&username.equals("admin")&&
		   password!=null&&password.equals("123456")){
			msg += "登录成功";
		}else{
			msg += "登录失败";
		}
		//返回信息给客户端
		out.print(msg);
		//刷新输出流
		out.flush();
		//关闭输出流
		out.close();	
	}
}
程序运行结果如下:



2、使用Apache HTTP客户端

Android集成了Apache HTTP客户端,使得针对HTTP的编程更加方便、高效。在Servlet编程中我们会用HttpServletRequest和HttpServletResponse来表示请求和响应。Apache HTTP客户端也对请求和响应进行封装,根据请求方法的不同,我们会用到HttpGet和HttpPost两个对象。响应对象是HttpResponse,使用DefaultHttpClient执行请求获得响应。

DefaultHttpClient是默认的一个HTTP客户端,我们可以使用它创建一个HTTP连接,代码如下:

HttpClient httpclient = new DefaultHttpClient();
HttpResponse是一个HTTP连接响应,当执行一个HTTP连接后,就会返回一个HttpResponse,可以通过HttpResponse获得一些响应的信息。下面是请求一个HTTP连接并获得该请求是否成功的代码。

HttpResponse httpResponse = httpclient.execute(httpRequest);
			if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
				//连接成功
			}
我们把上面的例子改成使用HttpClient方式实现用户登录功能。

private OnClickListener getListener = new OnClickListener() {		
		@Override
		public void onClick(View v) {
			String urlStr = "http://192.168.0.100:8080/myweb/servlet/LoginAction?";
			String param = "username="+etUsername.getText().toString()+"&password="+etPassword.getText().toString();
			urlStr += param;
			//HttpGet连接对象
			HttpGet httpRequest = new HttpGet(urlStr);
			//获得HttpClient对象
			HttpClient httpclient = new DefaultHttpClient();
			HttpResponse httpResponse;
			try {
				httpResponse = httpclient.execute(httpRequest);
				if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
					//连接成功
					//获取返回的字符串
					String msg = EntityUtils.toString(
							httpResponse.getEntity());
					Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();
					//显示结果
					tvresult.setText(msg);
				}
				else{
					tvresult.setText("请求失败");
				}
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}

		}
	};
Post方式比Get方式稍微复杂一点,首先使用HttpPost来构件一个Post方式的请求。需要使用NameValuePair来保存要被传递的参数,然后通过add方法添加这个参数到NameValuePair中。最后通过HttpClient来请求这个连接,返回响应并处理。

private OnClickListener postListener = new OnClickListener() {
		@Override
		public void onClick(View arg0) {
			String urlStr = "http://192.168.0.100:8080/myweb/servlet/LoginAction";
			//httpPost连接对象
			HttpPost httpRequest = new HttpPost(urlStr);
			//使用NameValuePair来保存要传递的Post参数
			List<NameValuePair> params = new ArrayList<NameValuePair>();
			//添加要传递的参数
			params.add(new BasicNameValuePair("username", etUsername.getText().toString()));
			params.add(new BasicNameValuePair("password", etPassword.getText().toString()));
			
			HttpEntity entity;
			try {
				
				entity = new UrlEncodedFormEntity(params);
				//设置请求参数
				httpRequest.setEntity(entity);
				//获得默认的HttpClient
				HttpClient httpclient = new DefaultHttpClient();
				//获得HttpResponse
				HttpResponse httpResponse = httpclient.execute(httpRequest);
				if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
					//连接成功
					//获取返回的字符串
					String msg = EntityUtils.toString(
							httpResponse.getEntity());
					Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();
					//显示结果
					tvresult.setText(msg);
				}
				else{
					tvresult.setText("请求失败");
				}
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}		
	};
程序运行会得到同上面的结果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: