在Servlet API中,定义了一个HttpServletResponse接口
它继承自ServletResponse接口
它专门用来封装HTTP响应消息
下面会针对Response的常用方法进行介绍!
一.响应状态码相关方法
1.setStatus(int status)方法:设置状态码
***正常情况下,Web服务器会默认产生一个状态码为200的状态行
package controller;
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;
/**
* @Author weihuanwen
* @Date 2019/7/24 10:45
* @Version 1.0
*/
@WebServlet(urlPatterns = "/status")
public class StatusServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置状态码为404
resp.setStatus(404);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
测试请求路径:http://localhost:8080/rr/status
前端响应结果如下:
这种设置状态码的方式设置404,并不会导致浏览器报出404页面
2.sendError(XX)方法
① sendError(int code):设置错误状态码
package controller;
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;
/**
* @Author weihuanwen
* @Date 2019/7/24 10:45
* @Version 1.0
*/
@WebServlet(urlPatterns = "/status")
public class StatusServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置错误状态码404
resp.sendError(404);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
测试请求路径:http://localhost:8080/rr/status
前端响应结果如下:
②sendError(int code, String message):设置错误状态码和错误信息
package controller;
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;
/**
* @Author weihuanwen
* @Date 2019/7/24 10:45
* @Version 1.0
*/
@WebServlet(urlPatterns = "/status")
public class StatusServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置错误状态码404,以及错误信息
resp.sendError(404,"找寻资源失败!");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
测试请求路径:http://localhost:8080/rr/status
前端响应结果如下:
二.响应消息头相关方法
1.AddXxx(String name,Xxx xxx):设置响应头字段
package controller;
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;
/**
* @Author weihuanwen
* @Date 2019/7/24 10:45
* @Version 1.0
*/
@WebServlet(urlPatterns = "/header")
public class HeaderServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.addHeader("Who","Guess");
resp.addIntHeader("Quantity",200);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
测试请求路径:http://localhost:8080/rr/header
前端响应展示:
2.setXxx(String name,Xxx xx):修改响应头同名字段的值
package controller;
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;
/**
* @Author weihuanwen
* @Date 2019/7/24 10:45
* @Version 1.0
*/
@WebServlet(urlPatterns = "/header")
public class HeaderServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.addHeader("Who","Guess");
resp.addIntHeader("Quantity",200);
resp.setHeader("Who","Howie");
resp.setIntHeader("Quantity",100);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
测试请求路径:http://localhost:8080/rr/header
前端响应展示:
3.setContentLength(int len):设置响应消息的实体内容的大小,单位为字节
三.设置响应编码格式
1.void setContentType(String type):
设置Servlet输出内容的MIME类型,对于HTTP协议来说,就是设置Content-Type响应头字段的值
- 如果发送到客户端的内容是jpeg格式的图像数据,就需要将响应头字段的类型设置为“image/jpeg”
- 如果响应的内容为文本,setContentType()方法的还可以设置字符编码,如:text/html;charset=UTF-8
2.void setCharacterEncoding(String charset)
设置输出内容使用的字符编码,对HTTP 协议来说,就是设置Content-Type头字段中的字符集编码
(一般不使用)
下面单介绍setContentType(String type)!
package controller;
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;
/**
* @Author weihuanwen
* @Date 2019/7/24 10:45
* @Version 1.0
*/
@WebServlet(urlPatterns = "/ce")
public class CharacterEncodingServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
// resp.setCharacterEncoding("UTF-8");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
测试请求路径:http://localhost:8080/rr/ce
前端响应展示:
四.响应消息体相关方法
1.getOutputStream()方法
- 获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字 节
- 再由Tomcat服务器将字节内容组成Http响应返回给浏览器
- 获取的字节输出流对象为ServletOutputStream类型,ServletOutputStream是OutputStream的子类
- 用于输出二进制格式的响应正文
测试前准备:web目录下增加图片(/img/bhbl.jpg)
演示代码如下:
package controller;
import javax.servlet.ServletContext;
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.OutputStream;
/**
* @Author weihuanwen
* @Date 2019/7/23 18:29
* @Version 1.0
*/
@WebServlet(urlPatterns = "/img")
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//输出二进制格式的响应正文前需要先获取字节输出流
OutputStream os = resp.getOutputStream();
//获取Servlet上下文引用
ServletContext context = getServletContext();
//获取文件的绝对路径
String realPath = context.getRealPath("/img/bhbl.jpg");
//创建输入流读取图片文件
FileInputStream fis = new FileInputStream(realPath);
byte[] bytes = new byte[200*1024];
int len = 0;
while ((len=fis.read(bytes))!=-1){
os.write(bytes);
}
fis.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
测试请求路径:http://localhost:8080/rr/img
前端界面响应如下:
2.getWriter()方法
- 获取的字符输出流对象为PrintWriter类型
- 用于输出字符格式的文本文件
测试前准备:web目录下增加txt文件
package controller;
import utils.FileUtils;
import javax.servlet.ServletContext;
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.*;
/**
* @Author weihuanwen
* @Date 2019/7/24 16:34
* @Version 1.0
*/
@WebServlet(urlPatterns = "/text")
public class TextServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置响应体编码格式
resp.setContentType("text/html;charset=UTF-8");
//输文本格式的响应正文前需要先获取字符输出流
PrintWriter pw = resp.getWriter();
//获取Servlet上下文引用
ServletContext context = getServletContext();
//获取文件的绝对路径
String realPath = context.getRealPath("/text/noodle.txt");
//创建字符输入流读取文件内容
InputStreamReader isr = new InputStreamReader(new FileInputStream(realPath),FileUtils.getCharset(realPath));
BufferedReader br = new BufferedReader(isr);
String lineStr = "";
while ((lineStr = br.readLine())!=null){
System.out.println(lineStr);
pw.write(lineStr);
pw.println("<br/>");
}
isr.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
测试请求路径:http://localhost:8080/rr/text
前端展示效果:
期间遇到了txt文件的编码非UTF-8而导致前端显示的文字为乱码
后来新增加了FileUtils类用于获取txt文本文件的编码格式,以便于在输入流中动态进行编码格式处理
关于FileUtils以后再详说!
五.中文文件下载
在学习文件下载的过程中遇到的问题就是,如果文件名称为中文,附件界面文件名称是显示不出来的
下面主要解决这个问题
测试前准备:web目录下增加相关资源文件
package controller;
import sun.misc.BASE64Encoder;
import javax.servlet.ServletContext;
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.OutputStream;
import java.net.URLEncoder;
/**
* @Author weihuanwen
* @Date 2019/7/24 22:11
* @Version 1.0
*/
@WebServlet(urlPatterns = "/download")
public class DownloadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取文件名
String filename=req.getParameter("name");
//获取HTTP的请求头,键对应的值,是浏览器的名字
String agent = req.getHeader("User-Agent");
//附件名称,并赋默认值
String attachFileName = "unknown";
if (agent.contains("MSIE")) {
// IE浏览器
attachFileName = URLEncoder.encode(filename, "utf-8");
attachFileName = attachFileName.replace("+", " ");
} else if (agent.contains("Firefox")) {
// 火狐浏览器
BASE64Encoder base64Encoder = new BASE64Encoder();
attachFileName = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else {
// 其它浏览器
attachFileName = URLEncoder.encode(filename, "utf-8");
}
//通知前端附件名称
resp.setHeader("Content-Disposition","attachment;filename="+attachFileName);
//读取服务器中该文件
OutputStream os = resp.getOutputStream();
//获取文件的路径
ServletContext context = getServletContext();
String realPath = context.getRealPath("/resource/" + filename);
//获取输入流,读取文件
FileInputStream fis = new FileInputStream(realPath);
byte[] bytes = new byte[200*1024];
int len =0;
while ((len = fis.read(bytes))!=-1){
os.write(bytes,0,len);
}
fis.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
前端页面:
<%--
Created by IntelliJ IDEA.
User: WHW
Date: 2019/7/23
Time: 18:27
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<fieldset>
<a href="http://localhost:8080/rr/download?name=巴霍巴利王.jpg">巴霍巴利王.jpg</a><br>
</fieldset>
<fieldset>
<a href="http://localhost:8080/rr/download?name=相亲相爱一家人.mp3">相亲相爱一家人.mp3</a><br>
</fieldset>
<fieldset>
<a href="http://localhost:8080/rr/download?name=笑傲江湖.mp4">笑傲江湖.mp4</a><br>
</fieldset>
<fieldset>
<a href="http://localhost:8080/rr/download?name=朋友.txt">朋友.txt</a><br>
</fieldset>
<fieldset>
<a href="http://localhost:8080/rr/download?name=宝藏.zip">宝藏.zip</a><br>
</fieldset>
</body>
</html>
测试结果如下: