网站开发--详解Servlet

💕"Echo"💕
作者:Mylvzi
文章主要内容:网站开发–详解Servlet
在这里插入图片描述

一.基本介绍

tomcat是Java中开发服务器的重要的一个工具,任何开发的服务器都要部署在tomcat之上,可以说tomcat是所有服务器的底座,为了更好的操作http,tomcat对原生的api进行了封装,封装为Servlet*,通过servlet就可以非常方便的完成和http协议的祥光操作

关于Servlet的学习,主要学习以下三个类即可:

  1. HttpServlet
  2. HttpRequestServlet
  3. HttpResponseServlet

掌握好这三个类,就能很好的使用Servlet

二.HttpServlet

HttpServlet是Servlet中最核心的一个类,我们创建的用于进行交互的类都必须要继承于HttpServlet

在这里插入图片描述

HttpServlet中常用方法
在这里插入图片描述

  1. init()方法会在一个Servlet对象被创建好之后,自动的调用这个方法,完成初始化操作
  2. destroy()方法会在Servlet对象被销毁之前进行调用,完成一些释放资源的工作
  3. service()方法实际上并不会直接使用到,而是被doGet(),doPost()给替代

init(),destroy(),service()这三个方法在实际的开发中很少用到,都是tomcat自动的在合适的时机帮助我们调用的,这三个方法经常会出现到一个经典的面试题中:

经典面试题:Servlet的生命周期

Servlet的生命周期是指Servlet实例被创建出来到被销毁的过程,具体来说可以分为以下几点:

  1. Servlet实例的创建:当客户端发送请求,服务器就要创建出一个Servlet实例来处理请求,通过构造方法创建出一个Servlet实例
  2. 初始化:在实例被创建好之后,会自动调用init()方法,来完成一些初始化操作,比如:读取配置文件,数据库的连接,一些资源的初始化
  3. 处理请求:当有客户端的http请求发送到服务器时,Servlet会先调用service()方法,判断请求的具体类型(根据请求的方法),service()方法就像是火车的中转站一样,看你的目的是什么,再给你对应的路线.这里也是一样,如果请求是GET方法,就会交给代码中的doGet()方法处理,如果是POST请求,就会交给doPost()方法
  4. 实例的销毁:当我们不再使用Servlet实例时(客户端不再有请求发送过来/人为关闭),先调用destroy()方法,做一些清理工作,比如数据库的断开,资源释放等

这个过程类似于生命周期中的起始、成长、运行和结束阶段,每个阶段都有其特定的任务和目的。

总的来说,我们所写的代码都要继承于HttpServlet这个类,重写里面的方法,并将重写的方法插入到tomcat已有的框架之中,我们只需关注数据处理部分,其余操作都是tomcat自动帮助我们完成

二.HttpServletRequest

1.介绍

HttpServletRequest表示一个Http请求类,用于接受从客户端传输过来的http请求

HttpServletRequest中的很多属性和请求头的相关属性相同,理解好请求头中的相关属性有助于学习HttpServletRequest类

一个Http请求由四部分组成:

  1. 首行 = 方法 + URL + 版本号
  2. 请求头:由键值对组成
  3. 空行
  4. body

2.HttpServletRequest常用方法介绍

在这里插入图片描述

在这里插入图片描述

1.获取首行信息和header中的数据**

@WebServlet("/request1")
public class RequestParameter extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 尝试获取请求报文中的详细信息
        StringBuffer stringBuffer = new StringBuffer();// 这个是线程安全的

        // 1.获取首行信息
        stringBuffer.append(req.getMethod());
        stringBuffer.append("<br>");// <br>是html中的换行标签
        stringBuffer.append(req.getRequestURI());
        stringBuffer.append("<br>");
        stringBuffer.append(req.getProtocol());
        stringBuffer.append("<br>");
        
        // 2.获取请求头信息
        Enumeration<String> enumeration = req.getHeaderNames();
        while (enumeration.hasMoreElements()){// 利用迭代器访问每一个头部key
            String key = enumeration.nextElement();
            String val = req.getHeader(key);// 获取key的值
            stringBuffer.append(key + ":" + val + "<br>");
        }

        resp.getWriter().write(stringBuffer.toString());
    }
}

