android学习笔记之使用Eclipse搭建web服务器实现Android客户端登录

接触Android有半年了,一直啃不下也不敢去触碰的一块儿硬骨头就是客户端与服务端的通信。

上一篇文章写了通过谷歌官方通信框架Volly实现手机号码归属地查询,但这并不是真真意义上的掌握客户端与服务端之间的数据交换,

因为服务端是调用了由聚合网提供的一个接口API,所以这次我尝试使用eclipse亲手搭建自己的web服务器并实现一个简单的登录功能。


本文实现了Volley框架的get/post以及java原生类HttpURLConnection的get/post方式进行数据请求。

由于我是超级菜鸟型,所以本文适合超级入门级菜鸟参考,大神请无视奋斗


话不多说,先看DEMO效果:(为简单起见,未使用数据库,只在服务端判断用户名和密码是否为admin和123)



布局文件很简单就不说了,有需要的可以私信我要源码。

一、服务端的搭建及配置

1、File-New-Dymanic Web Project (文件-新建-动态web工程)




2、输入web项目名称、选择使用的tomcat版本、选择新建web版本。
web版本建议使用3.0以上,因为3.0以上可以通过注解 @WebServlet("/MyServlet") ,免去配置web.xml的繁琐步骤,具体下面看源代码。




3、如果步骤2中没有3.0以上的web版本,此处必须勾选创建web.xml用来配置Servlet,如果有3.0以上版本,也建议勾选。
点击finish完成项目创建。



4、在项目Java Resources-src目录下,创建包com.xxx.servertest(xxx可任意,注意必须全小写),在创建的包中新建Servlet类。




5、在Class name:中填入Servlet类名,点击finish完成创建



6、此处的URL mappings中的/Servlet即客户端请求中的请求地址,默认即可,点击finish完成。




7、默认勾选doPost和doGet即可,此处对应http的两种请求方式post和get,点击finish即可完成Servlet类创建。



下面是MyServlet.java 源码:
<pre name="code" class="java">package com.fukang.servertest;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONException;
import org.json.JSONObject;

/**
 * Android服务端开发,简单的web servlet实例
 * 
 * @author fk 2015.08.11
 */
