Servlet详解

目录

  • 一、第一个Servlet程序
    • 1.1 创建项目
    • 1.2引入依赖
    • 1.3 创建目录
    • 1.4 编写代码
    • 1.5 打包程序
    • 1.6 部署程序
    • 1.7 验证程序
  • 二、Servlet 运行原理
  • 三、Tomcat 的伪代码
  • 四、Servlet API 详解
    • 4.1 HttpServlet
    • 4.2 HttpServletRequest
      • 获取 POST 请求中的参数(1)
      • 获取 POST 请求中的参数(2)
    • 4.2 HttpServletResponse

Servlet 是一种 实现动态页面的技术. 是一组 Tomcat 提供给程序猿的 API, 帮助程序猿简单高效的开发一个 web app.

动态页面与静态页面:
静态页面也就是内容始终固定的页面. 即使用户不同/时间不同/输入的参数不同 , 页面内容也不会发生变化. (除非网站的开发人员修改源代码, 否则页面内容始终不变).
动态页面指的就是 用户不同/时间不同/输入的参数不同, 页面内容会发生变化。

Servlet 就是 Tomcat 这个 HTTP 服务器提供给 Java 的一组 API, 来完成构建动态页面这个任务。

一、第一个Servlet程序

1.1 创建项目

使用 IDEA 创建一个 Maven 项目.

  1. 菜单 -> 文件 -> 新建项目 -> Maven

1.2引入依赖

Maven 项目创建完毕后, 会自动生成一个 pom.xml 文件.我们需要在 pom.xml 中引入 Servlet API 依赖的 jar 包.
1)在中央仓库 https://mvnrepository.com/ 中搜索 “servlet”, 一般第一个结果就是:
Servlet详解_第1张图片
2)选择版本. 一般我们使用 3.1.0 版本:
Servlet详解_第2张图片

Servlet 的版本要和 Tomcat 匹配.如果我们使用 Tomcat 8.5, 那么就需要使用 Servlet 3.1.0
可以在 http://tomcat.apache.org/whichversion.html 查询版本对应关系.

3)把中央仓库中提供的 xml 复制到项目的 pom.xml 中.一定要把xml写入dependencies内.
Servlet详解_第3张图片
修改后的pom.xml为:


<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>

    <groupId>org.examplegroupId>
    <artifactId>servlet_projectartifactId>
    <version>1.0-SNAPSHOTversion>

    <properties>
        <maven.compiler.source>8maven.compiler.source>
        <maven.compiler.target>8maven.compiler.target>
    properties>

    <dependencies>
        
        <dependency>
            <groupId>javax.servletgroupId>
            <artifactId>javax.servlet-apiartifactId>
            <version>3.0.1version>
            <scope>providedscope>
        dependency>

    dependencies>

    <packaging>warpackaging>
    <build>
        <finalName>hello102finalName>
    build>
project>

标签内部放置项目依赖的 jar 包. maven 会自动下载依赖到本地

1.3 创建目录

当项目创建好了之后, IDEA 会帮我们自动创建出一些目录.
此时,还需创建:

  1. 创建 webapp 目录
    在 main 目录下, 和 java 目录并列, 创建一个 webapp 目录。
    2)创建 web.xml
    然后在 webapp 目录内部创建一个 WEB-INF 目录, 并创建一个 web.xml 文件。
    Servlet详解_第4张图片
  2. 编写 web.xml
    web.xml 中拷贝以下代码.
DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Applicationdisplay-name>
web-app>

webapp 目录就是未来部署到 Tomcat 中的一个重要的目录. 当前我们可以往 webapp 中放一些静态资源, 比如 html , css 等.
在这个目录中还有一个重要的文件 web.xml. Tomcat 找到这个文件才能正确处理 webapp 中的动态资源 .

1.4 编写代码

