JavaWeb:Servlet、ServletContext、HttpServletResponse、HttpServletRequest 的详细内容

news2024/11/15 4:53:42

文章目录

  • JavaWeb - 02
  • 一、Servlet
    • 1. 简介
    • 2. HelloServlet
    • 3. Servlet 原理
    • 4. Mapping 原理
  • 二、ServletContext
    • 1. 共享数据
    • 2. 获取初始化参数
    • 3. 请求转发
    • 4. 读取资源文件
  • 三、HttpServletResponse
    • 1. 方法介绍
    • 2. 应用:下载文件
    • 3. 应用:创建验证码
    • 4. 应用:重定向
    • 5. 总结
  • 四、HttpServletRequest
    • 1. 获取前端传递的参数
    • 2. 请求转发
  • 注意:

JavaWeb - 02

一、Servlet

1. 简介

Servlet 是 Sun 公司开发动态 Web 的一门技术,在这些 API 中提供了一个接口就是:Servlet,开发一个 Servlet 程序需要两个步骤

  • 编写一个类,实现 Servlet 接口;
  • 把开发好的 java 类部署到 Web 服务器中。

把实现了 Servlet 接口的 Java 程序叫做 Servlet

2. HelloServlet

  • 创建一个普通的 Maven 项目,注意在 Settings 中修改 Maven 地址,并删除 src 文件夹。

  • 在 pom 文件中导入用到的 jar 包
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
</dependency>

<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.1</version>
</dependency>

注意:在 Maven 仓库中下载,groupId路径artifactIdjar 包名version版本

  • 建立 Module 模块(子项目)

注意:父项目中的 jar 包,子项目可以直接使用。

  • Maven 环境优化(2 步)

第一步:修改子项目中 webapp.WEB-INF 中的 web.xml 配置文件(可以用 apache-tomcat-8.5.85\webapps\ROOT\WEB-INF 中的 web.xml 配置文件替换),修改原因:因为是直接用 Maven 模板,版本太低,用新版本

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1"
         metadata-complete="true">
</web-app>

第二步:将 Maven 的结构搭建完整:在子项目的 main 中建立 java 以及 resources 文件夹,并标记功能

  • 编写一个 Servlet 程序(3 步)

第一步:刷新子项目的 pom.xml 文件,可以创建一个新的 Servlet,并重写 doPost 和 doGet 方法。

public class HelloServlet extends HttpServlet {

    // 由于 get 或者 post 都是请求实现的不同方式,可以相互调用,业务逻辑都一样
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter writer = response.getWriter();  // 响应流
        writer.println("Hello, Servlet!");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

}

注意:由于 get 或者 post 都是请求实现的不同方式,可以相互调用,业务逻辑都一样。

第二步:在 web.xml 中编写 Servlet 的映射,因为我们写的是 Java 程序,但是要通过浏览器访问,而浏览器需要连接 Web 服务器,所以我们需要在 Web 服务器中注册我们写的 Servlet,给一个浏览器能够访问的路径。

<!-- 注册 Servlet -->
<servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>com.Sun3285.servlet.HelloServlet</servlet-class>
</servlet>

<!-- Servlet 的请求路径 -->
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
</servlet-mapping>

注意

  • servlet-name 可以随便起,但上下要一致
  • servlet-class 是在 Web 服务器中注册我们写的 Servlet(Web 服务器 – Java 程序);
  • url-pattern 是 Servlet 的请求路径,浏览器连接 Web 服务器(Web 服务器 – 浏览器)。

第三步:配置 Tomcat:注意配置项目发布的路径。

  • 启动测试

注意:请求 s1 进入主页 index.jsp,再请求 /hello 进入 web.xml 中找 url-pattern > servlet-name > servlet-class,然后进入自己编写的 Java 程序 HelloServlet.java

3. Servlet 原理

Servlet 原理(Web 服务器 – Java 程序实现的过程)

Web 服务器在收到浏览器请求之后,会进行如图所示过程。

注意:自己的实现类重写方法作用

  • 接受并处理请求
  • 给出响应的信息。

4. Mapping 原理

  1. 一个 Servlet 的请求可以指定一个或多个映射路径
<!-- 映射路径 hello1 和 hello2 都对应同一个 Servlet 的请求 -->
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello1</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello2</url-pattern>
</servlet-mapping>
  1. 一个 Servlet 的请求可以指定通用映射路径
