Servlet 常见的API

文章目录

    • 写在前面
    • Smart Tomcat 插件
    • Servlet 中常见的API
      • 1. HttpServlet
        • init 方法
        • destroy 方法
        • service 方法
        • Servlet 的生命周期
      • 使用 postman 构造请求
      • 使用 ajax 构造请求
      • 2. HttpServletRequest
      • 3. 前端给后端传参
        • 1). GET, query string
        • 2). POST, form
        • 3). json
      • 4. HttpServletResponse

写在前面

上一篇我们写了第一个 Servlet 程序, 是使用 Servlet 最朴素的方式. 我们也可以通过一些操作来简化这些步骤.

这就不得不提到插件了
IDEA 功能非常强大吗, 但也不是面面俱到的, IEDA 提供了一些 API , 可以让程序员开发插件对 IDEA 现有的功能进行扩展.


Smart Tomcat 插件

在这里插入图片描述
在这里插入图片描述
安装好重启 IDEA 即可

首次使用这个插件的时候, 我们需要配置一下.

  1. 新增一个运行配置
    在这里插入图片描述
  2. 新增配置

在这里插入图片描述

  1. 设置一下 Tomcat 的位置, 其他的保持默认即可

在这里插入图片描述

  1. 运行

在这里插入图片描述
在这里插入图片描述
运行之后, idea 就会自己调用 Tomcat 执行了.

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

这样的话我们是不是就方便了许多呢, 就算我们修改数据之后也只需在 idea 中重启一下服务器即可, 就不需要手动打包部署了.

smart tomcat 的工作原理
它不是把 war 包拷贝了(webapp 里没变), idea是通过另一种方式来启动 tomcat 的
tomcat 支持启动的时候显示指定一个特定的 webapp 目录, 相当于是让 tomcat 加载单个 webapp 运行.
在这里插入图片描述
idea 直接调用 tomcat , 让 tomcat 加载当前项目中的目录.
这个过程其实没有打 war 包的过程, 也没有拷贝, 也没有解压缩的过程.

在这里插入图片描述

Servlet 中常见的API

1. HttpServlet

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

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

在这里插入图片描述
然后我们重启服务器, 重新访问

在这里插入图片描述
我们多刷新几次

在这里插入图片描述

tomcat 收到了 /hello 这样路径的请求就会调用 hello_servlet_1 进行实例化(实例化只进行一次)
后续在收到 /hello 此时不必再进行实例化, 直接复用之前的 hello_servlet_1 即可

destroy 方法

在这里插入图片描述

然后关闭服务器

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

但是这里的 destroy 不一定被执行到

  1. 如果是通过 smart tomcat 的停止按钮, 这个操作本质上是通过 tomcat 的 8005 端口, 主动停止, 能够触发 destroy.
  2. 如果是直接杀进程, 此时可能来不及执行 destroy 就关闭了.

因此不太推荐使用 destroy, 不靠谱

service 方法
Servlet 的生命周期
  1. 开始的时候, 执行 init
  2. 每次收到请求, 执行 service
  3. 销毁之前, 执行 destroy

在这里插入图片描述


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 {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("doGet");resp.getWriter().write("doGet");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("doPost");resp.getWriter().write("doPost");}@Overrideprotected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("doPut");resp.getWriter().write("doPut");}@Overrideprotected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("doDelete");resp.getWriter().write("doDelete");}
}

根据不同的请求, 返回不同的响应

使用 postman 构造请求

在这里插入图片描述

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


使用 ajax 构造请求

首先创建一个 html 文件, 一定注意文件位置在 webapp 目录下
在这里插入图片描述

引入 jQuery cdn 链接, 编写代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><!-- 使用这个页面来构造 ajax 请求--><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script><script>$.ajax({type:'get',// 相对路径// url:'method',// 绝对路径url:'/test2/mothod',success: function(body, status) {console.log(body);}})</script>
</body>
</html>

这里的 url 是个相对路径, 相对路径的基准目录就是该 html 所在的路径

然后重新启动服务器, 重新访问
在这里插入图片描述

改这里的 type 类型就能构造出不同的请求
在这里插入图片描述

2. HttpServletRequest

核心方法

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

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 {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 这里设置 content-typeresp.setContentType("text/html");// 搞个StringBuild , 把这些的 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>");stringBuilder.append("<br>");stringBuilder.append("<br>");stringBuilder.append("<br>");stringBuilder.append("<br>");// 获取 header 中的键值对Enumeration<String> headerNames = req.getHeaderNames();while (headerNames.hasMoreElements()) {String headerName = headerNames.nextElement();stringBuilder.append(headerName + ":" + req.getHeader(headerName));stringBuilder.append("<br>");}resp.getWriter().write(stringBuilder.toString());}
}

在这里插入图片描述


3. 前端给后端传参

1). GET, query string

在前端给后端传练个数字, 一个是同学的 studentiId, 一个是 classId

?studentIt=10&classId=20

下面编写代码来处理这个请求

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 {@Overrideprotected 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");resp.getWriter().write("studentId = " + studentId + " class = " + classId);}
}

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

2). POST, form

