Servlet 的 API

HttpServlet

        init:当 tomcat 收到了 /hello 这样的路径是请求后就会调用 HelloServlet,于是就需要对 HelloServlet 进行实例化(只实例一次,后续再有请求也不实例了)。

        destory:如果是通过 smart tomcat 的停止按钮,这个操作本质上是通过 tomcat 的 8005 端口主动停止,能够触发 destory。但如果是直接杀进程,此时很可能来不及执行 destory(这种情况比较常见)。

        service:每次收到请求都会先执行 service,然后再根据请求的类型调用对应的 doxxx。

因此:Servlet 的生命周期就可以理解为:1. 一开始的时候,执行 init;2. 每次收到请求,执行 service;3. 销毁之前,执行 destory。

处理请求

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

        这里默认是 get 请求,为了构造别的方法请求可以使用 postman 来构造,也可以通过 Ajax 写代码来进行构造

postman

Ajax

首先得在 webapp 目录下创建一个 .html 的文件

<!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.7.1/jquery.min.js"></script>
    <script>
        $.ajax({
            type: 'post',
            //这是相对路径的写法
            //url: 'method',
            //这是绝对路径的写法
            url: '/hello_servlet/method',
            success: function (body, status) {
                console.log(body);
            }
        });
    </script>
</body>
</html>

HttpServletRequest

        当 Tomcat 通过 Socket API 读取 HTTP 请求(字符串), 并且按照 HTTP 协议的格式把字符串解析成 HttpServletRequest 对象.

:因为 query string 是键值对形式(form 表单构造的 body 也是),所以就可以通过 getParameter 放法来根据 key 获取到 value。

获取 GET 请求中的参数

        GET 请求中的参数一般都是通过 query string 传递给服务器的. 形如:/getParameter?studentId=10&classId=20

        此时浏览器通过 query string 给服务器传递了两个参数, studentId 和 classId, 值分别是 10 和 11,此时在服务器端就可以通过 getParameter 来获取到参数的值.

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

        getParameter 的返回值类型为 String. 必要的时候需要手动把 String 转成 int 。当没有 query string的时候, getParameter 获取的值为 null.

获取 POST 请求中的参数

        POST 请求的参数一般通过 body 传递给服务器. body 中的数据格式有很多种. 如果是采用 form 表单的形式, 仍然可以通过 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("/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);
    }
}

创建 testPost.html, 放到 webapp 目录中:

<form action="postParameter" method="POST">
    <input type="text" name="userId">
    <input type="text" name="classId">
    <input type="submit" value="提交">
</form>

form 表单点击 提交 一定会发生页面跳转的

获取 POST 请求中的参数(2)

        如果 POST 请求中的 body 是按照 JSON 的格式来传递, 那么获取参数的代码就要发生调整。因为通过 json 传递数据,服务器这边默认是把整个 body 都读过来,即没有按照键值对的方式来处理,也就不能根据 key 获取 value。

        因此,要使用第三方库 “Jackson” 来解析 json 格式。在 maven 仓库里搜 Jackson,然后选一个版本点进去把 xml 片段粘贴到 pom.xml 的 <dependencies> 中即可。

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;

class Student {
    // 把属性设为 public 的原因是能让 外面的Jackson 获取到这里有什么属性
    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 的,得到的是没有被处理过的 json
        // 通过这个方法来处理 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);


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

HttpServletResponse

        Servlet 中的 doXXX 方法的目的就是根据请求计算得到相应, 然后把响应的数据设置到

HttpServletResponse 对象中. 然后 Tomcat 就会把这个 HttpServletResponse 对象按照 HTTP 协议的格式, 转成一个字符串, 并通过 Socket 写回给浏览器.

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.bilibili.com");  // 这是直接构造了重定向响应

        // 上面的一行代码也可以分成下面两行:先设置状态码,然后再设置需要跳转到哪里
        resp.setStatus(302);
        resp.setHeader("Location", "https://www.bilibili.com");
    }
}

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

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

相关文章

存在重复元素 II[简单]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给你一个整数数组nums和一个整数k&#xff0c;判断数组中是否存在两个不同的索引i和j&#xff0c;满足nums[i] nums[j]且abs(i - j) < k。如果存在&#xff0c;返回true&#xff1b;否则&#xff0c;返回false。 示例 1&#…

Netty初识Hello World 事件循环对象(EventLoop) 事件循环组 (EventLoopGroup)

初始Netty-HelloWorld Netty在网络通信中的地位就如同Spring框架在JavaEE开发中的地位。 基于Netty网络通信开发简易的服务端、客户端&#xff0c;以实现客户端向服务端发送hello world&#xff0c;服务端仅接收不返回数据。 服务端代码&#xff1a; Slf4j public class Hell…

ICML2024 定义新隐私保护升级:DP-BITFIT新型微调技术让AI模型学习更安全

DeepVisionary 每日深度学习前沿科技推送&顶会论文分享&#xff0c;与你一起了解前沿深度学习信息&#xff01; 引言&#xff1a;差分隐私在大模型微调中的重要性和挑战 在当今的深度学习领域&#xff0c;大型预训练模型的微调已成为提高各种任务性能的关键技术。然而&am…

开放式耳机哪个品牌音质好用又实惠耐用?五大公认卷王神器直入!

​在现今耳机市场&#xff0c;开放式耳机凭借其舒适的佩戴体验和独特的不入耳设计&#xff0c;备受消费者追捧。它们不仅让你在享受音乐时&#xff0c;仍能察觉周围的声音&#xff0c;确保与人交流无障碍&#xff0c;而且有利于耳朵的卫生与健康。对于运动爱好者和耳机发烧友而…

