在 WEB 开发中,常常用到的服务器是 Tomcat,想把 WEB 项目在手机上实现时,最省事的办法就是只需要在 Android 上实现 UI 编程即可,服务器还是用原来 WEB 项目的服务器,所以后台代码几乎不需要修改,这样可以省下不少开发时间。
那么如何用让 Android 和 Tomcat 实现数据的交互呢?由于 WEB 项目开发大多用 post 请求,所以为了实现后台代码的复用,在 Android 中用 HttpPost 请求服务器即可。
后台接受请求的代码如下:
- protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- request.setCharacterEncoding("utf-8");
- response.setCharacterEncoding("utf-8");
- String jsonStr = request.getParameter("JSONDATA");
- }
那么,在 Android 中用 HttpPost 发送请求的方式如下:
- // URL使用基本URL即可,其中不需要加参数
- HttpPost httpPost = new HttpPost(http://127.0.0.1:8080/android/funcServlet");
- // 需要客户端对象来发送请求
- HttpClient httpClient = new DefaultHttpClient();
- HttpResponse response = null;
- // 设置参数
- List<NameValuePair> params = new ArrayList<NameValuePair>();
- params.add(new BasicNameValuePair("JSONDATA", data));
- // 生成请求实体
- HttpEntity requestHttpEntity = new UrlEncodedFormEntity(params, "utf-8");
- // 将请求体内容加入请求中
- httpPost.setEntity(requestHttpEntity);
- // 发送请求
- response = httpClient.execute(httpPost);
处理返回的 response:
- String result = "";
- if (null == response) {
- return "无数据返回!";
- }
- HttpEntity httpEntity = response.getEntity();
- try {
- InputStream inputStream = httpEntity.getContent();
- BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
- String line = "";
- while (null != (line = reader.readLine())) {
- result += line;
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- System.out.println(result);
但是,运用的过程中,在以前的 Android 版本中,如 2.2、2.3 等,这样发送请求没有问题,但是在新版本中,如 4.0 以上,会报错,提示请求异常。原因是 Android 新版本不允许主线程运行网络请求,4.0 以后不能在主线程访问网络,而必须在一个新线程中访问才可以。
所以,解决方法有两种,一种方法是新创建一个线程,在新线程中访问数据。还有一种简便的方法,就是在 Android 的主画面的 Activity 的 onCreate 方法中,加入下面的代码即可。
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- int SDK_INT = android.os.Build.VERSION.SDK_INT;
- if (SDK_INT >= 11) {
- StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
- .detectDiskReads().detectDiskWrites()
- .detectNetwork() // 这里可以替换为detectAll()
- // 就包括了磁盘读写和网络I/O
- .penaltyLog() // 打印logcat,当然也可以定位到dropbox,通过文件保存相应的log
- .build());
- StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
- .detectLeakedSqlLiteObjects() // 探测SQLite数据库操作
- .penaltyLog() // 打印logcat
- .penaltyDeath().build());
- }
- }
注意,请求时,一定要在 Android 配置文件 AndroidManifest.xml 中加入访问网络的权限(如下),否则怎么调试都白搭。
- <uses-permission android:name="android.permission.INTERNET"/>