获取结果:
在这里插入图片描述

总结:
对于请求报文来说,获取首行中的信息(版本号/方法/URL),可以直接通过指定的get方法来获取,获取请求头(header)中内容,可以利用迭代器,将请求头中的所有键值对都存储到一个集合之中,再利用getHeader方法,指定参数,来获取对应的value值

2.获取请求报文中的query string**

query string,译为查询字符串,往往和用户的关键信息相关(登录密码),在日常的开发中,我们也经常利用到query string来完成一些业务上的逻辑,所以获取请求报文中的query string是一个很频繁且重要的操作

query string在请求报文中的位置是不固定的,具体位置取决于请求报文中的方法(method),如果方法是Get,query string就位于URL之中,如果方法是Post,query string就位于body之中

注意:实际上URL中是包含query string的,但是在servlet的getURL类似的方法中返回的是一个不携带query string的URL(可能是因为查询字符串这个操作过于频繁,就单独拿出来进行包装了)

1.方法为Get

说明:前后端交互的一个关键点在于前端和后端要对传输内容的格式都了然于胸,后端要知道前端是如何组织数据进行传输的

比如,规定好客户端发送的请求报文中的query string的格式是类似于:

username=zhangsan&password=123456

那么服务器这边就可以规定好的格式进行解析

代码演示:

@WebServlet("/request2")
public class GetRequestParameter extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取用户传输过来的query string
        // 假设用户传输过来的query string的格式是形如 username='lisi'&password='123'这样的形式
        // servlet会自动将query string中的所有内容存储到一个Map结构之中(键值对都存储到其中
        // 后端程序员只需通过getParameter()方法来获取具体的值即可
        // 注意你构造的query string内部不需要有引号!!!
        // 可以根据这个特性来完成很多操作  比如判断用户名是否正确
        // 在传输中文的时候最好传输urlencode之后的内容

        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println("username=" + username);
        System.out.println("password=" + password);
        
    }
}

在这里插入图片描述

当在浏览器中输入:“http://127.0.0.1:8080/testsevlet/request2?username=zh&password=123”

在终端上显示:
在这里插入图片描述

如果不添加query string,显示的结果就是null

在这里插入图片描述

总结:

对于Get方法的请求,query string位于首行中,直接使用getParameter方法,并制定参数,就能获取到对应的值

2.方法为Post

此时query string位于body之中,而body的传输是有不同的格式的,对于不同格式的body,要采用不同的方法来进行解析,获取query string,常用的body格式有两种:

  1. form表单
  2. json
1.form表单格式

body通过form表单来进行数据的组织,内部是键值对,Content-Type:application/x-www-form-urlencoded

获取body中的内容和上面获取query string的方法一致

通过postman发送一个post请求
在这里插入图片描述
服务器的代码不变,打印结果为:
在这里插入图片描述

总结:如果body的格式是form表单,虽然此时query string位于body之中,但是也可以直接使用**getParameter()**方法,并指定参数来获取要查询的内容

2.json格式

如果body是通过json格式来进行组织,原生的Servlet是不支持解析json格式的数据的,此时需要进入第三方库jackson来帮助进行json格式数据解析(jackson也是spring官方推荐的用于解析JSON格式数据的第三方库)

准备:引入jackson依赖

在maven中找到jackson,选择合适的版本进行路径的复制,并在项目中的pom.xml中引入

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

在这里插入图片描述

在这里插入图片描述
引入好依赖之后就可以使用jackson中的api解析json格式的数据

具体的操作依赖于一个类和两个核心方法:
在这里插入图片描述
ObjectMapper(对象映射器),是JSON数据与Java对象转换的核心枢纽,在交互时,通过JSON字符串进行网络传输,处理逻辑,使用Java对象

