【javaweb发展】

一、什么是javaweb

  首先,客户端浏览器(Browser)到服务器(Client)是需要http协议沟通的。通过抓包工具查看一些http信息。

image

 

 可以看到在请求数据报文中,http请求包含了三个部分,第一部分叫请求行,包含请求方法,url,协议,协议版本等。第二部分叫请求头,第三部分叫请求体。客户端(浏览器)发起这样的http请求。再来看响应数据报文。

image

 一般来说,http响应包含了三个部分,第一部分叫响应行。第二部分叫响应头,第三部分叫响应体。一般来说,第三部分是html,类似以下数据:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>巴巴博弈</title>
</head>
<body>
<div id="app" class="fit">
    <router-view></router-view>
</div>
</body>
</html>

  那么在服务器端实现这样的http响应就能实现数据传输给客户端了,首先,http传输是基于tcp连接的,那么我们使用java自带的socket来写就行。以下是别人写好的代码(侵删)

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(8080); // 监听指定端口
        System.out.println("server is running...");
        for (;;) {
            Socket sock = ss.accept();
            System.out.println("connected from " + sock.getRemoteSocketAddress());
            Thread t = new Handler(sock);
            t.start();
        }
    }
}

class Handler extends Thread {
    Socket sock;

    public Handler(Socket sock) {
        this.sock = sock;
    }

    public void run() {
        try (InputStream input = this.sock.getInputStream()) {
            try (OutputStream output = this.sock.getOutputStream()) {
                handle(input, output);
            }
        } catch (Exception e) {
        } finally {
            try {
                this.sock.close();
            } catch (IOException ioe) {
            }
            System.out.println("client disconnected.");
        }
    }

    private void handle(InputStream input, OutputStream output) throws IOException {
        var reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
        var writer = new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8));
        // TODO: 处理HTTP请求
    }
}

  接下来只需要在handle中用reader读取http请求,用writer返回http响应即可实现服务器自动返回http数据。

private void handle(InputStream input, OutputStream output) throws IOException {
    System.out.println("Process new http request...");
    var reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
    var writer = new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8));
    // 读取HTTP请求:
    boolean requestOk = false;
    String first = reader.readLine();
    if (first.startsWith("GET / HTTP/1.")) {
        requestOk = true;
    }
    for (;;) {
        String header = reader.readLine();
        if (header.isEmpty()) { // 读取到空行时, HTTP Header读取完毕
            break;
        }
        System.out.println(header);
    }
    System.out.println(requestOk ? "Response OK" : "Response Error");
    if (!requestOk) {
        // 发送错误响应:
        writer.write("HTTP/1.0 404 Not Found\r\n");
        writer.write("Content-Length: 0\r\n");
        writer.write("\r\n");
        writer.flush();
    } else {
        // 发送成功响应:
        String data = "<html><body><h1>Hello, world!</h1></body></html>";
        int length = data.getBytes(StandardCharsets.UTF_8).length;
        writer.write("HTTP/1.0 200 OK\r\n");
        writer.write("Connection: close\r\n");
        writer.write("Content-Type: text/html\r\n");
        writer.write("Content-Length: " + length + "\r\n");
        writer.write("\r\n"); // 空行标识Header和Body的分隔
        writer.write(data);
        writer.flush();
    }
}

  像这样,监听特定端口,解析http请求,返回http数据报的服务器程序,就是web服务器。实际上使用时不用自己写服务器,我们有现成的web服务器-tomcat,以下是使用tomcat里边的servlet实现web服务的例子(需要注意的是servlet服务需要导入jar包,请查看自己的包管理器怎么导入servletAPI的jar包):

// WebServlet注解表示这是一个Servlet,并映射到地址/:
@WebServlet(urlPatterns = "/")
public class HelloServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // 设置响应类型:
        resp.setContentType("text/html");
        // 获取输出流:
        PrintWriter pw = resp.getWriter();
        // 写入响应:
        pw.write("<h1>Hello, world!</h1>");
        // 最后不要忘记flush强制输出:
        pw.flush();
    }
}

  可以看到,相比于自己写web服务,servlet简化了大量的操作。但是这样开发任然存在效率低下,配置时间长,代码耦合度高的弊端。

一、现代web开发。

  现代web开发是tomcat向上集成在spring,再向上集成在springboot。

  没有什么是增加中间层解决不了的,如果有,就在加一层。

  为了解决代码耦合的问题,我们将返回http数据报的部分划分为三个部分,也就是MVC架构。对于现代javaweb开发,一般三层架构是指controller-处理用户请求,返回响应。service-逻辑处理。mapper(DAO)-数据库CRUD。不管哪种代码设计架构,都只是一些规范,重点在于架构实现了什么样的效果,比如mvc架构实现了代码的部分解耦,但是层与层之间还是耦合的,比如在service层调用mapper层的类,必然会导入mapper的包,那么mapper包改名之后,service层也得修改名称。为了实现完全解耦,spring引入了一个中间层-IoC容器。将创建对象的事情交给IoC容器来做,这样代码就实现了完全解耦,可以任意修改一层的代码而不必改动其他使用了该层的代码。详情可以找之前的博客。

二、springcloud

  随着时代发展,springboot也不能很好解决大型、复杂且需要快速迭代和持续交付的项目开发。为了解决这样的问题,我们又加了四个中间层,Nacos(服务注册,在里面存ip:端口),OpenFeign服务调用(类似tomcat,实现底层协议书写(如http)),Sentinel(流量管理与安全层),RocketMQ(消息队列,实现异步通信)。

posted @ 2025-12-16 11:34  意外路过的番茄酱骑士  阅读(4)  评论(0)    收藏  举报