Web服务器收到客户端(浏览器)的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象,和代表响应的response对象。

request和response对象既然代表请求和响应,那我们要获取客户机提交过来的数据,只需要找request对象就行了。要向客户机输出数据,只需要找response对象就行了。

一、HttpServletResponse对象介绍

HttpServletResopnse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。查看其API

http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/http/HttpServletResponse.html ,可以看到这些相关的方法。

1.1、负责向浏览器发送数据的相关方法

1.2、负责向浏览器发送响应头的相关方法

1.3、负责向浏览器发送响应状态码的相关方法

1.4、响应状态码的常量

HttpServletResponse定义了很多状态码的常量(具体可以查看servlet的API),当需要向客户端发送响应状态码时,可以使用这些常量,避免了直接写数字,常见的状态码对应的常量

状态码404对应的常量

状态码200对应的常量

状态码500对应的常量

二、HttpServletResponse对象常见应用

2.1、使用outputstream流向客户端浏览器输出中文数据

使用浏览器以UTF-8的编码显示数据。

例子:

package my.servlet.demo;

import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class ServletDemo7 extends HttpServlet { private static final long serialVersionUID = 4312868947607181532L; public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
outputChineseByOutputStream(response);//使用OutputStream流输出中文
} /**
* 使用OutputStream流输出中文
* @param request
* @param response
* @throws IOException
*/
public void outputChineseByOutputStream(HttpServletResponse response) throws IOException{
/**使用OutputStream输出中文注意问题:
* 在服务器端,数据是以哪个码表输出的,那么就要控制客户端浏览器以相应的码表打开,
* 比如:outputStream.write("中国".getBytes("UTF-8"));//使用OutputStream流向客户端浏览器输出中文,以UTF-8的编码进行输出
* 此时就要控制客户端浏览器以UTF-8的编码打开,否则显示的时候就会出现中文乱码,那么在服务器端如何控制客户端浏览器以以UTF-8的编码显示数据呢?
* 可以通过设置响应头控制浏览器的行为,例如:
* response.setHeader("content-type", "text/html;charset=UTF-8");//通过设置响应头控制浏览器以UTF-8的编码显示数据
*/
String data = "中国";
OutputStream outputStream = response.getOutputStream();//获取OutputStream输出流
response.setHeader("content-type", "text/html;charset=UTF-8");//通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码
/**
* data.getBytes()是一个将字符转换成字节数组的过程,这个过程中一定会去查码表,
* 如果是中文的操作系统环境,默认就是查找查GB2312的码表,
* 将字符转换成字节数组的过程就是将中文字符转换成GB2312的码表上对应的数字
* 比如: "中"在GB2312的码表上对应的数字是98
* "国"在GB2312的码表上对应的数字是99
*/
/**
* getBytes()方法如果不带参数,那么就会根据操作系统的语言环境来选择转换码表,如果是中文操作系统,那么就使用GB2312的码表
*/
byte[] dataByteArr = data.getBytes("UTF-8");//将字符转换成字节数组,指定以UTF-8编码进行转换
outputStream.write(dataByteArr);//使用OutputStream流向客户端输出字节数组
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} }

2.2、使用PrintWriter流向浏览器输出中文数据

使用PrintWriter流向浏览器输出中文注意问题:

  在获取PrintWriter输出流之前首先使用“response.setCharacterEncoding(charset)”设置字符以什么样的编码输出到浏览器,如:response.setCharacterEncoding("UTF-8");设置将字符以“UTF-8”编码输出到浏览器,然后再使用response.getWriter();获取PrintWriter输出流,这两个步骤不能颠倒。如下:

response.setCharacterEncoding("UTF-8");//设置将字符以"UTF-8"编码输出到客户端浏览器
/**
* PrintWriter out = response.getWriter();这句代码必须放在response.setCharacterEncoding("UTF-8");之后
* 否则response.setCharacterEncoding("UTF-8")这行代码的设置将无效,浏览器显示的时候还是乱码
*/
PrintWriter out = response.getWriter();//获取PrintWriter输出流

然后再使用response.setHeader("content-type","text/html;charset=字符编码");设置响应头,控制浏览器以指定的字符编码进行显示,例如:

 //通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码
response.setHeader("content-type", "text/html;charset=UTF-8");

除了上面这种设置响应头来控制浏览器以指定的字符编码进行显示这种方式以外,还以为用如下的方式来模拟响应头的作用:

  /**
* 多学一招:使用HTML语言里面的<meta>标签来控制浏览器行为,模拟通过设置响应头控制浏览器行为
*response.getWriter().write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>");
* 等同于response.setHeader("content-type", "text/html;charset=UTF-8");
*/
response.getWriter().write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>");

例子:

package my.servlet.demo;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class ServletDemo7 extends HttpServlet { private static final long serialVersionUID = 4312868947607181532L; public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
outputChineseByPrintWriter(response);//使用OutputStream流输出中文
} /**
* 使用OutputStream流输出中文
* @param request
* @param response
* @throws IOException
*/
public void outputChineseByPrintWriter(HttpServletResponse response) throws IOException{
String data = "中国";
response.setCharacterEncoding("UTF-8");
PrintWriter out=response.getWriter();
response.setHeader("content-type", "text/html;charset=UTF-8");
//out.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>");
out.write(data); } public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} }

当需要向浏览器输出字符数据时,使用PrintWriter比较方便,省去了将字符转化为字符数组的那一步。

2.3、使用OutputStream或者PrintWriter向浏览器输出数字

例子:

package my.servlet.demo;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class ResponseDemo01 extends HttpServlet { private static final long serialVersionUID = 4312868947607181532L; public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { outputOneByOutputStream(response);//使用OutputStream输出1到客户端浏览器 } /**
* 使用OutputStream流输出数字1
* @param request
* @param response
* @throws IOException
*/
public void outputOneByOutputStream(HttpServletResponse response) throws IOException{
response.setHeader("content-type", "text/html;charset=UTF-8");
OutputStream outputStream = response.getOutputStream();
outputStream.write("使用OutputStream流输出数字1:".getBytes("UTF-8"));
outputStream.write((1+“”).getBytes());
} }

使用PrintWriter则:

/**
* 使用PrintWriter流输出数字1
* @param request
* @param response
* @throws IOException
*/
public void outputOneByPrintWriter(HttpServletResponse response) throws IOException{
response.setHeader("content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();//获取PrintWriter输出流
out.write("使用PrintWriter流输出数字1:");
out.write(1+"");
}

不能直接写成out.write(1)。

在开发过程中,如果希望服务器输出什么浏览器就能看到什么,那么服务器端都要以字符串的形式进行输出。

2.4、文件下载

文件下载功能是web开发中经常使用到的功能,使用HttpServletResponse对象就可以实现文件的下载。

文件下载功能的实现思路:

  1.获取要下载的文件的绝对路径

  2.获取要下载的文件名

  3.设置content-disposition响应头控制浏览器以下载的形式打开文件

  4.获取要下载的文件输入流

  5.创建数据缓冲区

  6.通过response对象获取OutputStream流

  7.将FileInputStream流写入到buffer缓冲区

  8.使用OutputStream将缓冲区的数据输出到客户端浏览器

例子:(图片位置:E:\Project\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\MyServlet\download )

package my.servlet.demo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; @WebServlet("/ServletDemo8")
public class ServletDemo8 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
downloadFileByOutputStream(response);
}
//下载文件,通过OutputStream流
private void downloadFileByOutputStream(HttpServletResponse response) throws IOException {
//1. 获取要下载的文件绝对路径
String realPath=this.getServletContext().getRealPath("/download/1.JPG");
//2.获取要下载的文件名
String fileName=realPath.substring(realPath.lastIndexOf("\\")+1);
//3.设置content-disposition响应头控制浏览器以下载的形式打开文件
response.setHeader("content-disposition", "attachment;filename="+fileName);
//4.获取要下载的文件输入流
InputStream in=new FileInputStream(realPath);
int len=0;
//5.创建数据缓冲区
byte[] buffer=new byte[1024];
//6.通过response对象获取OutputStream对象
OutputStream out=response.getOutputStream();
//7.将FileInputStream流写入到buffer缓冲区
while((len=in.read(buffer))>0){
//8.使用PutputStream将缓冲区的数据输出到客户端浏览器
out.write(buffer, 0, len);
}
in.close();
} protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
} }