站在服务器的角度,我们收到的数据是JSON字符串,需要将其转化为Java对象(read放哪发),来完成一些业务上的逻辑,完成后,还需要将处理好的Java对象转化为JSON字符串(write方法)

1.创建一个类 用于接收JSON字符串

// 创建一个类  用于接收JSON字符串
class Request {
    public String username;
    public String password;
}

2.交互

    // 创建出ObjectMapper实例
    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.将JSON字符串转化为Java对象
        Request request = objectMapper.readValue(req.getInputStream(),Request.class);

        // 2.获取query string
        String username = request.username;
        String password = request.password;

        // 3.打印
        String user = "username=" + username + "<br>password=" + password;
        System.out.println(user);

        // 4.将打印的结果传输给客户端
        // 这个方法就是和上面的read方法相反
        // 这里把Java对象转化为json字符串,传输给客户端
        String respBody = objectMapper.writeValueAsString(user);
        resp.getWriter().write(respBody);
    }

3.发送请求并打印结果

在这里插入图片描述
在这里插入图片描述

objectMapper.readValue()内部做了很多工作,最终的结果是把JSON字符串转化为Request的Java对象,内部具体实现细节为:

  1. 根据请求报文的输入流(就是方法的第一个参数)获取到请求报文中的body部分的所有内容
  2. 按照JSON格式进行解析,并把解析出来的所有的键值对都存储到一个Map之中
  3. 通过第二个参数(反射)来明确要转化的Java对象,拿着Java对象中的属性从Map之中寻找对应的值,并把对应的值赋给赋给创建出来的Java对象

通过以上三步就完成了JSON字符串到Java对象的转化,举一个简单的例子
在这里插入图片描述

以上就是关于HttpRequestServlet的所有内容,可以观察到,这个类中大部分方法都是get方法,主要原因是因为我们是想通过这个类获取到客户端发送的请求报文,而不是去修改请求报文,所以不需要设置set方法,而在下面要介绍的HttpResponseServlet类中,更多的方法就是set方法(服务器这边要返回一个响应报文)

三.HttpResponseServlet

常用方法:
在这里插入图片描述

setStatus() 设置状态码

@WebServlet("/status")
public class StatusServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        resp.setStatus(404);// 此时响应报文的状态码就被设置为404

        // 如果只传输上述的状态码  浏览器是空白界面  不会有任何信息
        // 我们一般看到的都是有一个"错误界面"
        // 可以通过
        resp.sendError(404,"你小子搜的是什么资源???");
        // 这里面就比较的灵活了
        // 根据一定的逻辑  来灵活的输出状态码信息
    }
}

当需要发送报错信息时,更推荐使用第二种方式,更加灵活
结果显示:
在这里插入图片描述

setHeader 在头部中设置一些属性

自动刷新

每间隔1s就自动刷新界面,利用header中的refresh字段

@WebServlet("/refresh")
public class RefreshServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setHeader("refresh","1");// 1s 后自动刷新界面
        resp.getWriter().write("" + System.currentTimeMillis());
    }
}

在这里插入图片描述
在这里插入图片描述

sendRedirect() 构造重定向

当状态码是3xx时,就代表要进行重定向,利用sendRedirect方法可以直接跳转

@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        // 一个重定向的报文包含两部分:状态码 和 要跳转的界面
//        resp.setStatus(302);// 核心是要有对应的状态码(以3开头),以及要跳转的界面(Location字段)
//        resp.setHeader("Location","https://sogou.com");// 此时就会自动跳转到搜狗界面

        // 上述写法比较繁琐  一般来说会使用下面这个方法来设置一个跳转的响应报文
        resp.sendRedirect("https://sogou.com");
    }
}

不仅可以通过服务器这边设置跳转的界面,还可以在前端中使用JS定时器来实现相同的效果

