Java Web App体系结构

本文介绍了Java Web应用程序的体系结构,包括简单的Web服务器创建、路由/调度、HTTP请求处理等方面。作者通过创建自己的Java Web框架Takes,强调了面向对象、可测试性、不可变性和无反射原则。文章还探讨了Takes框架如何实现这些概念,包括请求分派、HTTP响应生成以及单元测试。Takes框架以电影拍摄的快照为灵感,将每次请求的处理比喻为一次获取。
摘要由CSDN通过智能技术生成

我曾经利用Servlet,JSP,JAX-RS,Spring框架,Play框架,带有Facelets的JSF和一些Spark框架。 以我的拙见,所有这些解决方案都远非面向对象和优雅的。 它们都充满了静态方法,无法测试的数据结构和肮脏的骇客。 因此,大约一个月前,我决定创建自己的Java Web框架。 我将一些基本原则纳入其基础:1)没有NULL,2)没有公共静态方法,3)没有可变的类以及4)没有类的转换,反射和instanceof运算符。 这四个基本原则应保证干净的代码和透明的体系结构。 这就是Takes框架的诞生方式。 让我们看看创建了什么以及它如何工作。

教父的制作(1972),弗朗西斯·福特·科波拉

教父的制作(1972),弗朗西斯·福特·科波拉

简而言之,Java Web体系结构

简单来说,这就是我理解Web应用程序体系结构及其组件的方式。

首先,要创建Web服务器,我们应该创建一个新的网络套接字 ,该套接字在某个TCP端口上接受连接。 通常是80,但是我将使用8080进行测试。 这是通过Java使用ServerSocket类完成的:

import java.net.ServerSocket;
public class Foo {
  public static void main(final String... args) throws Exception {
    final ServerSocket server = new ServerSocket(8080);
    while (true);
  }
}

这足以启动Web服务器。 现在,套接字已准备就绪并且正在侦听端口8080。当有人在其浏览器中打开http://localhost:8080时,将建立连接,浏览器将永远旋转其等待轮。 编译此代码段,然后尝试。 我们只是构建了一个简单的Web服务器,而没有使用任何框架。 我们尚未对传入的连接做任何事情,但是我们也不拒绝它们。 所有这些都在该server对象内对齐。 它是在后台线程中完成的。 这就是为什么我们需要将while(true)放在后面。 没有这种无休止的暂停,该应用程序将立即完成其执行,并且服务器套接字将关闭。

下一步是接受传入的连接。 在Java中,这是通过对accept()方法的阻塞调用来完成的:

final Socket socket = server.accept();

该方法正在阻塞其线程,并等待新的连接到达。 一旦发生这种情况,它将返回Socket的实例。 为了接受下一个连接,我们应该再次调用accept() 。 因此,基本上,我们的Web服务器应该像这样工作:

public class Foo {
  public static void main(final String... args) throws Exception {
    final ServerSocket server = new ServerSocket(8080);
    while (true) {
      final Socket socket = server.accept();
      // 1. Read HTTP request from the socket
      // 2. Prepare an HTTP response
      // 3. Send HTTP response to the socket
      // 4. Close the socket
    }
  }
}

这是一个无休止的循环,接受一个新的连接,理解它,创建一个响应,返回响应,然后再次接受一个新的连接。 HTTP协议是无状态的,这意味着服务器不应记住任何先前连接中发生的情况。 它关心的只是此特定连接中的传入HTTP请求。

HTTP请求来自套接字的输入流,看起来像是多行文本块。 如果读取套接字的输入流,将看到以下内容:

final BufferedReader reader = new BufferedReader(
  new InputStreamReader(socket.getInputStream())
);
while (true) {
  final String line = reader.readLine();
  if (line.isEmpty()) {
    break;
  }
  System.out.println(line);
}

您将看到如下内容:

GET / HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,ru;q=0.6,uk;q=0.4

客户端(例如Google Chrome浏览器)将此文本传递到已建立的连接中。 它连接到localhost端口8080,一旦连接就绪,它将立即将文本发送到其中,然后等待响应。

我们的工作是使用在请求中获得的信息来创建HTTP响应。 如果我们的服务器非常原始,那么我们基本上可以忽略请求中的所有信息,而只需返回“ Hello,world!”。 到所有请求(为简单起见,我使用IOUtils ):

import java.net.Socket;
import java.net.ServerSocket;
import org.apache.commons
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值