在 java 目录中创建一个类 HelloServlet, 代码如下:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created With IntelliJ IDEA
 * Description:
 * Users: yyyyy
 * Date: 2022-05-20
 * Time: 9:57
 */
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("hello world");
        resp.getWriter().write("hello world"  + System.currentTimeMillis());
    }
}
  • 创建一个类 HelloServlet , 继承自 HttpServlet.
  • 在这个类上方加上 @WebServlet("/hello") 注解, 表示 Tomcat 收到的请求中, 路径为 /hello的请求才会调用 HelloServlet 这个类的代码. (这个路径未包含 Context Path)
  • 重写 doGet 方法. doGet 的参数有两个, 分别表示收到的 HTTP 请求 和要构造的HTTP 响应. 这个方法会在 Tomcat 收到 GET 请求时触发.
  • HttpServletRequest 表示 HTTP 请求. Tomcat 按照 HTTP 请求的格式把 字符串 格式的请求转成了一个 HttpServletRequest 对象. 后续想获取请求中的信息(方法, url, header, body 等) 都是通过这个对象来获取.
  • HttpServletResponse 表示 HTTP 响应. 代码中把响应对象构造好(构造响应的状态码, header,body 等)
    resp.getWriter() 会获取到一个流对象, 通过这个流对象就可以写入一些数据, 写入的数据会被构造成一个 HTTP 响应的 body 部分, Tomcat 会把整个响应转成字符串, 通过 socket 写回给浏览器.

1.5 打包程序

使用 maven 进行打包. 打开 maven 窗口 (一般在 IDEA 右侧就可以看到 Maven 窗口, 如果看不到的话,可以通过 菜单 -> View -> Tool Window -> Maven 打开),然后展开 Lifecycle , 双击 package 即可进行打包.
Servlet详解_第5张图片
打包成功后, 可以看到在 target 目录下, 生成了一个 jar 包,这样的 jar 包并不是我们需要的, Tomcat 需要识别的是另外一种 war 包格式.

war 包和 jar 包的区别
jar 包是普通的 java 程序打包的结果. 里面会包含一些 .class 文件.
war 包是 java web 的程序, 里面除了会包含 .class 文件之外, 还会包含 HTML, CSS, JavaScript, 图片, 以及其他的 jar 包. 打成 war 包格式才能被 Tomcat 识别.

所以,需要在 pom.xml 中新增一个 packing 标签, 表示打包的方式是打一个 war 包,在 pom.xml 中再新增一个 build 标签, 内置一个 finalName 标签, 表示打出的 war 包的名字是hello102(完整代码如1.2中所示):
Servlet详解_第6张图片
重新使用 maven 打包, 可以看到生成的新的 war 包的结果:
Servlet详解_第7张图片

1.6 部署程序

把 war 包拷贝到 Tomcatwebapps 目录下.启动 Tomcat , Tomcat 就会自动把 war 包解压缩.

一种更方便的部署方式,直接利用Smart Tomcat插件也可以:
Servlet详解_第8张图片

Servlet详解_第9张图片

1.7 验证程序

此时通过浏览器访问 http://127.0.0.1:8080/hello102/hello,就可以看到结果了。
Servlet详解_第10张图片
URL 中的 PATH 分成两个部分, 其中 hello102为 Context Path, hello 为 Servlet Path.

什么时候浏览器发的是GET请求?

  1. 直接在地址栏里,输入URL
  2. 通过a标签跳转~
  3. 通过img/link/script…
  4. 通过form表单, method指定为GET
  5. 通过ajax, type指定为GET

什么时候浏览器发的是POST请求?

  1. 通过form表单, method指定为POST
  2. 通过ajax, type指定为POST

二、Servlet 运行原理

在 Servlet 的代码中我们并没有写 main 方法, 那么对应的 doGet 代码是如何被调用的呢? 响应又是如何返回给浏览器的?

Servlet详解_第11张图片
当浏览器给服务器发送请求的时候, Tomcat 作为 HTTP 服务器, 就可以接收到这个请求。
HTTP Server (Tomcat)在调用Servlet,尤其是在处理请求的时候。

HTTP 协议作为一个应用层协议, 需要底层协议栈来支持工作. 如下图所示

