NanoHttpd Demo是个好东西

前几天,在做一个视频BT项目的时候,看各种博文之类的,突然就看到提出了一个NanoHttpd视频服务器的博文。于是就跟进去看了一下,发现,里面就一个链接。
GitHub地址:https://github.com/NanoHttpd/nanohttpd
然后就没了。。。
本来像这种标题党,我已经举报他。可是,我又很想知道,所以我就跟进去看了一下,NanoHttpd,嗯,一个Java文件的项目,嗯。
然后研究了一下源码,发现,从所未有的爽,的确,给个链接就够了。

这里贴一个简单的Demo,来自NanoHttpd。

package fi.iki.elonen;/** #%L* NanoHttpd-Samples* %%* Copyright (C) 2012 - 2015 nanohttpd* %%* Redistribution and use in source and binary forms, with or without modification,* are permitted provided that the following conditions are met:* * 1. Redistributions of source code must retain the above copyright notice, this*    list of conditions and the following disclaimer.* * 2. Redistributions in binary form must reproduce the above copyright notice,*    this list of conditions and the following disclaimer in the documentation*    and/or other materials provided with the distribution.* * 3. Neither the name of the nanohttpd nor the names of its contributors*    may be used to endorse or promote products derived from this software without*    specific prior written permission.* * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* OF THE POSSIBILITY OF SUCH DAMAGE.* #L%*/import java.util.Map;
import java.util.logging.Logger;import fi.iki.elonen.util.ServerRunner;/*** An example of subclassing NanoHTTPD to make a custom HTTP server.*/
public class HelloServer extends NanoHTTPD {/*** logger to log to.*/private static final Logger LOG = Logger.getLogger(HelloServer.class.getName());public static void main(String[] args) {ServerRunner.run(HelloServer.class);}public HelloServer() {super(8080);}@Overridepublic Response serve(IHTTPSession session) {Method method = session.getMethod();String uri = session.getUri();HelloServer.LOG.info(method + " '" + uri + "' ");String msg = "<html><body><h1>Hello server</h1>\n";Map<String, String> parms = session.getParms();if (parms.get("username") == null) {msg += "<form action='?' method='get'>\n" + "  <p>Your name: <input type='text' name='username'></p>\n" + "</form>\n";} else {msg += "<p>Hello, " + parms.get("username") + "!</p>";}msg += "</body></html>\n";return newFixedLengthResponse(msg);}
}

只要你导包,然后运行上面的东西就可以用浏览器访问8080端口,就能看到输出了,简单明了。
因此我就对他进行了一些改动,变成一个视频网站的项目,代码如下。

