Android 搭建Http服务器,接收各端的 HTTP 请求访问以及 挂载HTML网页
- 依赖库
implementation 'org.nanohttpd:nanohttpd:2.3.1'
- 服务器实现
public class HttpServer extends NanoHTTPD {
private static final int HTTP_PORT = 8080;//端口,尽量设置一个不常规的
HttpServer() {
super(HTTP_PORT);
}
}
/**
* 数据接收
*
* @param session
* @return
*/
@Override
public Response serve(IHTTPSession session) {
return parseRequest(session);
}
/**
* 数据解析
* @param session
* @return
*/
private NanoHTTPD.Response parseRequest(NanoHTTPD.IHTTPSession session) {
NanoHTTPD.Response response = null;
if (session.getMethod() == NanoHTTPD.Method.GET) {
response = parseGetRequest(session);
} else if (session.getMethod() == NanoHTTPD.Method.POST) {
response = parsePostRequest(session);
} else {
response = responseForNotFound();
}
return response;
}
/**
* 解析post请求
* /xxx/接口1:代表 两端定义的访问接口,例如:/user/info
* @param session
* @return
*/
private Response parsePostRequest(IHTTPSession session) {
final Map files = parseBody(session);
NanoHTTPD.Response response = null;
String paramsMiss = "";
Map params = session.getParms();
if (session.getParms() == null) {
return responseParamsNotFound(ResourceUtil.getString(R.string.server_params_error));
}
switch (session.getUri()) {
case "/xxx/接口1":
//根据自己业务返回不同的需求
response = responseForConfig(HttpResult.getConfigResult());
break;
case "/xxx/接口2":
response=responseForConfig(HttpResult.getNetConfig(mEthernetHelper));
break;
default:
response = responseForNotFound();
break;
}
return response;
}
/**
* 返回指令未知
*
* @return
*/
private NanoHTTPD.Response responseForNotFound() {
NanoHTTPD.Response.Status status = NanoHTTPD.Response.Status.NOT_FOUND;
final String mimeType = "text/html";
return NanoHTTPD.newFixedLengthResponse(status, mimeType, "NOT_FOUND");
}
/**
*返回指定的错误信息
*/
rivate NanoHTTPD.Response responseParamsNotFound(String msg) {
NanoHTTPD.Response.Status status = NanoHTTPD.Response.Status.NOT_FOUND;
final String mimeType = "text/html";
return NanoHTTPD.newFixedLengthResponse(status, mimeType, msg);
}
/**
*返回json串
*result:可以是任意Bean转成的字符串,
* @return
*/
private Response responseForConfig(String result) {
NanoHTTPD.Response.Status status = NanoHTTPD.Response.Status.OK;
String mimeType = "application/json;charset=UTF-8";
LogHelper.v(TAG, "正在向客户端发送数据 -> " + result);
return NanoHTTPD.newFixedLengthResponse(status, mimeType, result);
}
/**
* 解析get 请求
*
* @param session
* @return
*/
private Response parseGetRequest(IHTTPSession session) {
return getHtmlFileStream(session);
}
/**
* 解析访问的mintype类型
* @param session
* @return
*/
private Response getHtmlFileStream(IHTTPSession session) {
String uri = session.getUri();
String filename = uri.substring(1);
boolean is_ascii = true;
if (uri.equals("/")) {
filename = "index.html";
}
String mimetype = "text/html";
if (filename.contains(".html") || filename.contains(".htm")) {
mimetype = "text/html";
is_ascii = true;
} else if (filename.contains(".js")) {
mimetype = "text/javascript";
is_ascii = true;
} else if (filename.contains(".css")) {
mimetype = "text/css";
is_ascii = true;
} else if (filename.contains(".gif")) {
mimetype = "text/gif";
is_ascii = false;
} else if (filename.contains(".jpeg") || filename.contains(".jpg")) {
mimetype = "text/jpeg";
is_ascii = false;
} else if (filename.contains(".png")) {
mimetype = "image/png";
is_ascii = false;
} else if (filename.contains(".svg")) {
mimetype = "image/svg+xml";
is_ascii = false;
} else {
filename = "index.html";
mimetype = "text/html";
}
if (is_ascii) {
return loadHtml(filename, mimetype);
} else {
return loadOrder(filename, mimetype);
}
}
/**
* 加载非html 类型
*
* @param filename
* @param mimetype
* @return
*/
private Response loadOrder(String filename, String mimetype) {
AssetManager assetManager = BasicApplication.getAppContext().getAssets();
InputStream isr;
try {
isr = assetManager.open(filename);
return newFixedLengthResponse(Response.Status.OK, mimetype, isr, isr.available());
} catch (IOException e) {
e.printStackTrace();
return newFixedLengthResponse(Response.Status.OK, mimetype, "");
}
}
/**
* 加载html
*
* @param filename
* @param mimetype
* @return
*/
private Response loadHtml(String filename, String mimetype) {
AssetManager assetManager = BasicApplication.getAppContext().getAssets();
//通过AssetManager直接打开文件进行读取操作
StringBuilder response = new StringBuilder();
String line = "";
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(assetManager.open(filename, AssetManager.ACCESS_BUFFER)));
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
return newFixedLengthResponse(Response.Status.OK, mimetype, "");
}
return newFixedLengthResponse(Response.Status.OK, mimetype, response.toString());
}
}
到此,一个既有post请求也有 HTML网页访问 的HTTP服务器 搭建完毕。
- 返回Result
/**
* 此类属于完全自定义,根据自己业务写
*/
public class HttpResult {
private static final int RESULT_CODE_SUCCESS = 0;
private static final int RESULT_CODE_FILE = 1;
/**
* 状态码
*/
public int code;
/**
* 返回结果信息
*/
public String msg;
/**
* 预留
*/
/**
* 结果信息
**/
public T results;
/**
* 获取成功
*
* @return
*/
public static final String getSuccess() {
final HttpResult httpResult = new HttpResult<>();
httpResult.code = RESULT_CODE_SUCCESS;
httpResult.msg = ResourceUtil.getString(
R.string.server_result_success);
return JsonUtil.objectToJson(httpResult);
}
/**
* 请求失败
*
* @return
*/
public static String getFail(String paramsMiss) {
final HttpResult httpResult = new HttpResult<>();
httpResult.code = RESULT_CODE_FILE;
httpResult.msg = ResourceUtil.getString(
R.string.server_result_fail) + (TextUtils.isEmpty(paramsMiss) ? "" : ("," + paramsMiss));
return JsonUtil.objectToJson(httpResult);
}
}
- 启动服务
一般来说,NanoHttp 服务器在Android 上最好放在Service 上去启动或停止 如下:
ublic class HttpService extends Service {
private HttpServer httpServer;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
httpServer = new HttpServer();
try {
httpServer.start(30000);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onDestroy() {
if (httpServer != null) {
httpServer.stop();
}
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_STICKY;
}
/**
* 启动服务
*
* @param context
*/
public static final void startService(Context context) {
Intent intent = new Intent(context,
HttpService.class);
context.startService(intent);
}
/**
* 关闭服务
*/
public static void stopService(Context context) {
Intent intent = new Intent(context, HttpService.class);
context.stopService(intent);
}
以上就是关于一个简单的NanoHTTP 搭建的场景