Servlet详解_第12张图片
Tomcat其实是一个应用程序.运行在用户态的普通进程(Tomcat其实也是一个Java进程).
用户写的代码(根据请求计算相应),通过Servlet和Tomcat进行交互.Tomcat进一步的和浏览器之间的网络传输,仍然是之前学过的网络原理中的那一套(封装和分用).
Servlet详解_第13张图片

  1. 接收请求:
  • 用户在浏览器输入一个 URL, 此时浏览器就会构造一个 HTTP 请求.
  • 这个 HTTP 请求会经过网络协议栈逐层进行 封装成二进制的 bit 流, 最终通过物理层的硬件设备转换成光信号/电信号传输出去.
  • 这些承载信息的光信号/电信号通过互联网上的一系列网络设备, 最终到达目标主机(这个过程也需要网络层和数据链路层参与).
  • 服务器主机收到这些光信号/电信号, 又会通过网络协议栈逐层进行 分用, 层层解析, 最终还原成HTTP 请求. 并交给 Tomcat 进程进行处理(根据端口号确定进程)
  • Tomcat 通过 Socket 读取到这个请求(一个字符串), 并按照 HTTP 请求的格式来解析这个请求, 根据请求中的 Context Path 确定一个 webapp, 再通过 Servlet Path 确定一个具体的 类. 再根据当前请求的方法 (GET/POST/…), 决定调用这个类的 doGet 或者 doPost 等方法. 此时我们的代码中的doGet / doPost 方法的第一个参数 HttpServletRequest 就包含了这个 HTTP 请求的详细信息.
  1. 根据请求计算响应:
    在我们的 doGet / doPost 方法中, 就执行到了我们自己的代码. 我们自己的代码会根据请求中的一些信息, 来给 HttpServletResponse 对象设置一些属性. 例如状态码, header, body 等.
  2. 返回响应:
  • 我们的 doGet / doPost 执行完毕后, Tomcat 就会自动把 HttpServletResponse 这个我们刚设置好的对象转换成一个符合 HTTP 协议的字符串, 通过 Socket 把这个响应发送出去.
  • 此时响应数据在服务器的主机上通过网络协议栈层层 封装, 最终又得到一个二进制的 bit 流, 通过物理层硬件设备转换成光信号/电信号传输出去.
  • 这些承载信息的光信号/电信号通过互联网上的一系列网络设备, 最终到达浏览器所在的主机(这个过程也需要网络层和数据链路层参与).
  • 浏览器主机收到这些光信号/电信号, 又会通过网络协议栈逐层进行 分用, 层层解析, 最终还原成HTTP 响应, 并交给浏览器处理.
  • 浏览器也通过 Socket 读到这个响应(一个字符串), 按照 HTTP 响应的格式来解析这个响应. 并且把body 中的数据按照一定的格式显示在浏览器的界面上.

三、Tomcat 的伪代码

Tomcat 初始化流程

  1. 让Tomcat先从指定的目录中找到所有要加载的Servlet类,前面部署的时候,是把Servlet代码编译成了.class,然后打了war包,然后拷贝到了webapps里面,Tomcat就会从webapps里来找到那些.class对应的Servlet类,并且需要进行加载。
  2. 根据刚才类加载的结果,给这些类创建Servlet 实例.
  3. 实例创建好之后,就可以调用当前Servlet 实例的init方法了.init是Servlet自带的方法.默认情况下init啥都不干.咱们在继承一个HttpServlet的时候,也可以自己重写init,就可以在这个阶段帮我们做一些初始化工作了.
  4. 创建TCP socket,监听8080端口,等待有客户端来连接.
  5. 如果循环退出了,Tomcat也要结束了.就会依次循环调用每个Servletdestroy方法.

Tomcat 处理请求流程:
Servlet详解_第14张图片

Servlet 的 service 方法的实现

class Servlet {
public void service(HttpServletRequest req, HttpServletResponse resp) {
	String method = req.getMethod();
	if (method.equals("GET")) {
		doGet(req, resp);
		} else if (method.equals("POST")) {
			doPost(req, resp);
		} else if (method.equals("PUT")) {
			doPut(req, resp);
		} else if (method.equals("DELETE")) {
			doDelete(req, resp);
		}
	......
	}
}