运行结果:

点击【保存】按钮就可以把文件保存下来

另外,需要注意使用response实现中文名称文件下载

  下载中文文件时,需要注意的地方就是中文文件名要使用URLEncoder.encode方法进行编码(URLEncoder.encode(fileName,"字符编码")),否则会出现文件名乱码。

例子:

package my.servlet.demo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; @WebServlet("/ServletDemo8")
public class ServletDemo8 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
downloadChineseFileByOutputStream(response);
}
//下载文件,通过OutputStream流
private void downloadChineseFileByOutputStream(HttpServletResponse response) throws IOException {
//1. 获取要下载的文件绝对路径
String realPath=this.getServletContext().getRealPath("/download/图片.JPG");
//2.获取要下载的文件名
String fileName=realPath.substring(realPath.lastIndexOf("\\")+1);
//3.设置content-disposition响应头控制浏览器以下载的形式打开文件
//中文文件名要使用URLEncoder.encode方法进行编码,否则会出现中文乱码
response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));
//4.获取要下载的文件输入流
InputStream in=new FileInputStream(realPath);
int len=0;
//5.创建数据缓冲区
byte[] buffer=new byte[1024];
//6.通过response对象获取OutputStream对象
OutputStream out=response.getOutputStream();
//7.将FileInputStream流写入到buffer缓冲区
while((len=in.read(buffer))>0){
//8.使用PutputStream将缓冲区的数据输出到客户端浏览器
out.write(buffer, 0, len);
}
in.close();
} protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
} }

运行截图:

文件下载注意事项:编写文件下载功能时推荐使用OutputStream流,避免使用PrintWriter流,因为OutputStream流是字节流,可以处理任意类型的数据,而PrintWriter流是字符流,只能处理字符数据,如果用字符流处理字节数据,会导致数据丢失。

反例:使用PrintWriter流下载文件

package my.servlet.demo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; @WebServlet("/ServletDemo8")
public class ServletDemo8 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
downloadChineseFileByPrintWriter(response);
}
//下载文件,通过OutputStream流
private void downloadChineseFileByPrintWriter(HttpServletResponse response) throws IOException {
//1. 获取要下载的文件绝对路径
String realPath=this.getServletContext().getRealPath("/download/图片.JPG");
//2.获取要下载的文件名
String fileName=realPath.substring(realPath.lastIndexOf("\\")+1);
//3.设置content-disposition响应头控制浏览器以下载的形式打开文件
//中文文件名要使用URLEncoder.encode方法进行编码,否则会出现中文乱码
response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));
//4.获取要下载的文件输入流
FileReader in=new FileReader(realPath);
int len=0;
//5.创建数据缓冲区
char[] buffer=new char[1024];
//6.通过response对象获取OutputStream对象
PrintWriter out=response.getWriter();
//7.将FileInputStream流写入到buffer缓冲区
while((len=in.read(buffer))>0){
//8.使用PutputStream将缓冲区的数据输出到客户端浏览器
out.write(buffer, 0, len);
}
in.close();
} protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
} }

运行截图:

正常弹出下载框,此时我们点击【保存】按钮将文件下载下来,如下所示:

可以看到,只下载了354kb,而这张图片的原始大小为

这说明在下载时候数据丢失了,所以下载不完全,所以这张图片虽然能够正常下载下来,但是却是无法打开的,因为丢失掉了部分数据,如下所示:

所以使用PrintWriter流处理字节数据,会导致数据丢失,这一点要注意,所以在编写下载文件功能时,要使用OutputStream流,避免使用PrintWriter流,因为OutputStream流是字节流,可以处理任意类型的数据,而PrintWriter流是字符流,只能处理字符数据,如果用字符流处理字节数据,会导致数据丢失。

