一、背景

  • Spring生态的强大与完善,使得大多数的Java程序员,在刚刚接触Java Web应用开发时,往往依赖于SSM、SpringBoot等各种高级框架。
  • Java Web的基础的体系结构是什么?到底是怎么运作的?这些高级的框架与基础的体系结构之间是什么关系?
  • 只有真正理清了这些底层基础的结构,才能完全理解高级框架的设计原理,在使用框架开发项目时做到事半功倍。
  • 本文旨在暂时抛开这些高级框架,重走Java Web底层之路。

二、Web应用

  • Web应用的基础模型
  1. 用户通过Web浏览器向某个Web应用发出一个请求
  2. Web服务器得到请求后,处理并查找资源,并向Web浏览器返回一个响应结果。

2.1 HTML

  • Web服务器需要对客户端的请求提供响应内容,Web浏览器需要将这些响应内容呈现给用户。两者需要形成统一的对话语言,Web应用中形成的共同的语言被称为HTML(HyperText Markup Language:超文本标记语言)。

  • HTML包含数十个标记,数千种标记属性,能过这些标记定义了网页内容的含义和结构;正是无数个具有相互链接的HTML网页构成了我们现在的互联网世界。

标记 描述
html 定义HTML文档的边界
head 定义HTML文档头部的边界
body 定义HTML文档本体的边界
tile 定义HTML文档本体的标题
form 定义一个表单
a 定义一个超链接
... ...
  1. <!-- HTML基础 -->
  2. <html>
  3. <head>
  4. <title>欢迎</title>
  5. </head>
  6. <body>
  7. <a href="https://www.baidu.com">百度</a>
  8. </body>
  9. </html>

2.2 HTTP

  • Web浏览器与Web服务器之间相互通信同样需要建立统一的协议:Web应用的标准协议被称为HTTP(Hyper Text Transfer Protocol)超文本传输协议。
  • HTTP协议规定了超文本传输所要遵守的规则:HTTP请求可发起常用的GET或者POST请求;HTTP的响应中可以包含HTML内容。

  1. curl https://www.baidu.com -v
  2. <!-- 通过HTTPURL地址www.baidu.com发起 GET请求-->
  3. > GET / HTTP/1.1
  4. > User-Agent: curl/7.29.0
  5. > Host: www.baidu.com
  6. > Accept: */*
  7. <!-- Web服务器HTTP响应-->
  8. < HTTP/1.1 200 OK
  9. < Accept-Ranges: bytes
  10. < Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
  11. < Connection: keep-alive
  12. < Content-Length: 2443
  13. < Content-Type: text/html
  14. < Date: Tue, 25 Aug 2020 04:04:01 GMT
  15. < Etag: "588603eb-98b"
  16. < Last-Modified: Mon, 23 Jan 2017 13:23:55 GMT
  17. < Pragma: no-cache
  18. < Server: bfe/1.0.8.18
  19. < Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
  20. <
  21. <!DOCTYPE html>
  22. <!--STATUS OK-->
  23. <html>
  24. <head>
  25. ...
  26. <title>百度一下,你就知道</title>
  27. </head>
  28. <body link=#0000cc>
  29. ...
  30. </body>
  31. </html>

2.3 URL

  • Web应用上的每个资源都有唯一的地址进行定位,被称为URL(Uniform Resource Locatiors)统一资源定位符。

    1. URL中可包含额外的参数,会追加到URL的最后,以?开头,以&分隔各个参数,如:http://www.web.com:8080/welcome/hello.html?name=jack&age=20
    2. Web服务器中的应用一般默认在80端口运行,端口号为80的在URL中可省略不书写。

2.4 Servlet

  • Servlet是Server Applet的简写,也被称为运行在服务端的小程序,通过Servlet程序可以生成动态Web内容,实现Java Web服务器功能的扩展。
  • Servlet需要依付于Servlet容器(比如Tomcat等)才能运行

2.4.1 编写第一个Servlet程序

  • Java Servlet是一个接口,定义了Java类被浏览器访问到的规则。

  • Java程序员自定义一个类,实现Servlet接口并重写接口中的方法,Web服务器(如Tomcat等)就可以识别并执行这个程序。

  • 创建JavaEE项目



  • 定义一个类,实现Servlet接口,实现或重写接口中的方法

  1. /**
  2. * HttpServlet
  3. *
  4. * @author zhuhuix
  5. * @date 2020-08-25
  6. */
  7. public class HttpServletDemo extends HttpServlet {
  8. // 重写Get请求方法
  9. @Override
  10. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  11. // 业务逻辑处理
  12. LocalDate date = LocalDate.now();
  13. // 动态输出HTML页面
  14. PrintWriter out = resp.getWriter();
  15. out.println("<html>" +
  16. "<body>" +
  17. "<h1>"+date.toString()+"</h1> " +
  18. "<h2>hello world</h2> " +
  19. "</body>" +
  20. "</html>"
  21. );
  22. }
  23. }
  • 在web.xml配置Servlet
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
  5. version="4.0">
  6. <!-- 配置Servlet -->
  7. <servlet>
  8. <servlet-name>http-demo</servlet-name>
  9. <servlet-class>demo.servlet.HttpServletDemo</servlet-class>
  10. </servlet>
  11. <servlet-mapping>
  12. <servlet-name>http-demo</servlet-name>
  13. <url-pattern>/http-demo</url-pattern>
  14. </servlet-mapping>
  15. </web-app>
  • 运行

  • 访问http://localhost:8080/servlet_war_exploded/http-demo路径

