写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文!

本博客全网唯一合法URL:http://www.cnblogs.com/acm-icpcer/p/8521625.html

   最近尝试了一下使用tomcat把自己的笔记本作为项目的服务器。

  tomcat下载:https://tomcat.apache.org/download-90.cgi

  当然啦,你可以选择点击zip进行免安装下载(即下载了zip包之后解压即可),或者点击32-bit/64-bit windows service installer进行.exe安装包的下载。

  下载后我一般喜欢在我选择的下载路径里面的bin文件夹下双击Tomcat9w.exe启动。

  启动之后的界面:

  点击start后,tomcat就启动了,它所产生的进程就一直处于监听有没有访问请求的状态。

  tomcat服务器的细节配置方法比较原始,是在安装路径下的conf文件夹下面的server.xml文件里进行代码的改写来自定义配置,在此先不详述。

  安装好后我们可以用一个小的web项目来测试服务器是否安装成功:

  我使用的项目是我寒假为我的网页游戏弹弹堂的公会做的官方网站,因为纯粹是前端项目,所以正好可以用来测试。主要方法是:将网站的代码包整个的复制到tomcat下的webapps文件夹(这样就算是在服务器端部署成功了)。

  然后测试访问的有效性:先在命令行模式下通过ipconfig命令查看计算机的ipv4地址:

  可以看到我的地址是172.16.124.241,然后在浏览器上输入172.16.124.241:8080/shengyu_shenhua来访问,":8080"是tomcat服务器默认的访问端口,端口号可以在前面提到的server.xml文件里进行修改,"/shengyu_shenhua"是放在服务端webapps文件夹里的网站项目的名字。当然了,使用localhost:8080/shengyu_shenhua来访问也是可以的,但我更习惯使用IP地址访问。

  可以访问网页了就说明现在tomcat服务器安装好了。但是此时的tomcat服务器只能给连接在相同路由器的终端访问,因为通常来说,isp给你通的网都不会有固定的ip,所以过一段时间你的电脑ip就会改变,除非isp给你牵了专线。所以通过IP的访问是不稳定的,在没有固定服务器或者云服务的情况下,tomcat还是适合在局域网内使用。

