【Servlet】(Servlet API HttpServlet 处理请求 HttpServletRequest 打印请求信息 前端给后端传参)

文章目录

  • Servlet API
    • HttpServlet
      • 处理请求
    • HttpServletRequest
      • 打印请求信息
      • 前端给后端传参


Servlet API

Servlet中常用的API

HttpServlet

在这里插入图片描述
实际开发的时候主要重写 doXXX 方法, 很少会重写 init / destory / service

destory 服务器终止的时候会调用.

//下面的注解把当前类和一个HTTP请求的路径关联起来
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    @Override
    public void init() throws ServletException {
        //重写init 插入自己"初始化"相关的逻辑
        System.out.println("init");
    }
    @Override
    public void destroy() {
        System.out.println("destroy");
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //这个只是在服务器的控制台打印
        System.out.println("hello world");
        //要想把hello world返回到客户端,需要使用下面的代码
        //getWriter 会得到一个Writer对象
        resp.getWriter().write("hello world");
    }
}

在这里插入图片描述
上面的destroy能不能被执行到有待商榷,如果是通过Smart Tomcat 的停止按钮,这个操作本质上是通过Tomcat的8005端口,主动停止,可以触发destroy.如果是直接杀进程,此时可能就来不及执行destroy就没了.因此不太推荐使用destroy.

service每次收到http请求就出触发(路径匹配)

@Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.service(req, resp);
    }

init / destory / service 这三个方法是HttpServlet中最关键的三个方法.

Servlet的声明周期是怎么回事?

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

处理请求

@WebServlet("/method")
public class MethodServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet");
        resp.getWriter().write("doGet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doPost");
        resp.getWriter().write("doPost");
    }

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doPut");
        resp.getWriter().write("doPut");
    }

    @Override
    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doDelete");
        resp.getWriter().write("doDelete");
    }
}

我们刷新页面只有doGet请求,想要获得别的请求可以利用postman这个软件来实现:

在这里插入图片描述
也可以通过ajax来构造请求:先在webapp目录下创建test.html.
在这里插入图片描述

<!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.6.4/jquery.min.js"></script>
    <script>
        $.ajax({
            type: 'get',
            url: 'method',
            success: function(body, status){
                console.log(body);
            }
        });
    </script>
</body>
</html>

然后重启服务器,在网址栏输入:http://127.0.0.1:8080/hello_servlet/test.html然后刷新在控制台就能看到doGet请求了.想要获取别的请求,直接在代码中改就可以了,需要注意的是我们在编写Servlet代码的时候,每次修改代码,要及得重新启动服务器.
在这里插入图片描述

此处写的路径是相对路径,相对路径的基准目录是该html所在的路径.此处写method就相当于在http://127.0.0.1:8080/hello_servlet的基础上,再拼上一个method
在这里插入图片描述

绝对路径的写法:

在这里插入图片描述

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(String name)返回一个字符串对象的数组,包含所有给定的请求参数的值,如果参数不存在则返回 null
Enumeration getHeaderNames()返回一个枚举,包含在该请求中包含的所有的头名
String getHeader(String name)以字符串形式返回指定的请求头的值
String getCharacterEncoding()返回请求主体中使用的字符编码的名称
String getContentType()返回请求主体的 MIME 类型,如果不知道类型则返回 null
int getContentLength()以字节为单位返回请求主体的长度,并提供输入流,或者如果长度未知则返回 -1
InputStream getInputStream()用于读取请求的 body 内容. 返回一个 InputStream 对象

打印请求信息

@WebServlet("/showRequest")
public class ShowRequestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置响应的 content-type 告诉浏览器 响应的body里的格式是啥样的
        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>");

        //获取到 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());
    }
}

在浏览器通过 URL http://127.0.0.1:8080/hello_servlet/showRequest 访问, 可以看到:
在这里插入图片描述

前端给后端传参

1.通过GET里的query string

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

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

在这里插入图片描述
如果key在query string中不存在,此时就返回值就是null

2.通过POST,借助form表单的方式
对于前端是form表单这样格式的数据(也是键值对,和query string的格式一样,只是这部分内容在body中),后端还是使用getParameter来获取.

前端代码:

<!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>

在这里插入图片描述

后端代码:

@WebServlet("/postParameter")
public class PostParameterServlet extends HttpServlet {
    @Override
    protected 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 + " classId = " + classId);
    }
}

