JSD-2204-WebServer(项目)-Day13

1.V10(版本)

在index页面上显示一张图片

实现:
1:准备一张图片,取名为logo.png
2:在index.html页面上使用<img>标签将其显示出来
3:启动服务端,使用浏览器请求该页面查看图片的显示情况.

测试发现图片无法加载.
原因:
当页面上需要加载其他资源(图片,样式文件,脚本文件等)时,浏览器会自动发起请求去下载
这些资源.因此当我们的页面上有其他资源时,呈现一个页面一问一答就不够了,需要多次的
请求响应来完成.

解决:
将WebServerApplication的start方法中的代码加上死循环,重复接收多次客户端的
连接即可.

1.1项目目录

 

1.2Java页面

1.2.1ClientHandler

package com.webserver.core;

import com.webserver.http.HttpServletRequest;
import com.webserver.http.HttpServletResponse;

import java.io.*;
import java.net.Socket;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

/**
 * 该线程任务是负责与一个客户端进行一次HTTP交互
 * 浏览器与服务端交互组从一问一答的原则。因此服务端处理一次HTTP交互,步骤如下:
 * 1:解析请求(接受浏览器发送过来的请求内容)
 * 2:处理请求(根据浏览器发送的请求理解其意图并进行对应的处理)
 * 3:发送响应(将处理结果发送给浏览器)
 *
 *
 */
public class ClientHandler implements Runnable{
    private Socket socket;
    public ClientHandler(Socket socket){
        this.socket = socket;
    }

    public void run() {
        try {
            //1解析请求
            HttpServletRequest request = new HttpServletRequest(socket);
            HttpServletResponse response = new HttpServletResponse(socket);

            //2处理请求
            DispatcherServlet servlet = new DispatcherServlet();
            servlet.service(request,response);

            //3发送响应
            response.response();



        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                //按照HTTP协议要求,一次交互后要断开连接
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }





}


1.2.2DispatcherServlet

package com.webserver.core;

import com.webserver.http.HttpServletRequest;
import com.webserver.http.HttpServletResponse;

import java.io.File;
import java.net.URISyntaxException;

/**
 * 负责处理请求环节
 */
public class DispatcherServlet {
    private static File rootDir;
    private static File staticDir;

    static{
        try {
            rootDir = new File(
                    ClientHandler.class.getClassLoader()
                            .getResource(".").toURI()
            );
            staticDir = new File(rootDir,"static");
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }

    public void service(HttpServletRequest request, HttpServletResponse response){
        String path = request.getUri();

        File file = new File(staticDir,path);
        System.out.println("资源是否存在:"+file.exists());
        if(file.isFile()){
            //将请求的实际文件设置到response的正文上等待响应
            response.setContentFile(file);
        }else{
            file = new File(staticDir,"/root/404.html");
            //将404内容设置到response上等待响应
            response.setStatusCode(404);
            response.setStatusReason("NotFound");
            response.setContentFile(file);
        }
    }
}


1.2.3WebServerApplication

package com.webserver.core;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * WebServer主类
 * WebServer是一个Web容器,实现了Tomcat的基础功能。
 * 通过本次项目我们的目标是:
 * 1:理解Tomcat底层工作原理
 * 2:理解HTTP协议的规定
 * 3:理解SpringBoot
 */
public class WebServerApplication {
    private ServerSocket serverSocket;

    /**
     * 初始化WebServer
     */
    public WebServerApplication(){
        try {
            System.out.println("正在启动服务端...");
            /*
                当端口被其他程序占用时,这里会抛出异常:
                java.net.BindException:address already in use:JVM
                解决:
                1:杀死该java进程(推荐)
                2:重启电脑(不推荐)
                3:更换端口(通常重启后还不行,说明被其他程序占用该端口了)
             */
            serverSocket = new ServerSocket(8088);
            System.out.println("服务端启动完毕!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 服务端开始工作的方法
     */
    public void start(){
        try {
            while(true) {
                System.out.println("等待客户端连接...");
                Socket socket = serverSocket.accept();
                System.out.println("一个客户端连接了!");
                //启动一个线程处理该客户端交互
                ClientHandler clientHandler = new ClientHandler(socket);
                Thread thread = new Thread(clientHandler);
                thread.start();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        WebServerApplication webServerApplication = new WebServerApplication();
        webServerApplication.start();
    }
}


1.2.4HttpServletRequest

package com.webserver.http;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

/**
 * 请求对象
 * 该类的每一个实例用于表示客户端发送过来的一个HTTP请求
 * 每个请求由三部分构成:
 * 请求行,消息头,消息正文
 */
public class HttpServletRequest {
    private Socket socket;

    //请求行的相关信息
    private String method;//请求方式
    private String uri;//抽象路径
    private String protocol;//协议版本

    //用一个Map保存所有的消息头,其中key:消息头名字,value:消息头的值
    private Map<String,String> headers = new HashMap<>();

    public HttpServletRequest(Socket socket) throws IOException {
        this.socket = socket;
        //1.1解析请求行
        parseRequestLine();
        //1.2解析消息头
        parseHeaders();
        //1.3解析消息正文
        parseContent();
    }

    //解析请求行
    private void parseRequestLine() throws IOException {
        String line = readLine();
        System.out.println(line);
        //将请求行按照空格拆分为三部分,并赋值给三个变量
        String[] data = line.split("\\s");
        method = data[0];
        uri = data[1];
        protocol = data[2];
        //测试路径:http://localhost:8088/myweb/index.html
        System.out.println("method:"+method);//method:GET
        System.o
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值