<!DOCTYPE html>
<html>
<head>
    <title>页面跳转示例</title>
    <script>
        // 在页面加载后,等待 3 秒后跳转到新页面
        window.onload = function() {
            setTimeout(function() {
                window.location.href = "https://www.sogou.com";
            }, 3000); // 3 秒
        };
    </script>
</head>
<body>
    <h1>页面将在 3 秒后跳转到搜狗主页</h1>
</body>
</html>

以上就是<<网站开发–详解Servlet>>的所有内容,重点掌握三个类的api的基本用法,多多使用就能融会贯通,实现更复杂的交互!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/410678.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python 进程笔记一 (概念+示例代码)

1. 进程的概念 进程是资源分配的最小单位&#xff0c;也是线程的容器&#xff0c;线程&#xff08;python 线程 &#xff08;概念示例代码&#xff09;&#xff09;是CPU调度的基本单位&#xff0c;一个进程包括多个线程。 程序&#xff1a;例如xxx.py是一个程序 进程&#xf…

C++初阶 | [八] (下) vector 模拟实现

摘要&#xff1a;vector 模拟实现讲解&#xff08;附代码示例&#xff09;&#xff0c;隐藏的浅拷贝&#xff0c;迭代器失效 在进行 vector 的模拟实现之前&#xff0c;我们先粗略浏览一下 stl_vector.h 文件中的源码来确定模拟实现的大体框架。 这里提供一些粗略浏览源码的技巧…

如何使用GAP-Burp-Extension扫描潜在的参数和节点

关于GAP-Burp-Extension GAP-Burp-Extension是一款功能强大的Burp扩展&#xff0c;该工具在getAllParams扩展的基础上进行了升级&#xff0c;该工具不仅可以帮助广大研究人员在安全审计过程中扫描潜在的参数&#xff0c;而且还可以搜索潜在的链接并使用这些参数进行测试&#…

HarmonyOS—代码Code Linter检查

Code Linter代码检查 Code-Linter针对ArkTS/TS代码进行最佳实践、编程规范方面的检查&#xff0c;目前还会检查ArkTS语法规则。开发者可根据扫描结果中告警提示手工修复代码缺陷&#xff0c;或者执行一键式自动修复&#xff0c;在代码开发阶段&#xff0c;确保代码质量。 检查…

Linux之项目部署与发布

目录 一、Nginx配置安装&#xff08;自启动&#xff09; 1.一键安装4个依赖 2. 下载并解压安装包 3. 安装Nginx 4. 启动 nginx 服务 5. 对外开放端口 6. 配置开机自启动 7.修改/etc/rc.d/rc.local的权限 二、后端部署tomcat负载均衡 1. 准备2个tomcat 2. 修改端口 3…

【Vue3】学习watch监视:深入了解Vue3响应式系统的核心功能(上)

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

基于Java的艺培管理解决方案

✍✍计算机毕业编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java、…

抖音小程序获取手机号

1、* 手机号获取和登录需要分开 &#xff08;规定&#xff09; 2、 抖音小程序首先得先通过试运营 没有通过试运营的 会提示没有权限 getPhoneNumber:fail auth deny 3、上代码 <button class"phone toutiaoSq" v-if"!userInfo.phone && isLogin&…

[AutoSar]BSW_Com03 DBC详解 (一)

目录 关键词平台说明一、DBC 定义1.1 相关工具 二、主要组成部分介绍2.1 Networks2.2 ECUs2.3 Network nodes2.4 messages2.5 signal2.6 Value Tables 三、主要组成部分关系图 关键词 嵌入式、C语言、autosar、OS、BSW 平台说明 项目ValueOSautosar OSautosar厂商vector &am…

本地项目如何上传到gitee

文章目录 一、在gitee上新建远程仓库二、初始化本地仓库三、执行git命令上传代码 一、在gitee上新建远程仓库 仓库名称必填&#xff0c;路径自动跟仓库名称保持一致 解释说明&#xff1a; 仓库名称&#xff1a;必填&#xff0c;每个仓库都需要有一个名称&#xff0c;同一个码…

