ServletAPI的使用

目录

一、HttpServlet

1.1 HttpServlet的核心方法

1.2 Servlet的生命周期

1.3 代码示例:通过postman来发送请求

1.4 代码示例:通过ajax来发送请求

二、HttpServletRequest

2.1 代码示例:打印请求信息:

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

2.2 代码示例:通过form表单获取POST请求中的参数

2.3 代码示例:通过json获取POST请求中的参数

三、HttpServletResponse

3.1 代码示例: 设置状态码

3.2 代码示例: 重定向


虽然Servlet提供的类和方法很多,但是最主要的其实也就三个:HttpServlet、HttpServletRequest、HttpServletResponse。

一、HttpServlet

1.1 HttpServlet的核心方法

写servlet代码时,创建的类往往都继承自HttpServlet,并重写其中的方法。

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

我们实际开发的时候主要重写 doXXX 方法, 很少会重写 init / destory / service

需要注意的是:

1)  init方法是在HttpServlet首次实例化的时候被Tomcat调用(非自己调用)。

HttpServlet什么时候被实例化呢?

当Tomcat首次收到和该类相关联的请求的时候(这种模式类似于懒汉模式)

举个例子:

2) destory是不一定能够执行到的。

因为如果是通过直接杀死进程的方式,那么destroy就可能来不及执行就没了

如果是通过smart tomcat的停止按钮(本质是通过控制tomcat上的8005这个端口进行主动停止),是可以的。

3)Tomcat每次收到请求后(收到的前提是路径得匹配),实际上是先调用service 。

在service中再根据方法,调用不同的doXXX方法。实际开发的过程中很少重写service,基本是重写doXXX方法。

1.2 Servlet的生命周期

Servlet 生命周期可被定义为:从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:

  1. 当一个请求从Http服务器转发给Servlet容器的时候,容器检查对应的Servlet是否创建,没有创建就实例化该Servlet,并调用init()方法,init()方法只调用一次,之后的请求都是从第二步开始。
  2. Servlet 调用 service() 方法,根据请求类型转发给对应的方法来处理,如doGet,doPost等等。
  3. Servlet 销毁前调用 destroy() 方法,该方法只调用一次。
  4. 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

1.3 代码示例:通过postman来发送请求

1.4 代码示例:通过ajax来发送请求

什么是Ajax?

Ajax即”Asynchronous JavaScript and XML“(异步的JavaScript与XML技术),指的是一套综合了多项技术的浏览器端网页开发技术。

传统的Web应用允许用户端填写表单(form),当提交表单时就向网页服务器发送一个请求。服务器接收并处理传来的表单,然后送回一个新的网页,但这个做法浪费了许多带宽,因为在前后两个页面中的大部分HTML码往往是相同的。由于每次应用的沟通都需要向服务器发送请求,应用的回应时间依赖于服务器的回应时间。这导致了用户界面的回应比本机应用慢得多。

与此不同,AJAX应用可以仅向服务器发送并取回必须的数据,并在客户端采用JavaScript处理来自服务器的回应。因为在服务器和浏览器之间交换的数据大量减少,服务器回应更快了。同时,很多的处理工作可以在发出请求的客户端机器上完成,因此Web服务器的负荷也减少了。

二、HttpServletRequest

在 Servlet API 中,定义了一个 HttpServletRequest 接口,它继承自 ServletRequest 接口。HttpServletRequest 对象专门用于封装 HTTP 请求消息,简称 request 对象。

HTTP 请求消息分为请求行、请求消息头和请求消息体三部分,所以 HttpServletRequest 接口中定义了获取请求行、请求头和请求消息体的相关方法:

方法描述
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 对象.

 2.1 代码示例:打印请求信息:

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 ShowRequestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        这里给响应的数据类型设置Content-type
        resp.setContentType("text/html");
//        定义一个StringBuilder,把这些操作api结果拼起来,统一写到响应中
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(req.getProtocol());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getMethod());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getRequestURI());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getContextPath());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getQueryString());
        stringBuilder.append("<br>");
        resp.getWriter().write(stringBuilder.toString());
        resp.getWriter().write("<br>");
//        获取header的所有键值对
        Enumeration<String> headerNames = req.getHeaderNames();
        while(headerNames.hasMoreElements()) {
            String headerName = headerNames.nextElement();
            resp.getWriter().write(headerName+" :"+req.getHeader(headerName));
            resp.getWriter().write("<br>");
        }
    }
}

 响应界面:

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

Get请求中的参数一般是通过query string 传递给服务器的,形如;

http://127.0.0.1:8080/hello_servlet2/getParameter?classId=2&name=22

此时的浏览器是通过query string 给服务器传递两个参数,classId和name,分别为2和22.