JAVAWEB学习总结 HttpServletResponse对象(一)的更多相关文章

  1. JavaWeb学习 (七)————HttpServletResponse对象(一)

    一.HttpServletResponse对象介绍

  2. JAVAWEB学习总结 HTTPSERVLETRESPONSE对象(二)

    一.HttpServletResponse常见应用--生成验证码 1.1.生成随机图片用作验证码 生成图片主要用到了一个BufferedImage类 步骤: 1. 在内存中创建一张图片 2.得到图片 ...

  3. JavaWeb学习 (八)————HttpServletResponse对象(二)

    一.HttpServletResponse常见应用——生成验证码 1.1.生成随机图片用作验证码 生成图片主要用到了一个BufferedImage类,

  4. JavaWeb总结(二)—HttpServletResponse对象

    Web服务器收到客户端的http请求,会针对每一次的请求,分别创建一个用于代表请求的request对象和response对象.我们要获取客户端提交的数据,只需要找request对象.要向客户端输出数据 ...

  5. JavaWeb温习之HttpServletResponse对象

    以下内容均根据"方立勋JavaWeb视频教程"进行总结 1. HttpServletResponse常见应用——设置响应头控制浏览器的行为 1.1 设置http响应头控制浏览器禁止 ...

  6. JavaWeb学习 (九)————HttpServletRequest对象(一)

    一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象 ...

  7. javaweb学习总结(七)——HttpServletResponse对象(一)

    Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象.request和response对象即然代表请求和响应,那我们要 ...

  8. javaweb学习总结(七)——HttpServletResponse对象(一)(转)

    Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象. request和response对象即然代表请求和响应,那我们 ...

  9. javaweb学习总结(七)——HttpServletResponse对象(一)(转)

    转载自 http://www.cnblogs.com/xdp-gacl/p/3789624.html Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对 ...

随机推荐

  1. 做为一名PHP程序员,应该关注的互联网IT大牛!

    俗话说:“读万卷书不如行万里路,行万里路不如高人指路”,做为一名新人,以后的路还很长,多年你的成就取决于今天的自己付出,选中自己的方向比什么都重要,关注大牛,向他们学习,才不会迷失自己! 1.惠新宸( ...

  2. #pragma pack(push,1)与#pragma pack(1)的区别

    这是给编译器用的参数设置,有关结构体字节对齐方式设置, #pragma pack是指定数据在内存中的对齐方式. #pragma pack (n)             作用:C编译器将按照n个字节对 ...

  3. C#读写config配置文件

    应用程序配置文件(App.config)是标准的 XML 文件,XML 标记和属性是区分大小写的.它是可以按需要更改的,开发人员可以使用配置文件来更改设置,而不必重编译应用程序. 对于一个config ...

  4. ldconfig和ldd用法

    一.ldconfig ldconfig是一个动态链接库管理命令,为了让动态链接库为系统所共享,还需运行动态链接库的管理命令--ldconfig. ldconfig 命令的用途,主要是在默认搜寻目录(/ ...

  5. How to Develop blade and soul Skills

    How to Develop Skills Each skill can be improved for variation effects. Some will boost more strengt ...

  6. blade and soul zone overview

    The world of Blade and Soul, is a vast extension of land containing two continents (the Southern Con ...

  7. 如何更方便地调试javascript代码

    开发者工具 现在一般的浏览器都内置了开发者工具,快捷键F12可以打开,如Chrome浏览器下,Sources面板下找到对应的js文件 这是首选方法,但是对于SPA程序(比如easyui),可能找不到内 ...

  8. js判断qq浏览器

    if(navigator.userAgent.toLowerCase().toString().indexOf('qqbrowser') > -1){ console.log('qq');}el ...

  9. 学习solr

    1.下载地址 http://apache.opencas.org/lucene/solr/

  10. jQuery的基本用法:

    随着WEB2.0及ajax思想在互联网上的快速发展传播,陆续出现了一些优秀的Js框架,其中比较著名 的有Prototype.YUI. jQuery.mootools.Bindows以及国内的JSVM框 ...