Response
response对象表示web服务器给浏览器返回的响应消息
开发人员可以使用response对象的相关方法,设置要返回给浏览器的相应信息
设置响应行
void setStatus(int sc)设置状态码
设置响应头
void setHeader(String name, String value)设置指定头名称和对应的值
设置响应体
PrintWriter getWriter()字符输出流,不支持中文,默认编码是ISO-8859-1
ServletOutputStream getOutputStream()字节输出流
注意在同一个servle中,两种类型的输出流不能同时存在,它们之间存在互斥
重定向
就是资源的跳转方式
用户通过访问浏览器,服务器可以通过浏览器重定向到别的Servlet
实现步骤
- 设置状态码
response.setStatus(302);//302表示重定向
- 设置响应头
response.setHeader(“Location”,“重定向网络地址”)
- 以上合并简写形式
response.sendRedirect(“重定向网络地址”);
代码演示
通过浏览器访问/responseRedirect1Servlet,通过重定向到/responseRedirect2Servlet来执行相应的业务功能
@WebServlet("/responseRedirect1Servlet")
public class ResponseRedirect1Servlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 处理post请求乱码问题
request.setCharacterEncoding("utf-8");
//设置状态码
/*response.setStatus(302);
//设置响应头
response.setHeader("Location","/responseRedirect2Servlet");*/
//重定向简写方式
response.sendRedirect("/responseRedirect2Servlet");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
@WebServlet("/responseRedirect2Servlet")
public class ResponseRedirect2Servlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 处理post请求乱码问题
request.setCharacterEncoding("utf-8");
System.out.println("responseRedirect2Servlet执行了");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
定时刷新Refresh
访问当前Servlet停留3秒跳转到百度
@WebServlet("/refreshServlet")
public class RefreshServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 处理post请求乱码问题
request.setCharacterEncoding("utf-8");
//通过response设置响应头refresh
response.setHeader("Refresh","3;https://www.baidu.com");
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("操作成功,3秒后跳转到百度首页");
// 响应中文数据
//指定服务器响应编码方式
// response.setCharacterEncoding("UTF-8");
//统一浏览器和服务器编码
//response.setContentType("text/html;charset=utf-8");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
文件下载案例
目录结构
前端代码:
<body>
<a href="/downLoadServlet?filename=demo.docx">word文档</a><br>
<a href="/downLoadServlet?filename=girl.jpg">靓女</a><br>
<a href="/downLoadServlet?filename=禽兽.jpg">禽兽</a><br>
<a href="/downLoadServlet?filename=test.zip">压缩包</a><br>
</body>
后端代码:
@WebServlet("/downLoadFileServlet")
public class DownLoadFileServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 处理post请求乱码问题
request.setCharacterEncoding("utf-8");
//设置相应数据的编码
response.setContentType("text/html;charset=utf-8");
//获取文件名
String filename = request.getParameter("filename");
//获取服务器文件的真是路径
ServletContext servletContext = this.getServletContext();
String realPath = servletContext.getRealPath("/download"+filename);
//创建本地流读取文件
FileInputStream fis = new FileInputStream(new File(realPath));
//获取文件的真实类型
String mimeType = servletContext.getMimeType(filename);
//设置响应头
response.setHeader("content-type",mimeType);
//知晓用户用的是什么浏览器
String userAgent = request.getHeader("user-agent");
filename = DownLoadUtils.getName(userAgent, filename);
//设置以附件的形式打开文件
response.setHeader("content-disposition","attachment;filename="+filename);
//获取字节输出流
ServletOutputStream os = response.getOutputStream();
//读取字符。一次读取一个字节
int len;
byte[] bytes = new byte[1024];
while ((len=fis.read(bytes)) != -1){
os.write(bytes,0,len);
}
//释放资源
os.close();
fis.close();
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
解决乱码工具类
/*
解决浏览器中文兼容性的问题的
*/
public class DownLoadUtils {
public static String getName(String agent, String filename) throws UnsupportedEncodingException {
if (agent.contains("Firefox")) {
// 火狐浏览器
//BASE64Encoder base64Encoder = new BASE64Encoder();
Base64.Encoder encoder = Base64.getEncoder();
//filename = "=?utf-8?B?" + encoder.encode(filename.getBytes("utf-8")) + "?=";
filename = "=?utf-8?B?" + encoder.encodeToString(filename.getBytes("utf-8")) + "?=";
} else {
// 其它浏览器
filename = URLEncoder.encode(filename, "utf-8");
}
return filename;
}
}
说明
如果自己电脑安装的jdk高于1.8可以直接用上面的工具类
如果jdk低于1.8可以使用注释的代码,并将其对应的代码注释起来
面试题
forword VS redirect
重定向(redirect)
- 浏览器访问地址栏会发生变化
- 可以访问其他站点(服务器)的资源(跨域访问)
- 重定向是两次请求,不能使用request对象来共享数据
- 最终响应给浏览器的由最后一Servlet来决定相应的内容
- URL重定向不能访问WEB-INF目录下的资源
转发(forward)
- 转发地址栏路径不会改变
- 转发只能访问当前服务器下的资源
- 转发是一次请求,可以使用request对象来共享数据
使用场景
- 分析各自的特点
- 必须使用forward
如果需要共享同一次请求中的数据
要访问WEB-INF目录下的资源- 如果要跨域访问必须使用redirect