JDK 内置的轻量级 HTTP 服务器 --- HttpServer
来源:互联网 发布:自制漫画软件下载 编辑:程序博客网 时间:2024/05/16 17:21
本文链接: 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() { @Override public 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() { @Override public void handle(HttpExchange httpExchange) throws IOException { // 处理匹配当前上下文 path 的请求 }});
请求 URI 的根路径匹配关系:
4. 处理器: HttpHandler ( HttpExchange )
HttpHandler 是 HttpContext 对应的请求处理监听器,监听器回调时传入的HttpExchange
对象封装了对 http 请求和响应的所有数据操作。
HttpExchange 与 请求 相关的方法:
// 获取请求的 URI, 请求链接除去协议和域名端口后的部分, 如: http://www.abc.com/aa/bb, URI 为 /aa/bbURI getRequestURI()// 获取请求客户端的 IP 地址InetSocketAddress getRemoteAddress()// 获取请求协议, 例如: HTTP/1.1String 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() { @Override public 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() { @Override public 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/aa
、http://localhost:8080/aa/bb
,输出: Hello World AA
- JDK 内置的轻量级 HTTP 服务器 --- HttpServer
- 轻量级的服务器http-server
- 使用Net内置的轻量级Web服务器
- java HttpServer构建http服务器
- java HttpServer构建http服务器
- java HttpServer构建http服务器
- java HttpServer构建http服务器
- 简易http服务器的实现(实现)httpserver.c
- JDK6.0的新特性:轻量级HttpServer
- 基于JDK HttpServer的RESTEasy
- 基于JDK HttpServer的RESTEasy
- 自定义轻量级的HTTP WebServer (WEB服务器)
- java编写的轻量级HTTP服务器nanohttpd
- java编写的轻量级HTTP服务器nanohttpd
- 轻量级HTTP服务器
- 轻量级http服务器 nginx
- 轻量级http服务器nginx
- JDK自带的轻量级HTTP Server进行加载。
- leetcode解题方案--153--Find Minimum in Rotated Sorted Array
- 进程与线程的区别
- LeetCode--Palindromic Substrings
- 算法期中 : 1005. 最小和
- 牛腩之SQLHelper
- JDK 内置的轻量级 HTTP 服务器 --- HttpServer
- 详解CAP理论
- ⚔疯狂输出⚔ 数组中的折半查找
- 填坑待补 线性基学习笔记
- [LeetCode] Frog Jump
- python2和python3 is用法的不同,有点坑
- HTML(十八)
- 巧用CAS解决数据一致性问题
- 无题