这时候服务器端可以通过getParameter的方式来获取数据打印到页面上:

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

@WebServlet("/getParameter")
public class GetParameterServlet extends HelloServlet{
//    假设前端传来的数据是classId和name
//    我们可以通过req里面的getParameter(返回的对象是String)来解决
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String classId = req.getParameter("classId");
        String name = req.getParameter("name");
        //需要注意的是这里的setContentType需要写在resp.getWriter().write()的上面
        resp.setContentType("text/html; charset=utf8");
        resp.getWriter().write("班级Id = "+classId + " 姓名 = "+name);
    }
}

 当然 如果query string里没有对应的值的时候,返回的对象是null:

2.2 代码示例:通过form表单获取POST请求中的参数

2.3 代码示例:通过json获取POST请求中的参数

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;
import java.io.InputStream;

class Student {
    public int studentId;
    public int classId;
}
@WebServlet("/postParameter2")
public class PostParameter2Servlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //使用jackson所涉及到的核心对象
        ObjectMapper objectMapper = new ObjectMapper();
        //readValue就是把json格式的字符串转化成java对象
        Student student = objectMapper.readValue(req.getInputStream(),Student.class);
        System.out.println(student.studentId + " , " + student.classId);

    }
}

三、HttpServletResponse

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

核心方法

方法描述
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 中写入二进制格式数据

3.1 代码示例: 设置状态码

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

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 {
        String status = req.getParameter("status");
        if (status != null) {
            resp.setStatus(Integer.parseInt(status));
        }
        resp.getWriter().write("status: " + status);
    }
}


3.2 代码示例: 重定向

实现一个程序, 返回一个重定向 HTTP 响应, 自动跳转到另外一个页面:

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.sendRedirect("https://www.sogou.com");
        resp.setStatus(302);
        resp.setHeader("Location","https://www.sogou.com");
    }

}

 以下为fiddler抓包结果:

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

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

相关文章

强化学习——初探强化学习

本文引自&#xff1a;《 动手学强化学习 》 第 1 章 初探强化学习 1.1 简介 亲爱的读者&#xff0c;欢迎来到强化学习的世界。初探强化学习&#xff0c;你是否充满了好奇和期待呢&#xff1f;我们想说&#xff0c;首先感谢你的选择&#xff0c;学习本书不仅能够帮助你理解强…

COI实验室技能:python控制相机的方法——采集、处理、显示、实时

COI实验室技能&#xff1a;python控制相机的方法——采集、处理、显示、实时本文介绍如何利用python控制办公摄像头、工业相机和科研相机。将数据采集和处理统一到python代码中。   主要围绕解决采用什么库、掌握这个库的控制相机方法(参数配置、读取数据等等)、结合自己的算…

Go 反射

目录 什么是反射 反射的弊端 reflect 包 Go 提供的反射方法 type Type 类型 type Kind 类型 TypeOf ValueOf 什么是反射 ​反射&#xff08;reflection&#xff09;是在 Java 出现后迅速流行起来的一种概念&#xff0c;通过反射可以获取丰富的类型信息&#xff0c;并可…

实战!项目管理实施过程的五大难点和痛点

作为一个在项目摸爬滚打十余年的管理人员&#xff0c;对项目管理的难点和痛点深有体会&#xff0c;这就结合我自身体验来说一说。 我认为&#xff0c;项目管理实施中的难点和痛点其实可以归结为两类&#xff1a;一类是对于项目任务本身&#xff0c;另一类则涉及到团队内部的管…

2023年,转行学Java还是web前端?

2023年要想顺利入行IT建议选择Java。 理由很简单&#xff0c;前端开发岗位需求大量减少&#xff0c;大厂裁员导致大量有经验的前端开发人员或者初级后端开发人员流入就业市场&#xff1b;作为新人缺乏技能优势和项目优势&#xff0c;而用人单位也更愿意招聘熟手&#xff0c;或…

Python 自动化指南(繁琐工作自动化)第二版:八、输入验证

原文&#xff1a;https://automatetheboringstuff.com/2e/chapter8/ 输入验证代码检查用户输入的值&#xff0c;比如来自input()函数的文本&#xff0c;格式是否正确。例如&#xff0c;如果您希望用户输入他们的年龄&#xff0c;您的代码不应该接受无意义的答案&#xff0c;如负…

chatgpt大模型赋能人形机器人之我见

我个人的看法&#xff08;不涉及任何和他项目相关的细节或商业机密&#xff0c;仅仅是我个人的泛泛而谈&#xff09;&#xff1a; 1、从大趋势来说&#xff0c;人形机器人的灵活度和通用性确实非常的高&#xff0c;是有前景的。另外轮式足式也不是他独一例&#xff0c;像 ETH …

