技术栈

java.net.Socket

java.net.ServerSocket

执行流程

创建一个ServerSocket对象;

调用ServerSocket对象的accept方法,等待连接,连接成功会返回一个Socket对象,否则一直阻塞等待;

从Socket对象中获取InputStream和OutputStream字节流,这两个流分别对应request请求和response响应;

处理请求:读取InputStream字节流信息,转成字符串形式,并解析,这里的解析比较简单,仅仅获取uri(统一资源标识符)信息;

处理响应:根据解析出来的uri信息,从WEB_ROOT目录中寻找请求的资源资源文件, 读取资源文件,并将其写入到OutputStream字节流中;

关闭Socket对象;

转到步骤2,继续等待连接请求;

代码实现

服务器

package com.kunlinr.lifealien.servlet.server;

import java.io.File;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.InetAddress;

import java.net.ServerSocket;

import java.net.Socket;

public class HttpServer {

/**WEB_ROOT是HTML和其它文件存放的目录. 这里的WEB_ROOT为工作目录下的WebContent目录*/

public static final String WEB_ROOT = System.getProperty("user.dir")+File.separator+"WebContent";

//关闭服务命令

public static final String SHUTDOWN_COMMAND = "/SHUTDOWN";

public static void main(String[] args) {

HttpServer server = new HttpServer();

server.await();

}

/**

* 等待连接请求

*/

private void await() {

ServerSocket serverSocket = null;

int port = 8080;

try {

//服务器套接字对象

serverSocket = new ServerSocket(port,0,InetAddress.getByName("127.0.0.1"));

}catch (Exception e) {

e.printStackTrace();

System.exit(1);

}

//循环等待请求

while(true) {

Socket socket = null;

InputStream input = null;

OutputStream output = null;

try {

socket = serverSocket.accept();

input = socket.getInputStream();

output = socket.getOutputStream();

//创建Request

Request request = new Request(input);

//检查是否关闭服务命令

if(request.getUri().equals(SHUTDOWN_COMMAND)) {

break;

}

//创建Response

Response response = new Response(output);

response.setRequest(request);

response.sendStaticResource();

//关闭socket

socket.close();

}catch(Exception e) {

e.printStackTrace();

continue;

}

}

}

}

Request

package com.kunlinr.lifealien.servlet.server;

import java.io.ByteArrayOutputStream;

import java.io.InputStream;

@SuppressWarnings("unused")

public class Request {

private InputStream input;

private String uri;

public Request(InputStream input) {

this.input = input;

parse();

}

/**

* 从inputStream中读取request信息,获取uri值。

*/

public void parse() {

StringBuffer request = new StringBuffer(2048);

int i;

byte[] buffer = new byte[2048];

try {

i = input.read(buffer);

}catch (Exception e) {

e.printStackTrace();

i = -1;

}

for(int j=0;j

request.append((char)buffer[j]);

}

uri = parseUri(request.toString());

}

/**

* requestString形式如下:

* GET /index.html HTTP/1.1

* Host: localhost:8080

* Connection: keep-alive

* Cache-Control: max-age=0

* ...

* 获取/index.html字符串

* @param string

* @return

*/

private String parseUri(String string) {

int index1,index2;

index1 = string.indexOf(' ');

if (index1 != -1) {

index2 = string.indexOf(' ', index1 + 1);

if (index2 > index1)

return string.substring(index1 + 1, index2);

}

return "";

}

public String getUri() {

return uri;

}

}

Response

package com.kunlinr.lifealien.servlet.server;

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.util.ArrayList;

import java.util.List;

public class Response {

private static final int BUFFER_SIZE = 1024;

private Request request;

private OutputStream output;

public Response(OutputStream output) {

this.output = output;

}

public void setRequest(Request request) {

this.request = request;

}

/**

* 发送静态资源

* @throws IOException

*/

public void sendStaticResource() throws IOException {

byte[] bytes = new byte[BUFFER_SIZE];

FileInputStream fis = null;

try {

//将web文件写入到OutputStream字节流中

File file = new File(HttpServer.WEB_ROOT, request.getUri());

if (file.exists()) {

fis = new FileInputStream(file);

List contentbytes = new ArrayList<>();

int ch = fis.read(bytes, 0, BUFFER_SIZE);

int size = 0;

while (ch != -1) {

contentbytes.add(bytes);

ch = fis.read(bytes, 0, BUFFER_SIZE);

size += BUFFER_SIZE;

}

String head = "HTTP/1.1 200 OK\r\n" + "Content-Type: text/html\r\n"

+ "Content-Length: "+size+"\r\n" + "\r\n";

byte[] headbytes = head.getBytes();

output.write(headbytes,0,headbytes.length);

for(byte[] contentbyte:contentbytes) {

output.write(contentbyte);

}

} else {

// file not found

String errorMessage = "HTTP/1.1 404 File Not Found\r\n" + "Content-Type: text/html\r\n"

+ "Content-Length: 23\r\n" + "\r\n" + "

File Not Found

";

output.write(errorMessage.getBytes());

}

} catch (Exception e) {

// thrown if cannot instantiate a File object

System.out.println(e.toString());

} finally {

if (fis != null)

fis.close();

}

}

}

