Servlet中的response对象

2023-05-16

目录

  • 目录
  • 前言
  • 简介
  • 向客户端输出数据
    • response对象的getOutputStream方法
    • response对象的getWriter方法
  • 实现文件下载
  • 生成图片验证码
  • 实现浏览器定时刷新
  • 控制浏览器缓存
  • 实现请求重定向

前言

  这里讲述的是Servlet中的response对象的使用(request对象将在下文进行介绍)。如下:
1. 使用ServletOutputStream或PrintWriter向客户端输出数据;
2. 文件的下载;
3. 输出图片验证码;
4. 控制浏览器缓存当前请求内容;
5. 通过response实现请求重定向。

简介

  • Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象和代表响应的response对象。
  • request和response对象既然代表请求和响应,那我们要获取客户机提交过来的数据,只需要找request对象就行了。要向客户机输出数据,只需要找response对象就行了。
  • HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。

向客户端输出数据

  • getOutputStreamgetWriter方法分别用于得到输出二进制数据、输出文本数据的ServletOutputStreamPrintWriter对象。
  • getOutputStreamgetWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。请求转发的情况下同样不能同时调用这两个方法,如请求转发前的Servlet调用了getOutputStream方法,请求转发后的Servlet调用了getWriter方法,这样的做法同样会使程序报错。同时调用response的getOutputStream和getWriter方法会抛出:java.lang.IllegalStateException: getOutputStream() has already been called for this response 异常。
  • Servlet程序向ServletOutputStreamPrintWriter对象中写入的数据将被Servlet引擎从response里面获取,Servlet引擎将这些数据当前响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端。
  • Servlet的service方法结束后,Servlet引擎将检查getWritergetOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象。所以在实际开发过程中,我们无需调用close方法关闭getWritergetOutputStream方法返回的输出流对象。但是对于我们自己创建的流对象就需要调用close方法手动关闭。

response对象的getOutputStream方法

  使用字节流 ServletOutputStream 向客户端输出数据,注意中文数据输出和数字输出的问题。

package com.wm103.response;

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.OutputStream;

/**
 * Created by DreamBoy on 2017/4/28.
 */

/**
 * 在servlet中用OutputStream输出数据的问题
 */
@WebServlet(name = "ResponseDemo1", urlPatterns = {"/ResponseDemo1"})
public class ResponseDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

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

    /**
     * 设置Content-type响应头
     * @param response
     * @throws IOException
     */
    private void test1(HttpServletResponse response) throws IOException {
        response.setHeader("Content-type", "text/html;charset=UTF-8");
        String data = "中国";
        OutputStream out = response.getOutputStream();
        out.write(data.getBytes("UTF-8"));
    }

    /**
     * 用html技术中meta标签模拟了一个http响应头,来控制浏览器的行为
     * @param response
     * @throws IOException
     */
    private void test2(HttpServletResponse response) throws IOException {
        String data = "中国";
        OutputStream out = response.getOutputStream();
        out.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'>".getBytes());
        out.write(data.getBytes("UTF-8"));
    }

    /**
     * 输出数字
     * @param response
     * @throws IOException
     */
    private void test3(HttpServletResponse response) throws IOException {
        OutputStream out = response.getOutputStream();
        //out.write(1); // 在浏览器中看不到1这个结果,需要以字符串形式输出数字
        out.write((1 + "").getBytes());
    }
}

response对象的getWriter方法

  使用字符流 PrintWriter 向客户端输出字符串数据,注意中文数据输出乱码问题。

package com.wm103.response;

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.PrintWriter;

/**
 * Created by DreamBoy on 2017/4/28.
 */

/**
 * 通过response的write流输出数据的问题
 */
@WebServlet(name = "ResponseDemo2", urlPatterns = {"/ResponseDemo2"})
public class ResponseDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

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

    /**
     * response.getWriter()输出中文数据显示的问题
     * @param response
     * @throws IOException
     */
    private void test1(HttpServletResponse response) throws IOException {
        // 设置response使用的码表,以控制response以什么码表向浏览器写出数据。(默认用的是ISO-8859-1)
        response.setCharacterEncoding("UTF-8");
        // 控制浏览器以什么码表显示服务器发送的数据
        response.setHeader("Content-type", "text/html;charset=utf-8");

        String data = "中国";
        PrintWriter out = response.getWriter();
        out.println(data);
        out.write(data);
    }

    /**
     * 以下方法相当于上述方法
     * @param response
     * @throws IOException
     */
    private void test2(HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("UTF-8"); // 这句话也可以不写
        response.setContentType("text/html;charset=utf-8");
        String data = "中国";
        PrintWriter out = response.getWriter();
        out.println(data);
        out.write(data);
    }
}