对于前端是 form 表单这样格式的数据, 后端还是使用 getParameter 来获取.

form 表单 这种格式也是键值对, 和 query string 的格式一样
只是这部分内容存在 body 中

下面我们编写代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><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></body>
</html>

在这里插入图片描述
输入内容提交就能构造出一个 POST 请求, body 就是form 表单格式.
在这里插入图片描述

我们也可以抓包看看

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

下面我们编写后端的代码

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("/postParameter")
public class PostParameterServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String studentId = req.getParameter("studentId");String classId = req.getParameter("classId");resp.setContentType("text.html ");resp.getWriter().write("studentId: " + studentId + " class " + classId);}
}

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

使用 getParameter 方法, 既可以获取到 query string 中的键值对, 也可以获取到 form 表单构造的 body 中的键值对.

3). json

json 也是一种非常主流的数据格式, 也是键值对结构.
我们可以把 body 部分 按照这个格式来组织
前端可以使用 ajax 的方式来构造出这个内容. 还可以用 postman 直接构造

在这里插入图片描述

编写代码

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.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;/*** @author chenhongfei* @version 1.0* @describe* @date 2023/11/14*/
@WebServlet("/postParameter2")
public class PostParameter2Servlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 通过这个方法来处理 body 为 json 格式的值// 直接把 req 对象里 body 完整读取出来// getInputStream// 在流对象中读多少个字节, 取决于 Content-Lengthint length = req.getContentLength();byte[] buffer = new byte[length];InputStream inputStream = req.getInputStream();inputStream.read(buffer);// 把这个字节数组构造成 StringString body = new String(buffer,0,length,"UTF8");System.out.println("body " + body);resp.getWriter().write(body);}
}

在这里插入图片描述
服务器这边我们也能看到

在这里插入图片描述

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

这个代码的执行流程, 和上个通过 form 表单传参, 流程是类似的. 只不过是传输的数据类型不同罢了.

form 表单是形如 classId=20&studentId=10

json 的格式形如:
{
classId:20,
studentId:10
}


本质上来说, 这三种方式都是等价的.

当前通过 json 传递数据, 但是服务器这边只是把整个 body 读出来, 还没有按照键值对的方式来处理(不能根据 key 获取 value)
form 表单是可以根据 key 获取 value (getParameter 就支持了).

这里我们推荐使用第三方库, Jackson

通过 Meven 引入第三方库
meven 库

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

把代码复制到 pom.xml

在这里插入图片描述

编写代码

          Student student = objectMapper.readValue(req.getInputStream(),Student.class);
  1. 这个代码会从 body 中取出 json 格式的字符串
    {
    classId: 20,
    studentId 10
    }
  2. 根据第二个参数类对象, 创建 Student 对象
  3. 解析上述 json 的字符串, 处理成 map 键值对结构
  4. 遍历所有键值对, 看键的名字和 Student 实例的哪个属性名字匹配, 就把对应的属>性 value 设置到该属性中
  5. 返回该 Student 实例

4. 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(Stringtype)设置被发送到客户端的响应的内容类型。
void setCharacterEncoding(String charset)设置被发送到客户端的响应的字符编码(MIME 字符集)例如,UTF-8。
void sendRedirect(String location)使用指定的重定向位置 URL 发送临时重定向响应到客户端。
PrintWriter getWriter()用于往 body 中写入文本格式数据.
OutputStream getOutputStream()用于往 body 中写入二进制格式数据.

设置字符编码

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 {@Overrideprotected 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("utf-8");resp.getWriter().write("学生 = " + studentId + " 班级 = " + classId);}
}

在这里插入图片描述

在这里插入图片描述

重定向

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 {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.sendRedirect("https://www.sogou.com");}
}

在这里插入图片描述
点击就跳转到了搜狗了

在这里插入图片描述

单独设置也可以

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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

竞赛选题 深度学习的视频多目标跟踪实现

