Android_访问网络一(使用HttpURLConnection访问)

PS:看了9年的小说,自己开始动手写了一本,请各位猿们动动手指,点击下,有起点账号的可以收藏下!!《武意长存》


Android 为我们提供了两种访问网络的方式:

一、 HttpURLConnection

二、        HttpClient

当然,除了以上两种,还有其它一些封装好的框架,我们可以很方便的拿来使用,比如android-async-http,以及Google提供的Volley

 

现在,先来看看如何使用HttpURLConnection对网络资源进行访问

首先,我们先自己搭个简单的后台,用来验证用户登录

public class LoginServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		
		
		if("zhangsan".equals(username) && "123".equals(password)){
			out.println("login success!");
		}else {
			out.println("login fail!");
		}
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doGet(request, response);
	}
}

接下来就开始编写Android客户端,使之可以访问网络

Android中要访问网络必须得有权限,所以我们得先在manifest文件中添加权限

<uses-permission android:name="android.permission.INTERNET"/>
<p><span style="background:silver;">
</span></p><p><span style="background:silver;">LoginService</span>.java : 用来提供访问网络的类</p><p><pre name="code" class="java">public class LoginService {
<span style="white-space:pre">	</span>private static final String BASE_PATH = "http://110.89.138.70:8080/server/LoginServlet";

	/**
	 * GET方式登陆到服务器
	 * @param username 用户名
	 * @param password 密码
	 * @return 服务器返回的消息
	 */
	public static String loginByGet(String username, String password){
		String path = BASE_PATH + "?username="+username+"&password="+password;
		
		try {
			URL url = new URL(path);
//打开连接, 获取HttpURLConnection 的对象
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(5000);	//设置链接超时时间
			conn.setRequestMethod("GET");	//设置请求方式
			
			int code = conn.getResponseCode();		//获取返回码
			if(code == 200){
				InputStream is = conn.getInputStream();
				return StreamTools.readInputStream(is);
			}else {
				return null;
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
	
	/**
	 * POST方式登陆到服务器
	 * @param username    用户名
	 * @param password    密码
	 * @return 服务器返回的消息
	 */
	public static String loginByPost(String username, String password){
		try {
			String data = "username="+username+"&password="+password;
			
			URL url = new URL(BASE_PATH);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			
			//1.设置请求方式 为 post
			conn.setRequestMethod("POST");
			
			//2. 设置请求的头
			conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			conn.setRequestProperty("Content-Length", String.valueOf(data.length()));
			
			conn.setConnectTimeout(5000);
			
			//3.设置 允许向服务器写数据
			conn.setDoOutput(true);
			conn.getOutputStream().write(data.getBytes());
			
			int code = conn.getResponseCode();
			if(code == 200){
				InputStream is = conn.getInputStream();
				return StreamTools.readInputStream(is);
			}else {
				return null;
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
	}
}



 
public class StreamTools {
	public static String readInputStream(InputStream is){
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		
		int len = -1;
		try {
			while((len=is.read(buffer)) != -1){
				baos.write(buffer);
			}
			
			is.close();
			baos.close();
			
			byte[] result = baos.toByteArray();
			return new String(result);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		
	}
}

下图是程序的界面:


当我们点击loginByGet按钮时,调用以下方法

public void loginByGet(View view){
		final String username = etUsername.getText().toString().trim();
		final String password = etPassword.getText().toString().trim();
		
		if(TextUtils.isEmpty(username) || TextUtils.isEmpty(password)){
			Toast.makeText(this, "用户名或密码不能为空!", Toast.LENGTH_SHORT).show();
		}else {
			new Thread(){
				public void run() {
					final String result = LoginService.loginByGet(username, password);
					if(null != result){	//请求成功
						runOnUiThread(new Runnable() {
							@Override
							public void run() {
								Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
							}
						});
					}else {
						runOnUiThread(new Runnable() {
							@Override
							public void run() {
								Toast.makeText(MainActivity.this, "请求失败", Toast.LENGTH_SHORT).show();
							}
						});
					}
				};
			}.start();
		}
	}

当我们输入的是zhangsan和123时,登录成功




当我们输入错误时,如密码输入321,则登录失败



当我们点击loginByPost按钮时,调用以下方法

public void loginByPost(View view){
		final String username = etUsername.getText().toString().trim();
		final String password = etPassword.getText().toString().trim();
		
		if(TextUtils.isEmpty(username) || TextUtils.isEmpty(password)){
			Toast.makeText(this, "用户名或密码不能为空!", Toast.LENGTH_SHORT).show();
		}else {
			new Thread(){
				public void run() {
					final String result = LoginService.loginByPost(username, password);
					if(null != result){	//请求成功
						runOnUiThread(new Runnable() {
							@Override
							public void run() {
								Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
							}
						});
					}else {
						runOnUiThread(new Runnable() {
							@Override
							public void run() {
								Toast.makeText(MainActivity.this, "请求失败", Toast.LENGTH_SHORT).show();
							}
						});
					}
				};
			}.start();
		}
	}

(此处不再截图,参照上面两幅截图)

输入的zhangsan和123时,登录成功                  

输入错误时,如密码输入321,则登录失败

post请求方式和get不同的是,post的参数不是放在url字符串里,而是放在http请求数据中。

另外还有一点需要注意的是,HttpURLConnection的setRequestMethod(),传入的字符串必须是全大写的,GET或POST,其它的全小写或者首字母大写的形式都不行


以上的代码并没有对中文乱码进行处理,当我们把服务端的代码改为

public class LoginServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		
<span style="white-space:pre">		</span>System.out.println("username----------"+username);
		if("张三".equals(username) && "123".equals(password)){
			out.println("登录成功!");
		}else {
			out.println("登录失败!");
		}
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doGet(request, response);
	}
}

则会出现乱码问题


服务端控制台输出的username为


这是由于Java在网络传输中使用的默认编码是ISO-8859-1,因此服务端接收到的数据是乱码,要解决这问题,只需在Android程序中重新进行编码,再在服务端以相应的编码方式进行解码,如下

把loginByGet()里的路径替换成下面一行代码

String path = BASE_PATH +"?username="+URLEncoder.encode(username,"utf-8")+"&password="+URLEncoder.encode(password,"utf-8");

 URLEncoder.encode(username,"utf-8")表示把字符串username以utf-8的编码方式重新进行编码

 

服务端解码如下

username = new String(username.getBytes("iso8859-1"), "utf-8");
System.out.println("username----------"+username);
if("张三".equals(username) && "123".equals(password)){
	out.println("登录成功!");
}else {
	out.println("登录失败!");
}

服务端控制台输出的username如下图




解决了从Android传参到服务端的乱码问题后,还有从就是从服务器返回数据到Android客户端,看到这里有人或许会有疑问,上面的例子不是可以正常的返回

中文字符串吗?

这是因为上面的例子,我们已经指定了返回数据时以utf-8的方式进行编码response.setCharacterEncoding("utf-8");

Android的默认编码方式也是utf-8,所以中文能正常显示,但当我们把服务端的编码方式改为gbk

这时就会出现乱码问题response.setCharacterEncoding("gbk");

返回的信息信息出现了乱码,有了前面解决乱码的经验,我想大家都能很容易解决这个乱码问题了,这时我们只要在StreamTools.java中把下面两行代码替 换掉

			byte[] result = baos.toByteArray();
			return new String(result);

替换成

<span style="white-space:pre">	</span>byte[] result = baos.toByteArray();
	String temp = new String(result, "gbk");
	return temp;

归根结底,乱码问题就是客户端和服务端采用的编码不一致而导致的,只要想办 法让两边以同样的编码方式进行编码和解码就 OK 了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值