糟糕,又得重新认识上古技术--Servlet/JSP

Java Web 系列文章:

前言

上一篇讲解了Look My Eyes 最新IDEA快速搭建Java Web工程的两种方式,本篇分析如何通过Servlet、JSP快速渲染网页。
有些小伙伴可能疑惑了:Servlet、JPS是多古老的技术了,我SpringBoot一梭哈,还在这卷啥呢?其实不然,SpringBoot也是基于Servlet封装的,通过编写简单的Servlet,认识基本原理,后续可以更好地理解SpringBoot,同时也了解Java Web发展历程。
通过本篇文章,你将了解到:

  1. TCP/IP协议栈
  2. HTTP协议
  3. Servlet 处理Get/Post请求
  4. Servlet、JSP珠联璧合

1. TCP/IP协议栈

讲Servlet之前先来了解前置知识。
OSI 模型(Open Systems Interconnection Model,开放系统互连模型),它是由国际标准化组织(ISO)提出的一种网络通信框架,用于标准化网络协议和通信过程,总共有7层。
而事实上的网络模型是TCP/IP,它有四层:
image.png
当发起HTTP请求时,BS架构数据流转如下:
image.png
所谓协议,其实就是B、S双方约定好如何处理特定的数据规范,而这些规范是固化在网络栈(主要是传输层/网络层/数据链路层)。
Browser实现了HTTP客户端功能,而Server端实现了HTTP服务端的功能,两者通过HTTP协议进行了联动。

2. HTTP协议

HTTP是应用层协议,它提供了许多请求方式,以最常用的Get、Post请求为例。

Get 请求

Get 请求格式:
image.png

在浏览器地址栏里输入如下网址:

http://localhost:8080/java_web_war_exploded/myServlet?key=name

打开F12,查看网络选项:
image.png

GET—>请求方式
java_web_war_exploded/myServlet?key=name—>请求路径,其中?之后为key-value对,是Get请求携带的参数
HTTP/1.1 请求协议版本

Post 请求

image.png
Post比Get请求多了个请求体。
向服务端发起Post请求:
image.png
请求头里的Content-Type表明请求体的内容是什么类型,此处是表单类型,因此实际请求体为:
image.png

响应格式

当客户端发起Get/Post请求时,服务端需要返回针对该请求的响应。
image.png

实际内容如下:
image.png

HTTP/1.1—>协议版本
200—>状态码

Content-Type 用于指定响应体的内容格式,此处是html,而我们实际返回就是一个html内容:
image.png

3. Servlet 处理Get/Post请求

处理Get请求

前置知识了解之后,接下来进入Servlet世界探索吧。
现在有个需求:

在浏览器地址栏访问网页,该网址显示内容:Welcome to Java Web

分几个步骤实现该需求:

  1. 引入Servlet库
    在pom.xml里引入Servlet。
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>

此处是provided模式,意思是编译期会借助这个库使得能够正常编译,实际打包时不会打进JAR/WAR包里,因为Servlet相关库在Tomcat里有实现。
2. 编写Servlet类,处理Get请求

public class WelcomeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置响应内容类型为 HTML
        resp.setContentType("text/html");

        // 提取 PrintWriter 对象
        PrintWriter out = resp.getWriter();

        // 输出 HTML 内容
        out.println("<html>");
        out.println("<head><title>Welcome</title></head>");
        out.println("<body>");
        out.println("<h1>Welcome to Java Web</h1>");
        out.println("</body>");
        out.println("</html>");
    }
}
  1. 配置访问映射
    有了Servlet处理类,还需要将该Servlet与访问路径绑定起来,映射关系在web.xml里体现:
  <servlet>
    <servlet-name>WelcomeServlet</servlet-name>
    <servlet-class>com.example.WelcomeServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>WelcomeServlet</servlet-name>
    <url-pattern>/welcome</url-pattern>
  </servlet-mapping>

/welcome 表示访问的路径,访问该路径时映射到WelcomeServlet,而该Servlet实际的类是:com.example.WelcomeServlet,因此最终是它处理了Get请求。

  1. 查看效果
    在地址栏输入待访问的地址。
    image.png

可以看出:

当在浏览器发起Get请求后,服务端根据访问的路径找到对应处理的Servlet,该Servlet输出HTML内容,该内容作为HTTP响应返回到浏览器,浏览器解释执行该HTML,最终展示页面。

