Http响应response(⽂件下载、验证码)
Http响应response
response:响应
作⽤:  往浏览器写东西
组成部分:  响应⾏响应头响应体
操作响应⾏
格式: 协议/版本状态码状态码说明
状态码:
1xx:已发送请求
2xx:已完成响应
200:正常响应
3xx:还需浏览器进⼀步操作
302:重定向配合响应头:location
304:读缓存
4xx:⽤户操作错误
404:⽤户操作错误.
405:访问的⽅法不存在
5xx:服务器错误
500:内部异常
常⽤⽅法:
setStatus(int状态码):针对于 1xx  2xx  3xx
了解 :sendError(int状态码):针对于 4xx和5xx
操作响应头
  格式:  key:value(value可以是多个值)
常⽤的⽅法:
setHeader(String key,String value):设置字符串形式的响应头
了解:setIntHeader(String key,int value):设值整形的响应头
了解:setDateHeader(String key,long value):设值时间的响应头
addHeader(String key,String value):添加字符串形式的响应头之前设置过则追加,若没有设置过则设置
了解:addIntHeader(String key,int value):添加整形的响应头
了解:addDateHeader(String key,long value):添加时间的响应头
常⽤的响应头:
location:重定向
refresh:定时刷新
content-type:设置⽂件的mime类型,设置响应流的编码及告诉浏览器⽤什么编码打开
content-disposition:⽂件下载
重定向:
⽅式1:
★response.sendRedirect("/day10/loc2");
⽅式2:
response.setStatus(302);
respooen.setHeader("location","/day10/loc2");
案例1:请求重定向
<servlet>
<servlet-name>SHServlet1</servlet-name>
<servlet-class>quest_response.SHServlet1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SHServlet1</servlet-name>
<url-pattern>/servlet1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>SHServlet2</servlet-name>
<servlet-class>quest_response.SHServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SHServlet2</servlet-name>
<url-pattern>/servlet2</url-pattern>
</servlet-mapping>
SHServlet1.java源码
package quest_response;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SHServlet1 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //重定向⽅式⼀
//1.设置状态码
response.setStatus(302);
//2.设置响应头
//response.setHeader("location", "/Servlet/servlet2");
//重定向⽅式⼆:设置响应头
response.sendRedirect("/Servlet/servlet2");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        doGet(request, response);
}
}
SHServlet2.java源码:
package quest_response;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SHServlet2 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        response.setContentType("text/html;charset=utf-8");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        doGet(request, response);
}
}
定时刷新:
⽅案1:设置头 refresh
respooen.setHeader("refresh","秒数;url=跳转的路径");
⽅案2:http的meta标签
<meta http-equiv="refresh" content="3;url=/day10/refresh2.html">
package com.hjh.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.hjh.domain.User;
import com.hjh.service.UserService;
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.设置编码
response.setContentType("text/html;charset=utf-8");
//2.接收⽤户名和密码
String username = Parameter("username");
String password = Parameter("password");
//3.调⽤UserService的login(username,password),返回⼀个user对象
User user  = new UserService().login(username,password);
//4.判断user是否为空
if(user==null) {
//user为空
//优化,定时跳转
response.setHeader("refresh","3;url=/Servlet/login.html");
}else {
//user为不为空
}
}
}
案例⼆:
refresh1.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!--
http-equiv:响应头
content:响应体
-->
<meta  http-equiv="refresh" content="3;url=/Servlet/refresh2.html" >
<title>注册页⾯</title>
</head>
<body>
注册成功,<span id="sid">5</span>秒之后跳转到登录页⾯
</body>
<script type="text/javascript">
onload=function(){
//设置定时器
setInterval(changeS,1000);
}
i=5;
function changeS(){
/
/1.获取元素
var obj = ElementById("sid");
//2.操作元素的标签体
obj.innerHTML=--i;
}
</script>
</html>
refresh2.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录页⾯</title>
</head>
<body>
访问前,请先进⾏登录!
</body>
</html>
页⾯上时间会⾃减,5秒后页⾯跳转到refresh2.html
操作响应体:页⾯上要展⽰的内容
常⽤⽅法:
Writer getWriter():字符流
ServletOutputStream getOutputStream() :字节流
⾃⼰写的东西⽤字符流,其他⼀概⽤字节流.
处理响应中⽂乱码:
⽅式1:★
response.setContentType("text/html;charset=utf-8");
⽅式2:理解
response.setHeader("content-type", "text/html;charset=utf-8");
注意:
两个流互斥。当响应完成之后,服务器会判断⼀下流是否已经关闭,若没有关闭,服务器会帮我们关闭.(底层使⽤的缓冲流)
案例:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="/2001/XMLSchema-instance" xmlns="/xml/ns/javaee" xsi:schemaLocation="/xml/ns/javaee /xml/ns/javaee  <servlet>
<servlet-name>PrintServlet</servlet-name>
<servlet-class>com.hjh.servlet.PrintServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PrintServlet</servlet-name>
<url-pattern>/print</url-pattern>
</servlet-mapping>
</web-app>
PrintServlet.java源码如下:
package com.hjh.servlet;
import java.io.IOException;
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 PrintServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//处理响应的中⽂乱码
response.setContentType("text/html;charset=utf-8");
//打印表格
//获取字符流
PrintWriter writer = Writer();
writer.print("<table border='1'><tr>");
writer.print("<td>⽤户名:</td>");
writer.print("<td>tom</td></tr>");
writer.print("<tr><td>密码:</td>");
writer.print("<td>123</td>");
writer.print("</tr></table>");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        doGet(request, response);
}
}
在没有红⾊标注的这段代码时,启动项⽬访问,浏览器中显⽰的是以下数据:
在加上红⾊标注的代码时,启动项⽬访问,浏览器中显⽰的是以下数据:
⽂件下载:
下载⽅式:
1.超链接下载
<a href="/day10/">下载 </a>
若浏览器能解析该资源的mime类型,则打开;若不能接下则下载;
2.编码下载通过servlet完成
<a href="/day10/download?">下载 </a>
a.设置⽂件的mime类型
String MimeType(⽂件名)
response.setContentType(mimeType);
b.设置下载头信息 content-disposition
response.setHeader("content-disposition", "attachment;filename="+⽂件名称);
c.提供流
1.超链接下载⽂件:
download.html内容如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>超链接⽂件下载</title>
</head>
<body>
<a href='/Servlet/file/1.html'>1.html</a>
<a href='/Servlet/'&</a>
<a href='/Servlet/file/3.docx'>3.docx</a>
</body>
</html>
启动项⽬,浏览器中输⼊url回车,页⾯显⽰如下:
点击1.html这个超链接,浏览器能够识别html的⽂件类型,所以将1.html⽂件内容显⽰在浏览器中,页⾯显⽰如下:
点击2.txt这个超链接,浏览器能够识别txt的⽂件类型,所以将2.txt⽂件内容显⽰在浏览器中,页⾯显⽰如下:
点击3.docx这个超链接,浏览器⽆法识别docx的⽂件类型,浏览器中弹出选择下载保存位置,页⾯显⽰如下:
案例⼆:编码下载,通过servlet实现
download2.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>超链接⽂件下载</title>
</head>
<body>
<a href="/Servlet/download?name=1.html">1.html</a><br/>
<a href="/Servlet/download?"&</a><br/>
<a href="/Servlet/download?name=3.docx">3.docx</a><br/>java浏览器下载
</body>
</html>
DownloadServlet.java源码:
package com.hjh.servlet;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DownloadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取当前下载⽂件的⽂件名
String fileName = Parameter("name");
System.out.println(fileName);
//获取上下⽂
ServletContext context = ServletContext();
//⽂件下载
//1.⾸先获取⽂件的mime类型,并设置其类型
String mimeType = MimeType(fileName);
response.setContentType(mimeType);
//2.设置下载的头信息
response.setHeader("content-disposition", "attchment;filename="+fileName);
//3.对拷流
//3.1获取输⼊流
InputStream is = ResourceAsStream("/file/"+fileName);
//3.2获取输出流
ServletOutputStream os = OutputStream();
int len = -1;
byte[] b = new byte[1024];
while((ad(b))!=-1) {
os.write(b, 0,len);
}
/
/关闭流
os.close();
is.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        doGet(request, response);
}
}
<servlet>
<servlet-name>DownloadServlet</servlet-name>
<servlet-class>com.hjh.servlet.DownloadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DownloadServlet</servlet-name>
<url-pattern>/download</url-pattern>
</servlet-mapping>
启动项⽬,浏览器中输⼊url,回车,页⾯显⽰如下:
点击1.html、2.txt、3.docx超链接,浏览器中弹出选择下载保存位置,页⾯显⽰如下:
⽂件下载优化:解决⽂件名带中⽂
  download.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>超链接⽂件下载</title>
</head>
<body>
<a href='/Servlet/file/1a.html'>1a.html</a>
<a href='/Servlet/'&</a>
<a href='/Servlet/file/3答案.docx'>3答案.docx</a>
</body>
</html>
  ⼯具类DownLoadUtils.java源码:
package com.hjh.util;
import java.io.UnsupportedEncodingException;