【Redis学习】Redis管道

理论简介 问题由来 客户端向服务端发送命令分四步(发送命令→命令排队→命令执行→返回结果)&#xff0c;并监听Socket返回&#xff0c;通常以阻塞模式等待服务端响应。 服务端处理命令&#xff0c;并将结果返回给客户端。 上述两步称为:Round Trip Time(简称RTT,数据包往返…

STM32基于STM32CubeMX DMA + EXTI读取DS1307数据

STM32基于STM32CubeMX DMA EXTI读取DS1307数据✨申明&#xff1a;本文章仅发表在CSDN网站&#xff0c;任何其他网站&#xff0c;未注明来源&#xff0c;见此内容均为盗链和爬取&#xff0c;请多多尊重和支持原创!&#x1f341;对于文中所提供的相关资源链接将作不定期更换。&a…

JVM垃圾回收机制简介

内存管理 Java的内存管理很大程度指的就是对象的管理&#xff0c;其中包括对象空间的分配和释放。 对象空间的分配&#xff1a;使用new关键字创建对象即可 对象空间的释放&#xff1a;将对象赋值null即可。垃圾回收器将负责所有“不可达”对象的内存空间。 垃圾回收过程 任…

蓝桥杯web备赛——Node.js

node.js之前只能说是略有了解&#xff0c;这次好好了解一下吧&#xff01; 东西还是比较多的。 目前来看就了解比赛会用到的http模块就可以了&#xff0c;其他的暂且不做了解 const http require("http");//1.引入http模块const app http.createServer();//2.创建…

华为OD机试题【狼羊过河 or 羊、狼、农夫过河】用 C++ 编码,速通

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:狼羊过河 or 羊、狼、农夫过河…

Stata 回归结果详解

目录一、数据信息二、指标1.上半部分2.下半部分三、详细解释SSM - 模型平方和SSR - 残差平方和SST - 总平方和R-squared - R方 - 拟合系数Adj R-squared - 调整后的拟合系数df - 自由度MS - 均方差F - 总体显著性检验Prob > F - P值Root MSECoef.Std. Err.tP > | t |95% …

Python(黄金时代)—— python深入使用

深拷贝和浅拷贝 可变类型与不可变类型 可变对象是指&#xff0c;一个对象在不改变其引用的前提下&#xff0c;可以修改其所指向的地址中的值 不可变对象是指&#xff0c;一个对象引用指向的值是不能修改的 浅拷贝 浅拷贝是对于一个对象的顶层拷贝&#xff1b; 简单理解就是&…

蓝桥杯基础8:BASIC-7试题 特殊的数字

资源限制 内存限制&#xff1a;512.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 153是一个非常特殊的数&#xff0c;它等于它的每位数字的立方和&#xff0c;即1531*1*15*5*53*3*3。编程求所有满足这种条件…

JavaSE——运算符

目录 一.运算符 二.赋值运算符 三.算术运算符 1.四则运算 2.加法运算 3.除法运算 4.取模运算 5.增量运算符 6.自增自减 四.关系运算符 五.逻辑运算符 1.逻辑与 && 2.逻辑或 || 3.逻辑非 &#xff01; 4. 短路求值 六.位运算符 1.按位与& 2.按位…

6款无版权可商用的图片网站

今天给大家分享几个无版权可商用的图片网站&#xff0c;无论是网页设计、还是数字营销、商业海报制作等等都可以非常简单方便的查询到自己想要的图片。 免费可商用图标库 unDraw https://undraw.co/illustrations unDraw是作者Katerina Limpitsouni一手创作的扁平化图标库&…

国内IT软件外包公司汇总(2023 最新版)!

大环境不行&#xff0c;面试太少了&#xff0c;很多本科生想进外包都没机会。非常时期&#xff0c;不需要在意那么多&#xff0c;外包作为过渡也是没问题的&#xff0c;很多外包其实比小公司还要好多了。 也不要太担心去外包会污染自己的简历&#xff0c;只要接触的项目还可以…

电商平台API接口,店铺所有商品

item_search_shop-店铺的所有商品 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥&#xff08;注册Key和secret接入&#xff1a; https://o0b.cn/anzexi&#xff09;api_nameString是API接口名称&#xff08;包括…

动态规划-构造最优二叉树的解路径_20230403

动态规划-最优二叉搜索树的解路径&#xff08;算法导论) 前言 本文将探索递归的先序和后续对信息表达的影响&#xff0c;通过考察最优二叉搜索树的解roo[i][j]的解&#xff0c;我们可以分析先序和后续遍历之间的互相转换关系&#xff0c;以及为了转换&#xff0c;所付出的空间…