处理Post请求

WelcomeServlet 除了能够处理Get请求,也可以处理Post请求(通常一个Servlet只处理一种方式的请求,此处为了方便就一起描述了)。
只需要重写相关post方法:

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置响应内容类型为 HTML
        resp.setContentType("text/html");

        // 提取 PrintWriter 对象
        PrintWriter out = resp.getWriter();

        // 输出 HTML 内容
        out.println("<html>");
        out.println("<head><title>Welcome</title></head>");
        out.println("<body>");
        out.println("<h1>Welcome to Java Web I'm from post</h1>");
        out.println("</body>");
        out.println("</html>");
    }

浏览器访问默认发起的是Get请求,我们使用APIFOX进行Post请求:
image.png
同样的,Servlet正常处理了Post请求,并输出HTML内容。

4. Servlet、JSP珠联璧合

上面输出的都是静态页面,现在有个场景:需要将用户的姓名、邮箱展示出来。

  1. Get请求携带姓名和邮箱的数据
    浏览器访问如下地址
http://localhost:8080/java_web_war_exploded/welcome?name=fish&email=313@gmail.com
  1. Servlet处理Get请求并取出参数
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置响应内容类型为 HTML
        resp.setContentType("text/html");

        // 提取 PrintWriter 对象
        PrintWriter out = resp.getWriter();

        // 从请求中获取 name 和 email 参数
        String name = req.getParameter("name");
        String email = req.getParameter("email");

        // 输出 HTML 内容
        out.println("<html>");
        out.println("<head><title>Welcome</title></head>");
        out.println("<body>");
        out.println("<h1>Welcome to Java Web</h1>");

        // 展示用户的姓名和邮箱
        if (name != null && email != null) {
            out.println("<p>Name: " + name + "</p>");
            out.println("<p>Email: " + email + "</p>");
        } else {
            out.println("<p>No name or email provided.</p>");
        }

        out.println("</body>");
        out.println("</html>");
    }

最终效果:
image.png

虽然能够动态输出了页面,但页面渲染和业务逻辑耦合在Servlet里,如果有单独处理页面渲染的方式就好了。
于是JSP(Java Server Pages)出场了。
Servlet将与页面相关的渲染交给JSP,自己只处理逻辑相关的动作,而JSP则专注于页面,当然JSP最终也会编译为Servlet执行。

通过以下几个步骤使用JSP改造WelcomeServlet。

  1. 创建welcome.jsp
<html>
<head>
    <title>WelcomeJSP</title>
</head>
<body>
<h1>Welcome to Java Web In JSP</h1>
</body>
</html>

可以看出,JSP和html语法基本一致。
2. 将Servlet转发到JSP
当Servlet收到Get请求时,转发给JSP:

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取 RequestDispatcher 对象,用于转发请求到 welcome.jsp
        RequestDispatcher dispatcher = req.getRequestDispatcher("welcome.jsp");

        // 转发请求
        dispatcher.forward(req, resp);
    }

最终效果:
image.png

当然此时的JSP依然静态的,我们还需要处理name和email。
Servlet保持不变,只需要改动JSP:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>WelcomeJSP</title>
</head>
<body>
<h1>Welcome to Java Web In JSP</h1>

<%
    // 从请求中提取 name 和 email 参数
    String name = request.getParameter("name");
    String email = request.getParameter("email");
%>

<!-- 显示 name 和 email -->
<p>Name: <%= name != null ? name : "No name provided" %></p>
<p>Email: <%= email != null ? email : "No email provided" %></p>

</body>
</html>

<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>
使用的脚本语言是Java,最终输出html。

request是JSP内置的属性,我们可以像编写Java逻辑一样处理JSP里的逻辑。处理逻辑的地方需要使用<% %>框起来,表示需要执行Java 代码。

最后的效果:
image.png

可以看到,使用JSP之后,Servlet就简洁了许多,同时我们可以在JSP里方便设计各种样式的页面,而不用在Servlet写一堆输出html的代码。
因为JSP里可以执行Java代码,通过代码产生的结果渲染不同的页面,因此JSP是名副其实的动态页面。

本篇涉及代码均在此处

下一篇,将会以Servlet 写一个登录注册的的例子,用以加深对前后端交互的理解。
如果你觉得有帮助,请一键三连哦~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值