【JavaEE初阶】Servlet (二) Servlet中常用的API

news2024/9/20 18:35:38

文章目录

  • HttpServlet
    • 核心方法
  • HttpServletRequest
    • 核心方法
  • HttpServletResponse
    • 核心方法

Servlet中常用的API有以下三个:

  • HttpServlet
  • HttpServletRequest
  • HttpServletResponse

HttpServlet

我们写 Servlet 代码的时候, 首先第一步就是先创建类, 继承自 HttpServlet, 并重写其中的某些方法.

核心方法

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

说明:

  • init:tomcat首次收到和该类相关联的请求时触发.(类似于前面学的懒汉模式).例如:在这里插入图片描述
    tomcat收到 /hello 的路径请求,就会调用到HelloServlet进行实例化,于是就需要先对helloServlet进行实例化.(实例化只进行一次). 后续再收到 /hello,就不必重复实例化了,直接复用之前的HelloServlet实例即可.
  • destroy:通过重写我们可以看到:在这里插入图片描述
  • service:收到http请求就会触发(路径匹配请求).

以上三个方式是HTTPServlet最关键的三个方法.

面试题:Servlet的声明周期是什么?

  1. 开始的时候,执行init
  2. 每次收到请求的时候,执行service
  3. 销毁之前,执行destroy

在这里插入图片描述
在浏览器中直接输入URL可以看到doGet请求:
在这里插入图片描述
那么其他请求怎么构造呢?

  1. 可以使用Postman.
    在这里插入图片描述
    同时我们可以服务器处看到日志:
    在这里插入图片描述
  2. 使用ajax构造请求
    注意文件创建位置.
    在这里插入图片描述
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <!-- 构造ajax请求访问服务器 -->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
    <script>
        $.ajax({
            type:'get',
            url:'method',
            success:function(body,status){
                console.log(body);
            }
        })
    </script>
</body>
</html>

在这里插入图片描述
上述代码中url:'method'相对路径.url:"/hello_servlet/method"绝对路径.(浏览器中的要求) 注意两种路径的写法.还有在@WebServlet("/hello")这个注解中,这个路径必须/开头,但是并非表示绝对路径(Servlet中的要求)

HttpServletRequest

HttpServletRequest表示的是HTTP请求. 这个对象是Tomcat自动构造的.Tomcat会实现监听端口,接受连接,读取请求,构造请求对象等工作.

核心方法

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

说明:

  • query String是键值对结构,使用getParameter就可以根据key获取到value.
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("/showRequest")
public class ShowRequestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");

        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());
    }
}

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

前端给后端传参的三种方式 :

  1. GET,queryString
  2. POST,from
  3. POST,json
  1. GET,queryString
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 GetParameterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 预期浏览器会发一个形如 /getParameter?studentId=10&classId=20 请求.
        // 借助 req 里的 getParameter 方法就能拿到 query string 中的键值对内容了.
        // getParameter 得到的是 String 类型的结果.
        String studentId = req.getParameter("studentId");
        String classId = req.getParameter("classId");
        resp.setContentType("text/html; charset=utf8");
        // resp.setCharacterEncoding("utf8");
        resp.getWriter().write("学生id = " + studentId + " 班级id = " + classId);
    }
}

在这里插入图片描述
在这里插入图片描述
如果key在queryString中不存在,此时就返回null.

  1. POST,from

对于前端from表单这样的数据结构,后端还是使用GetParameter来获取.注意,from表单也是键值对,和queryString的格式一样,只是这部分内容在body中

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <form action="postParameter" method="post">
        <input type="text" name="studentId">
        <input type="text" name="classId">
        <input type="submit" value="提交">
    </form>
    <!-- 构造ajax请求访问服务器 -->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <script>
        // $.ajax({
        //     type:'get',
        //     url:'method',
        //     success:function(body,status){
        //         console.log(body);
        //     }
        // })
    </script>

</body>
</html>

在这里插入图片描述
请添加图片描述
使用getparameter既可以获取到queryString键值对,也可以获取到form表单构造的body中的键值对.

上述过程,是前后端交互的过程.
在这里插入图片描述
在这里插入图片描述
3. POST,json
json是一种非常主流的数据结构,也是键值对结构
使用Postman构造POST:
在这里插入图片描述
下面写PostParameter2服务器代码:

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;

@WebServlet("/postParameter2")
public class PostParameter2Servlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 通过这个方法来处理 body 为 json 格式的数据.
        // 直接把 req 对象里 body 完整的读取出来.
        // getInputStream
        // 在流对象中读多少个字节? 取决于 Content-Length
        int length = req.getContentLength();
        byte[] buffer = new byte[length];

        InputStream inputStream = req.getInputStream();
        inputStream.read(buffer);
        // 把这个字节数组构造成 String, 打印出来.
        String body = new String(buffer, 0, length, "utf8");
        System.out.println("body = " + body);
    }
}