package com.chen.video.resource;import fi.iki.elonen.NanoHTTPD;import java.io.FileInputStream;
import java.io.FileNotFoundException;import static fi.iki.elonen.NanoHTTPD.newChunkedResponse;/*** Created by CHEN on 2016/8/14.*/
public class VideoResource {public static NanoHTTPD.Response getVideo(String videoURI) {try {FileInputStream fis = new FileInputStream(videoURI);return newChunkedResponse(NanoHTTPD.Response.Status.OK, "movie.mp4", fis);}catch (FileNotFoundException e) {e.printStackTrace();return null;}}}
package com.chen.video;import fi.iki.elonen.NanoHTTPD;
import fi.iki.elonen.NanoHTTPD.Response.Status;
import fi.iki.elonen.util.ServerRunner;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;/*** Created by CHEN on 2016/8/14.*/
public class VideoServer extends NanoHTTPD{public static final int DEFAULT_SERVER_PORT = 8080;public static final String TAG = VideoServer.class.getSimpleName();public String filePath= "movie.mp4";private static final String REQUEST_ROOT = "/";private String mVideoFilePath;private int mVideoWidth  = 0;private int mVideoHeight = 0;private static final int VIDEO_WIDTH= 320;private static final int VIDEO_HEIGHT = 240;public VideoServer() {super(DEFAULT_SERVER_PORT);mVideoFilePath = filePath;mVideoWidth  = VIDEO_WIDTH;mVideoHeight = VIDEO_HEIGHT;}@Overridepublic Response serve(IHTTPSession session) {if(REQUEST_ROOT.equals(session.getUri())) {return responseRootPage(session);}else if("/movie.mp4".equals(session.getUri())) {return responseVideoStream(session);}return response404(session,session.getUri());}public Response responseRootPage(IHTTPSession session) {String rootURL=this.getClass().getResource("/").getPath();File file = new File(rootURL+"/com/chen/video/"+mVideoFilePath);/* if(!file.exists()) {return response404(session,mVideoFilePath);}*/StringBuilder builder = new StringBuilder();builder.append("<!DOCTYPE html><html><body>");builder.append("<video ");builder.append("width="+getQuotaStr(String.valueOf(mVideoWidth))+" ");builder.append("height="+getQuotaStr(String.valueOf(mVideoHeight))+" ");builder.append("controls>");builder.append("<source src="+getQuotaStr("/movie.mp4")+" ");builder.append("type="+getQuotaStr("video/mp4")+">");builder.append("Your browser doestn't support HTML5");builder.append("</video>");builder.append("</body></html>\n");return newFixedLengthResponse(builder.toString());}public Response responseVideoStream(IHTTPSession session) {try {FileInputStream fis = new FileInputStream(this.getClass().getResource("/").getPath()+"/com/chen/video/"+mVideoFilePath);return newChunkedResponse(Status.OK, "movie.mp4", fis);}catch (FileNotFoundException e) {e.printStackTrace();return response404(session,mVideoFilePath);}}public Response response404(IHTTPSession session,String url) {StringBuilder builder = new StringBuilder();builder.append("<!DOCTYPE html><html><body>");builder.append("Sorry, Can't Found "+url + " !");builder.append("</body></html>\n");return newFixedLengthResponse(builder.toString());}protected String getQuotaStr(String text) {return "\"" + text + "\"";}public static void main(String[] args) {ServerRunner.run(VideoServer.class);}
}
package com.chen.video;import com.chen.video.resource.VideoResource;
import fi.iki.elonen.NanoHTTPD;
import fi.iki.elonen.util.ServerRunner;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;import static com.chen.video.resource.VideoResource.getVideo;
import static jdk.nashorn.internal.objects.NativeString.substring;/*** Created by CHEN on 2016/8/14.*/
public class MyVideoServer extends NanoHTTPD {public static void main(String[] args) {ServerRunner.run(MyVideoServer.class);}public MyVideoServer() {super(8088);}@Overridepublic Response serve(IHTTPSession session) {//在这里做一些跳转的控制/*注释说明:这里感觉太耗资源了,没必要,所以改成以下形式if(session.getUri().contains("page")) {//说明是页面} else if(session.getUri().contains("resource")) {}*///TODO 规定一级路径为类,二级路径为方法//TODO 规定资源都是一级路径//现在暂时简单实现,毕竟是教学String uri = session.getUri();String[] uriSplit = uri.split("/");Response response = null;switch (uriSplit[1].charAt(0)){case 'p': {//pageString classURI = uriSplit[2].substring(0, 1).toUpperCase() + uriSplit[2].substring(1) + "Controller";try {Class clazz = Class.forName("com.chen.video.controller."+classURI);java.lang.reflect.Method method = clazz.getMethod("getVideoPage");response = (Response) method.invoke(null);} catch (Exception e) {//TODO 其实抛出了很多的异常 但是为了代码不要被异常包围,先统一处理e.printStackTrace();}}break;case 'r': {//resource//本来应该有一个资源分类的 比如说是音频还是书籍 但是这里也统一处理了 默认是音频String resourceURI=uriSplit[2];response= VideoResource.getVideo(this.getClass().getResource("/").getPath()+"com/chen/video/"+resourceURI);}break;default: {}break;}//异常处理if(null!=response) {return response;} else {//TODO 处理return null;}}
}

请注意一点,NanoHttpd是一个BIO项目。

源码解读

NanoHttpd Demo是个好东西相关推荐

  1. 通讯框架 t-io 学习——给初学者的Demo:ShowCase设计分析

    前言 最近闲暇时间研究Springboot,正好需要用到即时通讯部分了,虽然springboot 有websocket,但是我还是看中了 t-io框架.看了部分源代码和示例,先把helloworld敲 ...

  2. 使用NanoHttpd在Android上实现HttpServer

    使用NanoHttpd在Android上实现HttpServer 最近的项目中需要在Androd上搭建一个HttpServer,这个Server用于接收智能设备的实时数据,这个时候就需要使用Java打 ...

  3. 微信小程序官方示例 Demo 源代码获取