Servlet 的 service 方法内部会根据当前请求的方法, 决定调用其中的某个 doXXX 方法.
在调用 doXXX 方法的时候, 就会触发 多态 机制, 从而执行到我们自己写的子类中的 doXXX 方法

在上面这整套流程过程中,涉及到了关于Servlet的关键方法,主要有三个.

  • init:初始化阶段,对象创建好了之后,就会执行到.用户可以重写这个方法,来执行一些初始化逻辑.
  • service:在处理请求阶段来调用.每次来个请求都要调用一次service
  • destroy:退出主循环, tomcat结束之前会调用,用来释放资源.

上述几个关键的方法,就称为Servlet的生命周期

四、Servlet API 详解

4.1 HttpServlet

核心方法
Servlet详解_第15张图片
代码示例: 处理 GET 请求

创建一个MethodServlet 类:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@WebServlet("/method")
public class MethodServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html; charset=utf-8");
        resp.getWriter().write("post 响应");

    }
}

创建一个test.html:

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js">script>
    <script>
        $.ajax({
            type: 'post',
            url: 'method',
            success: function (body) {
                console.log(body);
            }
        });
    script>
body>
html>

在浏览器中输入URL,访问页面:
Servlet详解_第16张图片
可以在控制台中看到结果:
Servlet详解_第17张图片

4.2 HttpServletRequest

当 Tomcat 通过 Socket API 读取 HTTP 请求(字符串), 并且按照 HTTP 协议的格式把字符串解析成HttpServletRequest 对象.

HttpServletRequest对应到一个HTTP请求.HTTP请求中有啥,这里就有啥。
HttpServletResponse 对应到一个HTTP响应.HTTP响应中有啥,这里就有啥。

核心方法

方法 描述
String getProtocol() 返回请求协议的名称和版本
String getMethod() 返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT
String getRequestURI() 从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请求的 URL 的一部分
String getContextPath() 返回指示请求上下文的请求 URI 部分。
String getQueryString() 返回包含在路径后的请求 URL 中的查询字符串,得到完整的查询字符串
Enumeration getParameterNames() 返回一个 String 对象的枚举,包含在该请求中包含的参数的名称,得到所有的key,以 Enum的方式来表示.
String getParameter(String name) 以字符串形式返回请求参数的值,或者如果参数不存在则返回null ,根据key来拿到value
String[] getParameterValues(String name) 返回一个字符串对象的数组,包含所有给定的请求参数的值,如果参数不存在则返回 null
Enumeration getHeaderNames() 返回一个枚举,包含在该请求中包含的所有的头名
String getHeader(String name) 以字符串形式返回指定的请求头的值
String getCharacterEncoding() 返回请求主体中使用的字符编码的名称
String getContentType() 返回请求主体的 MIME 类型,如果不知道类型则返回 null
int getContentLength() 以字节为单位返回请求主体的长度,并提供输入流,或者如果长度未知则返回 -1
InputStream getInputStream() 用于读取请求的 body 内容. 返回一个 InputStream 对象

通过上面这些方法可以获取到一个请求中的各个方面的信息.

注意: 请求对象是服务器收到的内容, 不应该修改. 因此上面的方法也都只是 “读” 方法, 而不是 "写"方法.

代码示例: 打印请求信息

创建一个showRequest类:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;


@WebServlet("/showRequest")
public class ShowRequest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("

首行部分

"
); stringBuilder.append(req.getProtocol()); stringBuilder.append("
"
); stringBuilder.append(req.getMethod()); stringBuilder.append("
"
); stringBuilder.append(req.getRequestURI()); stringBuilder.append("
"
); stringBuilder.append(req.getContextPath()); stringBuilder.append("
"
); stringBuilder.append(req.getQueryString()); stringBuilder.append("
"
); stringBuilder.append("

header 部分

"
); Enumeration<String> headerNames = req.getHeaderNames(); while (headerNames.hasMoreElements()){ String headerName = headerNames.nextElement(); String headerValue = req.getHeader(headerName); stringBuilder.append(headerName + ": " + headerValue + "
"
); } resp.setContentType("text/html; charset=utf-8"); resp.getWriter().write(stringBuilder.toString()); } }

