本文介绍了如何使用 Android 搭建客户端, 实现手机和服务器的交互。 让我们了解如何采用 SSH 框架,把服务器端的信息用 JSON 的形式发送到手机端。
   
    笔者以前是学的 Java EE,由于项目需要要开发 Android,所以临时补了一个多星期, 主要是手机端和服务器端交互,双向开发的。 首先在服务器端,我采用的是 SSH 框架,struts 2 集合了 JSON 插件,服务器和客户端 的信息交互采用的 JSON 来传输,由于在服务器端用了 Struts 2,所以我就用装了一个 JSON 插件。这样,很轻易的就把服务器端的信息用 JSON 的形式发送到了手机端。以下是代码: 首先,在服务器端搭建好 SSH 框架,具体细节就不在陈述。struts.xml 配置如下:
    1. 2. 
    3. <resulttype="json">
    result</re sult> 4. 5. 6. 7. 8. 
    9. <resulttype="json">
    result </result> 10. 11.    
    手机端的代码如下: 首先,手机端有一个缓存类,主要用于缓存一些手机端需要访问的数据,这样的好处是 可以达达节省手机和服务器的交互,用单例实现的:
    1. 2. 3. 4. 5. 6. 7. privateUserUser; publicclassCache{ importcom.jclick.bean.User; packagecom.jclick.cache;
    8. 9. 10. 11. } 12. /构造单例/ 13. privatestaticclassCacheHolder{ 14. privatestaticfinalCacheINSTANCE=newCache(); 15. } 16. publicCachegetInstance(){ 17. returnCacheHolder.INSTANCE; 18. } 19. publicUsergetUser(){ 20. returnUser; 21. } 22. publicvoidsetUser(UserUser){ 23. this.User=User; 24. } 25. 26. } 27. 28. packagecom.jclick.cache; 29. 30. importcom.jclick.bean.User; 31. 32. publicclassCache{ 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. } } publicvoidsetUser(UserUser){ this.User=User; } publicUsergetUser(){ returnUser; } publicCachegetInstance(){ returnCacheHolder.INSTANCE; } /构造单例/ privatestaticclassCacheHolder{ privatestaticfinalCacheINSTANCE=newCache(); privateCache(){ privateUserUser; privateCache(){
    52. 53. }
    接着开始书写手机端的协议, 用户向服务器发送请求, 同时服务器反馈给手机端信息的:
    1. 2. 3. 4. 5. 6. 7. 8. 9. importorg.apache.http.HttpResponse; importorg.apache.http.NameValuePair; importjava.io.BufferedReader; importjava.io.InputStreamReader; importjava.util.ArrayList; importjava.util.List; packagecom.jclick.protocol;
    10. importorg.apache.http.client.HttpClient; 11. importorg.apache.http.client.entity.UrlEncodedFormEntity; 12. importorg.apache.http.client.methods.HttpPost; 13. importorg.apache.http.impl.client.DefaultHttpClient; 14. importorg.apache.http.message.BasicNameValuePair; 15. importorg.json.JSONException; 16. importorg.json.JSONObject; 17. 18. publicclassBaseProtocol{ 19. privateStringBuildersb=newStringBuilder(); 20. 21. privateHttpClienthttpClient; 22. privateHttpPosthttpRequest; 23. privateHttpResponseresponse; 24. 25. privateList<NameValuePair>nameValuePair=newArrayList<NameValuePair>( ); 26. 27. BaseProtocol(){ 28. httpClient=newDefaultHttpClient(); 29. } 30. 31. / 32. 向服务器端发送请求 33.  34. @paramurl 35. @throwsException 36. / 37. protectedvoidpack(Stringurl)throwsException{ 38. httpClient=newDefaultHttpClient();
    39. httpRequest=newHttpPost(url); 40. 41. httpRequest.setEntity(newUrlEncodedFormEntity(nameValuePair)); 42. response=httpClient.execute(httpRequest); 43. } 44. 45. / 46. 得到返回数据 47.  48. @paramurl 49. @return 50. @throwsException 51. / 52. protectedvoidparse()throwsException{ 53. //TODO 状态处理 500200 54. if(response.getStatusLine().getStatusCode()==200){ 55. 56. BufferedReaderbufferedReader2=newBufferedReader( 57. newInputStreamReader(response.getEntity().getContent())); 58. for(Strings=bufferedReader2.readLine();s!=null;s=bufferedReader2 59. .readLine()){ 60. sb.append(s); 61. } 62. } 63. } 64. 65. / 66. 向服务器发送信息 67.  68. @paramkey 69. @paramvalue 70. / 71. publicvoidaddNameValuePair(Stringkey,Stringvalue){ 72. nameValuePair.add(newBasicNameValuePair(key,value)); 73. } 74. 75. / 76. 返回 JSONObject 对象数据模型 77.  78. @return 79. @throwsJSONException 80. / 81. publicJSONObjectgetJSON()throwsJSONException{ 82. returnnewJSONObject(sb.toString());
    83. } 84. 85. } 86. 87. packagecom.jclick.protocol; 88. 89. importjava.io.BufferedReader; 90. importjava.io.InputStreamReader; 91. importjava.util.ArrayList; 92. importjava.util.List; 93. 94. importorg.apache.http.HttpResponse; 95. importorg.apache.http.NameValuePair; 96. importorg.apache.http.client.HttpClient; 97. importorg.apache.http.client.entity.UrlEncodedFormEntity; 98. importorg.apache.http.client.methods.HttpPost; 99. importorg.apache.http.impl.client.DefaultHttpClient; 100. importorg.apache.http.message.BasicNameValuePair; 101. importorg.json.JSONException; 102. importorg.json.JSONObject; 103. 104. publicclassBaseProtocol{ 105. 106. 107. 108. 109. 110. 111. privateList<NameValuePair>nameValuePair=newArrayList<NameValuePa privateHttpClienthttpClient; privateHttpPosthttpRequest; privateHttpResponseresponse; privateStringBuildersb=newStringBuilder();
    ir>(); 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. / 向服务器端发送请求  @paramurl @throwsException / protectedvoidpack(Stringurl)throwsException{ httpClient=newDefaultHttpClient(); httpRequest=newHttpPost(url); } BaseProtocol(){ httpClient=newDefaultHttpClient();
    126. 127. ); 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. tent())); 144. dReader2 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. / 返回 JSONObject 对象数据模型  @return @throwsJSONException / } / 向服务器发送信息  @paramkey @paramvalue / publicvoidaddNameValuePair(Stringkey,Stringvalue){ nameValuePair.add(newBasicNameValuePair(key,value)); } } } .readLine()){ sb.append(s); for(Strings=bufferedReader2.readLine();s!=null;s=buffere BufferedReaderbufferedReader2=newBufferedReader( newInputStreamReader(response.getEntity().getCon / 得到返回数据  @paramurl @return @throwsException / protectedvoidparse()throwsException{ //TODO 状态处理 500200 if(response.getStatusLine().getStatusCode()==200){ } response=httpClient.execute(httpRequest); httpRequest.setEntity(newUrlEncodedFormEntity(nameValuePair)
    167. 168. 169. 170. 171. }
    publicJSONObjectgetJSON()throwsJSONException{ returnnewJSONObject(sb.toString()); }
    接着是登陆协议,在这里我只是模拟登陆使用的一个类,仅供大家参考:
    1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. publicbooleancheckLogin(Userusr){ 12. try{ 13. pack(URL); 14. parse(); 15. JSONObjectobj=this.getJSON(); 16. if(obj.getString("result").equals("failed")){ 17. returnfalse; 18. }else{ 19. returntrue; 20. } 21. }catch(Exceptione){ 22. e.printStackTrace(); 23. returnfalse; 24. } 25. } 26. 27. } 28. 29. packagecom.jclick.protocol; 30. 31. importorg.json.JSONObject; 32. 33. importcom.jclick.bean.User; 34. 35. publicclassLoginProtocolextendsBaseProtocol{ 36. privatefinalstaticStringURL="localhost:8080/test/login"; publicclassLoginProtocolextendsBaseProtocol{ importcom.jclick.bean.User; importorg.json.JSONObject; packagecom.jclick.protocol;
    37.
    privatefinalstaticStringURL="localhost:8080/test/login";
    38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. } } } } }catch(Exceptione){ e.printStackTrace(); returnfalse; publicbooleancheckLogin(Userusr){ try{ pack(URL); parse(); JSONObjectobj=this.getJSON(); if(obj.getString("result").equals("failed")){ returnfalse; }else{ returntrue;
    然后是 User 实体类,主要用于保存用户信息:
    1. 2. 3. 4. 5. 6. 7. 8. 9. publicclassUser{ privateStringusername; privateStringpassword; publicStringgetUsername(){ returnusername; } publicvoidsetUsername(Stringusername){ packagecom.jclick.bean;
    10. this.username=username; 11. } 12. publicStringgetPassword(){ 13. returnpassword; 14. } 15. publicvoidsetPassword(Stringpassword){ 16. this.password=password; 17. } 18. 19. } 20. 21. packagecom.jclick.bean;
    22. 23. publicclassUser{ 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. } } } publicvoidsetPassword(Stringpassword){ this.password=password; } publicStringgetPassword(){ returnpassword; } publicvoidsetUsername(Stringusername){ this.username=username; privateStringusername; privateStringpassword; publicStringgetUsername(){ returnusername;
    最后就是 LoginActivity 里边判断登陆的代码了, 详细代码不再贴出来了, 仅贴一个判 断登陆的代码:
    1. 2. privatevoidcheckedData(){ username=((EditText)findViewById(R.id.username)).getText().toString( ); 3. password=((EditText)findViewById(R.id.password)).getText().toString( ); 4. 5. 6. 7. 8. 9. 10. 11. if(result){SpiderCache.getInstance().setUserSession(user); 12. Toast.makeText(getApplicationContext(),"登录成功",1000).show(); 13. Intentintent=newIntent(); 14. intent.setClass(LoginActivity.this,WelcomeActivity.class); 15. startActivity(intent); 16. }else{Toast.makeText(LoginActivity.this,"密码或用户名不匹配,请重新输入! ",1000).show(); 17. } 18. } 19. Useruser=newUser(); user.setUsername(username); user.setPassword(password); LoginProtocollogin=newLoginProtocol(); booleanresult=login.checkLogin(user);
    20. 21.
    privatevoidcheckedData(){ username=((EditText)findViewById(R.id.username)).getText ().toString();
    22.
    password=((EditText)findViewById(R.id.password)).getText ().toString();
    23. 24. 25. 26. 27. 28. 29. 30. if(result){ rSession(user); 31. ",1000).show(); 32. 33. lass); 34. 35. startActivity(intent); }else{ Toast.makeText(LoginActivity.this," Intentintent=newIntent(); intent.setClass(LoginActivity.this,WelcomeActivity.c Toast.makeText(getApplicationContext(),"登录成功 SpiderCache.getInstance().setUse Useruser=newUser(); user.setUsername(username); user.setPassword(password); LoginProtocollogin=newLoginProtocol(); booleanresult=login.checkLogin(user);
    密码或用户名不匹配,请重新输入!",1000).show(); 36. 37. } }
    以上代码为了跟大家分享一下,感觉手机端和服务器双向开发非常过瘾。同时对 Android 的兴趣大大提升,它也没有我们想象中的那么难。