Servlet详解

news2024/11/6 17:34:43

目录

一. Servlet介绍

1.1 概念

2.2 Servlet架构

 二. 创建一个Servlet程序

2.1 创建一个Maven项目

2.2 引入 jar 包

2.3 创建目录

2.4 编写代码

2.5 打包程序

2.6 部署程序

2.7 验证程序

三. Servlet常用API

 3.1 HttpServlet

 3.2 HttpServletRequest

 3.2 HttpServletResponse


一. Servlet介绍

1.1 概念

Servlet 是一种实现动态页面的技术. 是一组 Tomcat 提供给程序猿的 API, 帮助程序猿简单高效的开发一个 web app,使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页;


2.2 Servlet架构


 二. 创建一个Servlet程序

一般创建一个简单的 Servlet 程序需要一下几个步骤:

2.1 创建一个Maven项目

2.2 引入 jar 包

打开创建好的Maven工程,点击pro.xml文件,我们需要去中央仓库去引入相对应的依赖,可以去官网复制相应的代码,点击这个网址直接跳转到中央仓库:

https://mvnrepository.com/https://mvnrepository.com/

注意:这里要选择3.1.0的版本,因为这个版本是和 Tomcat8.5 相匹配的,不同的Servlet就要对应不同的Tomcat;

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

把这段代码复制粘贴到Maven工程的pro.xml文件里就OK了,这里需要新增一个<dependencies>标签,这样IDEA就会自动识别并且下载相对应的jar包了;

2.3 创建目录

在main的目录下创建一个webapp的目录,在此目录下创建一个WEB-INF目录,在WEB-INF目录下创建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 Application</display-name>
</web-app>

2.4 编写代码

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    // 这里的rep是HTTP请求,resp是HTTP响应
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf8");
        resp.getWriter().write("hello world");
        resp.getWriter().write("你好 世界");
    }
}

2.5 打包程序

打包做的事情有:

  1. 检查代码中是否存在一些依赖,依赖是否下载好;
  2. 把代码进行编译,生成.class文件;
  3. 把这些.class文件或者.xml文件按照一定格式进行打包;

这里我们双击package,同时我们要在pom.xml文件中插入相应代码,来调整打包生成的格式,如果双击package打出来的包就是jar包,但是我们需要的war包;

// 指定打包格式
<packaging>war</packaging>
    <build>
// 生成包的名字
        <finalName>helloServlet</finalName>
    </build>

 这里我们看见就打包成功了;

2.6 部署程序

我们需要把打好的war包移到 tomcat 的webapp目录下

 

2.7 验证程序

这里我们需要再IDEA上安装一个Smart Tomcat,安装的过程就不细说了,安装完成后,点击运行,在浏览器输入url,localhost:8080/servlet/hello,就可以看到你想显示的东西了;

但是要正确启动一个servlet程序,还需要注意一下路径的问题,否则就会启动失败:


三. Servlet常用API

3.1 HttpServlet

HttpServlet是Servlet接口的一个实现类,并且它是一个抽象类,servlet.http包中定义了采用HTTP通信协议(一个无状态协议)的HttpServlet类;

核心方法:

方法名称调用时机
init在 HttpServlet 实例化之后被调用一次
destory在 HttpServlet 实例不再使用的时候调用一次
service收到 HTTP 请求的时候调用
doGet收到 GET 请求的时候调用(由 service 方法调用)
doPost收到 POST 请求的时候调用(由 service 方法调用)
doPut/doDelete/doOptions/...收到其他请求的时候调用(由 service 方法调用)

1)关于 init 方法:

HttpServlet被实例化之后,当首次收到匹配的请求的时候,才会调用到,一般使用这个方法来做一些初始化相关的工作,init只会调用一次;

2)关于 destroy 方法:

这个方法是webapp被销毁前执行一次,用来做一些收尾工作(不建议使用);

3)关于 servlet 方法:

每次收到路径匹配的请求调用一次;


✅常见面试题:让你说一说Servlet的生命周期?

  1. init 是初始情况下调用一次;
  2. destroy 是结束之前调用一次;
  3. service 是每次收到路径匹配的请求调用一次;

 3.2 HttpServletRequest

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息;

核心方法:

方法描述
String getProtocol()返回请求协议的名称和版本。
String getMethod()返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT。
String getRequestURI()从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请
求的 URL 的一部分。
String getContextPath()返回指示请求上下文的请求 URI 部分。
String getQueryString()返回包含在路径后的请求 URL 中的查询字符串。
Enumeration
getParameterNames()
返回一个 String 对象的枚举,包含在该请求中包含的参数的名
称。
String getParameter(String
name)
以字符串形式返回请求参数的值,或者如果参数不存在则返回
null。
String[]
getParameterValues(String
name)
返回一个字符串对象的数组,包含所有给定的请求参数的值,如
果参数不存在则返回 null。
Enumeration
getHeaderNames()
返回一个枚举,包含在该请求中包含的所有的头名。
String getHeader(String
name)
以字符串形式返回指定的请求头的值。
String
getCharacterEncoding()
返回请求主体中使用的字符编码的名称。
String getContentType()返回请求主体的 MIME 类型,如果不知道类型则返回 null。
int getContentLength()以字节为单位返回请求主体的长度,并提供输入流,或者如果长
度未知则返回 -1。
InputStream
getInputStream()
用于读取请求的 body 内容. 返回一个 InputStream 对象
@WebServlet("/ServletRequest")
public class ServletRequest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        StringBuilder stringBuilder = new StringBuilder();
        // 返回请求协议的名称和版本
        stringBuilder.append(req.getProtocol());
        stringBuilder.append("<br>");
        // 返回请求的 HTTP 方法的名称
        stringBuilder.append(req.getMethod());
        stringBuilder.append("<br>");
        // 返回URI
        stringBuilder.append(req.getRequestURI());
        stringBuilder.append("<br>");
        // 返回在路径后的请求 URL 中的查询字符串
        stringBuilder.append(req.getQueryString());
        stringBuilder.append("<br>");
        // 在响应中设置body的类型
        resp.setContentType("text/html;charset=utf8");
        resp.getWriter().write(stringBuilder.toString());

    }
}

这里介绍一个最常用的API,就是getParameter,我们在开发的需求中,前端给后端传递数据时是非常常见的需求,假设这里我们把前端的姓名和密码传到后端,就可以这样写:

1)通过 query string 传递

@WebServlet("/getParameter")
public class GetParameter extends HttpServlet {
    // 通过 query string 传递
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if(username == null){
            System.out.println("username 在 query string 中不存在");
        }
        if(password == null){
            System.out.println("password 在 query string 中不存在");
        }
        System.out.println("username = " + username + " ,password = " + password);
        resp.getWriter().write("ok");
    }
}


2)通过body传递

 @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置编码方式,以防乱码
        req.setCharacterEncoding("utf8");
        // 前端通过body,以form表单的格式,把用户名和密码传给服务器
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if(username == null){
            System.out.println("username 在 query string 中不存在");
        }
        if(password == null){
            System.out.println("password 在 query string 中不存在");
        }
        System.out.println("username = " + username + " ,password = " + password);
        resp.getWriter().write("ok");
    }

 我们通过Postman构造请求可以发现:


3)通过json传递(最常用的)

  在使用json之前,我们引入一个第三方库,这里可以去Maven中央仓库下载:

 <!-- 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>
class User {
    public String username;
    public String password;
}

@WebServlet("/json")
public class JsonServlet extends HttpServlet {
    // 这个对象可以把 json 格式的字符串解析成 java 对象,同时也可以把 java 对象转化成一个 json 格式字符串
    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 通过 post 请求的 body 传递一个 json 格式的字符串
        User user = objectMapper.readValue(req.getInputStream(), User.class);
        System.out.println("username = " + user.username + ", password = " + user.password);
        resp.getWriter().write("ok");

    }
}

通过Postman构造请求可以发现:

 

 上述的 readValue 方法主要做的是:

  1. 1.解析json字符串,转换成若干个字符串;
  2. 2.根据第二个参数类对象(Use.class),去找到 User 里的 public 的属性;
  3. 3.遍历属性,根据属性的名字,去查询键值对,看看这个属性的名字是否存在对应的 value,如果存在,就把 value 赋值到该属性中;

 3.2 HttpServletResponse

HttpServletResponse表示一个HTTP响应

核心方法:

