- Android客户端与服务端交互之登陆示例
-
今天了解了一下android客户端与服务端是怎样交互的,发现其实跟web有点类似吧,然后网上找了大神的登陆示例,是基于IntentService的
1.后台使用简单的servlet,支持GET或POST。这个servlet最终返回给前台一个字符串flag,值是true或false,表示登录是否成功。
servlet使用之前需要配置,主义servlet的servlet-name要和servlet-mapping的servlet-name一致,否则找不到路径
我是在myEclipse上创建的一个web service 项目,然后部署到tomcat服务器上以便android客户端访问
1 import java.io.IOException; 2 import java.io.PrintWriter; 3 4 import javax.servlet.ServletException; 5 import javax.servlet.http.HttpServlet; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 import javax.servlet.http.HttpSession; 9 10 import com.zhongzhong.wap.bean.UserBean; 11 12 public class HelloServlet extends HttpServlet { 13 14 @Override 15 protected void doGet(HttpServletRequest req, HttpServletResponse resp) 16 throws ServletException, IOException { 17 doPost(req, resp); 18 } 19 20 @Override 21 protected void doPost(HttpServletRequest req, HttpServletResponse resp) 22 throws ServletException, IOException { 23 24 resp.setContentType(text/html); 25 PrintWriter out = resp.getWriter(); 26 Boolean flag = false; 27 String userName = req.getParameter(un); 28 String password = req.getParameter(pw); 29 if(userName.equals(htp)&&password.equals(123)) 30 { 31 flag = true; 32 } 33 34 else flag = false; 35 System.out.println(userName:+userName+ password:+password); 36 out.print(flag); 37 out.flush(); 38 out.close(); 39 } 40 41 }
2.然后我是在安卓的ADT上创建一个安卓项目,建立两个Activity,分别作为登录界面和登录成功界面。1 1 <relativelayout 2 android:layout_height="match_parent" 3 android:layout_width="match_parent" 4 android:paddingbottom="@dimen/activity_vertical_margin" 5 android:paddingleft="@dimen/activity_horizontal_margin" 6 android:paddingright="@dimen/activity_horizontal_margin" 7 android:paddingtop="@dimen/activity_vertical_margin" 8 tools:context=".MainActivity" 9 xmlns:android="http://schemas.android.com/apk/res/android" 10 xmlns:tools="http://schemas.android.com/tools"> 11 2 12 3 <textview android:id="@+id/textView1" 13 android:layout_alignparenttop="true" 14 android:layout_centerhorizontal="true" 15 android:layout_height="wrap_content" 16 android:layout_margintop="40dp" 17 android:layout_width="wrap_content"android:text="HelloWorld登陆示例"> 18 19 <edittext
android:ems="10" 20 android:hint="请输入账号" 21 android:id="@+id/et_user" 22 android:layout_below="@+id/textView1" 23 android:layout_centerhorizontal="true" 24 android:layout_height="wrap_content" 25 android:layout_margintop="33dp" 26 android:layout_width="wrap_content"> 27 28 <requestfocus> 29 </requestfocus> 30 </edittext> 31 32 <edittext
android:ems="10" 33 android:hint="请输入密码" 34 android:id="@+id/et_psw" 35 android:inputtype="textPassword" 36 android:layout_below="@+id/et_user" 37 android:layout_centerhorizontal="true" 38 android:layout_height="wrap_content" 39 android:layout_margintop="40dp" 40 android:layout_width="wrap_content"> 41 42 <button
android:id="@+id/btn_login" 43 android:layout_below="@+id/et_psw" 44 android:layout_centerhorizontal="true" 45 android:layout_height="wrap_content" 46 android:layout_margintop="37dp" 47 android:layout_width="wrap_content" 48 android:text="登陆"> 49 </button> 50 </edittext> 51 </textview> 52 </relativelayout> -
<relativelayout android:layout_height="match_parent" android:layout_width="match_parent" android:paddingbottom="@dimen/activity_vertical_margin" android:paddingleft="@dimen/activity_horizontal_margin" android:paddingright="@dimen/activity_horizontal_margin" android:paddingtop="@dimen/activity_vertical_margin" tools:context=".NaviActivity" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <textview android:layout_alignparenttop="true" android:layout_centerhorizontal="true" android:layout_height="wrap_content" android:layout_margintop="46dp" android:layout_width="wrap_content" android:text="登陆成功"> </textview></relativelayout>
3.HTTP的访问公共类,用于处理GET和POST请求
1 package com.example.logindemo; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 import java.util.Map; 6 7 import org.apache.http.HttpResponse; 8 import org.apache.http.NameValuePair; 9 import org.apache.http.client.HttpClient; 10 import org.apache.http.client.entity.UrlEncodedFormEntity; 11 import org.apache.http.client.methods.HttpGet; 12 import org.apache.http.client.methods.HttpPost; 13 import org.apache.http.impl.client.DefaultHttpClient; 14 import org.apache.http.message.BasicNameValuePair; 15 import org.apache.http.util.EntityUtils; 16 17 import android.content.Entity; 18 import android.util.Log; 19 20 public class HttpUtil { 21 // 创建HttpClient对象 22 public static HttpClient httpClient = new DefaultHttpClient(); 23 public static final String BASE_URL = http://192.168.3.14:8090/HelloWord/; 24 25 /** 26 * 27 * @param url 28 * 发送请求的URL 29 * @return 服务器响应字符串 30 * @throws Exception 31 */ 32 public static String getRequest(String url) throws Exception { 33 // 创建HttpGet对象。 34 HttpGet get = new HttpGet(url); 35 // 发送GET请求 36 HttpResponse httpResponse = httpClient.execute(get); 37 // 如果服务器成功地返回响应 38 if (httpResponse.getStatusLine().getStatusCode() == 200) { 39 // 获取服务器响应字符串 40 String result = EntityUtils.toString(httpResponse.getEntity()); 41 return result; 42 } else { 43 Log.d(服务器响应代码, (new Integer(httpResponse.getStatusLine() 44 .getStatusCode())).toString()); 45 return null; 46 } 47 } 48 49 /** 50 * 51 * @param url 52 * 发送请求的URL 53 * @param params 54 * 请求参数 55 * @return 服务器响应字符串 56 * @throws Exception 57 */ 58 public static String postRequest(String url, Map<string, string=""> rawParams) 59 throws Exception { 60 // 创建HttpPost对象。 61 HttpPost post = new HttpPost(url); 62 // 如果传递参数个数比较多的话可以对传递的参数进行封装 63 List<namevaluepair> params = new ArrayList<namevaluepair>(); 64 for (String key : rawParams.keySet()) { 65 // 封装请求参数 66 params.add(new BasicNameValuePair(key, rawParams.get(key))); 67 } 68 // 设置请求参数 69 post.setEntity(new UrlEncodedFormEntity(params, UTF-8)); 70 // 发送POST请求 71 HttpResponse httpResponse = httpClient.execute(post); 72 // 如果服务器成功地返回响应 73 if (httpResponse.getStatusLine().getStatusCode() == 200) { 74 // 获取服务器响应字符串 75 String result = EntityUtils.toString(httpResponse.getEntity()); 76 return result; 77 } 78 return null; 79 } 80 } 81 </namevaluepair></namevaluepair></string,>
1 package com.example.logindemo; 2 3 import java.util.HashMap; 4 5 import android.app.IntentService; 6 import android.content.Intent; 7 import android.util.Log; 8 9 public class ConnectService extends IntentService { 10 private static final String ACTION_RECV_MSG = com.example.logindemo.action.RECEIVE_MESSAGE; 11 12 public ConnectService() { 13 super(TestIntentService); 14 // TODO Auto-generated constructor stub 15 } 16 17 @Override 18 protected void onHandleIntent(Intent intent) { 19 // TODO Auto-generated method stub 20 /** 21 * 经测试,IntentService里面是可以进行耗时的操作的 22 * IntentService使用队列的方式将请求的Intent加入队列, 23 * 然后开启一个worker thread(线程)来处理队列中的Intent 24 * 对于异步的startService请求,IntentService会处理完成一个之后再处理第二个 25 */ 26 Boolean flag = false; 27 //通过intent获取主线程传来的用户名和密码字符串 28 String username = intent.getStringExtra(username); 29 String password = intent.getStringExtra(password); 30 flag = doLogin(username, password); 31 Log.d(登录结果, flag.toString()); 32 33 Intent broadcastIntent = new Intent(); 34 broadcastIntent.setAction(ACTION_RECV_MSG); 35 broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT); 36 broadcastIntent.putExtra(result, flag.toString()); 37 sendBroadcast(broadcastIntent); 38 39 } 40 41 // 定义发送请求的方法 42 private Boolean doLogin(String username, String password) 43 { 44 String strFlag = ; 45 // 使用Map封装请求参数 46 HashMap<string, string=""> map = new HashMap<string, string="">(); 47 map.put(un, username); 48 map.put(pw, password); 49 // 定义发送请求的URL 50 String url = HttpUtil.BASE_URL + queryOrder?un= + username + &pw= + password; //GET方式 51 // String url = HttpUtil.BASE_URL + LoginServlet; //POST方式 52 Log.d(url, url); 53 Log.d(username, username); 54 Log.d(password, password); 55 try { 56 // 发送请求 57 strFlag = HttpUtil.postRequest(url, map); //POST方式 58 // strFlag = HttpUtil.getRequest(url); //GET方式 59 Log.d(服务器返回值, strFlag); 60 } catch (Exception e) { 61 // TODO Auto-generated catch block 62 e.printStackTrace(); 63 } 64 65 if(strFlag.trim().equals(true)){ 66 return true; 67 }else{ 68 return false; 69 } 70 71 } 72 } 73 </string,></string,>
5。在AndroidManifest.xml中注册IntentService。注意uses-permission节点,为程序开启访问网络的权限。1 <!--?xml version=1.0 encoding=utf-8?--> 2 <manifest android:versioncode="1" android:versionname="1.0" package="com.example.logindemo" xmlns:android="http://schemas.android.com/apk/res/android"> 3 4 <uses-sdk android:minsdkversion="8" android:targetsdkversion="18"> 5 6 <uses-permission android:name="android.permission.INTERNET"> 7 8 9 10 <intent-filter> 11 12 13 <category android:name="android.intent.category.LAUNCHER"> 14 </category></action></intent-filter> 15 </activity> 16 17 </activity> 18 19 <service android:name="com.example.logindemo.ConnectService"> 20 </service> 21 </application> 22 23 </uses-permission></uses-sdk></manifest>
6.登陆界面处理,注意- 按钮监听事件中,使用Intent将要传递的值传给service。接收广播类中,同样使用Intent将要传递的值传给下一个Activity。在onCreate()中,动态注册接收广播类的实例receiver。在接收广播类中,不要使用完毕后忘记注销接收器,否则会报一个Are you missing a call to unregisterReceiver()? 的异常。
1 package com.example.logindemo; 2 3 import android.os.Bundle; 4 import android.app.Activity; 5 import android.content.BroadcastReceiver; 6 import android.content.Context; 7 import android.content.Intent; 8 import android.content.IntentFilter; 9 import android.util.Log; 10 import android.view.Menu; 11 import android.view.View; 12 import android.view.View.OnClickListener; 13 import android.widget.Button; 14 import android.widget.EditText; 15 import android.widget.Toast; 16 17 public class MainActivity extends Activity { 18 private static final String ACTION_RECV_MSG = com.example.logindemo.action.RECEIVE_MESSAGE; 19 private Button loginBtn; 20 private EditText et_username; 21 private EditText et_password; 22 private String userName; 23 private String passWord; 24 private MessageReceiver receiver ; 25 @Override 26 protected void onCreate(Bundle savedInstanceState) { 27 super.onCreate(savedInstanceState); 28 setContentView(R.layout.activity_main); 29 initView(); 30 //动态注册receiver 31 IntentFilter filter = new IntentFilter(ACTION_RECV_MSG); 32 filter.addCategory(Intent.CATEGORY_DEFAULT); 33 receiver = new MessageReceiver(); 34 registerReceiver(receiver, filter); 35 } 36 37 private void initView() { 38 // TODO Auto-generated method stub 39 et_username = (EditText)findViewById(R.id.et_user); 40 et_password =( EditText)findViewById(R.id.et_psw); 41 loginBtn = (Button)findViewById(R.id.btn_login); 42 loginBtn.setOnClickListener(new OnClickListener() { 43 44 @Override 45 public void onClick(View v) { 46 // TODO Auto-generated method stub 47 if(matchLoginMsg()) 48 { 49 // 如果校验成功 50 Intent msgIntent = new Intent(MainActivity.this, ConnectService.class); 51 msgIntent.putExtra(username, et_username.getText().toString().trim()); 52 msgIntent.putExtra(password, et_password.getText().toString().trim()); 53 startService(msgIntent); 54 } 55 56 } 57 }); 58 } 59 60 protected boolean matchLoginMsg() { 61 // TODO Auto-generated method stub 62 userName = et_username.getText().toString().trim(); 63 passWord = et_password.getText().toString().trim(); 64 if(userName.equals()) 65 { 66 Toast.makeText(MainActivity.this, 账号不能为空,Toast.LENGTH_SHORT).show(); 67 return false; 68 } 69 if(passWord.equals()) 70 { 71 Toast.makeText(MainActivity.this, 密码不能为空,Toast.LENGTH_SHORT).show(); 72 return false; 73 } 74 return true; 75 } 76 //接收广播类 77 public class MessageReceiver extends BroadcastReceiver { 78 @Override 79 public void onReceive(Context context, Intent intent) { 80 String message = intent.getStringExtra(result); 81 Log.i(MessageReceiver, message); 82 // 如果登录成功 83 if (message.equals(true)){ 84 // 启动Main Activity 85 Intent nextIntent = new Intent(MainActivity.this, NaviActivity.class); 86 startActivity(nextIntent); 87 // 结束该Activity 88 finish(); 89 //注销广播接收器 90 context.unregisterReceiver(this); 91 }else{ 92 Toast.makeText(MainActivity.this, 用户名或密码错误,请重新输入!,Toast.LENGTH_SHORT).show(); 93 } 94 95 } 96 } 97 @Override 98 public boolean onCreateOptionsMenu(Menu menu) { 99 // Inflate the menu; this adds items to the action bar if it is present. 100 getMenuInflater().inflate(R.menu.main, menu); 101 return true; 102 } 103 104 }
运行截图:
- 按钮监听事件中,使用Intent将要传递的值传给service。接收广播类中,同样使用Intent将要传递的值传给下一个Activity。在onCreate()中,动态注册接收广播类的实例receiver。在接收广播类中,不要使用完毕后忘记注销接收器,否则会报一个Are you missing a call to unregisterReceiver()? 的异常。