<!-- 用通配符 * -->
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello/*</url-pattern>
</servlet-mapping>

注意:指定了固有的映射路径优先级最高,如果找不到就会走通用的映射路径。

  1. 可以自定义后缀实现请求映射。
<!-- 用通配符 * -->
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>*.Sun3285</url-pattern>
</servlet-mapping>

注意:此时在 mapping 中 * 前面不能加项目映射的路径 /,如:/hello/*.Sun3285,而 /hello.Sun3285正确的


二、ServletContext

Web 在启动时,会为每个 Web 程序都创建一个对应的 ServletContext 对象,代表了当前的 Web 应用

注意:每个 Web 工程只有一个 ServletContext 对象,可以有多个 Servlet。

1. 共享数据

在 Servlet 中保存的数据,可以在另外一个 Servlet 中拿到。

方法名说明
void setAttribute(String var1, Object var2)键值对的形式保存数据
Object getAttribute(String var1)根据键获取数据
  • 放置数据的类
ServletContext context = this.getServletContext();

String name = "Sun3285";  // 数据
context.setAttribute("username", name);  // 将数据保存在 ServletContext 中
  • 读取数据的类
ServletContext context = this.getServletContext();
String name = (String) context.getAttribute("username");

response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
response.getWriter().println("用户名为:" + name);

注意:放置数据和读取数据中得到的 ServletContext 对象为同一个

  • 映射
<servlet>
    <servlet-name>setu</servlet-name>
    <servlet-class>com.Sun3285.servlet.OneServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>setu</servlet-name>
    <url-pattern>/setu</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>getu</servlet-name>
    <servlet-class>com.Sun3285.servlet.TwoServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>getu</servlet-name>
    <url-pattern>/getu</url-pattern>
</servlet-mapping>
  • 测试访问结果:先进行 setu,再进行 getu

2. 获取初始化参数

方法名说明
String getInitParameter(String var1)获取初始化参数

注意:方法由 ServletContext 对象调用。

3. 请求转发

方法名说明
RequestDispatcher getRequestDispatcher(String var1)请求转发,参数为转发的请求路径,如 /hello

例如

// 请求转发
RequestDispatcher requestDispatcher = context.getRequestDispatcher("/hello");
requestDispatcher.forward(request, response);  // 调用 forward 实现请求转发,最后结果为获取了 /hello 路径的内容

注意请求转发重定向区别。

  • 相同点:页面都会实现跳转。
  • 不同点请求转发时,URL 不会产生变化,状态码为 307;重定向时,URL 会发生改变,状态码为 302。

4. 读取资源文件

方法名说明
InputStream getResourceAsStream(String var1)产生一个资源流
  • 先准备一个 Properties 类型的文件
username = Sun3285
password = 123456

注意

  • Properties 文件最好放在 resources 目录下,最后生成在 target 文件的 classes 文件下;
  • main 文件下的 javaresources 运行后都被打包到了同一路径下,即 classes ,俗称类路径 classpath
  • 读取资源文件
ServletContext context = this.getServletContext();

InputStream is = context.getResourceAsStream("/WEB-INF/classes/aa.properties");

Properties prop = new Properties();
// 把要读取的属性文件以流的形式加载进去
prop.load(is);
String username = prop.getProperty("username");  // 获取属性
String password = prop.getProperty("password");

response.getWriter().println(username + " : " + password);

注意:读取资源文件需要一个文件流,用 ServletContext 对象来产生,其中路径是相对路径,从当前 Web 应用开始。


三、HttpServletResponse

Web 服务器接收到客户端的 Http 请求,针对这个请求,会分别创建一个代表客户端请求的 HttpServletRequest 对象和一个代表响应的 HttpServletResponse 对象。

  • HttpServletRequest :获取客户端请求过来的参数;
  • HttpServletResponse :给客户端响应的一些信息。

1. 方法介绍

HttpServletResponse 继承了 ServletResponse。

  • 负责向浏览器发送数据的方法
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
  • 负责向浏览器发送响应头的方法
void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
  • 设置响应的状态码
int SC_OK = 200;
int SC_NOT_FOUND = 404;
int SC_INTERNAL_SERVER_ERROR = 500;
int SC_BAD_GATEWAY = 502;
void setStatus(int var1);

HttpServletResponse 对象除了可以向浏览器输出消息外,还可以下载文件创建验证码以及重定向

2. 应用:下载文件

下载文件的步骤

  • 获取下载文件的路径和文件名;
  • 设置让浏览器能够支持下载;
  • 获取下载文件的输入流,创建缓冲区,文件拷贝。
// - 获取下载文件的路径和文件名
String realPath = "F:\\studying\\javastudy\\javaweb\\javaweb-03-servlet\\response\\src\\main\\resources\\涛涛.txt";
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);

System.out.println("下载文件的路径为:" + realPath);
System.out.println("下载文件的名称为:" + fileName);

// - 设置让浏览器能够支持下载
response.setHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
// response.setCharacterEncoding("utf-8");
// response.setContentType("text/html");

// - 获取下载文件的输入流,创建缓冲区,文件拷贝
InputStream is = new FileInputStream(realPath);
OutputStream os = response.getOutputStream();

InputStream bis = new BufferedInputStream(is);
OutputStream bos = new BufferedOutputStream(os);

byte[] buffer = new byte[1024];
int len;
while ((len = bis.read(buffer)) != -1) {
    bos.write(buffer, 0, len);
    bos.flush();
}

bos.close();
bis.close();

注意

  • realPath.substring(realPath.lastIndexOf("\\") + 1);获取文件名的常用方法;
  • response.setHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));设置浏览器能够支持下载,后面的 URLEncoder.encode(fileName, "utf-8") 可以使下载的文件名为 UTF-8 格式不乱码,如果没有这行代码,浏览器会直接显示文件内容,而不会下载;
  • 文件拷贝用字节缓冲输入流 + 字节缓冲输出流 + 以字节数组读取的组合;
  • 这里的输出流是 response 得到的输出流。

3. 应用:创建验证码

创建验证码步骤

  • 在内存中创建一个图片;
  • 告诉浏览器,这个请求用图片的方式打开;
  • 把图片写给浏览器。
response.setHeader("refresh", "3");  // 刷新

// 在内存中创建一个图片
BufferedImage image = new BufferedImage(110, 30, BufferedImage.TYPE_INT_RGB);
Graphics2D g = (Graphics2D) image.getGraphics();  // 得到图片,g 相当于画笔
g.setColor(Color.green);  // 设置图片的背景颜色
g.fillRect(0, 0, 110, 30);
g.setColor(Color.red);  // 给图片写数字
g.setFont(new Font(null, Font.BOLD, 20));  // 粗体,字号 20
g.drawString(makeNum(),10,20);  // 写入随机数

// 告诉浏览器,这个请求用图片的方式打开
response.setContentType("image/jpg");
response.setHeader("Cache-Control", "no-cache");  // 去除网站的缓存
response.setHeader("Pragma", "no-cache");

// 把图片写给浏览器
ImageIO.write(image, "jpg", response.getOutputStream());

生成 8 位随机数

// 生成 8 位的随机数
public String makeNum() {
    Random r = new Random();
    String num = String.valueOf(r.nextInt(99999999));  // 生成随机数
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < 8-num.length(); i++) {
        sb.append(r.nextInt(9));
    }
    String num1 = sb.toString();  // 补齐 8 位
    return num + num1;
}

4. 应用:重定向

// 重定向
response.sendRedirect("/r/image");

注意:重定向的时候一定要注意路径问题,否则 404。

相当于

response.setHeader("Location", "/r/image");  // 设置跳转地址
response.setStatus(302);  // 设置状态码

5. 总结

response 对象的方法使用

方法说明
response.getWriter()字符的形式向浏览器输出消息
response.getOutputStream()字节的形式向浏览器输出消息
response.setContentType(“text/html”)告诉浏览器用什么方式打开,如文本(text/html)、图片(image/jpg) 等
response.setCharacterEncoding(“utf-8”)设置编码格式
response.setHeader(“Content-Disposition”,“attachment;filename=” + URLEncoder.encode(fileName, “utf-8”))浏览器下载文件
response.setHeader(“refresh”, “x”)浏览器 x 秒刷新一次
response.setHeader(“Cache-Control”, “no-cache”)浏览器去缓存
response.setHeader(“Pragma”, “no-cache”)浏览器去缓存
response.sendRedirect(“跳转地址”)重定向,跳转地址需要从项目名开始
response.setHeader(“Location”, “跳转地址”)设置跳转地址
response.setStatus(302)设置状态码

四、HttpServletRequest

HttpServletRequest 代表客户端的请求,用户通过 Http 协议访问服务器,Http 请求中的所有信息会被封装到 HttpServletRequest 中,通过这个 HttpServletRequest 的方法,获得客户端的所有信息。

1. 获取前端传递的参数

调用方法说明
request.getParameter()获得一个参数的值
request.getParameterValues()获得多个参数的值
  • 删除原来的 index.jsp 文件,重新建立,并写前端内容。

注意${pageContext.request.contextPath}/login 表示 当前路径/login

  • 通过调用方法获取前端传递的参数
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");

String username = request.getParameter("username");
String password = request.getParameter("password");
String[] hobbies = request.getParameterValues("hobbies");
System.out.println("=============================");
System.out.println("username : " + username);
System.out.println("password : " + password);
System.out.println(Arrays.toString(hobbies));
System.out.println("=============================");
  • 效果

2. 请求转发

调用方法说明
request.getRequestDispatcher(“/转发路径”).forward(request, response)请求转发

注意:这里的 / 代表当前的 Web 应用,转发路径中不用再写项目名,因为转发是项目内部资源跳转。而重定向需要写项目名。

  • 建立跳转的页面 success.jsp

  • 请求转发
request.getRequestDispatcher("/success.jsp").forward(request, response);
  • 效果


注意:

  1. this 指当前类的对象

  2. 点击 clean 可以清除生成的 target 文件。

  1. random.nextInt(max) 表示生成 [0,max] 之间的随机数
  2. 请求转发和重定向的地址都是浏览器导航栏的路径

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

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

相关文章

office web apps在线office文件预览部署及问题处理

文件下载链接网盘&#xff1a; 链接: https://pan.baidu.com/s/1OmWM5END0jyWESGzFCniEw 提取码: ejpg 基本环境需要两台机&#xff0c;1台为域控&#xff0c;1台为 &#xff08;office web apps &#xff0c;需要加入到域&#xff09; 主机1&#xff1a;添加域控服务 安装完…

设备树简介

设备树 设备树简介 设备树是一种描述硬件的数据结构&#xff0c;它起源于OpenFirmware&#xff08;OF&#xff09;。 在Linux 2.6中&#xff0c; ARM架构的板极硬件细节过多地被硬编码在arch/arm/plat-xxx和arch/arm/mach-xxx中&#xff0c;采用设备树后&#xff0c;许多硬件…

python操作字典

# 字典 score{"张三":"23","王五":"45"} print(score) dctdict(name张三,age20) print(dict) print(type(score)) # 字典元素的获取 print(score[张三]) print(score.get(张三)) # 判断是否是字典中的元素 print(王五 in score) # 为字…

浅析AI视频智能识别技术如何助力智慧平安校园建设

校园安全一直是学生健康成长、全面发展的前提与保障。校园门口伤害事件的频发与校园内应急事件的突发&#xff0c;让建设平安校园的任务愈加急迫。校园人流量大、监控点多&#xff0c;安保人员无法同时盯住上百个视频画面&#xff0c;亦无法保证24小时有效监控。传统的校园安防…

软件测试简历项目经验怎么写?一篇足矣解决

一、前言&#xff1a;浅谈面试 面试是我们进入一个公司的门槛&#xff0c;通过了面试才能进入公司&#xff0c;你的面试结果和你的薪资是息息相关的。那如何才能顺利的通过面试&#xff0c;得到公司的认可呢?面试软件测试要注意哪些问题呢?下面和笔者一起来看看吧。这里分享一…

OpenGL(十一)——材质

目录 一、前言 二、物体材质 三、光源材质 一、前言 OpenGL材质是模拟现实世界中不同材质物体表面&#xff0c;如木制箱子和钢制箱子对光的反射程度不同。物体材质对接受光散射程度不同&#xff0c;较少散射产生较小高光点&#xff0c;较多散射则会产生较大高光点。前面章节…

如何节约ChatGPT消耗的token

如何节约GPT的token.md 原文链接&#xff1a;小回博客 如何节约GPT的token 一、模拟一下携带上下文的流程&#xff1a; 第1次问答&#xff1a; 你&#xff1a;帮我写一个1000字的文案&#xff08;13&#xff09; gpt: xxxxxx (1000)第2次问答&#xff1a; 你&#xff1a;谢…

《我命由我不由天》蔡志忠——笔记三

目录 经典摘录 1、大脑是用来思考的 2、养生主 3、自己的问题&#xff0c;自己找答案 4、42岁自学英文 5、终身阅读 6、打不垮我们的终究使我们更强大 7、大环境下失业 8、生命只能兑现此刻 经典摘录 1、大脑是用来思考的 罗素非常反对制式教育&#xff0c;他说&#…

有哪些比较好的测试用例管理工具?

“新入职小型创业公司&#xff0c;想要一个比Excel高效且好用的工具。”我预料很多人会提TestLink、Jira、PingCode 等一堆平台&#xff0c;都2023年了&#xff0c;若还是复制粘贴的10年前这一套&#xff0c;那就让人看不下去了。为了让大家少走弯路&#xff0c;所以我写了这篇…

【自用】配置minGW、vscode配置ESP-IDF环境

步骤总览 1.配置minGW 2.下载安装esp-idf软件 3.将vscode esp-idf插件 和 esp-idf软件进行关联 一、配置minGW 1.下载 链接&#xff1a;https://pan.baidu.com/s/1j6ITlNDDyivKwpWNBjASvg?pwd0108 提取码&#xff1a;0108 2.解压 解压上面下载的压缩包即可 3.配置环境变…

EFDC建模方法及在地表水环境评价、水源地划分、排污口论证应用

目录 专题一 软件安装 专题二 EFDC模型讲解 专题三 一维河流模拟实操&#xff08;上机操作&#xff09; 专题四 建模前处理&#xff08;上机操作&#xff09; 专题五 EFDC网格剖分介绍&#xff08;上机操作&#xff09; 专题六 EFDC二维湖库水动力模拟/非保守染色剂模拟&…

prometheus监控数据持久化

前置条件 1.规划两台主机安装prometheus # kubectl get nodes --show-labels | grep prometheus nm-foot-gxc-proms01 Ready worker 62d v1.23.6 beta.kubernetes.io/archamd64,beta.kubernetes.io/oslinux,kubernetes.io/archamd64,kubernetes.io…

5.Redis持久化

5.Redis持久化 总体介绍持久双雄一图&#xff1a;Redis persistence RDB&#xff08;Redis Database&#xff09;官网介绍RDB&#xff08;Redis 数据库&#xff09;&#xff1a;RDB 持久性以指定的时间间隔执行数据集的时间点快照。能干嘛&#xff1f;案例演示&#xff1a;需求…

图像处理——连接IP摄像头上传到服务器实现目标识别

前言 1.项目的需求是&#xff0c;本地连接IP摄像头&#xff0c;然后把图像上传到图像处理服务器器进行处理&#xff0c;得到的结果返回本地。 2.IP摄像头使用的是大华的摄像头&#xff0c;目标识别用的yolov5的模型&#xff0c;服务器用的是flask&#xff0c;实现语言是pytho…

【闪击Python】字符串的创建和驻留机制

&#x1f48c; 博客内容&#xff1a;字符串的创建和驻留机制 &#x1f600; 作  者&#xff1a;陈大大陈 &#x1f680; 个人简介&#xff1a;一个正在努力学技术的准前端&#xff0c;专注基础和实战分享 &#xff0c;欢迎私信&#xff01; &#x1f496; 欢迎大家&#x…

Dear Reality 发布全新 EXOVERB MICRO 混响插件

空间感混响效果新高度 Dear Reality 发布全新 EXOVERB MICRO 混响插件 Dear Reality 针对立体声制作推出最新的混响插件 EXOVERB MICRO&#xff0c;提供一流的真实感和空间感混响效果&#xff0c;将立体声混音技术提升至新高度。这个紧凑型音频插件功能非常强大&#xff0c;采…

得物社区亿级ES数据搜索性能调优实践

1.背景 2020年以来内容标注结果搜索就是社区中后台业务的核心高频使用场景之一&#xff0c;为了支撑复杂的后台搜索&#xff0c;我们将社区内容的关键信息额外存了一份到Elasticsearch中作为二级索引使用。随着标注业务的细分、迭代和时间的推移&#xff0c;这个索引的文档数和…

VisualStudio2022配置PCL点云库教程

属性管理器 首先&#xff0c;打开属性管理器&#xff1a;视图–其他窗口–属性管理器 打开后如图所示&#xff0c;选中Debug|x64&#xff0c;右键单击&#xff0c;选择属性 如图所示&#xff0c;需要修改的是VC目录中的包含目录和库目录&#xff1a; ** 包含目录 添加内容…

Andorid:日常学习笔记(3)——掌握日志工具的使用

使用Android的日志工具Log 方法: Android中的日志工具类为Log,这个类提供了如下方法来供我们打印日志: 使用方法: Log.d("MainActivity","onCreate execute"); 第一个参数tag:一般传入当前类名就好,主要用于队打印信息进行过滤.第二个参数:msg,具体想打…