@WebServlet("/MyServlet")
public class MyServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	String name = null;
	String password = null;

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/json;charset=utf-8");
		response.setCharacterEncoding("utf-8");
		String name = request.getParameter("name");
		String password = request.getParameter("password");
		String id = request.getParameter("id");//测试httpPost方法能否传递多个参数
		JSONObject result = getResult(name, password);
		PrintWriter out = response.getWriter();
		out.print(result.toString());
		out.flush();
		out.close();
	}

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

	protected JSONObject getResult(String name, String password) {
		JSONObject result = new JSONObject();
		if ((name.equals("admin")) && (password.equals("123"))) {
			try {
				result.put("result", "true");
			} catch (JSONException e) {
				e.printStackTrace();
			}
		} else {
			try {
				result.put("result", "false");
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
		return result;
	}

}

 
 
 
 

二、Android客户端项目搭建


下面看 MainActivity.java

因为把四种请求方式放在一个java文件中,显得代码比较乱,看下图即可比较清晰直观。



volleyGet和volleyPost方法对应实现了volley的Get和Post方法,这个没什么说的。

由于HttpURLConnection类不允许在UI主线程中进行网络请求操作,因而需要实例化AsyncTask类,即异步任务处理类;

在该类的doInBackground方法中进行网络请求操作,并将响应信息返回给onPostExecute方法进行处理,例如对UI进行更新等。



<pre name="code" class="java">package com.fukang.servertestclient;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.android.volley.AuthFailureError;
import com.android.volley.Request.Method;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.Response.Listener;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

public class MainActivity extends Activity implements OnClickListener {
	EditText et_name; // 用户名输入框
	EditText et_password;// 用户密码输入框
	Button btn_volleyGet; // 四种登录按钮控件
	Button btn_volleyPost;
	Button btn_httpGet;
	Button btn_httpPost;
	TextView tv_result; // 显示登录结果文本框
	String name; // 登录用户名
	String password;// 登录密码

	// Activity被加载时调用该方法
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);// 加载布局资源
		initView();// 绑定布局资源中的控件
		ClickListener();// 设置按钮监听器
	}

	// 初始化布局资源,绑定控件
	private void initView() {
		et_name = (EditText) findViewById(R.id.et_name);// 获取输入的用户名及密码
		et_password = (EditText) findViewById(R.id.et_password);
		btn_volleyGet = (Button) findViewById(R.id.btn_VolleyGet); // 绑定不同的登录按钮控件资源
		btn_volleyPost = (Button) findViewById(R.id.btn_VolleyPost);
		btn_httpGet = (Button) findViewById(R.id.btn_HttpGet);
		btn_httpPost = (Button) findViewById(R.id.btn_HttpPost);
		tv_result = (TextView) findViewById(R.id.tv_result);// 用于显示结果
	}

	// 设置按钮点击事件
	@Override
	public void onClick(View v) {
		name = et_name.getText().toString();
		password = et_password.getText().toString();
		switch (v.getId()) {
		case R.id.btn_HttpGet:
			login_httpGet(name, password);// 调用login_httpGet方法
			break;
		case R.id.btn_HttpPost:
			login_httpPost(name, password);// 调用login_httpPost方法
			break;
		case R.id.btn_VolleyGet:
			login_volleyGet(name, password);// 调用login_volleyGet方法
			break;
		case R.id.btn_VolleyPost:
			login_volleyPost(name, password);// 调用login_volleyPost方法
			break;
		}
	}

	// 设置按钮点击监听器
	private void ClickListener() {
		btn_httpGet.setOnClickListener(this);
		btn_httpPost.setOnClickListener(this);
		btn_volleyGet.setOnClickListener(this);
		btn_volleyPost.setOnClickListener(this);
	}

	// volleyGet方式请求数据
	private void login_volleyGet(String name, String password) {
		RequestQueue queues = Volley.newRequestQueue(getApplicationContext());// Volley框架必用,实例化请求队列
		String url = "http://192.168.0.31:8080/ServerTest/MyServlet?" + "name="
				+ name + "&password=" + password;// 请求url
		StringRequest request = new StringRequest(Method.GET, url, // StringRequest请求
				new Listener<String>() {
					@Override
					public void onResponse(String arg0) {// 成功得到响应数据
						try {
							JSONObject result_jo = new JSONObject(arg0);
							String result = result_jo.getString("result");// 取出result值
							if (result.equals("true")) {
								tv_result.setText("volley_get请求登陆成功!");
								tv_result.setTextColor(Color
										.parseColor("#66CC00"));
							} else {
								tv_result.setText("volley_get请求登陆失败!");
								tv_result.setTextColor(Color
										.parseColor("#FF0033"));
							}
						} catch (JSONException e) {
							e.printStackTrace();
						}
					}
				}, new Response.ErrorListener() {// 未成功得到响应数据
					@Override
					public void onErrorResponse(VolleyError arg0) {
						tv_result.setText(arg0.toString());
					}
				});
		request.setTag("volleyGet");// 设置请求标签Tag
		queues.add(request);// 将请求加入队列queue中处理
	}

	// volleyPost方式请求数据
	private void login_volleyPost(String username, String userpass) {
		final String name = username;
		final String password = userpass;
		final String url = "http://192.168.0.31:8080/ServerTest/MyServlet";// post不加参数
		RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
		StringRequest request = new StringRequest(Method.POST, url,
				new Listener<String>() {

					@Override
					public void onResponse(String arg0) {
						try {
							JSONObject result_jo = new JSONObject(arg0);
							String result = result_jo.getString("result");
							if (result.equals("true")) {
								tv_result.setText("volley_post请求登陆成功");
								tv_result.setTextColor(Color
										.parseColor("#66CC00"));
							} else {
								tv_result.setText("volley_post请求登陆失败");
								tv_result.setTextColor(Color
										.parseColor("#FF0033"));
							}
						} catch (JSONException e) {
							e.printStackTrace();
						}
					}
				}, new Response.ErrorListener() {

					@Override
					public void onErrorResponse(VolleyError arg0) {
						tv_result.setText(arg0.toString());
					}
				}) {
			// 此处要实现getParams()方法来添加参数
			@Override
			protected Map<String, String> getParams() throws AuthFailureError {
				Map<String, String> map = new HashMap<String, String>();
				map.put("name", name);
				map.put("password", password);
				return map;
			}
		};
		request.setTag("volleyPost");
		queue.add(request);
	}

	// httpGet方式请求数据
	private void login_httpGet(String name, String password) {
		LoginTaskGet loginTask = new LoginTaskGet();// 实例化异步任务处理类进行请求
		loginTask.execute(name, password);// 传入参数,执行请求
	}

	// httpPost方式请求数据
	private void login_httpPost(String name, String password) {
		LoginTaskPost loginTask = new LoginTaskPost();
		String id = UUID.randomUUID().toString();// 随机产生一个id变量,测试能否post发送三个以上参数
		loginTask.execute(name, password, id);// 变量个数不限,类型要统一,以逗号隔开即可
	}

	/**
	 * 内部类,异步任务处理类。 高版本中,网络连接请求不能在UI线程中执行,需要调用该异步任务处理类。 此处为处理httpGet请求任务。
	 * 
	 * @author fk 2015.08.12
	 */
	class LoginTaskGet extends AsyncTask<String, Void, String> {

		/*
		 * @ 必须重写方法之一,用于异步处理网络请求!
		 * 
		 * @ 取参时,可以使用传入时的参数名,也可以使用param[index]索引值!
		 * 
		 * @ 对网络的请求操作都需要放在此方法中,对UI的操作尽量不要放在此方法中!
		 */
		@Override
		protected String doInBackground(String... params) {
			String result_json = null;
			// String urlPath = "http://192.168.0.31:8080/ServerTest/MyServlet?"
			// + "name=" + params[0] + "&password=" + params[1];
			// 上面这种取参方法也可以
			String urlPath = "http://192.168.0.31:8080/ServerTest/MyServlet?"
					+ "name=" + name + "&password=" + password;
			try {
				URL url = new URL(urlPath); // 实例化URL对象,传入urlPath
				HttpURLConnection conn = (HttpURLConnection) url
						.openConnection(); // 通过url打开一个HttpURLConnection连接对象
				if (conn.getResponseCode() == 200) { // 连接成功时响应码为200
					BufferedReader br = new BufferedReader(
							new InputStreamReader(conn.getInputStream()));
					StringBuffer sb = new StringBuffer();
					String temp = "";
					while ((temp = br.readLine()) != null) {
						sb.append(temp);// 依次读取响应输入流,并存入StringBuffer中
					}
					br.close();
					conn.disconnect();// 断开连接
					result_json = sb.toString();// 得到String类型的响应json
				}
			} catch (Exception e) {
				System.out.println("error!");
			}
			return result_json;// 将此响应json传递到onPostExecute方法中进行UI线程的操作
		}

		/*
		 * @ 此方法虽未要求必须实现,但一般都需实现,用于处理响应结果,对UI线程操作。
		 */
		@Override
		protected void onPostExecute(String result_json) {
			try {
				JSONObject jo = new JSONObject(result_json); // 根据响应json实例化json对象
				String result = jo.getString("result");// 取出json对象中的返回结果result值
				if (result.equals("true")) {// 判断登录是否成功
					tv_result.setText("http_get请求登录成功!");
					tv_result.setTextColor(Color.parseColor("#66CC00"));
				} else {
					tv_result.setText("http_get请求登录失败!");
					tv_result.setTextColor(Color.parseColor("#FF0033"));
				}
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}

	}

	/**
	 * 内部类,异步任务处理类。 高版本中,网络连接请求不能在UI线程中执行,需要调用该异步任务处理类。 此处为处理httpGet请求任务。
	 * 
	 * @author fk 2015.08.12
	 */
	class LoginTaskPost extends AsyncTask<String, Void, String> {
		String resultJson = "";

		@Override
		protected String doInBackground(String... params) {
			String urlPath = "http://192.168.0.31:8080/ServerTest/MyServlet";// post方式不需参数
			try {
				URL url = new URL(urlPath);
				HttpURLConnection conn = (HttpURLConnection) url
						.openConnection();
				conn.setUseCaches(false);// post方式需要:禁止使用缓存
				conn.setDoInput(true);// post方式需要:允许输入数据
				conn.setDoOutput(true);// post方式需要:允许输出数据
				conn.setRequestMethod("POST");// post方式需要:设置请求方式
				conn.setInstanceFollowRedirects(true);// post方式需要:连接遵循重定向
				conn.setRequestProperty("Content-Type",// post方式需要:设置请求头部
						"application/x-www-form-urlencoded");
				conn.connect();// 至此才可以进行连接,注意:getInputStream()是隐式连接,也不可以
				DataOutputStream dos = new DataOutputStream(
						conn.getOutputStream());// 实例化输出流对象,用于写入参数
				StringBuffer paramsBuffer = new StringBuffer();// 实例化StringBuffer缓冲器,用于存储参数
				paramsBuffer.append("&name=" + params[0]);// 每个参数都要使用"&name"+"value"形式
				paramsBuffer.append("&password=" + params[1]);
				paramsBuffer.append("&id=" + params[2]);
				dos.writeUTF(paramsBuffer.toString());// 使用UTF格式输出该参数
				dos.flush();// 输出缓冲
				dos.close();// 输出关闭
				BufferedReader br = new BufferedReader(new InputStreamReader(// 接收服务端返回数据
						conn.getInputStream()));
				StringBuffer sb = new StringBuffer();
				String temp = "";
				while ((temp = br.readLine()) != null) {
					sb.append(temp);
				}
				resultJson = sb.toString();
			} catch (Exception e) {
				e.printStackTrace();
			}
			return resultJson;// 将结果返回onPostExecute方法中对UI进行操作
		}

		@Override
		protected void onPostExecute(String resultJson) {
			try {
				JSONObject jo = new JSONObject(resultJson);
				String result = jo.getString("result");
				if (result.equals("true")) {
					tv_result.setText("http_post请求登录成功!");
					tv_result.setTextColor(Color.parseColor("#66CC00"));
				} else {
					tv_result.setText("http_post请求登录失败!");
					tv_result.setTextColor(Color.parseColor("#FF0033"));
				}
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
	}

}

 
 

使用了Volley框架后,大大简化了代码复杂程度,具体使用方法可以参考我另一篇博客 Volley框架的简单使用

本例目前只使用了最简单的get和post请求方式,服务端目前也只能处理简单的json数据,并不能处理JSONArray数据,接下来再慢慢研究服务端。

希望结识更多同为菜鸟的入门小伙伴,一起探讨,一起进步。




  • 3
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值