一、Response对象
在service()中可以使用request来获取请求数据,还可以使用response向客户端响应,response有响应流。request和response是一次性的,即每次请求都要创建新的。
response是类型是javax.servlet.http.HttpServlet.Response response对象和功能:
- 设置响应头信息;
- 发送状态码;
- 设置响应正文;
- 重定向;
设置响应头信息
response有两个响应流,一个是字符流,一个是字节流
- PrintWriter out = response.getWriter();//获取字符流
- ServletOutputStream out = response.getOutputStream();//获取字节流注意:在一个请求中不能同时使用response.getWriter()和response.getOutputStream()这两个流,不然会抛出非法的状态异常。
使用字符流有两个问题: 1、编码 在调用getWrite()方法之前使用setCharacterEncoding()来设置字符流编码,如果不设置默认是iso-8859-1。
浏览器一般默认使用gbk来解码。
//response.setCharacterEncoding("utf-8");//设置字符流的编码为utf-8,设置之后用字符流发送的字符串都是utf-8的。
response.setContentType("text/html;charset=utf-8");//设置字符流编码,而且还会添加content-Type响应头,这个头通知浏览器用utf-8解码。
response.getWriter("中国");
HttpServletResponse resp = Response.getInst();
resp.setContentType("application/x-msdownload;charset=GBK");
2、缓冲区:默认是8kb,就是说,在响应数据没输出8kb之前,数据都是存放在缓冲区中,而不会立刻发送到客户端,当servlet执行结束后,服务器才会去刷新流,使缓冲区的数据发送到客户端。 缓冲区刷新:
- response.getWriter.flush();
- response.flushBuffer();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
for(int i=0; i < 1024; i++) {
response.getWriter().print("A");
}
///System.out.println(response.isCommitted());//检测是否发送
/*刷新缓冲区,这下面两句话的效果相同
*
*/
//response.getWriter().flush();//
//response.flushBuffer();
try {
Thread.sleep(5000);//休眠5秒钟
} catch (InterruptedException e) {
e.printStackTrace();
}
}
3、响应头
下面操作会出现两个头:
response.addHeader("a","A");
response.addHeader("a","AA");
a:A
a:AA
下面操作只能出现一个头:
response.addHeader("Content-type","text/html;charset=utf-8");
response.addHeader("Content-type","text/html;charset=gbk");最后是gbk。
下面操作形成一个头覆盖:
response.setHeader("a","A");
response.setHeader("a","AA");
response.setHeader("Refresh","5;URL=www.baidu.com");5秒后自动跳转到百度主页
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setHeader("Refresh","5;URL=/day05_1/index.jsp");
response.setContentType("text/html;charset=utf-8");
response.getWriter().print("一会儿会自动跳转到主页");
}
4、状态码
response.setStatus(int code); response.sendError(int code , String msg);
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//response.setStatus(200);设置状态码
response.sendError(500,"您访问的资源找到了");//设置错误提示
}
5、重定向
- 重定向一定有两个请求。
- 重定向第一个请求无论是GET或者POST,第二个请求一定是GET。
- 重定向可以定向到其他应用中,不局限于当前应用。
- 重定向就不要去响应,重定向就不要再使用response.getWriter()或response.getOutputStram()输出数据,不然会出现异常。
response.getWriter().print("哈哈哈"); response.sendRedirect("/day05_2/index.jsp");
这会在重定向时抛出异常。
手动重定向
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
* 重定向:
* 1、状态码为302
* 2、响应头Location
*/
response.setStatus(302);
response.setHeader("Location", "/day05_2/index.jsp");
}
自动重定向
response.sendRedirect(“重定向的URL”);
/**
*所谓自动,其实就是response提供的简便方法,可以完成设置状态码和Location头。
*/
@WebServlet("/BServlet")
public class BServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*下面sendRedirect()两个功能:
* 1、设置状态码为302
* 2、设置响应头Location
*/
response.sendRedirect("/day05_2/index.jsp");
}
}
二、代理线程中的HttpServletResponse变量,使代码中可以通过静态方法访问response
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Locale;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
/**
* 代理线程中的HttpServletResponse变量,使代码中可以通过静态方法访问response
* @version $Revision: 9431 $
*/
public class Response {
/**
* 输出参数
* @version $Revision: 9431 $
*/
public enum out {
/** 总条数 */
TOTAL("total"),
/** 执行结果 */
RESULT("result");
/** 枚举字段对应值 */
private final String val;
/**
* 构造函数
* @param val 枚举字段对应值
*/
private out(String val) {
this.val = val;
}
/**
* {@inheritDoc} * @return String
*/
public String toString() {
return this.val;
}
}
/**
* 获取response实例。
* @return response实例
*/
public static HttpServletResponse getInst() {
return (HttpServletResponse) AppMgr.threadVar("response");
}
/**
* TODO$
* @param response void
*/
public static void setInst(HttpServletResponse response){
AppMgr.setThreadVar("response", response);
}
/**
* 设置响应的状态码。
* @param sc 状态码
*/
public static void setStatus(int sc) {
getInst().setStatus(sc);
}
/**
* 使用指定的状态码向客户端发送一个错误的响应。
* @param sc 状态码
* @param msg 消息
* @throws IOException IO异常 * @exception IllegalStateException
* 如果Response已被提交
*/
public static void sendError(int sc, String msg) throws IOException {
getInst().sendError(sc, msg);
}
/**
* 使用指定的状态码向客户端发送一个错误的响应。
* @param sc 状态码
* @throws IOException IO异常 * @exception IllegalStateException 如果响应已被提交
*/
public static void sendError(int sc) throws IOException {
getInst().sendError(sc);
}
/**
* 请求跳转。
* @param location 跳转的URL
* @throws IOException IO异常 * @exception IllegalStateException 响应已被提交或者是路径无效
*/
public static void sendRedirect(String location) throws IOException {
getInst().sendRedirect(location);
}
/**
* 用给出的name和value,设置一个响应报头。
* @param name 名称
* @param value 值
*/
public static void setHeader(String name, String value) {
getInst().setHeader(name, value);
}
/**
* 用给出的name和value,增加一个响应报头到响应中。
* @param name 名称
* @param value 值
*/
public static void addHeader(String name, String value) {
getInst().addHeader(name, value);
}
/**
* 检查是否设置了指定的响应头。
* @param name 名称
* @return boolean值
*/
public static boolean containsHeader(String name) {
return getInst().containsHeader(name);
}
/**
* 用一个给定的名称和日期值设置响应头,这里的日期值应该是自1970-1-1日(GMT)以来的精确到毫秒的长整数。
* @param name 名称
* @param date 长整数日期
*/
public static void setDateHeader(String name, long date) {
getInst().setDateHeader(name, date);
}
/**
* 增加一个给定名称和日期值响应头,这里的日期值应该是自1970-1-1日(GMT)以来的精确到毫秒的长整数。
* @param name 名称
* @param date 长整型日期
*/
public static void addDateHeader(String name, long date) {
getInst().setDateHeader(name, date);
}
/**
* 用一个给定的名称和整型值设置响应头。
* @param name 名称
* @param value 整型值
*/
public static void setIntHeader(String name, int value) {
getInst().setIntHeader(name, value);
}
/**
* 增加一个给定的名称和整型值响应头。
* @param name 名称
* @param value 整型值
*/
public static void addIntHeader(String name, int value) {
getInst().setIntHeader(name, value);
}
/**
* 向response增加一个cookie。
* @param cookie Cookie对象
*/
public static void addCookie(Cookie cookie) {
getInst().addCookie(cookie);
}
/**
* 对包含session ID的URL进行编码。
* @param url URL
* @return 编码后的URL
*/
public static String encodeURL(String url) {
return getInst().encodeURL(url);
}
/**
* 对sendRedirect方法使用的指定URL进行编码。
* @param url URL
* @return 编码后的URL
*/
public static String encodeRedirectURL(String url) {
return getInst().encodeRedirectURL(url);
}
/**
* 设定响应的content类型,例如:text/html;charset=UTF-8。
* @param type content类型
*/
public static void setContentType(String type) {
getInst().setContentType(type);
}
/**
* 获得响应的content类型。
* @return content类型
*/
public static String getContentType() {
return getInst().getContentType();
}
/**
* 获取响应体字符编码。
* @return 字符编码,如UTF-8
*/
public static String getCharacterEncoding() {
return getInst().getCharacterEncoding();
}
/**
* 设置响应体字符编码。
* @param charset String
*/
public static void setCharacterEncoding(String charset) {
getInst().setCharacterEncoding(charset);
}
/**
* 设置response的Locale对象。
* @param loc Locale对象
*/
public static void setLocale(Locale loc) {
getInst().setLocale(loc);
}
/**
* 获取response的Locale对象。
* @return Locale对象
*/
public static Locale getLocale() {
return getInst().getLocale();
}
/**
* 返回ServletOutputStream对象,用于在响应中写入二进制数据。
* @return ServletOutputStream对象
* @throws IOException IO异常
* @exception java.lang.IllegalStateException 如果这个响应已经调用getWriter()
*/
public static ServletOutputStream getOutputStream() throws IOException {
return getInst().getOutputStream();
}
/**
* 返回PrintWriter对象,用于发送字符文本到客户端。
* PrintWriter对象使用getCharacterEncoding()方法返回的字符编码。
* 如果没有指定响应的字符编码方式,默认将使用ISO-8859-1。
* @return PrintWriter对象
* @throws IOException IO异常
* @exception java.lang.IllegalStateException 如果响应对象已经调用getOutputStream()方法
*/
public static PrintWriter getWriter() throws IOException {
return getInst().getWriter();
}
/**
* 设置响应正文的缓存大小。
* @param size 缓存大小
* @exception java.lang.IllegalStateException 如果内容已经被写入或者响应对象已经被提交
*/
public static void setBufferSize(int size) {
getInst().setBufferSize(size);
}
/**
* 返回实际用于响应的缓存的大小。如果没有使用缓存,这个方法将返回0。
* @return 缓存大小
*/
public static int getBufferSize() {
return getInst().getBufferSize();
}
/**
* 强制把任何在缓存中的内容发送到客户端。
* @throws IOException IO异常
*/
public static void flushBuffer() throws IOException {
getInst().flushBuffer();
}
/**
* 指示是否已经提交了响应。
* @return boolean值
*/
public static boolean isCommitted() {
return getInst().isCommitted();
}
/**
* 清除在缓存中的任何数据,包括状态代码和消息报头。
* @exception java.lang.IllegalStateException 如果响应已经被提交
*/
public static void reset() {
getInst().reset();
}
/**
* 清除在缓存中的响应内容,保留状态代码和消息报头。
* @exception java.lang.IllegalStateException 如果响应已经被提交
*/
public static void resetBuffer() {
getInst().resetBuffer();
}
/**
* 在响应中,设置内容正文的长度。
* @param len 内容长度
*/
public static void setContentLength(int len) {
getInst().setContentLength(len);
}
}