实现文件下载

  设置response的content-disposition响应头,提示文件下载,具体实现文件下载的程序如下:(示例中供下载的图片放置在项目的web目录的download文件夹下(如果是MyEclipse的话则是WebRoot目录的download文件夹下))
  注意:如果供下载的文件是以中文命名,则文件名在设置content-disposition时要经过URL编码。

package com.wm103.response;

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.io.OutputStream;
import java.net.URLEncoder;

/**
 * Created by DreamBoy on 2017/4/28.
 */

/**
 * 文件下载
 */
@WebServlet(name = "ResponseDemo3", urlPatterns = {"/ResponseDemo3"})
public class ResponseDemo3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //String path = this.getServletContext().getRealPath("/download/1.jpg");
        String path = this.getServletContext().getRealPath("/download/图片.jpg");
        String filename = path.substring(path.lastIndexOf("\\") + 1);

        // 如果下载文件是以中文命名,则文件名需要经过url编码
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));

        InputStream in = null;
        OutputStream out = null;
        try {
            in = new FileInputStream(path);
            int len;
            byte buffer[] = new byte[1024];
            out = response.getOutputStream();
            while ((len = in.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

生成图片验证码

  使用Java中的BufferedImage类,调用getGraphics方法,获取Graphics类的对象,进行图片的绘制。绘制成功后设置响应头返回的数据类型为图片,并控制浏览器不需要缓存当前请求。示例如下:

package com.wm103.response;

import javax.imageio.ImageIO;
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.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
 * Created by DreamBoy on 2017/4/28.
 */

/**
 * 输出一张随机图片(图片验证码)
 */
@WebServlet(name = "ResponseDemo4", urlPatterns = {"/ResponseDemo4"})
public class ResponseDemo4 extends HttpServlet {
    public static final int WIDTH = 120;
    public static final int HEIGHT = 50;

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

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

        BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        Graphics g = image.getGraphics();

        // 1. 设置背景色
        this.setBackground(g);

        // 2. 设置边框
        this.setBorder(g);

        // 3. 画干扰线
        this.drawRandomLine(g);

        // 4. 写随机数
        this.drawRandomNum((Graphics2D) g);

        // 5. 图片写给浏览器
        response.setContentType("image/jpeg");
        // 控制浏览器不要缓存图片
        response.setDateHeader("expires", -1);
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");

        ImageIO.write(image, "jpg", response.getOutputStream());

    }

    private void drawVCode() {

    }

    private void setBackground(Graphics g) {
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, WIDTH, HEIGHT);
    }

    private void setBorder(Graphics g) {
        g.setColor(Color.BLUE);
        g.drawRect(1, 1, WIDTH - 2, HEIGHT - 2);
    }

    private void drawRandomLine(Graphics g) {
        g.setColor(Color.GREEN);
        for(int i = 0; i < 5; i++) {
            int x1 = new Random().nextInt(WIDTH);
            int y1 = new Random().nextInt(HEIGHT);

            int x2 = new Random().nextInt(WIDTH);
            int y2 = new Random().nextInt(HEIGHT);
            g.drawLine(x1, y1, x2, y2);
        }
    }

    private void drawRandomNum(Graphics2D g) {
        int fontSize = 20;
        g.setColor(Color.RED);
        g.setFont(new Font("宋体", Font.BOLD, fontSize));

        String base = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789";
        int fontNum = 4;
        int y = 32;
        int x = 18; String ch;
        for(int i = 0; i < fontNum; i++) {
            int degree = new Random().nextInt() % 30;
            double radian = degree * Math.PI / 180; // 弧度
            g.rotate(radian, x, y); // 设置旋转的弧度

            ch = base.charAt(new Random().nextInt(base.length())) + "";
            g.drawString(ch, x, y);

            g.rotate(-radian, x, y);
            x += 25;
        }
    }
}

  在页面中的使用,如下:

验证码:<img style="cursor:pointer;" src="/day06/ResponseDemo4" alt="换一张" onclick="this.src = '/day06/ResponseDemo4?' + new Date().getTime()">

实现浏览器定时刷新

  • 每隔3秒刷新当前页面
response.setHeader("refresh", "3");
  • 3秒后跳转某一页面
response.setHeader("refresh", "3;url='/index.jsp'");
  • 通过HTML实现定时跳转
<meta http-equiv="refresh" content="3;url=index.jsp">

控制浏览器缓存

  • 禁止浏览器缓存
response.setDateHeader("expires", -1);
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
  • 设置浏览器缓存时间,如缓存一个小时:
String data = "This is ResponseDemo5.";
        response.setDateHeader("expires", System.currentTimeMillis() + 1000 * 3600); // 缓存一个小时
        response.getWriter().write(data);

实现请求重定向

  重定向的特点:
1. 浏览器会向服务器发送两次请求;
2. 浏览器地址将发生变化
  用户登录和显示购物车时,通常会用到重定向技术。

/*response.setStatus(302);
response.setHeader("location", "/day06/index.jsp");*/

response.sendRedirect("/day06/index.jsp");
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Servlet中的response对象 的相关文章

  • 当指定另一个页面时重定向到 webapp 默认文档?

    IIS6 ASP NET 2 0 无表单身份验证 我正在调用 Response Redirect foo aspx 但出现了我网站的默认文档 Default aspx 更糟糕的是 这种情况只是间歇性地发生 有时重定向会显示正确的页面 我检查
  • 基于动态代理实现接口耗时计算

    对于动态代理模式 Java的反射机制提供了支持 耗时计算写在主逻辑代码存在很强的耦合性 这里提供了一种解耦合的方式去实现 在Spring框架aop也用了这一技术 登录接口 public class UserServiceImpl imple
  • Node.js HTTP 客户端中的自动 UTF-8 编码

    我尝试使用 Node js 从远程主机加载 XML 内容 问题是像 这样的德语 元音变音 被破坏了 就像在浏览器中一样 这通常是一个简单的编码问题 但由于远程主机上的 XML 内容是用 iso 8859 2 编码的 所以我没有成功让这些字母
  • Python Web 服务器:如何异步处理请求

    我需要创建一个 python 中间件来执行以下操作 a 接受来自多个客户端的http get post 请求 b 修改这些请求并将其分派到后端远程应用程序 通过套接字通信 我对此远程应用程序没有任何控制权 c 接收来自后端应用程序的处理结果
  • 如何下载和/或提取 R 中响应对象内“原始”二进制 zip 对象中存储的数据?

    我无法使用 httr 包从 API 请求下载或读取 zip 文件 我是否可以尝试另一个包 它允许我下载 读取存储在 R 中 get 请求的响应中的二进制 zip 文件 我尝试了两种方法 使用 GET 获取 application json
  • 来自 REST 端点的 PHP 模拟数据

    我正在围绕第三方 API 编写 PHP 包装器 对于练习来说更是如此 但我目前还没有在任何地方看到一个好的可用的 所以也许将来它会被其他人使用 我的单元测试非常简单 但现在我已经达到了极限 API 的开发人员有最大请求限制 每秒 1 个 每
  • 如何在node.js+express中捕获“响应结束”事件?

    我想编写一个快速中间件函数 它在响应的 结束 事件 如果存在 上设置一个侦听器 目的是根据最终处理程序决定发送的 http 响应代码进行清理 例如记录数据库事务的响应代码和回滚 提交 即 我希望此清理对于最终调用者是透明的 我想在快递中做类
  • 获取 BLE 设备的响应

    我对使用蓝牙设备还很陌生 到目前为止一切都很完美 但有一个问题我不知道如何处理 我有一个 LED 灯设备 我可以改变一切 从颜色到速度 闪烁 褪色等等 现在我想读取当前的设备状态 例如设备是打开还是关闭 我有一份该设备的文件 上面写着 询问
  • PHP Curl 输出缓冲区未收到响应

    我有一个协议 其中 file1 phpcurl 运行 file2 php file2 php 是一个长时间运行的文件 但它发送 或应该发送 一个响应回 file1 php 然后继续执行它的代码 我正在使用输出缓冲区来尝试发送此数据 但问题是
  • 使用 C# 控制台应用程序创建 HTTP POST 请求并接收响应

    我需要将数据发布到 URL https somesite com 以根据我发布的参数下载 responseStrem 中的文件 如何使用 C 控制台应用程序来做到这一点 参数 文件名 用户身份 密码 类型 using System usin
  • 由于 MIME 类型不匹配,IE9 脚本响应被阻止

    我使用以下代码片段将 google fusion 表中的数据加载为 json var fileref document createElement script fileref setAttribute type text javascri
  • 响应使浏览器不执行任何操作 - 这可能吗?

    是否有可能做出这样的 HTTP 响应 浏览器会忽略它并继续显示先前显示的页面 我的意思是以下场景 a 用户点击某物 b 一些 POST 发送到服务器 或 GET 但我们还是使用 POST 因为更有趣 c 服务器由于某种原因决定此时不想发送回
  • “response.clear()”是否删除内容和标题?

    我需要知道是否Response Clear 只是清除内容还是也删除标题 换句话说 如果我使用Response Clear 我还需要使用Response ClearHeader 或不 AS MSDN http msdn microsoft c
  • Response.End 之后关闭窗口

    例如我有一个表格ListView即处于编辑模式 发生了一些事情 导致列表视图正在使用的表不再可用 我只想在用户点击 保存 时能够关闭窗口 In Page Load 我检查桌子是否可用 如果没有 我打电话RegisterClientScrip
  • Symfony2 响应 - 清除后退按钮上的缓存标头

    当按下后退按钮时 我遇到了清除缓存的问题 我的标头信息表明我是从缓存加载的 Status Code 200 OK from cache 我的回复设置为 response new Response response gt expire res
  • 200 响应但未返回 JSON 数据 - Restangular 问题?

    使用 reangular 和存根 hub api 我可以在 Firefox RestClient 上点击此 API 并获取包含所有 JSON 数据的响应正文 但在我的应用程序中 我收到 200 但没有响应正文 内容长度甚至表明存在某些内容
  • 在 FB Graph API 中确定具有 id 的对象类型

    有没有办法确定给定 ID 代表什么类型的对象https graph facebook com ID 当我在 Graph API Explorer 工具中请求此操作时 响应中有一个名为type 其中可能包含user page album ph
  • Codeception API 测试响应返回“N/A”

    我正在使用 Laravel 和 Codeception 作为测试框架编写 API 我无法让 Codeception 返回响应代码 我可以从 Codeception 获取响应代码 以及 JSON 响应 我编写了一个简单的测试来从 GET 请求
  • 角度订阅响应

    好吧 我对 Angular 还很陌生 所以我遇到了这个小问题 所以我遵循 Angular 指南 https angular io guide http https angular io guide http 所以我的问题是我的 http r
  • 什么是内容语言和接受语言?

    我已经看到了 HTTP 标头Content Language and Accept Language 有人可以解释一下它们的用途以及它们之间的区别吗 我有一个多语言网站 想知道我是否应该将这两个网站设置为用户当前选择的语言 Content

随机推荐

  • PHP中的cURL函数

    今天看了一个接口的使用 xff0c 其中接口的示例中使用到PHP的cURL函数 xff0c 那么有趣的事情就来了 使用PHP向某个URL发送数据并接收响应数据 xff1a function request data url data 61
  • 设计模式之适配器(Adapter)模式

    转载自 xff1a 设计模式学习笔记 适配器 Adapter 模式 参考 xff1a Java设计模式之Adapter模式 2 自己阅读了原文中的例子颇有受益 xff0c 在此前常听到Java中adapter适配器一词 xff08 虽说现在
  • Java软件体系结构设计模式之结构模式 知识点摘录

    以下知识点摘录自 xff1a Java软件体系结构设计模式标准指南 一书 其中可能包含本人的一些感悟 Java软件体系结构设计模式之结构模式 xff08 11种 xff09 结构模式主要用来 xff1a 1 xff09 处理把责任委托给其他
  • 支付宝在线支付接口开发教程与总结

    转载自 xff1a 支付宝在线支付接口开发教程与总结 1 什么是第三方支付 所谓第三方支付 xff0c 就是一些和各大银行签约 并具备一定实力和信誉保障的第三方独立机构提供的交易支持平台 在通过第三方支付平台的交易中 xff0c 买方选购商
  • Android 应用商店评分+APP分享

    转载自 xff1a Android Market链接的生成 调用Market 搜索软件 Android 调用已安装市场 xff0c 进行软件评分的功能实现 参考 xff1a Android跳转到应用商店的APP详情页面 xff0c 以及 G
  • 用一个二维码做下载地址,自动区分是 ios 还是 android

    转载自 xff1a 用一个二维码做下载地址 xff0c 自动区分是 ios 还是 android 更多参考 xff1a 好推二维码如何通过应用宝微下载支持微信自动打开APP下载 xff1f 用一个二维码做下载地址 xff0c 自动区分是 i
  • Node中的JavaScript

    Node中的JavaScript global对象 在浏览器中 xff0c 全局对象指的就是window对象 xff1b Node中有两个类似却各自代表着不同含义的对象 xff1a global和process xff1b 任何global
  • Node中的HTTP

    来自对 了不起的Node js 一书的学习 HTTP协议 超文本传输协议 xff0c 又称为HTTP xff0c 是一种Web协议 HTTP协议构建在请求和响应的概念上 xff0c 对应在Node js中就是由http ClientRequ
  • Node中的Connect

    来自对 了不起的Node js 一书的学习 Connect Node js为常规的网络应用提供了基本的API 然而 xff0c 实际情况下 xff0c 绝大部分网络应用都需要完成一系列类似的操作 xff0c 这些类似的操作你一定不想每次都重
  • Node中的Connect——常用中间件

    接下来介绍一个Connect内置的一些中间件 xff1a static中间件 1 挂载 static允许将任意一个URL匹配到文件系统中任意一个目录 如 xff1a 将 my images URL和名为 images的目录对应起来 xff0
  • Flask-apscheduler 无法启动工作,报错Run time of job was missed by... 解决方法

    先说结论 xff1a flask apscheduler 中如果要调用 app context环境的话 xff0c 用 scheduler app app context 详细过程 xff1a 1 环境与背景 xff0c 使用Flask 还
  • Node.js中同步函数异步编程

    转载自 xff1a nodejs 代码设计模式1 xff1a 同步函数变异步 同步函数变异步 1 问题 xff1a 1 1 碰到需要调用你刚正在创建的对像 span class hljs function span class hljs k
  • 深入理解Express.js

    转载自 xff1a 深入理解Express js 本文针对那些对Node js有一定了解的读者 假设你已经知道如何运行Node代码 xff0c 使用npm安装依赖模块 但我保证 xff0c 你并不需要是这方面的专家 本文针对的是Expres
  • Angular2文档学习的知识点摘要——依赖注入

    目录 目录依赖注入 xff08 DI xff09 为什么需要依赖注入 xff1f Angular 依赖注入 配置注入器在 NgModule 中注册提供商在组件中注册提供商该用NgModule还是应用组件 xff1f 注入服务显性注入器的创建
  • mysql 单表多次查询和多表联合查询,哪个效率高

    引自高性能MySQL xff1a
  • JDK5中的重要特性

    目录 目录静态导入自动装箱拆箱增强for循环可变参数枚举类反射 加载类解剖类利用Constructor创建对象利用Method执行方法反射字段 内省IntrospectorBeanUtils框架泛型Generic 泛型的使用自定义泛型 自定
  • Tomcat虚拟目录与虚拟主机的配置

    目录 目录互联网上常用协议以及其工作端口虚拟目录的映射方式 Tomcat配置虚拟目录不重启Tomcat配置虚拟目录的方式让tomcat自动映射 配置虚拟主机使用Java编写最简单的服务器程序 互联网上常用协议以及其工作端口 协议端口http
  • Tomcat相关知识点及其应用

    目录 目录将Web应用打包成warTomcat体系架构Tomcat配置https连接器Tomcat服务器的管理平台 将Web应用打包成war 在Web应用目录下执行命令 xff1a jar cvf xxx span class hljs p
  • Servlet开发须知知识点

    目录 目录Web项目目录结构Servlet的调用过程Servlet的运行过程Servlet接口实现类Servlet的URL映射Servlet线程安全 Web项目目录结构 举例 xff0c 在Intellij IDEA中如下 xff1a 其中
  • Servlet中的response对象

    目录 目录前言简介向客户端输出数据 response对象的getOutputStream方法response对象的getWriter方法 实现文件下载生成图片验证码实现浏览器定时刷新控制浏览器缓存实现请求重定向 前言 这里讲述的是Servl