本文链接: http://blog.csdn.net/xietansheng/article/details/78704783

1. 概述

官方JavaDocsApi: com.sun.net.httpserver

HttpServer 是 JDK 1.6 以后内置的一个轻量级 HTTP 服务器(在 rt.jar 包中的 com.sun.net.httpserver 包下)。一个 HttpServer 实例被绑定到一个IP地址和端口号,并监听来自该地址的客户端TCP连接。其子类 HttpsServer 实现了 HTTPS 服务,还能处理 HTTPS 请求。

一个简单的 HTTP 服务器:

// 创建 http 服务器, 绑定本地 8080 端口
HttpServer httpServer = HttpServer.create(new InetSocketAddress(8080), 0);// 创建上下文监听, "/" 表示匹配所有 URI 请求
httpServer.createContext("/", new HttpHandler() {@Overridepublic void handle(HttpExchange httpExchange) throws IOException {/** PS: 必须按顺序设置响应: 添加响应头, 发送响应码和内容长度, 写出响应内容, 关闭处理器*/// 响应内容byte[] respContents = "Hello World".getBytes("UTF-8");// 设置响应头httpExchange.getResponseHeaders().add("Content-Type", "text/html; charset=UTF-8");// 设置响应code和内容长度httpExchange.sendResponseHeaders(200, respContents.length);// 设置响应内容httpExchange.getResponseBody().write(respContents);// 关闭处理器, 同时将关闭请求和响应的输入输出流(如果还没关闭)httpExchange.close();}
});// 启动服务
httpServer.start();

浏览器访问: http://localhost:8080,输出: Hello World

使用 HttpServer 实现一个 HTTP 服务器主要涉及下面几个类:

  • HttpServer: 表示一个服务器实例
  • HttpContext: 服务器监听器的上下文
  • HttpHandler: 上下文对应的 http 请求处理器
  • HttpExchange: 对 http 请求和响应的数据封装

2. 服务器: HttpServer

创建 HttpServer 实例:

/*** 创建 HttpServer 实例, 参数说明:*     addr: 服务绑定的地址端口*     backlog: TCP连接最大并发数, 传 0 或负数表示使用默认值*/
HttpServer httpServer = HttpServer.create​(InetSocketAddress addr, int backlog);

HttpServer 常用方法:

// 重新绑定地址和端口
void bind​(InetSocketAddress addr, int backlog)
// 获取当前绑定的地址
InetSocketAddress getAddress​()/*** 创建监听的上下文, 请求 URI 根路径的匹配, 根据不同的 URI 根路径选择不同的 HttpHandler 处理请求,* 路径必须以 "/" 开头。路径 "/" 表示匹配所有的请求 URI(没有其他更具体的匹配路径除外)。*/
HttpContext createContext​(String path)
HttpContext createContext​(String path, HttpHandler handler)// 移除上下文监听
void removeContext​(HttpContext context)
void removeContext​(String path)// 设置请求的线程执行器, 设置为 null 表示使用默认的执行器
void setExecutor​(Executor executor)
Executor getExecutor​()// 启动服务
void start​()
// 最长等待指定时间后停止服务
void stop​(int delay)

3. 上下文: HttpContext

HTTP 上下文,实际上就是对请求的 URI 根路径匹配的监听,可以创建多个 HttpContext,一个 HttpContext 对应一个 HttpHandler,不同的 URI 请求,根据添加的 HttpContext 监听器,分配到对应的 HttpHandler 处理请求。

PS: 一个 HTTP 请求只会被一个“最匹配”的 HttpContext 处理。

创建 HTTP 上下文监听器:

HttpServer httpServer = HttpServer.create(...);/** 上下文监听器对应的 URI 根路径,必须以 "/" 开头,* 表示以 "/xxx" 开头的 URI 请求都交给对应的 httpHandler 处理,* "/" 表示匹配所有的请求, 一个请求只会交给 path 最匹配的一个上下文去处理(不能重复处理)*/
String path = "/xxx";// 可以创建多个,以实现更细致的 URI 路径匹配来分开处理来自不同 URI 路径的请求
httpServer.createContext(path, new HttpHandler() {@Overridepublic void handle(HttpExchange httpExchange) throws IOException {// 处理匹配当前上下文 path 的请求}
});

请求 URI 的根路径匹配关系:

Context Context path
ctx1 “/”
ctx2 “/apps/”
ctx3 “/apps/foo/”
Request URI Matches context Context path
“http://foo.com/apps/foo/bar” ctx3 “/apps/foo/”
“http://foo.com/apps/Foo/bar” no match, wrong case
“http://foo.com/apps/app1” ctx2 “/apps/”
“http://foo.com/foo” ctx1 “/”

4. 处理器: HttpHandler ( HttpExchange )

HttpHandler 是 HttpContext 对应的请求处理监听器,监听器回调时传入的HttpExchange对象封装了对 http 请求和响应的所有数据操作。

HttpExchange 与 请求 相关的方法:

// 获取请求的 URI, 请求链接除去协议和域名端口后的部分, 如: http://www.abc.com/aa/bb, URI 为 /aa/bb
URI getRequestURI​()// 获取请求客户端的 IP 地址
InetSocketAddress getRemoteAddress​()// 获取请求协议, 例如: HTTP/1.1
String getProtocol​()// 获取请求的方法, "GET", "POST" 等
String getRequestMethod​()// 获取所有的请求头
Headers getRequestHeaders​()// 以输入流的方式获取请求内容
InputStream getRequestBody​()

HttpExchange 与 响应 相关的方法:

// 获取响应头的 Map, 要添加头, 获取到 headers 后调用 add(key, value) 方法添加
Headers getResponseHeaders​()// 发送响应头, 并指定 响应code 和 响应内容的长度
void sendResponseHeaders​(int rCode, long responseLength)// 获取响应内容的输出流, 响应内容写到该流
OutputStream getResponseBody​()

HttpExchange 其他方法:

// 关闭处理器, 同时将关闭请求和响应的输入输出流(如果还没关闭)
void close​()// 获取此请求对应的上下文对象
HttpContext getHttpContext​()// 获取收到请求的本地地址
InetSocketAddress getLocalAddress​()

5. 代码实例

package com.xiets.swing;import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;import java.io.IOException;
import java.net.InetSocketAddress;public class Main {public static void main(String[] args) throws Exception {// 创建 http 服务器, 绑定本地 8080 端口HttpServer httpServer = HttpServer.create(new InetSocketAddress(8080), 0);// 创上下文监听, "/" 表示匹配所有 URI 请求httpServer.createContext("/", new HttpHandler() {@Overridepublic void handle(HttpExchange httpExchange) throws IOException {System.out.println("addr: " + httpExchange.getRemoteAddress() +     // 客户端IP地址"; protocol: " + httpExchange.getProtocol() +               // 请求协议: HTTP/1.1"; method: " + httpExchange.getRequestMethod() +            // 请求方法: GET, POST 等"; URI: " + httpExchange.getRequestURI());                  // 请求 URI// 获取请求头String userAgent = httpExchange.getRequestHeaders().getFirst("User-Agent");System.out.println("User-Agent: " + userAgent);// 响应内容byte[] respContents = "Hello World".getBytes("UTF-8");// 设置响应头httpExchange.getResponseHeaders().add("Content-Type", "text/html; charset=UTF-8");// 设置响应code和内容长度httpExchange.sendResponseHeaders(200, respContents.length);// 设置响应内容httpExchange.getResponseBody().write(respContents);// 关闭处理器httpExchange.close();}});// 创建上下文监听, 处理 URI 以 "/aa" 开头的请求httpServer.createContext("/aa", new HttpHandler() {@Overridepublic void handle(HttpExchange httpExchange) throws IOException {byte[] respContents = "Hello World AA".getBytes("UTF-8");httpExchange.getResponseHeaders().add("Content-Type", "text/html; charset=UTF-8");httpExchange.sendResponseHeaders(200, respContents.length);httpExchange.getResponseBody().write(respContents);httpExchange.close();}});// 启动服务httpServer.start();}}

浏览器访问: http://localhost:8080/http://localhost:8080/bb,输出: Hello World

浏览器访问: http://localhost:8080/aahttp://localhost:8080/aa/bb,输出: Hello World AA

JDK 内置的轻量级 HTTP 服务器 --- HttpServer相关推荐

  1. 6. JDK内置命令行工具

    JDK自带的工具和程序分为2大类型: 开发工具 诊断分析工具 开发工具 工具 简介 java Java 应用的启动程序 javac JDK 内置的编译工具 javap 反编译 class 文件的工具 ...

  2. mysql内置的变量,MySQL服务器模式及相关内置变量

    本章我们主要包含两部分的内容: MySQL服务器模式 MySQL内置变量 1. MySQL服务器模式 不同的MySQL客户端可以通过不同的模式操作MySQL Server.DBA可以设置一个全局模式, ...

  3. jdk内置线程实例_EA问题的JDK14实例

    jdk内置线程实例 Tagir Valeev最近发布了一条有关即将发布的Java JDK14版本的预览功能的推文: #Java14模式匹配将名称隐藏带入了更高的疯狂程度. 在这里,我为FLAG字段添加 ...

  4. Java虚拟机学习总结(3)——JDK内置工具(jps、jstack、jmap、jstat)使用详解

    一.JDK内置工具 - javap 1. 介绍 java 反编译工具,主要用于根据Java字节码文件反汇编为Java源代码文件. 2.命令 javap <options> <clas ...

  5. JDK内置命令行工具

    java命令行 序号 接口 java Java 应用的启动程序 javac JDK 内置的编译工具 javap 反编译 class 文件的工具 javadoc 根据 Java 代码和标准注释,自动生成 ...

  6. JDK 内置命令行工具:工欲善其事,必先利其器

    很多情况下,JVM 运行环境中并没有趁手的工具,所以掌握基本的内置工具是一项基本功. JDK 自带的工具和程序可以分为 2 大类型: 开发工具 诊断分析工具 JDK 内置的开发工具 写过 Java 程 ...

  7. Log4j日志的简单替代:JDK内置log的简单封装

    前段时间Log4j爆出严重漏洞,其实我一直都不太喜欢这个臃肿的框架. 下面代码对JDK内置的log简单地封装了一下.直接复制到项目即可用.更不需要maven. 使用方法看main函数. import ...

  8. JDK内置并发AQS同步器的独占锁获取与释放

    作者简介:笔名seaboat,擅长工程算法.人工智能算法.自然语言处理.计算机视觉.架构.分布式.高并发.大数据和搜索引擎等方面的技术,大多数编程语言都会使用,但更擅长Java.Python和C++. ...

  9. node sqlite 插入数据_方便且实用,Python内置的轻量级数据库实操

    之前我们在很多项目案例中都使用了MySQL数据库.有的同学问:MySQL安装和配置太麻烦了,老是搞不定,有没有更简便的方法? 当然有咯! Python内置的sqlite3模块就是一个轻量级的数据库,不 ...

  10. 收藏!Python内置的轻量级数据库竟如此好用!全网最实用sqlite3实战项目。

    前段时间推送了一篇Python操作MySQL数据库的文章:我用 Python 处理3万多条数据,只要几秒钟--,文章发布后反应很好,很多粉丝给我私信,有的朋友说:MySQL安装起来太麻烦了,有没有更简 ...

最新文章

  1. 转:eclipse Failed to load JavaHL Library.
  2. Open ROADS Community首次正式会议在新加坡顺利召开
  3. [网鼎杯 2020 青龙组]bang
  4. Missing artifact com.github.pagehelper:pagehelper:jar:3.4.2-fix的解决方法
  5. Python丢弃返回值
  6. Dynamic AX ERP 4.0 数据导出(上)
  7. 以太坊智能合约编程之带菜鸟入门教程
  8. Xcode7 UI自动化测试详解 带demo UITests
  9. pandas处理大数据的一些小技巧
  10. 解决网页中不能复制文字的问题
  11. MySQL 一个库中表数量是否有限制?
  12. 在VB应用程序中调用Excel2000
  13. nginx正则表达式
  14. Cell子刊主编:文章被编辑拒稿,主要是这4大原因
  15. 7k7k游戏盒与逗游游戏库,你更喜欢哪个
  16. 使用vscode作为golang开发环境,无法跳转代码定义
  17. 怎样学习数据结构? 伯克利神课CS61B 总结感悟,学习指南和避坑建议
  18. 学嵌入式需要报培训班吗?
  19. 【校内模拟】八云蓝(线段树)(大力分类讨论)
  20. v2ex站长专访 - 100offer专访Livid:不仅仅是V站站长

热门文章

  1. Tools介绍:最快的DicomViewer软件 - RadiAnt Dicom Viewer
  2. java分层ppt_java程序设计第10章图形用户界面.ppt
  3. 个性化系统推送 java_个性化推送系统
  4. 【Android】mina框架使用详情
  5. JAVA版商城 B2B2C商城 多用户入驻商城 直播带货商城 新零售商城 o2o商城 拼团商城 分销商城 直播商城 短视频商城 VR商城 社交电商 分销商城 saas商城spring cloud商城
  6. 移动创业者,这么多免费资源,你不要?
  7. 酷Q机器人全自动聊天回复、管理Q群
  8. 安卓手机修改ntp服务器,修改安卓手机ntp服务器地址
  9. 进制之间的转换(史上最全自己纯手工总结)
  10. 阿铭Linux_传统IDC 部署网站学习笔记20190125