下面讲讲怎么让Android通过http访问局域网内tomcat服务器上的资源:

  一般来说,使用android开发进行http链接,会用url来访问资源,但是网络连接线程不能放在主线程,因为当网络连接不成功时会抛出主线程异常,所以一般会另开一个线程来保持网络连接:

  

  MainActivity.java代码:

  1. package com.example.administrator.tryserver;
  2.  
  3. import android.app.Activity;
  4. import android.graphics.Bitmap;
  5. import android.graphics.BitmapFactory;
  6. import android.os.Bundle;
  7. import android.os.Handler;
  8. import android.os.Message;
  9. import android.view.View;
  10. import android.view.View.OnClickListener;
  11. import android.widget.Button;
  12. import android.widget.ImageView;
  13.  
  14. import org.json.JSONException;
  15. import org.json.JSONObject;
  16.  
  17. import java.io.DataOutputStream;
  18. import java.io.IOException;
  19. import java.io.InputStream;
  20. import java.net.HttpURLConnection;
  21. import java.net.URL;
  22.  
  23. public class MainActivity extends Activity {
  24.  
  25. private ImageView ivImg;
  26. private Button btnDownload;
  27. private Bitmap img;
  28. private ImageHandler imgHandler = new ImageHandler();
  29. //测试Url
  30. private String url = "http://172.16.124.241:8080/img/1.jpg";
  31.  
  32. @Override
  33. protected void onCreate(Bundle savedInstanceState) {
  34. super.onCreate(savedInstanceState);
  35. setContentView(R.layout.activity_main);
  36. ivImg = (ImageView) findViewById(R.id.imageView1);
  37. btnDownload = (Button) findViewById(R.id.button1);
  38. //点击按钮开始下载
  39. btnDownload.setOnClickListener(new OnClickListener() {
  40. @Override
  41. public void onClick(View v) {
  42. downloadImg();
  43. }
  44. });
  45. }
  46.  
  47. /**
  48. * 异步从服务器加载图片数据
  49. */
  50. private void downloadImg(){
  51. new Thread(new Runnable() {
  52. @Override
  53. public void run() {
  54. Bitmap img = getImg();
  55. Message msg = imgHandler.obtainMessage();
  56. msg.what = 0;
  57. msg.obj = img;
  58. imgHandler.sendMessage(msg);
  59. }
  60. }).start();
  61. }
  62.  
  63. /**
  64. * 异步线程请求到的图片数据,利用Handler,在主线程中显示
  65. */
  66. class ImageHandler extends Handler{
  67. @Override
  68. public void handleMessage(Message msg) {
  69.  
  70. switch (msg.what) {
  71. case 0:
  72. img = (Bitmap)msg.obj;
  73. if(img != null){
  74. ivImg.setImageBitmap(img);
  75. }
  76. break;
  77.  
  78. default:
  79. break;
  80. }
  81. }
  82. }
  83.  
  84. /**
  85. * 从服务器读取图片流数据,并转换为Bitmap格式
  86. * @return Bitmap
  87. */
  88. private Bitmap getImg(){
  89. Bitmap img = null;
  90.  
  91. try {
  92. URL imgUrl = new URL(url);
  93. HttpURLConnection conn = (HttpURLConnection) imgUrl.openConnection();
  94.  
  95. conn.setRequestMethod("POST");
  96. conn.setConnectTimeout(1000 * 6);
  97. conn.setDoInput(true);
  98. conn.setDoOutput(true);
  99. conn.setUseCaches(false);
  100.  
  101. conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
  102. conn.setRequestProperty("Connection", "Keep-Alive");
  103. conn.setRequestProperty("Charset", "UTF-8");
  104. conn.connect();
  105.  
  106. //输出流写参数
  107. DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
  108. String param = getParam();
  109. dos.writeBytes(param);
  110. dos.flush();
  111. dos.close();
  112.  
  113. int resultCode = conn.getResponseCode();
  114.  
  115. if(HttpURLConnection.HTTP_OK == resultCode){
  116. InputStream is = conn.getInputStream();
  117. img = BitmapFactory.decodeStream(is);
  118. is.close();
  119. }
  120. } catch (IOException e) {
  121. e.printStackTrace();
  122. }
  123.  
  124. return img;
  125. }
  126.  
  127. /**
  128. * 测试参数
  129. * @return
  130. */
  131. private String getParam(){
  132. JSONObject jsObj = new JSONObject();
  133. try {
  134. jsObj.put("picFormat", "jpg");
  135. jsObj.put("testParam", "9527");
  136. } catch (JSONException e) {
  137. e.printStackTrace();
  138. }
  139.  
  140. return jsObj.toString();
  141. }
  142. }

  界面文件activity_main.xml文件代码:

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical" >
  6.  
  7. <EditText
  8. android:id="@+id/editText1"
  9. android:layout_width="match_parent"
  10. android:layout_height="wrap_content"
  11. android:ems="10" >
  12.  
  13. <requestFocus />
  14. </EditText>
  15.  
  16. <Button
  17. android:id="@+id/button1"
  18. android:layout_width="fill_parent"
  19. android:layout_height="wrap_content"
  20. android:text="点击获取URL资源" />
  21.  
  22. <ImageView
  23. android:id="@+id/imageView1"
  24. android:layout_width="wrap_content"
  25. android:layout_height="wrap_content"
  26. android:layout_gravity="center_horizontal"/>
  27.  
  28. </LinearLayout>

  当然了,不要忘了在AndroidManifest.xml文件里面加上打开网络权限的语句:

  1. <uses-permission android:name="android.permission.INTERNET"/>

  即AndroidManifest.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.example.administrator.tryserver">
  4. <uses-permission android:name="android.permission.INTERNET"/>
  5.  
  6. <application
  7. android:allowBackup="true"
  8. android:icon="@mipmap/ic_launcher"
  9. android:label="@string/app_name"
  10. android:roundIcon="@mipmap/ic_launcher_round"
  11. android:supportsRtl="true"
  12. android:theme="@style/AppTheme">
  13. <activity android:name=".MainActivity">
  14. <intent-filter>
  15. <action android:name="android.intent.action.MAIN" />
  16.  
  17. <category android:name="android.intent.category.LAUNCHER" />
  18. </intent-filter>
  19. </activity>
  20. </application>
  21.  
  22. </manifest>

  这个项目主要是在局域网环境下,当你点击button,就可以在android界面显示url里面指定服务器内的图片资源(在此是:http://172.16.124.241:8080/img/1.jpg)。如果希望在互联网访问Tomcat服务器资源,只需要设置路由器的路由映射,将路由器的IP地址指定映射到你的电脑的特定端口(在此是8080)即可,设置好后,就是使用http协议在互联网访问你的Tomcat服务器资源了。

  只要保持在同一局域网下,不论是android真机还是虚拟机都是可以的。只不过在用虚拟机访问的时候不能用"http://localhost:8080/img/1.jpg"这个url,因为这样的话,localhost指代虚拟机本机而不是运行虚拟机的主机,故使用"http://10.0.2.2:8080/img/1.jpg"来访问主机资源。在虚拟机下,"http://10.0.2.2:8080/img/1.jpg"以及"http://172.16.124.241:8080/img/1.jpg"这两个url都是可以的,唯独不能使用"http://localhost:8080/img/1.jpg"这个url。当然,使用Android真机调试的时候还会遇到手机连接到了主机usb接口,但是android studio识别不到的问题,一般是没有打开手机的开发者模式或者手机没有能正确的安装设备驱动程序(此时应该上手机的官方网站下载驱动)。

注:因为今天是女生节,所以测试用的图片资源是一个日系卡通萌妹子。原画作者:德田有希,日本漫画家&一个可爱的男孩子。

TZ@华中农业大学信息学院

2018/3/7

Android+Tomcat通过http获取本机服务器资源的更多相关文章

  1. Python 优雅获取本机 IP 方法【转】

    转自:https://www.cnblogs.com/lfxiao/p/9672975.html 见过很多获取服务器本地IP的代码,个人觉得都不是很好,例如以下这些 不推荐:靠猜测去获取本地IP方法 ...

  2. Python 优雅获取本机 IP 方法

    原文 见过很多获取服务器本地IP的代码,个人觉得都不是很好,例如以下这些 不推荐:靠猜测去获取本地IP方法 #!/usr/bin/env python # -*- coding: utf-8 -*- ...

  3. python 获取本机 IP

    原文 通过 UDP 获取本机 IP,目前见过最优雅的方法 这个方法是目前见过最优雅获取本机服务器的IP方法了.没有任何的依赖,也没有去猜测机器上的网络设备信息. 而且是利用 UDP 协议来实现的,生成 ...

  4. Android模拟器如何加载本机地址及访问本机服务器

    首先获取本机ip地址: 在cmd 命令窗口中输入 ipconfig 查看本地电脑ip地址如下: 获取服务器上的Json数据,并返回结果,部分代码如下: 注:StreamUtils是自定义的一个工具类, ...

  5. android获取本机的IP地址和mac物理地址

    /获取本机IP地址 public String getLocalIpAddress() { WifiManager wifiManager = (WifiManager) getSystemServi ...

  6. 获取本机 Android 默认sha1 秘钥

    获取本机 Android 默认sha1 秘钥: 以Windows操作系统为例,打开CMD,运行以下指令将得到所有默认秘钥. keytool -list -v -keystore C:\Users\pa ...

  7. Android 获取本机WIFI及3G网络IP

    获取本机WIFIprivate String getLocalIpAddress() { WifiManager wifiManager = (WifiManager) getSystemServic ...

  8. Android实现获取本机中所有图片

    本示例演示如何在Android中使用加载器(Loader)来实现获取本机中的所有图片,并进行查看图片的效果. 在这个示例中,我使用android-support-v4.jar中的加载器(Loader) ...

  9. android 中获取网络状态、判断3G、2G、wifi网络、判断wifi是否打开、获取本机地址、获取本机串号IMEI整理

    代码如下:package com.android.xym; import java.io.IOException; import java.net.HttpURLConnection; import ...

随机推荐

  1. CentOS7安装chrony替代ntp同步时间

    Chrony是一个开源的自由软件,它能保持系统时钟与时钟服务器(NTP)同步,让时间保持精确.它由两个程序组成:chronyd和chronyc:chronyd是一个后台运行的守护进程,用于调整内核中运 ...

  2. 服务端怎样暴露IBinder接口对象

    服务端怎样暴露IBinder接口对象: package com.example.mydownload; import android.app.Service; import android.conte ...

  3. Forward+ Shading架构

    Forward+ = Tile based Light Culling + Tile based Forward Rendering 整体渲染架构分为如下3大步骤: 1.PrePass将场景的min ...

  4. vs get set快捷键

    vs get set快捷键 光标放在空白处输入prop,然后tab两次,修改类型和名称即可

  5. Django基础学习之Cookie 和 Sessions 应用

    在Django里面,使用Cookie和Session看起来好像是一样的,使用的方式都是request.COOKIES[XXX]和request.session[XXX],其中XXX是您想要取得的东西的 ...

  6. Android自动化测试之Monkeyrunner从零开始

    最近由于公司在组织一个Free CoDE的项目,也就是由大家自己选择研究方向来做一些自己感兴趣的研究.由于之前我学过一点点关于android的东西,并且目前android开发方兴未艾如火如荼,但自动化 ...

  7. 教你一招:解决Win 10安装软件时提示:文件系统错误 (-1073740940)

    1.win+R输入 gpedit.msc 2.左边计算机配置 windows设置——安全设置——本地策略——安全选项 3.在安全选项右边选择 用户账户控制:管理员批准模式中管理员的提升权限提示的行为, ...

  8. vue.js是什么

    Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的 渐进式框架.与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计.Vue 的核心库只关注视图层,并且非常容易学习, ...

  9. java 汉诺塔实现自动演示

    1.增加计时功能,显示用户完成移动盘子所花费的时间 2.用户可以设置最大和最小盘子的大小 3.用户可以选择播放和暂停背景音乐 4.用户可以设置盘子的数目 5.用户可以设置盘子的颜色以及背景的颜色 6. ...

  10. debian系列下c++调用mysql, linux下面安装mysql.h文件

    mysql.h的报错还没有解决,你们不用看了,等我解决了吧还不知道什么时候 先用c吧 #include <stdio.h> #include <stdlib.h> #inclu ...