在Android设备上搭建Web服务器的方法,android webserver

6
回复
822
查看
[复制链接]

434

主题

1104

帖子

473

安币

手工艺人

发表于 2018-5-3 15:35:31 | 显示全部楼层 |阅读模式

            

        一般而言,android 应用在请求数据时都是以 get 或 post 等方式向远程服务器发起请求,那你有没有想过其实我们也可以在 android 设备上搭建一个小型 web 服务器,并且实现常规的下载图片、下载文件、提交表单等功能呢?

        下面要介绍的就是如何在 android 设备上搭建一个 web 服务器,这个 web 服务器的功能有如下几点:



  

    1. 接受客户端文件上传、下载文件


  

    2. 动态 http api,像 java 的 servlet 一样写接口


  

    3. 部署静态网站,例如纯html,支持 js、css、image 分离


  

    4. 部署动态网站
  

        这需要依赖一个开源库来实现:andserver

        andserver 类似于 apache 和 tomcat,支持在同个局域网下的设备能够以常规的网络请求方式来向 web 服务器请求数据,只要指明 web 服务器的 ip 地址和端口号即可

        那么,这个 web 服务器的用途有哪些呢?

        说下我现在遇到的一个需求吧!需要实现两台设备(android 或 ios 设备)在无网络情况下进行数据交流。本来是打算让设备之间的交流通道以 wifi 来链接,即某一台设备连上另一台设备的 wiif 热点,这样两者之间就建立起了一条“通道”,之后通过建立 socket 连接来获取输入输出流,通过输入输出流来交换数据。可是这样就需要处理好在高并发情况下的数据同步和解析问题,比较麻烦,而通过 andserver 就可以直接套用项目已有的网络请求框架,直接以网络请求的方式来交流数据,而服务端也较好的处理了并发问题

        gradle 远程依赖

[Java] 查看源文件 复制代码
implementation 'com.yanzhenjie:andserver:1.1.3'

        搭建服务器

        搭建服务器的方式很简单,支持链式调用。指明服务器在本机的 ip 地址上监听,并指定端口号为 1995 ,并开放了三个接口分别用于:下载文件、下载图片、post表单

[Java] 查看源文件 复制代码
    andserver server = andserver.serverbuilder()
        .inetaddress(netutils.getlocalipaddress()) //服务器要监听的网络地址
        .port(constants.port_server) //服务器要监听的端口
        .timeout(10, timeunit.seconds) //socket超时时间
        .registerhandler(constants.get_file, new downloadfilehandler()) //注册一个文件下载接口
        .registerhandler(constants.get_image, new downloadimagehandler()) //注册一个图片下载接口
        .registerhandler(constants.post_json, new jsonhandler()) //注册一个post json接口
        .filter(new httpcachefilter()) //开启缓存支持
        .listener(new server.serverlistener() { //服务器监听接口
          @override
          public void onstarted() {
            string hostaddress = server.getinetaddress().gethostaddress();
            log.e(tag, "onstarted : " + hostaddress);
            serverpresenter.onserverstarted(serverservice.this, hostaddress);
          }

          @override
          public void onstopped() {
            log.e(tag, "onstopped");
            serverpresenter.onserverstopped(serverservice.this);
          }

          @override
          public void onerror(exception e) {
            log.e(tag, "onerror : " + e.getmessage());
            serverpresenter.onservererror(serverservice.this, e.getmessage());
          }
        })
        .build();

        开启服务器

[Java] 查看源文件 复制代码
server.startup();

        停止服务器

[Java] 查看源文件 复制代码
server.shutdown();

        接口处理器

        在注册接口时,除了指明开放出来的 url 地址外,还需要指明相应的处理器,专门用于处理该接口的请求操作
开放出来的三个接口分别对应于三个地址

[Java] 查看源文件 复制代码
public class constants {

  //服务端接口的端口号
  public static final int port_server = 1995;

  public static final string get_file = "/file";

  public static final string get_image = "/image";

  public static final string post_json = "/json";

}



[Java] 查看源文件 复制代码
 ・・・
 .registerhandler(constants.get_file, new downloadfilehandler()) //注册一个文件下载接口
 .registerhandler(constants.get_image, new downloadimagehandler()) //注册一个图片下载接口
 .registerhandler(constants.post_json, new jsonhandler()) //注册一个post json接口
 ・・・

        例如,假设设备的 ip 地址是:192.168.0.101 ,那么在访问 http://192.168.0.101:1995/file 接口时,请求操作就会由 downloadfilehandler 来处理

        下载文件

        downloadfilehandler 实现了 requesthandler 接口,在 handle 方法中可以获取到请求头,表单数据这些信息,,通过注解声明支持 get 方式调用,在此直接返回一个文本文件用于下载

[Java] 查看源文件 复制代码
/**
 * 作者:leavesc
 * 时间:2018/4/5 16:30
 * 描述:https://github.com/leavesc/androidserver
 */
public class downloadfilehandler implements requesthandler {
  @requestmapping(method = {requestmethod.get})
  @override
  public void handle(httprequest httprequest, httpresponse httpresponse, httpcontext httpcontext) throws httpexception, ioexception {
    file file = createfile();
    httpentity httpentity = new fileentity(file, contenttype.create(getmimetype(file.getabsolutepath()), charset.defaultcharset()));
    httpresponse.setheader("content-disposition", "attachment;filename=file.txt");
    httpresponse.setstatuscode(200);
    httpresponse.setentity(httpentity);
  }

