我的编程空间,编程开发者的网络收藏夹
学习永远不晚

【NanoHTTPD】Android,使用NanoHTTPD搭建服务器,接受Http请求,最佳实践

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

【NanoHTTPD】Android,使用NanoHTTPD搭建服务器,接受Http请求,最佳实践

Android,NanoHTTPD搭建服务器,接受Http请求最佳实践

1,了解

安卓app,作为服务器,接受Http,get post 请求推送数据,NanoHTTPD是一个免费、轻量级的(只有一个Java文件) HTTP服务器,可以很好地嵌入到Java程序中。支持 GET, POST, PUT, HEAD 和 DELETE 请求,支持文件上传,占用内存很小。

开源地址:GitHub - NanoHttpd/nanohttpd: Tiny, easily embeddable HTTP server in Java.

2,引入依赖

implementation 'org.nanohttpd:nanohttpd:2.3.1'

3,开始集成

这里需要注意以下三点问题:

  • 系统端口:0~1023,用于运行标准服务,例如 HTTP 服务(端口 80)、FTP 服务(端口 21)等。
    注册端口:1024~49151,用于运行注册的应用程序或服务,例如 DNS 服务(端口 53)、SMTP 服务(端口 25)等。
    动态/私有端口:49152~65535,可以被动态分配给任何应用程序或服务,通常用于客户端。 所以,如下代码,我们声明监听的端口是 49152 ,避免端口被占用
  • 请求携带中文,需要将请求头设置 UTF-8 字符集,防止中文乱码,如下代码27行进行相关处理;
  • 客户端发送POST请求,获取 POSTBody参数,需要 session.parseBody(new HashMap()),如下代码40行处理,获取Body参数。

3.1 自定义类,继承 NanoHTTPD

public class MyNanoHttpdServer extends NanoHTTPD  {    //声明服务端 端口    private static final Integer HTTP_PORT = 49152;    public MyNanoHttpdServer(String hostname, int port) {        super(hostname, port);    }    private volatile static MyNanoHttpdServer myNanoHttpdServer; //TODO单例模式,获取实例对象,并传入当前机器IP    public static MyNanoHttpdServer getInstance(String ipAddress) {        if (myNanoHttpdServer == null) {            synchronized (MyNanoHttpdServer.class) {                if (myNanoHttpdServer == null) {                    myNanoHttpdServer = new MyNanoHttpdServer(ipAddress, HTTP_PORT);                }            }        }        return myNanoHttpdServer;    }    @Override    public Response serve(IHTTPSession session) {        //TODO  解决客户端请求参数携带中文,出现中文乱码问题        ContentType ct = new ContentType(session.getHeaders().get("content-type")).tryUTF8();        session.getHeaders().put("content-type", ct.getContentTypeHeader());        return dealWith(session);    }    private Response dealWith(IHTTPSession  session) {        Date dateTime = new Date();        if (Method.POST == session.getMethod()) {            //获取请求头数据            Map<String,String> header = session.getHeaders();            //获取传参参数            Map<String, String> params = new HashMap<String, String>();            try {                session.parseBody(params);                String paramStr = params.get("postData");                if(StringUtils.isEmpty(paramStr)){                    return newFixedLengthResponse("success");                }                paramStr = paramStr.replace("\r\n"," ");                JSONObject jsonParam = JSON.parseObject(paramStr);                Map<String,Object> result = new HashMap<>();//TODO 写你的业务逻辑.....     //响应客户端                 return   newFixedLengthResponse("success");            } catch (IOException e) {                e.printStackTrace();            } catch (ResponseException e) {                e.printStackTrace();            }            return   newFixedLengthResponse("success");        }else if (Method.GET == session.getMethod()){            Map<String, List<String>> parameters = session.getParameters();            return   newFixedLengthResponse("success");        }        return newFixedLengthResponse("404");    }    public static Response newFixedLengthResponse(String msg) {        return newFixedLengthResponse(Response.Status.OK, NanoHTTPD.MIME_HTML, msg);    }}

3.2 在 AndroidMainifest.xml,开启网络权限,注册服务,后台运行

<uses-permission android:name="android.permission.INTERNET" /><application>     <!--注册服务>     <service android:name=".nanoHttpd.MyNanoHttpService" />application>

自定义服务类,继承 Service

public class MyNanoHttpService extends Service {    private MyNanoHttpdServer httpServer = MyNanoHttpdServer.getInstance(null);    @Nullable    @Override    public IBinder onBind(Intent intent) {        return null;    }    @Override    public void onCreate() {        super.onCreate();        try {            httpServer.start();        } catch (Exception e) {            e.printStackTrace();            startService(new Intent(this,MyNanoHttpService.class));        }    }    @Override    public int onStartCommand(Intent intent, int flags, int startId){        return super.onStartCommand(intent, flags, startId);    }    public void onDestroy() {        httpServer.stop();    }}

MainActivity 启动服务

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main); //实例化 获取ip 地址         MyNanoHttpdServer.getInstance(getIPAddress());        //启动服务监听        startService(new Intent(this, MyNanoHttpService.class));    }         public  String getIPAddress() {        Context context = WelcomeActivity.this;        NetworkInfo info = ((ConnectivityManager) context                .getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();        if (info != null && info.isConnected()) {            if (info.getType() == ConnectivityManager.TYPE_MOBILE) {//当前使用2G/3G/4G网络                try {                    //Enumeration en=NetworkInterface.getNetworkInterfaces();                    for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {                        NetworkInterface intf = en.nextElement();                        for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {InetAddress inetAddress = enumIpAddr.nextElement();if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {    return inetAddress.getHostAddress();}                        }                    }                } catch (SocketException e) {                    e.printStackTrace();                }            } else if (info.getType() == ConnectivityManager.TYPE_WIFI) {//当前使用无线网络                WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);                WifiInfo wifiInfo = wifiManager.getConnectionInfo();                //调用方法将int转换为地址字符串                String ipAddress = intIP2StringIP(wifiInfo.getIpAddress());//得到IPV4地址                return ipAddress;            }        } else {            //当前无网络连接,请在设置中打开网络        }        return null;    }        public static String intIP2StringIP(int ip) {        return (ip & 0xFF) + "." +                ((ip >> 8) & 0xFF) + "." +                ((ip >> 16) & 0xFF) + "." +                (ip >> 24 & 0xFF);    }}

4,总结

  • 如果想要APP保持服务持久可用,又不被系统限制网络,,可以进入系统设置中设置“电池不优化”。
  • 根据之前的并发请求测试发现,只会返回同一条数据,而不是分别响应每一个接口请求。
    目前尚未找到适合的处理方式,暂且只能控制请求端的请求频次。
  • 如果并发请求大,请不要使用NanoHTTPD,还是通过JAVA和Spring 来做服务。

来源地址:https://blog.csdn.net/Crazy_Cw/article/details/131275226

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

【NanoHTTPD】Android,使用NanoHTTPD搭建服务器,接受Http请求,最佳实践

下载Word文档到电脑,方便收藏和打印~

下载Word文档

编程热搜

目录