2.5 JSP

  • JSP(Java Server Pages)也是一种Java servlet,主要用于实现Java web应用程序的用户界面部分。通过结合HTML代码、XHTML代码、XML元素以及嵌入JSP操作和命令来编写JSP。简而言之,就是在HTML网页中嵌入了Java。
  • JSP页面可以与处理业务逻辑的 Servlet 一起使用,这种模式被Java servlet 模板引擎所支持
  1. <%@ page import="java.time.LocalDate" %>
  2. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  3. <html>
  4. <body>
  5. <h1><%= LocalDate.now()%></h1>
  6. <h2>hello world!!!</h2>
  7. </body>
  8. </html>
  1. public class HttpServletDemo extends HttpServlet {
  2. // 重写Get请求方法
  3. @Override
  4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  5. // 调用jsp页面
  6. req.getRequestDispatcher("/index.jsp").forward(req,resp);
  7. }
  8. }

2.6 容器

  • 容器就是程序运行时需要的环境;比如Tomcat就是一个Servlet/JSP的容器。
  • Servlet 容器具备管理Servlet对象的功能。
    1. 通信支持:利用容器提供的方法,可以轻松实现Web服务器与Servlet进行通信,无需自己建立ServerSocket、监听端口,字节流传输等底层协议。
    2. 生命周期管理: 容器会负责Servlet的实例化、初始化、调用方法、释放资源等控制。
    3. 多线程支持:容器接收到每个Servlet请求时建立新的线程,并协调线程运行。
    4. 配置式管理:利用容器支持的xml进行配置式管理,在环境改变时,无需硬性修改程序及编译程序。



2.7 URL映射到Servlet

  • 通过JavaEE的XML配置部署文件中的元素〈servlet〉及 〈servlet-mapping〉,把URL映射到对应的Servlet上。

