国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

在Android設(shè)備上搭建Web服務(wù)器的方法

2019-12-12 01:01:52
字體:
供稿:網(wǎng)友

一般而言,Android 應(yīng)用在請(qǐng)求數(shù)據(jù)時(shí)都是以 Get 或 Post 等方式向遠(yuǎn)程服務(wù)器發(fā)起請(qǐng)求,那你有沒有想過其實(shí)我們也可以在 Android 設(shè)備上搭建一個(gè)小型 Web 服務(wù)器,并且實(shí)現(xiàn)常規(guī)的下載圖片、下載文件、提交表單等功能呢?

下面要介紹的就是如何在 Android 設(shè)備上搭建一個(gè) Web 服務(wù)器,這個(gè) Web 服務(wù)器的功能有如下幾點(diǎn):

  1. 接受客戶端文件上傳、下載文件
  2. 動(dòng)態(tài) Http API,像 Java 的 Servlet 一樣寫接口
  3. 部署靜態(tài)網(wǎng)站,例如純Html,支持 JS、CSS、Image 分離
  4. 部署動(dòng)態(tài)網(wǎng)站

這需要依賴一個(gè)開源庫來實(shí)現(xiàn):AndServer

AndServer 類似于 Apache 和 Tomcat,支持在同個(gè)局域網(wǎng)下的設(shè)備能夠以常規(guī)的網(wǎng)絡(luò)請(qǐng)求方式來向 Web 服務(wù)器請(qǐng)求數(shù)據(jù),只要指明 Web 服務(wù)器的 IP 地址和端口號(hào)即可

那么,這個(gè) Web 服務(wù)器的用途有哪些呢?

說下我現(xiàn)在遇到的一個(gè)需求吧!需要實(shí)現(xiàn)兩臺(tái)設(shè)備(Android 或 ios 設(shè)備)在無網(wǎng)絡(luò)情況下進(jìn)行數(shù)據(jù)交流。本來是打算讓設(shè)備之間的交流通道以 Wifi 來鏈接,即某一臺(tái)設(shè)備連上另一臺(tái)設(shè)備的 Wiif 熱點(diǎn),這樣兩者之間就建立起了一條“通道”,之后通過建立 Socket 連接來獲取輸入輸出流,通過輸入輸出流來交換數(shù)據(jù)。可是這樣就需要處理好在高并發(fā)情況下的數(shù)據(jù)同步和解析問題,比較麻煩,而通過 AndServer 就可以直接套用項(xiàng)目已有的網(wǎng)絡(luò)請(qǐng)求框架,直接以網(wǎng)絡(luò)請(qǐng)求的方式來交流數(shù)據(jù),而服務(wù)端也較好的處理了并發(fā)問題

Gradle 遠(yuǎn)程依賴

implementation 'com.yanzhenjie:andserver:1.1.3'

搭建服務(wù)器

搭建服務(wù)器的方式很簡(jiǎn)單,支持鏈?zhǔn)秸{(diào)用。指明服務(wù)器在本機(jī)的 IP 地址上監(jiān)聽,并指定端口號(hào)為 1995 ,并開放了三個(gè)接口分別用于:下載文件、下載圖片、Post表單

    AndServer server = AndServer.serverBuilder()        .inetAddress(NetUtils.getLocalIPAddress()) //服務(wù)器要監(jiān)聽的網(wǎng)絡(luò)地址        .port(Constants.PORT_SERVER) //服務(wù)器要監(jiān)聽的端口        .timeout(10, TimeUnit.SECONDS) //Socket超時(shí)時(shí)間        .registerHandler(Constants.GET_FILE, new DownloadFileHandler()) //注冊(cè)一個(gè)文件下載接口        .registerHandler(Constants.GET_IMAGE, new DownloadImageHandler()) //注冊(cè)一個(gè)圖片下載接口        .registerHandler(Constants.POST_JSON, new JsonHandler()) //注冊(cè)一個(gè)Post Json接口        .filter(new HttpCacheFilter()) //開啟緩存支持        .listener(new Server.ServerListener() { //服務(wù)器監(jiān)聽接口          @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();

開啟服務(wù)器

server.startup();

停止服務(wù)器

server.shutdown();

接口處理器

在注冊(cè)接口時(shí),除了指明開放出來的 Url 地址外,還需要指明相應(yīng)的處理器,專門用于處理該接口的請(qǐng)求操作
開放出來的三個(gè)接口分別對(duì)應(yīng)于三個(gè)地址

public class Constants {  //服務(wù)端接口的端口號(hào)  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";}
 ??? .registerHandler(Constants.GET_FILE, new DownloadFileHandler()) //注冊(cè)一個(gè)文件下載接口 .registerHandler(Constants.GET_IMAGE, new DownloadImageHandler()) //注冊(cè)一個(gè)圖片下載接口 .registerHandler(Constants.POST_JSON, new JsonHandler()) //注冊(cè)一個(gè)Post Json接口 ???

例如,假設(shè)設(shè)備的 IP 地址是:192.168.0.101 ,那么在訪問 http://192.168.0.101:1995/file 接口時(shí),請(qǐng)求操作就會(huì)由 DownloadFileHandler 來處理

下載文件

DownloadFileHandler 實(shí)現(xiàn)了 RequestHandler 接口,在 handle 方法中可以獲取到請(qǐng)求頭,表單數(shù)據(jù)這些信息,,通過注解聲明支持 Get 方式調(diào)用,在此直接返回一個(gè)文本文件用于下載

/** * 作者:leavesC * 時(shí)間: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,這是一段測(cè)試文本".getBytes());    } catch (IOException e) {      e.printStackTrace();    } finally {      if (outputStream != null) {        try {          outputStream.flush();          outputStream.close();        } catch (IOException e) {          e.printStackTrace();        }      }    }    return file;  }}

這里直接在瀏覽器中訪問接口(要和 Android Web服務(wù)器運(yùn)行在同個(gè)局域網(wǎng)下),可以直接下載到文件

下載圖片

類似的,下載圖片的接口處理器 DownloadImageHandler 可以如下設(shè)計(jì),在 handle 方法中返回應(yīng)用的圖標(biāo)

/** * 作者:leavesC * 時(shí)間: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) 函數(shù)可以獲取到表單數(shù)據(jù),這里直接檢測(cè)表單數(shù)據(jù)是否為 Json 字符串,是的話則為之多添加一個(gè)屬性 :"state" 作為返回值,否則返回只包含屬性 “state” 的 Json 字符串

/** * 作者:leavesC * 時(shí)間: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 這個(gè)工具上進(jìn)行 Post 操作

以上三個(gè)例子都是在電腦端調(diào)用的,這和在手機(jī)端調(diào)用是同個(gè)效果的

基本的操作就介紹到這里,再具體的內(nèi)容可以看示例代碼:AndroidServer

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 连云港市| 穆棱市| 郓城县| 乃东县| 万全县| 怀安县| 咸阳市| 孟连| 泰安市| 宜兴市| 友谊县| 桂阳县| 绥滨县| 苗栗县| 通江县| 博白县| 宾川县| 林西县| 大足县| 霍州市| 丹巴县| 那曲县| 宜兴市| 新乡县| 天峻县| 元江| 阿坝| 丰宁| 渭南市| 舞钢市| 疏勒县| 都匀市| 宜州市| 韶关市| 黄浦区| 富平县| 平遥县| 陆丰市| 志丹县| 仁化县| 政和县|