  private file createfile() {
    file file = null;
    outputstream outputstream = null;
    try {
      file = file.createtempfile("file", ".txt", mainapplication.get().getcachedir());
      outputstream = new fileoutputstream(file);
      outputstream.write("leavesc,这是一段测试文本".getbytes());
    } catch (ioexception e) {
      e.printstacktrace();
    } finally {
      if (outputstream != null) {
        try {
          outputstream.flush();
          outputstream.close();
        } catch (ioexception e) {
          e.printstacktrace();
        }
      }
    }
    return file;
  }
}

        这里直接在浏览器中访问接口(要和 android web服务器运行在同个局域网下),可以直接下载到文件

        

        下载图片

        类似的,下载图片的接口处理器 downloadimagehandler 可以如下设计,在 handle 方法中返回应用的图标

[Java] 查看源文件 复制代码
/**
 * 作者:leavesc
 * 时间:2018/4/5 16:30
 * 描述:https://github.com/leavesc/androidserver
 */
public class downloadimagehandler extends simplerequesthandler {
  private file file = new file(environment.getexternalstoragedirectory(), "leavesc.jpg");
  @requestmapping(method = {requestmethod.get})
  @override
  protected view handle(httprequest request) throws httpexception, ioexception {
    writetosdcard();
    httpentity httpentity = new fileentity(file, contenttype.create(getmimetype(file.getabsolutepath()), charset.defaultcharset()));
    return new view(200, httpentity);
  }

  private void writetosdcard() throws ioexception {
    if (!file.exists()) {
      synchronized (downloadimagehandler.class) {
        if (!file.exists()) {
          boolean b = file.createnewfile();
          if (!b) {
            throw new ioexception("what broken cell phone.");
          }
          bitmap bitmap = bitmapfactory.decoderesource(mainapplication.get().getresources(), r.mipmap.ic_launcher_round);
          outputstream outputstream = null;
          try {
            outputstream = new fileoutputstream(file);
            bitmap.compress(bitmap.compressformat.jpeg, 100, outputstream);
          } catch (filenotfoundexception e) {
            e.printstacktrace();
          } finally {
            if (outputstream != null) {
              outputstream.flush();
              outputstream.close();
            }
          }
        }
      }
    }
  }
}

        

        post表单

        这里需要将注解值改为 requestmethod.post,通过 httprequestparser.getcontentfrombody(httprequest) 函数可以获取到表单数据,这里直接检测表单数据是否为 json 字符串,是的话则为之多添加一个属性 :"state" 作为返回值,否则返回只包含属性 “state” 的 json 字符串

[Java] 查看源文件 复制代码
/**
 * 作者:leavesc
 * 时间:2018/4/5 16:30
 * 描述:https://github.com/leavesc/androidserver
 */
public class jsonhandler implements requesthandler {
  
  @requestmapping(method = {requestmethod.post})
  @override
  public void handle(httprequest httprequest, httpresponse httpresponse, httpcontext httpcontext) throws httpexception, ioexception {
    string content = httprequestparser.getcontentfrombody(httprequest);
    jsonobject jsonobject = null;
    try {
      jsonobject = new jsonobject(content);
    } catch (jsonexception e) {
      e.printstacktrace();
    }
    if (jsonobject == null) {
      jsonobject = new jsonobject();
    }
    try {
      jsonobject.put("state", "success");
    } catch (jsonexception e) {
      e.printstacktrace();
    }
    stringentity stringentity = new stringentity(jsonobject.tostring(), "utf-8");
    httpresponse.setstatuscode(200);
    httpresponse.setentity(stringentity);
  }

}

        这里在 postman 这个工具上进行 post 操作

        

        以上三个例子都是在电脑端调用的,这和在手机端调用是同个效果的

        基本的操作就介绍到这里,再具体的内容可以看示例代码:androidserver






        

20

主题

9285

帖子

2343

安币

Android大神

Rank: 6Rank: 6

发表于 2018-5-3 16:38:53 | 显示全部楼层
支持,感谢,祝巴士越来越好~

0

主题

9349

帖子

2404

安币

Android大神

Rank: 6Rank: 6

发表于 2018-5-3 19:13:21 | 显示全部楼层
支持,感谢,祝巴士越来越好~

308

主题

965

帖子

692

安币

手工艺人

发表于 2018-5-3 20:45:15 | 显示全部楼层
感谢分享,楼主V5~

0

主题

9243

帖子

2066

安币

Android大神

Rank: 6Rank: 6

发表于 2018-5-3 22:03:11 | 显示全部楼层
楼主是好人,回个帖会有安币吗?

446

主题

1129

帖子

1989

安币

手工艺人

发表于 2018-5-3 23:42:46 | 显示全部楼层
楼主威武,以后多发干货,多办活动~!

429

主题

1140

帖子

1907

安币

手工艺人

发表于 2018-5-4 02:09:19 | 显示全部楼层
感谢大神~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

领先的中文移动开发者社区
18620764416
7*24全天服务
意见反馈:1294855032@qq.com

扫一扫关注我们

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 粤ICP备15117877号 )