部署程序.在浏览器通过 URL http://127.0.0.1:8080/hello102/showRequest访问, 可以看到:
Servlet详解_第18张图片

代码示例: 获取 GET 请求中的参数

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@WebServlet("/getParameter")
public class GetParameter extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String userId = req.getParameter("userId");
        String classId = req.getParameter("classId");
        resp.getWriter().write("userId = " + userId + ", classId = " + classId);
    }
}

在网页上输入URL:http://127.0.0.1:8080/hello102/getParameter,会得到如下页面所示:当没有 query string的时候, getParameter 获取的值为 null.
Servlet详解_第19张图片
输入URL:http://127.0.0.1:8080/hello102/getParameter?userId=10&classId=20
可以看到:
Servlet详解_第20张图片
此时说明服务器已经获取到客户端传递过来的参数。

获取 POST 请求中的参数(1)

POST 请求的参数一般通过 body 传递给服务器. body 中的数据格式有很多种:

  • x-www-form-urlencoded

如果请求是这种格式,服务器获取参数的方式和GET一样,也是getParameter.

如何在前端构造一个这样格式的请求?

  1. form表单

采用 form 表单的形式, 仍然可以通过 getParameter 获取参数的值.

首先创建类 PostGetParameterServlet 类:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@WebServlet("/postGetParameter")
public class PostGetParameterServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //假设前端传过来的参数为userId = 10&classId = 20
        String userId = req.getParameter("userId");
        String classId = req.getParameter("classId");
        resp.getWriter().write("userId = " + userId + ", classId = " + classId);
    }
}

然后创建 tes.html, 放到 webapp 目录中:

  <form action="postGetParameter" method="post">
        <input type="text" name="userId">
        <input type="text" name="classId">
        <input type="submit" value="提交">
    form>

在浏览器中输入URL:http://127.0.0.1:8080/hello102/test.html,并点击提交按钮,可以看到跳转到了新的页面, 并显示出了刚刚传入的数据。
Servlet详解_第21张图片

Servlet详解_第22张图片
2) postman

  • json
    对于body是json的格式来说,手动处理比较麻烦,可以使用第三方的库来直接处理json格式数据.这里主要使用的库叫做Jackson (Spring官方推荐的库),通过mavenjackson这个库,给下载到本地并引入到项目中.
    Servlet详解_第23张图片
    Servlet详解_第24张图片
    在pom.xml中引入jackson依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>servlet_project</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>


        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.6.1</version>
        </dependency>


    </dependencies>

    <packaging>war</packaging>
    <build>
        <finalName>hello102</finalName>
    </build>
</project>

获取 POST 请求中的参数(2)

如果 POST 请求中的 body 是按照 JSON 的格式来传递, 那么获取参数的代码就要发生调整。

  1. 在浏览器前端代码(test.html)中,通过js 构造出body为json格式的请求
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>

    <input type="text" name="userId">
    <input type="text" name="classId">
    <input type="button" value="提交" id="submit">

    <script src="https://code.jquery.com/jquery-3.6.0.min.js">script>
    <script>
     
      let userIdInput = document.querySelector('#userId');
        let classIdInput = document.querySelector('#classId');
        let button = document.querySelector('#submit');
        button.onclick = function() {
            $.ajax({
                type: 'post',
                url: 'postJson',
                contentType: 'application/json',
                data: JSON.stringify({
                    userId: userIdInput.value,
                    classId: classIdInput.value
                }),
                success: function(body) {
                    console.log(body);
                }
            });
        }
    script>
body>
html>

2)在java后端代码中,通过jackson来进行处理
需要使用jackson把请求body 中的数据读取出来,并且解析成Java中的对象.

import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


class User{
    public  int userId;
    public  int classId;
}
@WebServlet("/postJson")
public class PostJsonServlet extends HttpServlet {
    //创建一个json的核心对象
    private   ObjectMapper objectMapper = new ObjectMapper();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //2.读取body中的请求,然后使用objectMapper来解析成需要的对象
        //readValue就是把json格式的字符串转换成java的对象
        //第一个参数对那个参数进行转换,第二个参数表示把这个json格式的字符串转换成哪个java对象
        User user = objectMapper.readValue(req.getInputStream(),User.class);
        resp.getWriter().write("userId = " + user.userId + ", classId = " + user.classId);

    }
}