文章目录 1 前言2 先上成果3 多目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学习的视频多目标跟踪实现 …

低价寄快递寄件微信小程序 实际商用版 寄快递 低价寄快递小程序(源代码+截图)前后台源码

盈利模式 快递代下CPS就是用户通过线上的渠道&#xff08;快递小程序&#xff09;&#xff0c;线上下单寄快递来赚取差价&#xff0c;例如你的成本价是5元&#xff0c;你在后台比例设置里面设置 首重利润是1元&#xff0c;续重0.5元&#xff0c;用户下1kg的单页面显示的就是6元…

Android修行手册 - 阴影效果的几种实现以及一些特别注意点

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列点击跳转>ChatGPT和AIGC &#x1f449;关于作者 专…

Copliot:让你一秒变身网页达人的神奇助手

Copliot&#xff1a;一款能够帮助你快速理解网页内容的智能助手 你是否有过这样的经历&#xff0c;当你浏览网页时&#xff0c;遇到了一些你不太了解的内容&#xff0c;比如一些专业术语&#xff0c;一些复杂的概念&#xff0c;或者一些有趣的话题&#xff1f;你是否想要快速地…

RobotFramework+Eclispe环境安装篇

环境安装是学习任何一个新东西的第一步&#xff0c;这一步没走舒坦&#xff0c;那后面就没有心情走下去了。 引用名句&#xff1a;工欲善其事必先利其器&#xff01;&#xff01; Robotframework&#xff1a;一款 自动化测试框架。 Eclipse&#xff1a;一款编辑工具。可以编…

数据分析场景下,企业如何做好大模型选型和落地?

在数据驱动的数字化时代&#xff0c;有效的数据分析已成为企业成功的关键因素。而随着大模型带来能力突破&#xff0c;让AI与数据分析相互结合&#xff0c;使分析结果更好支撑业务&#xff0c;促进企业内部数据价值释放&#xff0c;成为了当下企业用户尤为关注的话题。 如何按照…

普通测径仪升级的智能测径仪 增添11大实用功能!

普通测径仪能对各种钢材进行非接触式的外径及椭圆度在线检测&#xff0c;测量数据准确且无损&#xff0c;可测、监测、超差提示、系统分析等。在此基础上&#xff0c;为测径仪进行了进一步升级制成智能测径仪&#xff0c;为其增添更多智能化模块&#xff0c;让其使用更加方便。…

你的Edge浏览器难道不需要一个好看的浏览器起始页嘛

这是我登录后&#xff0c;并且上传了个人壁纸的页面 Br标签页 一 . 我们来看看界面和功能1.注册登录2.首页及右键功能3.添加小组件和app网址4.切换壁纸5. 计划页面 二 . Edge浏览器安装和chrome&#xff08;谷歌&#xff09;浏览器安装1. Edge浏览器安装2. chrome&#xff08;谷…

Mysql删除占用事务的线程

参考&#xff1a;https://www.jianshu.com/p/dd0291391188 产生原因&#xff1a;这个问题的原因是在mysql中产生了事务A&#xff0c;执行了修改的语句&#xff0c;比如&#xff1a; update t1 set aget18 where id1;此时事务并未进行提交&#xff0c;事务B开始运行&#xff0c…

MongoDB分片集群搭建

----前言 mongodb分片 一般用得比较少&#xff0c;需要较多的服务器&#xff0c;还有三种的角色 一般把mongodb的副本集应用得好就足够用了&#xff0c;可搭建多套mongodb复本集 mongodb分片技术 mongodb副本集可以解决数据备份、读性能的问题&#xff0c;但由于mongodb副本集是…

成本2元开发游戏,最快3分钟完成!全程都是AI智能体“打工”,大模型加持的那种

金磊 发自 凹非寺 量子位 | 公众号 QbitAI 家人们&#xff0c;OpenAI前脚刚发布自定义GPT&#xff0c;让人人都能搞开发&#xff1b;后脚国内一家大模型初创公司也搞了个产品&#xff0c;堪称重新定义开发——让AI智能体们协作起来&#xff01; 只需一句话&#xff0c;最快3分…

算法萌新闯力扣:找出字符串中第一个匹配项点下标

力扣热题&#xff1a;找出字符串中第一个匹配项点下标 开篇 这道题个人感觉非常不错&#xff0c;虽然是简单题&#xff0c;但可以巩固几个大家平时容易忘记的有关字符串的知识点&#xff0c;我在做题时也掉进去了。 题目链接&#xff1a;28.找出字符串中第一个匹配项点下标 …