java构建简单的HTTP服务器
使用Java技术构建Web应用时, 我们通常离不开tomcat和jetty之类的servlet容器,这些Web服务器功能强大,性能强劲,深受欢迎,是运行大型Web应用的必备神器。
虽然Java的设计初衷就是用来开发大型应用的,然而有时候我们开发的程序只是简单的小型应用,对于功能的需求和性能的要求并不高, 可能仅仅就几百行甚至几十行代码,这个时候使用tomcat之类的Web服务器去运行就显得有点大材小用了。 比如说只是将数据库中的数据读出来转换成JSON,以Web服务的形式吐给调用方这样的阉割型Web应用。 如下图所示
二、最简单的Java Http服务器
其实在jdk中已经内置了用于此类简单Web应用构建需求的类库了,sun公司提供的 com.sun.net.httpserver 包就是用来帮助我们解决这类问题的

- import com.sun.net.httpserver.HttpExchange;
- import com.sun.net.httpserver.HttpHandler;
- import com.sun.net.httpserver.HttpServer;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.net.InetSocketAddress;
- public class Main {
- public static void main(String[] arg) throws Exception {
- HttpServer server = HttpServer.create(new InetSocketAddress(8001), 0);
- server.createContext("/test", new TestHandler());
- server.start();
- }
- static class TestHandler implements HttpHandler{
- @Override
- public void handle(HttpExchange exchange) throws IOException {
- String response = "hello world";
- exchange.sendResponseHeaders(200, 0);
- OutputStream os = exchange.getResponseBody();
- os.write(response.getBytes());
- os.close();
- }
- }
- }

如上代码清单所示, 仅仅几行代码就可以构建一个五脏俱全的Web应用了。执行代码,在浏览器地址栏里代开链接
http://localhost:8001/test
就能运行这个段程序,输入的结果为helloworld
三、获得外部数据
那在这个程序中如何获取到外部传递过来的数据呢?比如说URL上的查询字符串,POST提交的数据等,其实也很简单

- import com.sun.net.httpserver.HttpExchange;
- import com.sun.net.httpserver.HttpHandler;
- import com.sun.net.httpserver.HttpServer;
- import org.apache.commons.io.IOUtils;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.io.UnsupportedEncodingException;
- import java.net.InetSocketAddress;
- import java.net.URLDecoder;
- import java.util.Arrays;
- import java.util.HashMap;
- import java.util.Map;
- public class Main {
- public static void main(String[] arg) throws Exception {
- HttpServer server = HttpServer.create(new InetSocketAddress(8001), 0);
- server.createContext("/test", new TestHandler());
- server.start();
- }
- static class TestHandler implements HttpHandler{
- @Override
- public void handle(HttpExchange exchange) {
- String response = "hello world";
- try{
- //获得查询字符串(get)
- String queryString = exchange.getRequestURI().getQuery();
- Map<String,String> queryStringInfo = formData2Dic(queryString);
- //获得表单提交数据(post)
- String postString = IOUtils.toString(exchange.getRequestBody());
- Map<String,String> postInfo = formData2Dic(postString);
- exchange.sendResponseHeaders(200,0);
- OutputStream os = exchange.getResponseBody();
- os.write(response.getBytes());
- os.close();
- }catch (IOException ie) {
- } catch (Exception e) {
- }
- }
- }
- public static Map<String,String> formData2Dic(String formData ) {
- Map<String,String> result = new HashMap<>();
- if(formData== null || formData.trim().length() == 0) {
- return result;
- }
- final String[] items = formData.split("&");
- Arrays.stream(items).forEach(item ->{
- final String[] keyAndVal = item.split("=");
- if( keyAndVal.length == 2) {
- try{
- final String key = URLDecoder.decode( keyAndVal[0],"utf8");
- final String val = URLDecoder.decode( keyAndVal[1],"utf8");
- result.put(key,val);
- }catch (UnsupportedEncodingException e) {}
- }
- });
- return result;
- }
- }