在这里插入图片描述

readValue是怎么完成转换的?
1.先把getInputStream对应的流对象里面的数据都读取出来;
2.针对这个json字符串进行解析,从字符串=>键值对;
3遍历这个键值对,依次获取到每一个key 。根据这个key 的名字,和User类里面的属性名字对比一下,看有没有匹配的名字!!如果发现匹配的属性,则把当前key对应的value赋值到该User类的属性中(赋值的过程中同时会进行类型转换),如果没有匹配的属性,就跳过,取下一个key.
4.当把所有的键值对都遍历过之后,此时User对象就被构造的差不多了.

4.2 HttpServletResponse

Servlet 中的 doXXX 方法的目的就是根据请求计算得到相应, 然后把响应的数据设置到HttpServletResponse 对象中.然后 Tomcat 就会把这个 HttpServletResponse 对象按照 HTTP 协议的格式 转成一个字符串, 并通过Socket 写回给浏览器.

核心方法
Servlet详解_第25张图片

代码示例: 设置状态码
实现一个程序, 用户在浏览器通过参数指定要返回响应的状态码.

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/status")
public class StatusServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setStatus(200);
        resp.getWriter().write("hello");
    }
}

Servlet详解_第26张图片
服务器返回的状态码,只是在告诉浏览器,当前的响应是个啥状态.并不影响浏览器照常去显示body中的内容。

代码示例: 自动刷新
实现一个程序, 让浏览器每秒钟自动刷新一次. 并显示当前的时间戳.
创建 AutoRefreshServlet 类:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@WebServlet("/autoRefresh")
public class AutoRefreshServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setHeader("Refresh","1");
        resp.getWriter().write("timeStamp" + System.currentTimeMillis());
    }
}

部署程序, 通过 URL :http://127.0.0.1:8080/hello102/autoRefresh访问, 可
以看到浏览器每秒钟自动刷新一次:
Servlet详解_第27张图片
代码示例: 重定向
实现一个程序, 返回一个重定向 HTTP 响应, 自动跳转到另外一个页面.
创建 RedirectServlet 类:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //实现重定向,让浏览器自动跳转到搜狗浏览器
        resp.setStatus(302);
        resp.setHeader("Location","https://www.sogou.com");
 		//另一种更简单的重定向写法
        //resp.sendRedirect("https://www.sogou.com");
    }
}

浏览器界面输入URL:http://127.0.0.1:8080/hello102/redirect,可以看到页面跳转到搜狗主页:
Servlet详解_第28张图片
代码示例: 服务器版表白墙
对于表白墙来说,主要要提供两个接口:

  1. 告诉服务器,当前留言了一条啥样的数据(当用户点击提交按钮的时候.就会给服务器发送一个HTTP请求,让服务器把这个消息给存下来)
    约定好,为了实现这个效果,客户端要发送一个啥样的HTTP请求,服务器返回一个啥样的HTTP响应.

按照上述的思路发散开,有无数种方式来约定请求格式!!方法可以变,路径可以变,参数的名字也可以变.

Servlet详解_第29张图片
我们这里采取下面这种请求,响应方式:
Servlet详解_第30张图片

  1. 从服务器获取到,当前都有哪些留言数据(当页面加载,就需要从服务器获取到曾经存储的这些消息内容)
    Servlet详解_第31张图片
    确定好接口之后,就可以编写代码了,既需要编写后端代码,也需要编写前端代码.

对象和JSON字符串之间的转换
Java
objectMapper.readValue把 json字符串转成对象
objectMapper.writeValueAsString把对象转成json字符串
JS
JSON.parse把 json字符串转成对象JSON.
stringify把对象转成json字符串

创建数据库:
在这里插入图片描述

你可能感兴趣的:(网络,servlet,java,tomcat)