tkinterFrame框架+标签框架LabelFrame+Toplevel窗口的使用

1.在tkinter中&#xff0c;Frame是一个容器小部件用于组织和管理其他小部件。它可以作为一个独立的可见区域&#xff0c;也可以作为其他小部件的父容器。 import tkinter as tk import tkinter.ttk as ttk import tkinter.messagebox as mbm tk.Tk() m.title("tkinter L…

Vue事件处理之v-on

1. 使用及定义 定义方法 function 方法名称(接受的event或是什么都不写) {//不管方法后括号内写与不写event,都可以接受到方法内表达式 }//定义一个接受参数的方法,此时也会在传入event function 方法名称(传入参数) {//可接受传入参数与event方法内表达式 } //定义一个接受参…

postgresql远程连接问题

修改pg_hba.conf文件&#xff0c;在文件末尾追加 host all all 0.0.0.0/0 md5

查看mysql数据库的版本

要查看MySQL数据库的版本&#xff0c;可以使用以下几种方法&#xff1a; 命令行&#xff08;已连接到MySQL服务器&#xff09;&#xff1a; 登录到MySQL服务器后&#xff0c;在MySQL提示符下执行&#xff1a; mysql> SELECT VERSION(); 或者&#xff0c;也可以执行 STATUS; …

啤酒:精酿啤酒与烧烤的热烈碰撞

在夏日的傍晚&#xff0c;烧烤与啤酒总是绝配。当Fendi Club啤酒遇上烧烤&#xff0c;它们将为我们带来一场热烈的美味碰撞。 Fendi Club啤酒&#xff0c;以其醇厚的口感和淡淡的麦芽香气而著称。这款啤酒在酿造过程中采用了特别的工艺&#xff0c;使得酒体呈现出诱人的金黄色&…

《业务建模驱动的企业架构转型白皮书》

当前&#xff0c;我国金融等国民经济重点行业和企业的数字化转型&#xff0c;仍存在战略落地难、业务技术协同难以及投入产出匹配难等问题&#xff0c;亟需通过实施企业架构&#xff0c;从顶层设计出发&#xff0c;制定符合自身需要的转型战略&#xff1b;从全局视角出发&#…

【JavaSE】集合框架

目录 程序场景分析 Java集合框架包含的内容List接口ArrayListLinkedListList接口的常用方法ArrayList案例背景分析代码示例扩展以下功能代码示例 LinkedList案例背景分析代码示例LinkedList的特殊方法 ArrayList与LinkedList对比 Set接口HashSet 集合的特点常用方法案例背景分析…

日志系统项目(2)项目实现(实用工具类、日志等级类、日志消息类、日志格式化输出类)

前面的文章中我们讲述了日志系统项目的前置知识点&#xff0c;再本文中我们将开始日志项目的细节实现。 日志系统框架设计 本项目实现的是一个多日志器日志系统&#xff0c;主要实现的功能是让程序员能够轻松的将程序运行日志信息落地到指定的位置&#xff0c;且支持同步与异…

成都直播基地作为产业重要载体,引领直播行业健康、多元发展

近年来&#xff0c;我国网络直播行业呈现出井喷式的发展态势。众多直播平台如雨后春笋般涌现&#xff0c;直播内容丰富多样&#xff0c;涵盖游戏、电竞、美食、旅游、教育等多个领域。同时&#xff0c;成都直播产业园规模持续扩大&#xff0c;产业不断完善&#xff0c;整体呈现…

常见的音频与视频格式

本专栏是汇集了一些HTML常常被遗忘的知识&#xff0c;这里算是温故而知新&#xff0c;往往这些零碎的知识点&#xff0c;在你开发中能起到炸惊效果。我们每个人都没有过目不忘&#xff0c;过久不忘的本事&#xff0c;就让这一点点知识慢慢渗透你的脑海。 本专栏的风格是力求简洁…
最新文章