打开Postman发送请求,在日志可以看到:
在这里插入图片描述
打开fiddler抓包可以看到:
在这里插入图片描述
小结:
在这里插入图片描述
当前通过json传递数据,但是服务器这边只是把整个body读取进来,并没有按照键值对的方式来处理(还不能根据key获取value),此时可以使用第三方库来解决这个问题.
打开maven中央仓库:
在这里插入图片描述
在这里插入图片描述

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);
        //resp.getWriter().write(body);

    }
}
  1. 会从body中读取json格式的字符串
  2. 根据第二个参数类对象,创建Student实例
  3. 解析上述json格式的字符串,处理成map键值对结构
  4. 遍历所有键值对,看键的名字和student实例中那个属性名字匹配,就把对应的value设置到该属性中.
  5. 返回该Student实例

在这里插入图片描述
如果请求中多一个参数,Student中没有,则会出现500 服务器内部错误.
在这里插入图片描述
如果请求中少一个参数,Student中有这个参数,则会返回默认值.
在这里插入图片描述

HttpServletResponse

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

核心方法

方法描述
void setStatus(int sc)为该响应设置状态码。
void setHeader(String name,String value)设置一个带有给定的名称和值的 header. 如果 name 已经存在,则覆盖旧的值.
void addHeader(Stringname, 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 中写入二进制格式数据.

说明:

  • sendRedirect重定向.
    两种写法:
@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.sendRedirect("https://www.baidu.com");
    }
}
@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.baidu.com");
    }
}

启动服务器,在地址栏中输入http://127.0.0.1:8080/hello_servlet/redirect可以看到网页跳转至百度页面:
在这里插入图片描述
使用fiddler可以看到:
在这里插入图片描述
上述GET请求触发resp.sendRedirect("https://www.baidu.com");代码,从而得到响应:
在这里插入图片描述

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

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

相关文章

springboot拿到yml文件中的配置,决绝将配置写在代码里