方法描述
void setStatus(int sc)为该响应设置状态码。
void setHeader(String name,
String value)
设置一个带有给定的名称和值的 header. 如果 name 已经存在,
则覆盖旧的值.
void addHeader(String
name, String value)
添加一个带有给定的名称和值的 header. 如果 name 已经存在,
不覆盖旧的值, 并列添加新的键值对
void setContentType(String
type)
设置被发送到客户端的响应的内容类型。
void
setCharacterEncoding(String
charset)
设置被发送到客户端的响应的字符编码(MIME 字符集)例如,
UTF-8。
void sendRedirect(String
location)
使用指定的重定向位置 URL 发送临时重定向响应到客户端。
PrintWriter getWriter()用于往 body 中写入文本格式数据.
OutputStream
getOutputStream()
用于往 body 中写入二进制格式数据.
@WebServlet("/response")
public class ServletResponse extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setStatus(200);
        resp.setContentType("text/html;charset=utf8");
        resp.getWriter().write("返回200响应");
    }
}

设置重定向:

@WebServlet("/redirect")
public class ServletRedirect extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置状态码
        resp.setStatus(302);
        // 设置重定向的网页地址
        resp.setHeader("location","https://www.baidu.com");
    }
}

 这里就直接跳转到了百度的网页了!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入了解SSM框架(案例(SSM+Jsp) + 详细分析 + 思维导图)

1.Spring Spring就像是整个项目中装配bean的大工厂&#xff0c;在配置文件中可以指定使用特定的参数去调用实体类的构造方法来实例化对象。也可以称之为项目中的粘合剂。 Spring的核心思想是IoC&#xff08;控制反转&#xff09;&#xff0c;即不再需要程序员去显式地new一个…

swagger 接口测试,用 python 写自动化时该如何处理?

在使用Python进行Swagger接口测试时&#xff0c;可以使用requests库来发送HTTP请求&#xff0c;并使用json库和yaml库来处理响应数据。以下是一个简单的示例代码&#xff1a; 如果你想学习自动化测试&#xff0c;我这边给你推荐一套视频&#xff0c;这个视频可以说是B站百万播…

vim编辑器基本使用

一、写在前面 今天在练习git相关操作时&#xff0c;无意间发现当你使用commit命令提交代码时&#xff0c;忘记添加备注信息会自动进入一个奇怪的模式&#xff0c;按esc键亦或是ctrlC都无法退出&#xff0c;这个奇怪的模式也就是vim编辑器。如下图&#xff1a; vim是一种文本…

前端工程化-VUE

前端工程化-VUE Vue-cliNode.js1&#xff0e;什么是Node.js2&#xff0e;Node.js的安装 高效的开发离不开基础工程的搭建。本章主要介绍如何使用Vue进行实际SPA项目的开发&#xff0c;这里使用的是目前热门的JavaScript应用程序模块打包工具Webpack&#xff0c;进行模块化开发、…

嵌入式C语言中if/else如何优化详解

观点一&#xff08;灵剑&#xff09;&#xff1a; 前期迭代懒得优化&#xff0c;来一个需求&#xff0c;加一个if&#xff0c;久而久之&#xff0c;就串成了一座金字塔。 当代码已经复杂到难以维护的程度之后&#xff0c;只能狠下心重构优化。那&#xff0c;有什么方案可以优雅…

Spring 源码解析 - FactoryBean 获取 Bean 过程

一、FactoryBean FactoryBean是Spring框架提供的一个核心接口之一&#xff0c;用来创建复杂或无法通过默认构造函数创建的对象。这种情况下通过实现FactoryBean接口&#xff0c;可以自定义实例化Bean的过程&#xff0c;包括Bean的对象类型、初始化、销毁等。 在应用场景中&am…

RK3588平台开发系列讲解(进程篇)程序的二进制格式 ELF

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、ELF 文件二、二进制文件组成三、运行程序为进程沉淀、分享、成长,让自己和他人都能有所收获!😄 📢CPU 是不能执行文本文件里面的指令的,这些指令只有人能看懂,CPU 能够执行的命令是二进制的,比如“0101”…

Selenium还能这么玩:自动管理浏览器

这是个系列文章&#xff0c;主要讲selenium一些实战操作&#xff0c;使用 Python 编写代码。可以把他们应用到自动化测试&#xff0c;也可以应用到网络爬虫中。 这篇文章介绍一个操作&#xff0c;可以让selenium 控制浏览器共用同一个 session。他的应用场景是&#xff1a;共用…

pwn3-绕过防御-ROP(1)

**ROP&#xff1a;**全程Return Oriented Programming(面向返回的编程)&#xff0c;在栈溢出基础上&#xff0c;利用程序中已有的小片段(gadgets)&#xff0c;改变寄存器或变量的值&#xff0c;从而控制程序执行流程&#xff0c;从而绕过NX防御&#xff0c;常见有ret2text,ret2…

Linux:samba服务 (smbd)