上面的代码清单标识了实现的方法。
注意,要保证上面代码编译通过, 需要引入commons-io.jar,此包中提供将InputStream转换成String的方法。
四、并发处理
com.sun.net.httpserver似乎默认不支持同时处理多个请求,一旦有并行的请求涌入,需要排队等待程序处理,导致Web程序响应卡顿。自定义实现的方法也很简单,为每个请求开一个新的线程处理即可, 如下代码清单所示

- import com.sun.net.httpserver.HttpExchange;
- import com.sun.net.httpserver.HttpHandler;
- import com.sun.net.httpserver.HttpServer;
- import org.apache.commons.io.IOUtils;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.io.UnsupportedEncodingException;
- import java.net.InetSocketAddress;
- import java.net.URLDecoder;
- import java.util.Arrays;
- import java.util.HashMap;
- import java.util.Map;
- public class Main {
- public static void main(String[] arg) throws Exception {
- HttpServer server = HttpServer.create(new InetSocketAddress(8001), 0);
- server.createContext("/test", new TestHandler());
- server.start();
- }
- static class TestHandler implements HttpHandler{
- @Override
- public void handle(HttpExchange exchange) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- try{
- String response = "hello world";
- //获得查询字符串(get)
- String queryString = exchange.getRequestURI().getQuery();
- Map<String,String> queryStringInfo = formData2Dic(queryString);
- //获得表单提交数据(post)
- String postString = IOUtils.toString(exchange.getRequestBody());
- Map<String,String> postInfo = formData2Dic(postString);
- exchange.sendResponseHeaders(200,0);
- OutputStream os = exchange.getResponseBody();
- os.write(response.getBytes());
- os.close();
- }catch (IOException ie) {
- ie.printStackTrace();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }).start();
- }
- }
- public static Map<String,String> formData2Dic(String formData ) {
- Map<String,String> result = new HashMap<>();
- if(formData== null || formData.trim().length() == 0) {
- return result;
- }
- final String[] items = formData.split("&");
- Arrays.stream(items).forEach(item ->{
- final String[] keyAndVal = item.split("=");
- if( keyAndVal.length == 2) {
- try{
- final String key = URLDecoder.decode( keyAndVal[0],"utf8");
- final String val = URLDecoder.decode( keyAndVal[1],"utf8");
- result.put(key,val);
- }catch (UnsupportedEncodingException e) {}
- }
- });
- return result;
- }
- }

