随笔 - 10  文章 - 0  评论 - 0  阅读 - 489

手写简易的WEB服务

环境:

  • JDK 1.8
  • Idea 工具
  • 新建Java项目

前提需要具备的基础

  • Socket
  • IO

思路

写一个服务端即可,用浏览器做现成的客户端

  • 启动Socket服务,循环接收浏览器的请求
  • 接收请求之后,将流中的数据取出
  • 判断目标是资源是否存在,若不存在,返回404页面
  • 若存在,将目标资源通过输出流响应给客户端(浏览器)

需要使用到的类

  • Server:开启Socket服务
  • Request:封装请求,处理请求的业务
  • Response:封装响应,处理响应的相关业务
  • Test: 测试类

Server服务器中

public class SimpleHttpServer {
//端口
private int port=8080;
//IP就是本地 不需要配置
//接收请求的方法
public void receiving(){
try {
//创建Socket服务
ServerSocket serverSocket = new ServerSocket(port);
//循环接收
while (true){
//每次请求就会拿到Socket对象就是接收一个请求
Socket socket = serverSocket.accept();
//System.out.println(socket);
//获取连接对象的输入流
InputStream inputStream = socket.getInputStream();
//创建request对象
SimpleHttpRequest simpleHttpRequest = new SimpleHttpRequest(inputStream);
//解析请求
simpleHttpRequest.parse();
//获取连接对象的输出流
OutputStream outputStream = socket.getOutputStream();
//创建Response
SimpleHttpResponse simpleHttpResponse = new SimpleHttpResponse(outputStream);
//进行响应
simpleHttpResponse.sendRedirect(simpleHttpRequest.getUri());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

Request对象解析请求

public class SimpleHttpRequest {
private InputStream inputStream;
//返回请求头中的网页资源路径
private String uri;
public SimpleHttpRequest(InputStream inputStream) {
this.inputStream = inputStream;
}
//进行解析
public void parse() {
try {
byte[] bytes = new byte[1024];
inputStream.read(bytes);
String request=new String(bytes);
System.out.println(request);
parseUri(request);
} catch (Exception e) {
e.printStackTrace();
}
}
//解析
public void parseUri(String request) {
int index1 ,index2;
//找到第一次的空格
index1 = request.indexOf(32);
index2 = request.indexOf(32, index1 + 1);
//截取中间的资源
uri = request.substring(index1 + 1, index2);
System.out.println(uri);
}
public String getUri() {
return this.uri;
}
}

Response对象进行对请求信息的响应

public class SimpleHttpResponse {
private OutputStream outputStream;
public SimpleHttpResponse(OutputStream outputStream) {
this.outputStream = outputStream;
}
public void sendRedirect(String uri) {
try {
//获取项目目录再拼接路径
String path = System.getProperty("user.dir") + "/WebContent" + uri;
//判断资源uri是否存在
File file = new File(path);
if (!file.exists()) {
//不存在返回404
String error = getResponseMessage("404", "404 File Not Found");
System.out.println(error);
this.outputStream.write(error.getBytes());
} else {
//存在就返回目标资源的数据
FileInputStream inputStream = new FileInputStream(file);
byte[] bytes = new byte[(int) file.length()];
inputStream.read(bytes);
String result = new String(bytes);
String responseMessage = getResponseMessage("200", result);
this.outputStream.write(responseMessage.getBytes());
}
} catch (Exception e) {
e.printStackTrace();
}
}
//响应的格式
public String getResponseMessage(String code, String message) {
return "HTTP/1.1" + code + "\r\n"
+ "Content-type: text/html\r\n"
+ "Content-Length: " + message.length()
+ "\r\n"
+ "\r\n"
+ message;
}
}

测试服务

public static void main(String[] args) {
SimpleHttpServer server = new SimpleHttpServer();
System.out.println("Server Startup Successfully");
server.receiving();
}

测试中的数据

  • Socket[addr=/0:0:0:0:0:0:0:1,port=51572,localport=8080] 整个port是浏览器提供的接口

  • 浏览器发送的请求消息

    GET /index.html HTTP/1.1
    Host: localhost:8080
    Connection: keep-alive
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8

记录错误:

java.net.SocketException: Socket is not bound yet 创建服务时忘记把端口传入进去

记录新发现:

System.getProperty("user.dir") ==> 获取项目的路径 本次获取的 D:\..\SimpleWebServer

posted on   万万没想到啊i  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示