在这里插入图片描述

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

在这里插入图片描述

3.POST里的json

json是一种非常主流的数据格式,也是键值对结构.
在这里插入图片描述
我们可以把body按照这个格式来组织.前端可以通过ajax的方式来构造出这个内容,更简单的方法使用postman直接构造.

在这里插入图片描述

后端代码:

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

然后在postman那块点击Send请求,服务器也相对应打印出了从body中读出的数据.
在这里插入图片描述

总结:借助postman构造出post请求,body就是json数据,请求到达Tomcat,Tomcat解析成req对象,再通过req.getInputStream读取body内容,把读出的结果构造成响应往回写,最后postman客户端收到了对应的结果.

当前通过json传递数据,但是服务器这边只是把整个body读出来,没有按照键值对的方式来处理,还不能根据key获取value,为了解决这个问题,我们可以使用jackson第三方库.

通过maven引入第三方库:

在这里插入图片描述

在这里插入图片描述

将所选的内容粘贴到pom.xml当中:

在这里插入图片描述

然后上面的后端代码就需要改变:

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 {
        Student student = objectMapper.readValue(req.getInputStream(),Student.class);
        System.out.println(student.studentId + ", " + student.classId);
    }
}

在这里插入图片描述

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

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

相关文章

urllib爬虫模块

urllib爬取数据 import urllib.request as request# 定义url url "https://www.baidu.com" #模拟浏览器发起请求获取响应对象 response request.urlopen(url)""" read方法返回的是字节形式的二进制数据 二进制--》字符串 解码 decode( 编码的格式…

部署lawyer-llama

Git - Downloading PackageGit - Downloading PackageGit - Downloading Package 下载git&#xff0c;wget需要下载一下 &#xff08;GNU Wget 1.21.4 for Windows&#xff09;&#xff0c; Windows中git bash完全可以替代原生的cmd&#xff0c;但是对于git bash会有一些Linu…

一个基于SpringBoot+Vue前后端分离高校心理健康系统详细设计实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

仓储二代拣货标签接口

1.批量拣货更新标签信息接口 http://localhost/smartpick/associate/lightTags 代码形式&#xff1a; { url : http://localhost/smartpick/associate/lightTags, requestMethed : POST, requestParameter : { [ {"mac":"99.99.22.03","devty…

Docker中部署redis

1.部署redis要求 2.部署教程 连接容器中的redis redis部署完毕

Oracle-如何判断字符串包含中文字符串(汉字),删除中文内容及保留中文内容

今天遇见一个问题需要将字段中包含中文字符串的筛选出来 --建表 CREATE TABLE HADOOP1.AAA ( ID VARCHAR2(255) ); --添加字段INSERT INTO HADOOP1.AAA(ID)VALUES(理解);....--查询表内容SELECT * FROM HADOOP1.AAA;在网上查找了一下有以下三种方式&#xff1a; 第一种&#…

开源数据库Mysql_DBA运维实战 (DCL/日志)

SQL&#xff08;Structured Query Language 即结构化查询语言&#xff09; a.DDL语句 数据库定义语言&#xff1a; 数据库&#xff0c;表&#xff0c;视图&#xff0c;索引&#xff0c;存储过程&#xff0c;函数&#xff0c;创建删除ALTER(CREATE DROP ALTER) b.DML语句 数…

在Excel中将数值差距极大的两个序列用对比明显的折线图表示

在Excel中&#xff0c;如果两个数据序列的数值差距太大&#xff0c;用这样的数据序列生成折线图时&#xff0c;折线图会显得过于平缓&#xff0c;趋势对比不明显。如下图&#xff1a; 这时候只要将趋势图设置成双坐标轴&#xff0c;将其中一条趋势线绘制到次坐标轴上&#xff0…

java毕业设计-智慧食堂管理系统-内容快览

首页 智慧食堂管理系统是一种可以提高食堂运营效率的管理系统。它将前端代码使用Vue实现&#xff0c;后端使用Spring Boot实现。这个系统的目的是简化食堂管理&#xff0c;提高食堂服务质量。在现代快节奏的生活中&#xff0c;人们对餐饮服务提出了更高的要求&#xff0c;食堂管…

【Quarkus技术系列】「云原生架构体系」在云原生时代下的Java“拯救者”是Quarkus,那云原生是什么呢?