smb服务器为centos7 使用的yum安装&#xff08;如果不会搭建本地yum仓库可以查看&#xff09; Linux&#xff1a;rpm查询安装 && yum安装_鲍海超-GNUBHCkalitarro的博客-CSDN博客 samba 简介 samba 使用了 1.SMB 协议 Server Message Block&#xff0c;服务消息块 2…

【LeetCode】769. 最多能完成排序的块

769. 最多能完成排序的块&#xff08;中等&#xff09; 方法一&#xff1a;贪心 思路 由于arr是[0,..., n-1] 的一个排列&#xff0c;若已遍历过的数中的最大值 max 与当前遍历到的下标相等&#xff0c;说明可以进行一次分割&#xff0c;累加答案。 代码 class Solution { …

javaScript蓝桥杯---用什么来做计算

目录 一、介绍二、准备三、目标四、代码五、完成 一、介绍 古以算盘作为计算工具。算盘常为木制矩框&#xff0c;内嵌珠子数串&#xff0c;定位拨珠&#xff0c;可做加减乘除等运算。站在前人的肩膀上&#xff0c;后人研究出计算器&#xff0c;便利了大家的生活&#xff0c;我…

从贝叶斯派的角度去看L1和L2

前沿 推导的两个角度 带约束条件的优化求解&#xff08;拉格朗日乘子法&#xff09;贝叶斯学派的&#xff1a;最大后验概率 理解的两个角度 贝叶斯学派的角度&#xff0c;L2参数符合高斯先验&#xff0c;L1参数符合laplace先验。从有约束问题角度&#xff0c;用拉格朗日转换…

一“幕”了然 ,平行云助力中车打造“掌上工厂”(文末活动报名)

“全球工业生产效率提高1%&#xff0c;成本降低300亿。” 所以工业界有这样一种说法&#xff0c;叫做“工业领域的1%革命”。 Gartner曾预言&#xff1a;到2021年&#xff0c;将有一半的大型工业公司使用数字孪生技术&#xff0c;而这可以使这些公司的生产有效性提高10%。如今…

rust学习 - 构建mini 命令行工具

rust 的运行速度、安全性、单二进制文件输出和跨平台支持使其成为构建命令行程序的最佳选择。 实现一个命令行搜索工具grep,可以在指定文件中搜索指定的字符串。想实现这个功能呢&#xff0c;可以按照以下逻辑流程处理&#xff1a; 获取输入文件路径、需要搜索的字符串读取文…

基于Alexnet网络实现猫狗数据集分类(Keras框架)

目录 1、作者介绍2、Alexnet网络2.1 网络介绍2.2 AlexNet网络的主要特点 3、基于Alexnet网络实现猫狗数据集分类3.1 猫狗大战数据集3.2 数据集处理3.3 准备工作3.4 训练过程3.4 对比实验3.4.1 HALCON平台下的Alexnet实验3.4.2 HALCON平台下的Resnet-50对比实验3.4.3 HALCON平台…

进程的通信——管道和共享内存

进程间的通信有很多种 管道 匿名管道pipe 命名管道 System V IPC System V 消息队列 System V 共享内存 System V 信号量 POSIX IPC 消息队列 共享内存 信号量 互斥量 条件变量 读写锁 这篇文章主要介绍管道和共享内存 管道 管道内核数据结构&#xff1a;在Linux2.6中 struct …

搭建自动化测试环境

目录 1、安装Python并配置环境变量。2、安装Pycharm开发工具。3、安装Selenium4、安装浏览器&#xff1a;Chrome和Firefox的其中之一。5、浏览器驱动&#xff1a;下载Chrome浏览器驱动或者是Firefox浏览器驱动。6、配置webdriver公众号粉丝福利 自动化测试环境&#xff1a; Pyt…

接口反应慢优化

遇到某个功能&#xff0c;页面转圈好久&#xff0c;需要优化 1.F12 查看接口时间 2.看参数 总共耗时9.6s Waiting for sercer response 时间是2秒 Content Download 7秒 慢在Content Download F12查看接口响应 显示Failed to load response data:Request content was e…

这些10款优秀的交互设计软件,你知道吗?

交互软件可以帮助设计师从“可用性”和“用户体验”的角度优化他们的作品。如果设计师想创建一个令人满意的交互设计作品&#xff0c;一个方便的交互设计软件是必不可少的。 根据设计师的个人喜好和方便&#xff0c;选择易于使用的交互设计软件来完成创建。本文盘点十款易于使…