雖然標題是有點浮誇,但的確實現了部分功能html
有時候要用android當服務器去進行數據傳輸,如局域網的文件傳輸功能,這些用http服務去作是比較好的選擇. 既然要用到http服務,那使用NanoHttpd是最好的選擇之一,只有一個文件但能夠完成不少http服務的功能. 但使用NanoHttpd的時候會有不少的不便,例如咱們每次都要對uri進行分析,這樣就使得代碼臃腫,請求的方法過多的話,那看上去就會一臉懵,大大的下降代碼可讀性.java
對於使用NanoHttpd的各類不便,而後就二次封裝了下,就出了我我的認爲是android界的spring-boot的http服務框架(有點傻的想法).android
是否是有點像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;
}
複製代碼
這是根據NanoHttpd二次開發的一個輕量級,使用簡單,功能比較強大的一個http服務框架. 能夠實現:spring
註解 | 含義 |
---|---|
@RequestBody | 方法裏的屬性註解,使用該註解可指定以對象返回 主要用於處理json請求 |
@RequestParam("") | 方法裏的屬性註解,使用該註解可指定param值返回 主要用於處理get,post的請求 |
@RequestMapping("") | 方法註解, 使用該註解是映射url ,把url 指定到對應的方法中處理數據 |
@ResponseBody | 方法註解,使用該方法能夠對象返回通過處理吐出json數據返回給客戶端 |
以上註解的使用可看前面的圖片數據庫
compile 'cn.hotapk:fhttpserver:0.2.0'
複製代碼
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
複製代碼
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");
}
...
複製代碼
fHttpManager.startServer();
複製代碼
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")//能夠這裏返回文件名稱
複製代碼
/**
* 文件上傳
*
* @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;
}
複製代碼
該框架默認打開index.html文件,若是不但願用這文件名可以下修改瀏覽器
fHttpManager.setIndexName(" ")
複製代碼
默認使用8080端口,瀏覽器訪問http://xxx.xx.xx.xx:8080 便可bash
這塊就不出詳細demo了 能夠到我另一個項目查看 這是一個android調試數據庫的神器
這方面就不講了,主要使用註解反射實現,其它也沒什麼的了
FHttpServer
以上是FHttpServer框架的所有內容,謝謝觀看,歡迎使用. 同時但願各位在使用中遇到什麼問題或建議能夠用如下聯繫方式進行反饋
github地址(感興趣的話,不妨點贊支持下)