android界的spring-boot http服務框架

雖然標題是有點浮誇,但的確實現了部分功能html

有時候要用android當服務器去進行數據傳輸,如局域網的文件傳輸功能,這些用http服務去作是比較好的選擇. 既然要用到http服務,那使用NanoHttpd是最好的選擇之一,只有一個文件但能夠完成不少http服務的功能. 但使用NanoHttpd的時候會有不少的不便,例如咱們每次都要對uri進行分析,這樣就使得代碼臃腫,請求的方法過多的話,那看上去就會一臉懵,大大的下降代碼可讀性.java

對於使用NanoHttpd的各類不便,而後就二次封裝了下,就出了我我的認爲是android界的spring-boot的http服務框架(有點傻的想法).android

DEMO代碼

代碼編寫風格

get請求返回html數據

以對象返回

請求時傳人json數據

是否是有點像spring的風格,代碼瞬間就簡潔了.整我的瞬間愉悅起來.git

框架原理

是根據NanoHttpd二次開發,主要使用了註解反射來實現url的映射,代碼也很少,輕量級,如下是關鍵代碼github

/**
     * 解析註解文件
     *
     * @param session
     * @param file_name
     * @return
     */
    private Response responseData(IHTTPSession session, String file_name) {
        Response response;
        Object[] objects = null;
        try {
            Map<String, java.lang.reflect.Method> methods = FHttpManager.getFHttpManager().getMethods();
            java.lang.reflect.Method method = methods.get(file_name);
            if (method != null) {
                method.setAccessible(true); //容許修改反射屬性
                Class cla = method.getDeclaringClass();//獲取該方法所在的類
                Object obj = cla.newInstance();//實例化類
                Class<?>[] parameterTypes = method.getParameterTypes(); //得到方法全部參數的類型
                if (parameterTypes.length > 0) {
                    objects = new Object[parameterTypes.length];
                    Map<String, String> sessionMap = session.getParms();//獲取請求參數
                    Annotation[][] parameterAnnotations = method.getParameterAnnotations();//獲取方法參數裏的註解
                    for (int i = 0; i < parameterAnnotations.length; i++) {
                        if (parameterTypes[i] == IHTTPSession.class) {
                            objects[i] = session;
                        } else if (parameterTypes[i] == Map.class) {
                            objects[i] = sessionMap;
                        } else {
                            Annotation parameterAnnotation = parameterAnnotations[i][0];//獲取參數中的第一個註解。因此每一個參數只能只有一個註解
                            if (parameterAnnotation.annotationType() == RequestBody.class) {//返回對象
                                byte[] buf = new byte[(int) ((HTTPSession) session).getBodySize()];
                                session.getInputStream().read(buf, 0, buf.length);
                                objects[i] = new Gson().fromJson(new String(buf), parameterTypes[I]);
                            } else if (parameterAnnotation.annotationType() == RequestParam.class) {//返回指定param
                                objects[i] = dataConversion(parameterTypes[i], sessionMap, (RequestParam) parameterAnnotation);
                            }
                        }
                    }
                }
                response = responseBody(method.getReturnType(), method.invoke(obj, objects), method.isAnnotationPresent(ResponseBody.class));
            } else {
                response = newFixedLengthResponse(Response.Status.NOT_FOUND, NanoHTTPD.MIME_PLAINTEXT, file_name + " Not Found");
            }
        } catch (Exception e) {
            response = newFixedLengthResponse(Response.Status.INTERNAL_ERROR, NanoHTTPD.MIME_PLAINTEXT, e.getMessage());
        }
        return response;
    }
複製代碼

框架功能及使用

1. 框架功能介紹

這是根據NanoHttpd二次開發的一個輕量級,使用簡單,功能比較強大的一個http服務框架. 能夠實現:spring

  1. 支持get請求
  2. 支持post請求
  3. 支持文件上傳
  4. 支持文件下載
  5. 支持自定義端口號
  6. 支持自定義靜態資源目錄(默認assets的根目錄,也能夠指定sd卡的自定義目錄)
  7. 支持靜態資源文件過濾(因爲指定的是assets根目錄,會有不少系統自帶的xml文件,就作了這個)
  8. 支持註解的使用(這框架不用註解還真無法用)
  9. 支持以對象來響應
  10. 支持請求以對象接收
  11. ... 基本知足http服務的正常使用需求(硬是瞎編了那麼多功能...)

2.框架裏的幾個註解

註解 含義
@RequestBody 方法裏的屬性註解,使用該註解可指定以對象返回 主要用於處理json請求
@RequestParam("") 方法裏的屬性註解,使用該註解可指定param值返回 主要用於處理get,post的請求
@RequestMapping("") 方法註解, 使用該註解是映射url ,把url 指定到對應的方法中處理數據
@ResponseBody 方法註解,使用該方法能夠對象返回通過處理吐出json數據返回給客戶端

以上註解的使用可看前面的圖片數據庫

3. 框架使用

  1. gradle添加
compile 'cn.hotapk:fhttpserver:0.2.0'
複製代碼
  1. manifest添加權限
<uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
複製代碼
  1. 初始化
fHttpManager = FHttpManager.init(this, UserController.class);
fHttpManager.setPort(9999);
...
複製代碼

UserController.class 是進行url映射的類, 可添加多個這樣的類json

public class UserController {

    @RequestMapping("userls")
    public NanoHTTPD.Response getUserLs() {
        return setResponse("user列表");
    }

    @ResponseBody
    @RequestMapping("getuser")
    public UserBean getUser() {
        return new UserBean("admin", "admin");
    }
...
複製代碼
  1. 開啓http服務
fHttpManager.startServer();
複製代碼
  1. 文件下載
NanoHTTPD.Response response = NanoHTTPD.newChunkedResponse(NanoHTTPD.Response.Status.OK, "application/octet-stream", inputStream);//這表明任意的二進制數據傳輸。

   response.addHeader("Accept-Ranges", "bytes");

   response.addHeader("Content-Disposition", "attachment; filename="+"test.java")//能夠這裏返回文件名稱

複製代碼
  1. 文件上傳
/**
       * 文件上傳
       *
       * @param session
       * @param fileDir 保存文件的目錄
       * @param parm    上傳文件的參數
       * @return
       */
      public static boolean uploadFile(NanoHTTPD.IHTTPSession session, String fileDir, String parm) {
          Map<String, String> files = new HashMap<>();
          try {
              session.parseBody(files);
              Map<String, String> parms = session.getParms();
              return FFileUtils.copyFileTo(files.get(parm), fileDir + "/" + parms.get(parm));
          } catch (IOException e) {
              e.printStackTrace();
          } catch (NanoHTTPD.ResponseException e) {
              e.printStackTrace();
          }
          return false;
      }

複製代碼
  1. index.html 文件衝突

該框架默認打開index.html文件,若是不但願用這文件名可以下修改瀏覽器

fHttpManager.setIndexName(" ")
複製代碼
  1. 瀏覽器打開

默認使用8080端口,瀏覽器訪問http://xxx.xx.xx.xx:8080 便可bash

4. 框架使用demo

這塊就不出詳細demo了 能夠到我另一個項目查看 這是一個android調試數據庫的神器

5.框架代碼講解

這方面就不講了,主要使用註解反射實現,其它也沒什麼的了

6.框架名稱

FHttpServer

以上是FHttpServer框架的所有內容,謝謝觀看,歡迎使用. 同時但願各位在使用中遇到什麼問題或建議能夠用如下聯繫方式進行反饋

android開發討論羣 320120776

我的博客

github地址(感興趣的話,不妨點贊支持下)

相關文章
相關標籤/搜索