简单页面

Hello,this is your own Page!

Everything is Simple!

效果

启动服务

发送请求

返回正文

Hello,this is your own Page!

Everything is Simple!

参考文档

java web容器_java-实现一个简单的java Web容器相关推荐

  1. java 语言 写字板_一个简单的java语言写字板.docx

    一个简单的java语言写字板.docx 一个简单的JAVA语言写字板一.需求分析1.需求分析:现在网络上各种文档编辑器数不胜数.功能也是应有尽有,有能改变字体的,有可以改变字体颜色的,但是,这些软件有 ...

  2. java实现web服务器_Java 实现一个简单的web服务器

    在日常的开发中,我们用过很多开源的web服务器,例如tomcat.apache等等.现在我们自己实现一个简单的web服务器,基本的功能就是用户点击要访问的资源,服务器将资源发送到客户端的浏览器.web ...

  3. java 缓存方法_Java实现一个简单的缓存方法

    Java实现一个简单的缓存方法 发布时间:2020-09-07 21:39:55 来源:脚本之家 阅读:99 作者:BrightLoong 缓存是在web开发中经常用到的,将程序经常使用到或调用到的对 ...

  4. java单机应用程序_一个简单的java桌面应用:单机版IFTTT

    1.项目背景: ifttt是"if this then that"的缩写,事实上是让你的网络行为能够引发连锁反应.让你使用更为方便.ifttt旨在帮助人们利用各网站的开放API,将 ...

  5. java编写服务器_java编写一个简单的回射服务器

    全部代码 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; im ...

  6. java实现堆栈_Java实现一个简单的堆栈

    堆栈(Stack)是一种常见的数据结构,符合后进先出(First In Last Out)原则,通常用于实现对象存放顺序的逆序.栈的基本操作有push(添加到堆栈),pop(从堆栈删除),peek(检 ...

  7. java五子棋盘_Java实现一个简单的两人五子棋游戏(二) 画棋盘

    棋盘模块: 画五子棋棋盘:19条横线.19条竖线 步骤一:显示棋盘 我有一张名为chessboard.png的棋盘,位置为根目录/res/drawable/chessboard/png,现在我要显示这 ...

  8. 一个简单的Java web服务器实现

    前言 一个简单的Java web服务器实现,比较简单,基于java.net.Socket和java.net.ServerSocket实现: 程序执行步骤 创建一个ServerSocket对象: 调用S ...

  9. 一个简单的Java EEDocker示例

    本文讲的是一个简单的Java EE&Docker示例,[编者的话]学习Docker的最好办法就是迅速在工作中应用它,本文作者使用Docker部署了一个Java EE应用,非常简单和方便.需要注 ...

最新文章

  1. 【怎样写代码】参数化类型 -- 泛型(九):泛型代码中的default关键字
  2. windows 生成 deploy key_推荐一个免费生成点线/方格/横线纸张的网站
  3. Quartus II12.0安装教程
  4. lunbuntu install maven
  5. Clumsy 弱网络环境模拟工具使用介绍
  6. Android之基于xmpp openfire smack开发之openfire介绍和部署[1]
  7. react 组件构建_让我们用100行JavaScript构建一个React Chat Room组件
  8. 语义分割双料冠军!微软 OCRNet化解语义分割上下文信息缺失难题|ECCV 2020
  9. 多种系统负载100%方法(高可用测试、性能压测用)
  10. org.apache.ibatis.builder.BuilderException: An invalid property ‘jdbcType ‘ was found in mapping
  11. Java设计模式(Design Patterns In Java)读书摘要——第1章 绪论
  12. Cocos2dx--Cocos2dx与Android平台的跨平台调用
  13. 手机app测试方法(二)App测试-常见测试点
  14. AMD ROCm 硬件支持情况
  15. Centos服务器ssh登录设置密钥对登录
  16. 视频流中的DTS/PTS到底是什么?
  17. 图书馆抢座系统(python) 附源码
  18. QPainter 画扇形
  19. 2021年网络安全十大发展趋势预测
  20. github上十二款最著名的Android播放器开源项目

热门文章

  1. 2021 年押宝哪个后端语言呢?
  2. 美团推出外卖版拼多多;iOS 14 Beta 3暂禁用3D Touch功能;Rust 1.45 发布| 极客头条
  3. 阿里云自研数据仓库 AnalyticDB 再捧 TPC 全球冠军
  4. Zoom 是如何击败科技巨头的?
  5. 2020 年,网络安全方面 5 大值得学习的编程语言
  6. 程序员都应该了解的一种数据格式之 JSON
  7. 15 年经验专家解读 IIoT 的挑战及应对思路!
  8. 程序员需要了解的硬核知识之操作系统和应用
  9. 程序员面向软件开发时,如何成功?
  10. 华为鸿蒙为什么非要碰物联网?