    一.引言 最近在学习微信小程序,莫名其妙的刷到了腾讯官方出的 小程序示例 的 Demo,感觉做的真的很好. 要是自己在写小程序之前,多多参考这个 Demo 里面的一些东西,应该会轻松很多,而且做出来的 ...

  4. java的showcase_通讯框架 t-io 学习——给初学者的Demo:ShowCase设计分析

    前言 最近闲暇时间研究Springboot,正好需要用到即时通讯部分了,虽然springboot 有websocket,但是我还是看中了 t-io框架.看了部分源代码和示例,先把helloworld敲 ...

  5. 【Go语言开发】简单了解一下搜索引擎并用go写一个demo

    写在前面 这篇文章我们一起来了解一下搜索引擎的原理,以及用go写一个小demo来体验一下搜索引擎. 简介 搜索引擎一般简化为三个步骤 爬虫:爬取数据源,用做搜索数据支持. 索引:根据爬虫爬取到的数据进 ...

  6. iOS 支付 [支付宝、银联、微信]

    这是开头语 前不久做了一个项目,涉及到支付宝和银联支付,支付宝和银联都是业界的老大哥,文档.SDK都是很屌,屌的找不到,屌的看不懂,屌到没朋友(吐槽而已),本文将涉及到的最新可用SDK.文档,以及本人 ...

  7. (iOS-框架封装)AFN3.x 网络请求封装

    AFNetworking 我项目里面的网络请求是一外包大牛基于AFN2.x封装的基本网络请求,感觉其封装的贼好,对服务端返回的错误码统一处理,对返回的 json 数据下发给每个继承自基本网络请求的子网 ...

  8. 使用IntelliJ IDEA开发SpringMVC网站(一)开发环境

    原文:使用IntelliJ IDEA开发SpringMVC网站(一)开发环境 摘要 主要讲解初期的开发环境搭建,Maven的简单教学. IDEA Spring MVC 目录[-] 文章已针对IDEA ...

  9. python学习笔记(六)——函数的作用域和装饰器

    目录 函数作用域 global和nonlocal关键字 递归 闭包 装饰器 函数作用域 global和nonlocal关键字 思考: def func():name = 'laowang' print ...

最新文章

  1. sharepoint 配置站点导航栏 顶级菜单栏的下拉菜单
  2. Android开发之Buidler模式初探结合AlertDialog.Builder讲解
  3. Android Fragment 简单实例
  4. 【操作系统复习】操作系统的发展与分类
  5. 世界第一台电脑_2020世界计算机大会今日开幕 给市民带来全方位观展体验 - 三湘万象 - 湖南在线...
  6. jquery --- Poshy Tip jQuery Plugin
  7. 64位linux下的gns3网络模拟器配置
  8. python loadlibrary_使用py2exe教程LoadLibrary(pythondll)失败错误
  9. JS和JS是IE上JavaScript或JScript的缩写。
  10. 「建模学习」3DsMAX贴图制作方法,足球贴图案例详细教程
  11. 555低电平出发定时器
  12. python爬取拉勾网职位信息_python-scrapy爬虫框架爬取拉勾网招聘信息
  13. 小白学习笔记之Python要点
  14. 群晖3617可以有几个网卡_Nvme pcie千兆有线网卡
  15. 用Python实现微信公众号WCI指数计算器
  16. Thread.setDaemon详解
  17. SpringCloudAlibaba nacos学习笔记
  18. 楷体描红字帖练起来@简洁字帖
  19. 计算机组装和维修资料库,电脑组装与维修题库资料.doc
  20. 资源 | 吴恩达斯坦福CS230深度学习课程全套资料放出(附下载)

热门文章

  1. LuaBox积木编程开发手册-精编版
  2. MFC 全局钩子dll注入监听键盘消息
  3. android 开机动画更换,教程:如何把安卓开机动画,换成谷歌新Logo
  4. Graphql中我们应该用什么姿势来实现Resolver?
  5. python使用大漠插件教程_python调用大漠插件教程04鼠键事件及基本项目思维
  6. SSH登录的两种方式
  7. react-router(路由)
  8. Thinkpad 系列电脑,装win10无限卡死在登录界面 解决方案及bug report!
  9. 关于Mybatis拦截器的说明与使用
  10. 多元函数的泰勒级数展开公式