虽然标题是有点浮夸,但的确实现了部分功能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地址(感兴趣的话,不妨点赞支持下)