第①章-一个简单的web服务器

主要内容:本节的主要内容介绍了http请求和响应报文,并且编写了一个简单的http服务器的例子,来说明java是如何创建web服务的。这个例子使用了三个类来实现分别是:

  1. HttpServer:主要用来接收浏览器的请求,并且创建Request对象和Response对象来进行请求资源的提取和对应返回给浏览器对应的数据。
  2. Request:主要用来提取请求报文中数据,提取uri
  3. Response:主要用来向浏览器返回对应的请求数据。

下面分别给出上述三个类的实现,这里作者的这种写法很面向对象,值得我们学习。

1.HttpServer

package demon1;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class HttpServer {
    private static final String SHUTDOWN_COMMAND="/shutdown";

    private boolean shutdown=false;

    private static final int PORT=8080;

    private static final String IP="127.0.0.1";

    public void await(){
        ServerSocket serverSocket=null;
        try {
            serverSocket=new ServerSocket(PORT,1, InetAddress.getByName(IP));
        } catch (IOException e) {
            e.printStackTrace();
        }

        //等价于while(true),只是比他更加的灵活
        while(!shutdown){
            try {
                assert serverSocket != null;

                //阻塞监听端口
                Socket socket = serverSocket.accept();
                //输入流,包含请求报文
                InputStream inputStream = socket.getInputStream();
                Request request=new Request(inputStream);
                request.parse();
                //输出流,向浏览器写入输出报文
                OutputStream outputStream = socket.getOutputStream();
                Response response=new Response(outputStream);
                response.setRequest(request);
                response.sendStaticResource();

                socket.close();
                shutdown=request.getUri().equals(SHUTDOWN_COMMAND);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

2.Request

package demon1;

import java.io.IOException;
import java.io.InputStream;

public class Request {
    /**
     * 输入流
     */
    private InputStream input;

    /**
     * 请求的资源
     */
    private String uri;

    public Request(InputStream input) {
        this.input = input;
    }

    /**
     * 解析报文方法
     */
    public void parse(){
        StringBuilder stringBuilder = new StringBuilder(2048);
        int readSum=0;
        byte[] buffer=new byte[2048];
        try {
            readSum= input.read(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        }
        for(int j=0;j<readSum;j++){
            stringBuilder.append((char) buffer[j]);
        }
        //解析请求资源
        uri=parseUri(stringBuilder.toString());
        System.out.println(uri);
    }

    private String parseUri(String requestString){

        int index1,index2=0;
        index1=requestString.indexOf(' ');
        if(index1!=-1){
            index2=requestString.indexOf(' ',index1+1);
        }
        if(index2>index1){
            //POST /chapter17/index.html HTTP/1.1
            //截取[)的内容,上述例子中截取内容为/chapter17/index.html
            return requestString.substring(index1+1,index2);
        }
        return null;
    }

    public String getUri(){
        return uri;
    }
}

3.Response

package demon1;

import java.io.*;

public class Response {
    private Request request;
    private OutputStream output;

    public Response(OutputStream output) {
        this.output = output;
    }
    public void setRequest(Request request){
        this.request=request;
    }

    /**
     * 发送静态资源给浏览器
     */
    public void sendStaticResource() throws IOException {
        byte[] bytes=new byte[1024];
        FileInputStream fis=null;
        try{
            System.out.println(PropertiesConst.WEB_ROOT);
            File file=new File(PropertiesConst.WEB_ROOT,request.getUri());
            if(file.exists()){
                fis = new FileInputStream(file);
                int ch=fis.read(bytes,0,1024);
                output.write("HTTP/1.1 200 OK\r\n\r\n".getBytes());
                while(ch!=-1){
                    output.write(bytes,0,ch);
                    ch=fis.read(bytes,0,1024);
                }
            }else {
                String errorMessge = "HTTP/1.1 404 FILE NOT Found\r\n" +
                        "Content-Type:text/html\r\n" +
                        "Content-Length:23\r\n" +
                        "\r\n" +
                        "<h1>file not found</h1>";
                output.write(errorMessge.getBytes());

            }
        }catch (Exception e){
            System.out.println(e.toString());
        }finally {
            if(fis!=null){
                fis.close();
            }
        }
    }
}

上述的代码是一个简单得web服务器,目前所实现得功能只能处理静态资源得访问,他的作用就是想用来说明servlet容器的运行原理是和他一样得,都是这么个大致的流程。

代码中设计到得问题注意事项:

1.绑定本地ip和端口号的时候,需要设置backlog的值,上述代码中给的是1(随便给的),这里解释一下?

https://www.cnblogs.com/qiumingcheng/p/9492962.html(转),内容详解此链接

2.在网络传输的过程中都是字节流,将其字符转成对应的字节去传送的。

最后附上HTTP请求报文和相应报文

请求报文:

例子:

 

响应报文

举例:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值