云原生时代下的Java"拯救者" 在云原生时代&#xff0c;其实Java程序是有很大的劣势的&#xff0c;以最流行的spring boot/spring cloud微服务框架为例&#xff0c;启动一个已经优化好&#xff0c;很多bean需要lazy load的application至少需要3-4秒时间&#xff0c;内…

C语言快速回顾(二)

前言 在Android音视频开发中&#xff0c;网上知识点过于零碎&#xff0c;自学起来难度非常大&#xff0c;不过音视频大牛Jhuster提出了《Android 音视频从入门到提高 - 任务列表》&#xff0c;结合我自己的工作学习经历&#xff0c;我准备写一个音视频系列blog。C/C是音视频必…

【Github】SourceTree技巧汇总

sourceTree登录github账户 会跳转到浏览器端 按照Git Flow 初始化仓库分支 克隆远程仓库到本地 推送变更到远程仓库 合并分支 可以看到目前的本地分支&#xff08;main、iOS_JS&#xff09;和远程分支&#xff08;origin/main、origin/HEAD、origin/iOS_JS&#xff09;目前所处…

C++多线程场景中的变量提前释放导致栈内存异常

多线程场景中的栈内存异常 在子线程中尝试使用当前函数的资源&#xff0c;是非常危险的&#xff0c;但是C支持这么做。因此C这么做可能会造成栈内存异常。 正常代码 #include <iostream> #include <thread> #include <windows.h>// 线程函数&#xff0c;用…

消防态势标绘工具,为消防基层工作助力

背景介绍 无人机测绘技术在消防领域的应用越来越普及&#xff0c;高清的二维正射影像和倾斜摄影实景三维模型能为消防态势标绘提供高质量的素材&#xff0c;消防队急需一个简便易用的、能够基于这些二三维的高清地图成果进行态势标绘的工具软件&#xff0c;使得消防“六熟悉”…

Rust 重载运算符|复数结构的“加减乘除”四则运算

复数 基本概念 复数定义 由实数部分和虚数部分所组成的数&#xff0c;形如a&#xff0b;bi 。 其中a、b为实数&#xff0c;i 为“虚数单位”&#xff0c;i -1&#xff0c;即虚数单位的平方等于-1。 a、b分别叫做复数a&#xff0b;bi的实部和虚部。 当b0时&#xff0c;a&…

(二)结构型模式:2、桥接模式(Bridge Pattern)(C++实现示例)

目录 1、桥接模式&#xff08;Bridge Pattern&#xff09;含义 2、桥接模式应用场景 3、桥接模式的UML图学习 4、C实现桥接模式的示例 1、桥接模式&#xff08;Bridge Pattern&#xff09;含义 桥接模式是一种结构型设计模式&#xff0c;它将抽象部分与实现部分分离&#…

解决ubantu驱动掉了的问题

这里写自定义目录标题 解决ubuntu驱动掉了的问题 解决ubuntu驱动掉了的问题 首先确定是否有驱动&#xff1a; ls /usr/src | grep nvidia若有&#xff0c;则大概率是驱动版本与内核版本对应不上&#xff0c;则把内核版本切换为初始版本即可。参照&#xff1a;https://blog.cs…

【小梦C嘎嘎——启航篇】string介绍以及日常使用的接口演示

【小梦C嘎嘎——启航篇】string 使用&#x1f60e; 前言&#x1f64c;C语言中的字符串标准库中的string类string 比较常使用的接口对上述函数和其他函数的测试代码演示&#xff1a; 总结撒花&#x1f49e; &#x1f60e;博客昵称&#xff1a;博客小梦 &#x1f60a;最喜欢的座右…

【Spring专题】Bean的生命周期流程图

目录 前言阅读指引 流程图一、之前推测的简单流程图&#xff08;一点点参考&#xff09;*二、Bean生命周期流程图&#xff08;根据Spring源码自结&#xff09;*三、阶段源码流程图&#xff08;不断更新&#xff09; 前言 我向来不主张【通过源码】理解业务&#xff0c;因为每个…

idea报错:java: 程序包org.springframework.web.bind.annotation不存在

这个错误通常都是maven仓库的问题&#xff0c;试了网上很多方法&#xff0c;都没有解决&#xff0c;如果大家有遇到这个问题&#xff0c;且试了很多方法之后都没有解决&#xff0c;不妨可以试试我这个方法 先编译一下已经写好的代码&#xff0c;这时候会出现以上报错&#xff…
最新文章