五、优点
Java内置Web服务器在功能、性能、稳定等方面是无法和tomcat和jetty之类的专业Web服务器相比的, 它的优点主要是开发和部署方便简单, 把程序代码编译成jar包后,丢到装有jvm的服务器上, 直接运行就可以了,省去了安装相关的软件、依赖, 配置复杂的环境等工作量。
但是, 在一些各方面要求都比较高的生产环境下,还是建议使用专门的Web服务器,毕竟它们久经考验,能满足所有功能需求,并且出问题的几率低。
知乎:https://www.zhihu.com/people/aspwebchh
github:https://github.com/aspwebchh
email: aspwebchh@gmail.com
java构建简单的HTTP服务器的更多相关文章
- JAVA 实现 简单的 HTTP服务器
关于JAVA的HTTP服务器的简单实现,还望大家给出宝贵建议,谢谢. 1.首先来说下HTTP所有的状态碼,相信对于网页开发的博友们,肯定不陌生. 状态码 状态码英文名称 中文描述 100 Contin ...
- 用Java实现简单的web服务器
运行结果: 1.WebServer.java文件 package webserver; import java.io.*; import java.net.*; public class WebSer ...
- 使用Java实现简单的Http服务器
在Java中可以使用HttpServer类来实现Http服务器,该类位于com.sun.net包下(rt.jar).实现代码如下: 主程序类 package bg.httpserver; import ...
- java实现一个简单的Web服务器
注:本段内容来源于<JAVA 实现 简单的 HTTP服务器> 1. HTTP所有状态码 状态码 状态码英文名称 中文描述 100 Continue 继续.客户端应继续其请求 101 Swi ...
- 计算机网络(13)-----java nio手动实现简单的http服务器
java nio手动实现简单的http服务器 需求分析 最近在学习HTTP协议,还是希望动手去做一做,所以就自己实现了一个http服务器,主要功能是将http请求封装httpRequest,通过解析 ...
- 三、使用Maven构建简单的java项目
前边,我刚搭建了Maven环境,还有给大家推荐了学习资源,这个小节,我们来就来,,简单的玩玩maven. 1.所需工具: 1.Eclipse 2.apache-maven-3.3.9 3. ...
- java实现简单web服务器(分析+源代码)
在日常的开发中,我们用过很多开源的web服务器,例如tomcat.apache等等.现在我们自己实现一个简单的web服务器,基本的功能就是用户点击要访问的资源,服务器将资源发送到客户端的浏览器.为了简 ...
- 基于 Java NIO 实现简单的 HTTP 服务器
1.简介 本文是上一篇文章实践篇,在上一篇文章中,我分析了选择器 Selector 的原理.本篇文章,我们来说说 Selector 的应用,如标题所示,这里我基于 Java NIO 实现了一个简单的 ...
- Ant—使用Ant构建简单Java项目(三)
博客<Ant-使用Ant构建简单Java项目(二)>我们简化了运行Test类中main方法须要运行的命令,本博客来介绍一下如何使build.xml文件和当中使用property标签定义的属 ...
随机推荐
- java中参数" ..."的用法和意思
public static void executebindParam(PreparedStatement pstmt,Object ...os){ int len = os.length; try ...
- tp中model加载机制
$user_model = D('User'); 如果当前模块下面有UserModel,就优先使用当前模块下的UserModel.如果当前模块下没有UserModel,就回去Common模块下找Use ...
- LInux因为缺失网关出现Name or service not known的解决方法
笔者使用的VMware和CentOS 7.0.在安装完镜像包后,便开始配置静态ip.命令如下 vi /etc/sysconfig/network-scripts/ifcfg-ens33 将BOOTPR ...
- OracleVM桥接网卡无法获取本地连接网卡
问题现象 VM虚拟机采用桥接网卡时,界面名称为"未指定",无法获取本地连接对应网卡信息: 处理方式: 进入本地连接,选择本地连接右键进入属性设置窗口; 选择安装,单击服务选项后点击 ...
- Vue 公众号开发 (菜鸡前段的血泪史)
首先vue-cli就不说了 接下来要说我们需要注意什么 公众号的每个页面都有一个title 所以我们在开发过程中 需要插件 安装vue-wechat-title 安装vue-js-sdk
- JMeter安装及简单应用示例
一.Jmeter下载 官网地址:http://jmeter.apache.org/ 1.进入官网 2.选中一个版本下载 3.解压安装即可 二.Jmeter环境变量配置 1. 电脑桌面----> ...
- Codeforces Round #499 (Div. 1) F. Tree
Codeforces Round #499 (Div. 1) F. Tree 题目链接 \(\rm CodeForces\):https://codeforces.com/contest/1010/p ...
- C# vb .net实现焦距淡色特效滤镜
在.net中,如何简单快捷地实现Photoshop滤镜组中的焦距淡色效果呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 第 ...
- 无法生成服务引用(添加WebService)
参考地址:http://www.52study.org/bencandy-120-1076-1.html 问题场景:.在工程中添加WebService,报错: 解决办法: 1.配置该服务引用 将下面 ...
- 实战Go内存泄露【转】
最近解决了我们项目中的一个内存泄露问题,事实再次证明pprof是一个好工具,但掌握好工具的正确用法,才能发挥好工具的威力,不然就算你手里有屠龙刀,也成不了天下第一,本文就是带你用pprof定位内存泄露 ...