AI大模型探索之路-实战篇7:Function Calling技术实战:自动生成函数

系列篇章&#x1f4a5; AI大模型探索之路-实战篇4&#xff1a;深入DB-GPT数据应用开发框架调研 AI大模型探索之路-实战篇5&#xff1a;探索Open Interpreter开放代码解释器调研 AI大模型探索之路-实战篇6&#xff1a;掌握Function Calling的详细流程 目录 系列篇章&#x1f4a…

Centos修改系統語言

一、使用命令行修系统语言 1、显示系统当前语言环 [rootkvm-suma ~]# localectl System Locale: LANGen_US.utf8 VC Keymap: cn X11 Layout: cn 2、查看系统支持字符集 [rootkvm-suma ~]# locale -a 2、设置系统语言环境 [rootkvm-suma ~]# localectl set-locale LANGz…

Gradio 搭建yolov8 分类系统

代码 import gradio as gr import pandas as pd from ultralytics import YOLO from skimage import data from PIL import Imagemodel YOLO(yolov8n-cls.pt) def predict(img):logging.info("Gradio 调用开始")result model.predict(sourceimg)logging.info("…

机器学习预测-CNN手写字识别

介绍 这段代码是使用PyTorch实现的卷积神经网络&#xff08;CNN&#xff09;&#xff0c;用于在MNIST数据集上进行图像分类。让我一步步解释&#xff1a; 导入库&#xff1a;代码导入了必要的库&#xff0c;包括PyTorch&#xff08;torch&#xff09;、神经网络模块&#xff0…

【Linux】Linux的安装

文章目录 一、Linux环境的安装虚拟机 镜像文件云服务器&#xff08;可能需要花钱&#xff09; 未完待续 一、Linux环境的安装 我们往后的学习用的Linux版本为——CentOs 7 &#xff0c;使用 Ubuntu 也可以 。这里提供几个安装方法&#xff1a; 电脑安装双系统&#xff08;不…

LeetCode热题100——矩阵

73.矩阵清零 题目 给定一个 *m* x *n* 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]] 示例…

OpenAI撤回有争议的决定:终止永久性非贬损协议

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Docker提示某网络不存在如何解决,添加完网络之后如何删除?

Docker提示某网络不存在如何解决&#xff1f; 创建 Docker 网络 假设现在需要创建一个名为my-mysql-network的网络 docker network create my-mysql-network运行容器 创建网络之后&#xff0c;再运行 mysqld_exporter 容器。完整命令如下&#xff1a; docker run -d -p 9104…

力扣刷题---2283. 判断一个数的数字计数是否等于数位的值【简单】

题目描述 给你一个下标从 0 开始长度为 n 的字符串 num &#xff0c;它只包含数字。 如果对于 每个 0 < i < n 的下标 i &#xff0c;都满足数位 i 在 num 中出现了 num[i]次&#xff0c;那么请你返回 true &#xff0c;否则返回 false 。 示例 1&#xff1a; 输入&a…

机器人物理引擎

机器人物理引擎是用于计算并模拟机器人及其交互环境在虚拟世界中运动轨迹的组件。 MuJoCo&#xff08;Multi-Joint Dynamics with Contact&#xff09;&#xff1a; 基于广义坐标和递归算法&#xff0c;专注于模拟多关节系统如人形机器人。采用了速度相关的算法来仿真连接点力…

AI菜鸟向前飞 — LangChain系列之十四 - Agent系列:从现象看机制(上篇)

上一篇介绍了Agent与LangGraph的基础技能Tool的必知必会 AI菜鸟向前飞 — LangChain系列之十三 - 关于Tool的必知必会 前面已经详细介绍了Promp、RAG&#xff0c;终于来到Agent系列&#xff08;别急后面还有LangGraph&#xff09;&#xff0c;大家可以先看下这张图&#xff1…

网络模型-路由策略

一、路由策略 路由策略(Routing Policy)作用于路由&#xff0c;主要实现了路由过滤和路由属性设置等功能&#xff0c;它通过改变路由属性(包括可达性)来改变网络流量所经过的路径。目的:设备在发布、接收和引入路由信息时&#xff0c;根据实际组网需要实施一些策略&#xff0c…

C++:关联容器及综合运用:

关联容器和顺序容器有着根本的不同:关联容器中的元素是按关键字来保存和访问的,而顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的。关联容器因此相比与顺序容器支持高效的关键字查找和访问。 其底层数据结构&#xff1a;顺序关联容器 ->红黑树&#xff0c;插入…

Redis离线安装(单机)

目录 1-环境准备1-1下载redis-4.0.11.tar.gz1-2gcc环境 2-上传解压3-编译安装(需要gcc环境)4-配置redis5-启动Redis6-开启防火墙(root)7-添加开机启动脚本8-设置权限9-设置开机启动10-测试redis服务11-检查是否安装成功12-创建redis命令软连接13-测试redis14-必要时设置防火墙 …

禅道密码正确但是登录异常处理

禅道密码正确&#xff0c;但是登录提示密码错误的异常处理 排查内容 # 1、服务器异常&#xff0c;存储空间、数据库异常 # 2、服务异常&#xff0c;文件丢失等异常问题定位 # 1、df -h 排查服务器存储空间 # 2、根据my.php排查数据库连接是否正常 # 3、修改my.pho,debugtrue…