三、一个完整的Java Web基础应用

  1. /**
  2. * HttpServlet
  3. *
  4. * @author zhuhuix
  5. * @date 2020-08-25
  6. */
  7. public class HttpServletDemo extends HttpServlet {
  8. // 重写Get请求方法,返回一个表单页面
  9. @Override
  10. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
  11. req.getRequestDispatcher("/form.jsp").forward(req, resp);
  12. }
  13. // 重写Post请求方法,提交表单上的数据,并返回结果页面
  14. @Override
  15. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  16. String name = req.getParameter("name");
  17. Integer age = Integer.parseInt(req.getParameter("age"));
  18. if (name != null && age != null) {
  19. User user = new User(name, age);
  20. req.setAttribute("name", name);
  21. req.setAttribute("age", age);
  22. if (user.checkName()) {
  23. req.setAttribute("result","登记成功");
  24. }else {
  25. req.setAttribute("result","登记失败:名称中包含非法字符");
  26. }
  27. RequestDispatcher view = req.getRequestDispatcher("/result.jsp");
  28. view.forward(req, resp);
  29. }
  30. }
  31. }
  1. /**
  2. * 用户类
  3. */
  4. public class User {
  5. private String name;
  6. private Integer age;
  7. public User() {
  8. }
  9. public User(String name, Integer age) {
  10. this.name = name;
  11. this.age = age;
  12. }
  13. // 判断名称是否非法
  14. public Boolean checkName() {
  15. return !this.name.contains("admin");
  16. }
  17. public String getName() {
  18. return name;
  19. }
  20. public void setName(String name) {
  21. this.name = name;
  22. }
  23. public Integer getAge() {
  24. return age;
  25. }
  26. public void setAge(Integer age) {
  27. this.age = age;
  28. }
  29. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
  5. version="4.0">
  6. <servlet>
  7. <servlet-name>http-demo</servlet-name>
  8. <servlet-class>demo.servlet.HttpServletDemo</servlet-class>
  9. </servlet>
  10. <servlet-mapping>
  11. <servlet-name>http-demo</servlet-name>
  12. <url-pattern>/http-demo</url-pattern>
  13. </servlet-mapping>
  14. </web-app>
  1. <!--表单页面-->
  2. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  3. <html>
  4. <head>
  5. <title>登记用户</title>
  6. </head>
  7. <body>
  8. <form method="post" action="http-demo">
  9. 姓名:<input name="name" type="text"/><br>
  10. 年龄:<input name="age" type="text"/><br>
  11. <input type="submit" title="提交" >
  12. </form>
  13. </body>
  14. </html>
  1. <!--结果页面-->
  2. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  3. <html>
  4. <head>
  5. <title>登记结果</title>
  6. </head>
  7. <body>
  8. <h2>姓名:${name} 年龄:${age} ${result} </h2><br>
  9. </body>
  10. </html>



四、小结

  • 以上三个小节,只对Java Web中的基础要素及这些要素组成的最小体系结构做了回顾。
  • Java EE中Web开发的要点还有很多,比如Servlet的请求与响应的具体细节、JSTL语法,过滤器与监听器,Session与Cookie等。
  • 在重度依赖各种框架开发的今天,谨以此文抛砖引玉,让我们先抛开框架,重拾基础。

重拾Java Web应用的基础体系结构的更多相关文章

  1. 【Java】 重拾Java入门

    [概论与基本语法] 取这个标题,还是感觉有些大言不惭.之前大三的时候自学过一些基本的java知识,大概到了能独立写一个GUI出来的水平把,不过后来随着有了其他目标,就把这块放下了.之后常年没有用,早就 ...

  2. java web filter 之一 基础实现

    本文主要对filter的基本使用进行了讲解,其中涉及到了 filter是什么 一个filter处理一个jsp 多个filter处理一个jsp filter是什么 Filter 是java下的一种过滤器 ...

  3. 重拾java系列一java基础(1)

    前言,不知不觉,从接触java到工作至今已有两年的时间,突然感觉自己的基础知识还很薄弱,有些知识虽然知道,但是停留在表面上,没有深挖,或者实践过,感觉掌握的很肤浅,而且时间一长,就觉得忘记了,我觉得这 ...

  4. 重拾java系列一java基础(3)

    这一章主要复习下以前所接触的算法, (1)选择排序法:在要排序的一组数中,选出最小的一个数与第一个位置的数交换:然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较 ...

  5. 重拾java系列一java基础(2)

    1.分支流程控制 if(布尔表达式/分支条件){  //语句块} if(布尔表达式/分支条件){  //语句块1}else{  //语句块2} if(条件1){  //语句块1}else if(条件2 ...

  6. 重拾java系列一java基础(4)

    本章主要回顾一些类的相关知识: (1)static: static 静态的: 属于类的资源, 使用类名访问.  静态属性: 只有一份的变量  静态方法: 是属于类方法, 可以使用类名直接访问. 静态方 ...

  7. 重拾java之路之webservice

         Web service平台是一套标准,它定义了应用程序如何在Web上实现互操作性.你可以用任何你喜欢的语言,在任何你喜欢的平台上写Web service ,只要我们可以通过Web servi ...

  8. Java Web(一) 前言及体系结构

    Web应用程序 Web程序是什么 Web应用程序就是一般所说的网站,由服务器,客户端浏览器以及网络组成.但Web程序又不是一般意义的网站,一般的网站是提供信息服务,重在内容,程序往往比较简单,但商用的 ...

  9. Java web struct入门基础知识

    1.Struts2的前身是Opensymphony的Webwork2,实际上Strut和Webwork2合并后形成Struts2.   2.一个HelloWord示例 1)创建Web应用,所需要的Ja ...

随机推荐

  1. __getattribute__小例子

    class student(object): def __init__(self,name=None,age=None): self.name = name self.age = age def __ ...

  2. PHP ftp_size() 函数

    定义和用法 ftp_size() 函数返回 FTP 服务器上指定文件的大小. 该函数以字节返回指定文件的大小,如果出错则返回 -1. 语法 ftp_size(ftp_connection,file) ...

  3. PDOStatement::fetchColumn

    PDOStatement::fetchColumn — 从结果集中的下一行返回单独的一列.(PHP 5 >= 5.1.0, PECL pdo >= 0.9.0)高佣联盟 www.cgewa ...

  4. [转]17个常用的JVM参数

    作者:SimpleSmile_5177 来源:https://www.cnblogs.com/Simple-Object/p/10272326.html 前言 大家都知道,jvm在启动的时候,会执行默 ...

  5. 笨办法学python3代码练习ex23.py 字符串字节串字符编码

    首先简单说一下字符编码的问题.平常遇到比较多的就是ASCII码(全称:美国信息交换标准码).ASCII码使用一个字节(8位)来表示一些常见的数字.英文字母以及一些控制字符.英语用128个符号编码就够了 ...

  6. Error: Cannot perform an interactive login from a non TTY device

    zhangjiawen@zhangjiawen-PC MINGW64 /d/Docker Toolbox$ docker login --username=绝世随机变量 registry.cn-han ...

  7. Android Studio简单的登陆界面

    在app->src->main->java里面找到MainActivity.java,将鼠标放到activity-main上按住Ctrl后单击跳转到activity-main.xml ...

  8. HTTP POST 请求的两种编码格式:application/x-www-form-urlencoded 和 multipart/form-data

    在常见业务开发中,POST 请求常常在这些地方使用:前端表单提交时.调用接口代码时和使用 Postman 测试接口时.我们下面来一一了解: 一.前端表单提交时 application/x-www-fo ...

  9. MinIO很强-让我放弃FastDFS拥抱MinIO的8个理由

    目前可用于文件存储的网络服务选择有很多,比如阿里云OSS.七牛云.腾讯云等等,但是收费都有点小贵.为了帮公司节约成本,之前一直是使用fastDFS作为文件服务器,准确的说是图片服务器.直到我发现了Mi ...

  10. DIFF算法浅析(三)在react中的实现

    在虚拟dom中diff的实现. 分别从4个方面: DIFF抽象概念(概述.时间复杂性分析) 在Vue2中的实现(版本2.6.11.必要性.执行方式) 在React中的实现(版本16.13.1,必要性. ...