springboot拿到yml文件中的配置 写你对应的文件 package com.gym.vueea.config;import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component;/*** author ymgu* Package com.gym.vueea.config* date 2023…

230717期班5G网络优化就业班正式开班!命运的齿轮开始转动~

当前&#xff0c;无论是个人生活还是商业领域&#xff0c;5G网络已经成为了不可或缺的一部分&#xff0c;所以各位同学看好这个行业&#xff0c;在这个炎炎夏日的七月&#xff0c;经历了8天的基础班之后&#xff0c;也愿意投身到5G网络优化这个行业中&#xff0c;所以继续参与2…

logback中文一直是乱码,logback中文问号

logback一直是乱码 方案一加上UTF-8 方案二我这边方案一不行 在启动参数加上 -Dfile.encodingutf-8 这个竟然就可以了

IDEA如何快捷创建serialVersionUID【详细图解】

在Java Bean&#xff0c;快速创建serialVersionUID&#xff0c;详细操作流程如下&#xff1a; 1.File->Settings->Editor->Inspections 在搜索框里搜索 Uid,选择下图中勾选的选择 2.如何使用 双击选中需要序列化Uid的类名&#xff0c;使用Alt enter&#xff0c;快捷…

软件测试基本知识

安全测试 安全防护策略&#xff1f;&#xff08;漏洞扫描、入侵检查、安全日志、隔离防护&#xff09; 安全日志&#xff1a;用于记录非法用户的登录名称、操作时间及内容等信息&#xff0c;以便发现问题并提出解决措施&#xff1b;安全日志仅记录相关信息&#xff0c;不对非…

openssl3.1.1关于国标支持的验证笔记

openssl3.1.1关于国标支持的验证笔记 openssl的版本差异日志 openssl虽然有3个大分支&#xff0c;我们就以3.1大分支查看关于国密的差异日志。 Changes between 1.1.0i and 1.1.1 [11 Sep 2018] Changes between 1.1.1b and 1.1.1c [28 May 2019] Changes between 1.1.1k and…

kotlin 编写一个简单的天气预报app(四)

编写界面来显示返回的数据 用户友好性&#xff1a;通过界面设计和用户体验优化&#xff0c;可以使天气信息更易读、易理解和易操作。有效的界面设计可以提高用户满意度并提供更好的交互体验。 增加城市名字的TextView <TextViewandroid:id"id/textViewCityName"…

H3C B5路由器审计分析(环境准备)

H3C B5路由器 固件下载固件解压与文件提取固件仿真方式大端模式小端模式高字节和低字节高地址和低地址物联网系统常见cpu架构固件下载 固件提取的几种方式 路由器供应商官网提供固件更新,可以去官网搜索下载,如H3C B5路由: 官方固件下载地址 B5路由器属于智能终端,所以进入…

基于罪名法务智能知识图谱(含码源):基于280万罪名预测、20W法务问答与法律资讯问答功能

项目设计集合&#xff08;人工智能方向&#xff09;&#xff1a;助力新人快速实战掌握技能、自主完成项目设计升级&#xff0c;提升自身的硬实力&#xff08;不仅限NLP、知识图谱、计算机视觉等领域&#xff09;&#xff1a;汇总有意义的项目设计集合&#xff0c;助力新人快速实…

会议OA项目之会议通知(需要反馈自己的参会情况)

一.主要功能点介绍 ①显示出所有的数据&#xff08;查询所有的待开会议&#xff09; ②模糊查询&#xff08;根据会议标题&#xff09; ③附有一个是否参会的操作&#xff1a;反馈结果&#xff08;参加/不参加&#xff09;当然&#xff0c;没有阅读此消息时&#xff0c;那么就会…

【数据分享】1999—2021年地级市的科技创新相关指标(免费获取\Shp\Excel格式)

1999-2021年地级市的人口相关数据、各类用地面积数据、污染物排放和环境治理相关数据、房地产投资情况和商品房销售面积、社会消费品零售总额和年末金融机构存贷款余额、地方一般公共预算收支状况、工业企业数、固定资产投资和对外经济贸易数据&#xff08;可查看之前的文章获悉…

奇特!AI换脸让康熙本人出演电视剧;LLM超全综述资料;业内深聊游戏行业中AI应用实践;吴恩达联合Hugging Face再出新课 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; B站UP主再出「邪招」&#xff0c;让康熙本人出演电视剧名场面 B站UP主 PAC_松柏 结合康熙画像和电视剧画面&#xff0c;对视频人物角色…

flutter:轮播

前言 介绍几个比较有不错的轮播库 swipe_deck 与轮播沾边&#xff0c;但是更多的是一种卡片式的交互式界面设计。它的主要概念是用户可以通过左右滑动手势浏览不同的卡片&#xff0c;每张卡片上都有不同的信息或功能。 Swipe deck通常用于展示图片、产品信息、新闻文章、社…

从C语言到C++_29(红黑树封装set和map)红黑树迭代器的实现

目录 1. set和map中的红黑树 2. 仿函数比较键值对 3. 红黑树迭代器的实现 3.1 迭代器 3.2 迭代器-- 3.3 map的operator[ ] 4. 完整代码 Set.h Map.h RedBlackTree.h Test.cpp 本章完&#xff0c; 1. set和map中的红黑树 前一篇红黑树的源代码&#xff1a; #pragm…

Python web实战 | 用 Flask 框架快速构建 Web 应用【实战】

概要 Python web 开发已经有了相当长的历史&#xff0c;从最早的 CGI 脚本到现在的全栈 Web 框架&#xff0c;现在已经成为了一种非常流行的方式。 Python 最早被用于 Web 开发是在 1995 年&#xff08;90年代早期&#xff09;&#xff0c;当时使用 CGI 脚本编写动态 Web 页面…

Python爬取IP归属地信息及各个地区天气信息

一、实现样式 二、核心点 1、语言&#xff1a;Python、HTML&#xff0c;CSS 2、python web框架 Flask 3、三方库&#xff1a;requests、xpath 4、爬取网站&#xff1a;https://ip138.com/ 5、文档结构 三、代码 ipquery.py import requests from lxml import etree # 请求…

Lambda-Java8新特性最佳实践

一、基本概念 1.背景 Lambda是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。 Lambda 表达式&#xff08;Lambda express…

视频孪生赋能智慧交通,视频孪生在9大交通场景的典型应用展示

《数字中国建设整体布局规划》中提出&#xff0c;要推动数字技术和实体经济深度融合&#xff0c;在交通领域加快数字技术创新应用。其中对“数字技术创新应用”的理解&#xff0c;一方面是指推动人工智能、大数据、云计算、数字孪生、物联网等新技术与交通行业深度融合&#xf…

深度学习入门(二):神经网络整体架构

一、前向传播 作用于每一层的输入&#xff0c;通过逐层计算得到输出结果 二、反向传播 作用于网络输出&#xff0c;通过计算梯度由深到浅更新网络参数 三、整体架构 层次结构&#xff1a;逐层变换数据 神经元&#xff1a;数据量、矩阵大小&#xff08;代表输入特征的数量…

1400*B. Toy Blocks

Example input 3 3 3 2 2 4 2 2 3 2 3 0 3 0 output 1 0 3 解析&#xff1a; 对于某个盒子&#xff0c;我们用其余盒子的最大值 mx 乘以其余的盒子数量&#xff08;n-1&#xff09;&#xff0c;再减去其余盒子当前的数量 ( sum-a[ i ] )&#xff0c;即为需要补上的数量 cnt…