Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。request和response对象即然代表请求和响应,那我们要获取客户机提交过来的数据,只需要找request对象就行了。要向客户机输出数据,只需要找response对象就行了。(注意到request和response对象都是web服务器端创建的)
HttpServletResponse对象介绍
HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。
HttpServletResponse对象的功能分为以下4种:
- 设置响应头信息
- 发送状态码
- 设置响应正文
- 重定向
查看HttpServletResponse的API,可以看到这些相关的方法。
一些常见的状态码常量
404:SC_NOT_FOUND
500:SC_INTERNAL_SERVER_ERROR
200:SC_OK
设置状态码
response.setStatus(200)://设置状态码;
response.sendError(404, “您要查找的资源不存在”)
HttpServletResponse对象常用方法
负责向客户端(浏览器)发送数据的相关方法
- ServletOutputStream getOutputStream() ;该方法用于返回Servlet引擎创建的""字节输出流""对象,Servlet程序可以按字节形式输出响应正文。
- PrintWriter getWriter();该方法用于返回Servlet引擎创建的字符输出流对象,Servlet程序可以按字符形式输出响应正文。
PrintWriter out = response.getWriter():获取字符流;
ServletOutputStream out = response.getOutputStream():获取字节流;
注意:
- 两个方法相互排斥,若同时使用,则会抛出IlegalStateException异常。
- getOutputStream()返回的字节输出流对象,类型为:ServletOutputStream,直接输出字节数组中的二进制数据;getWriter()方法将Servlet引擎的数据缓冲区包装成PrintWriter类型的字符输出流对象后返回,PrintWriter对象只能输出字符文本内容。
- 在使用response.getWriter()时需要注意默认字符编码为ISO-8859-1,如果希望设置字符流的字符编码为utf-8,可以使用response.setCharaceterEncoding(“utf-8”)来设置。这样可以保证输出给客户端的字符都是使用UTF-8编码的! 但客户端浏览器并不知道响应数据是什么编码的!如果希望通知客户端使用UTF-8来解读响应数据,那么还是使response.setContentType(“text/html;charset=utf-8”)方法比较好,因为这个方法不只会调用response.setCharaceterEncoding(“utf-8”),还会设置content-type响应头,客户端浏览器会使用content-type头来解读响应数据。
- response.getWriter()是PrintWriter类型,所以它有缓冲区,缓冲区的默认大小为8KB。也就是说,在响应数据没有输出8KB之前,数据都是存放在缓冲区中,而不会立刻发送到客户端。当Servlet执行结束后,服务器才会去刷新流,使缓冲区中的数据发送到客户端。 如果希望响应数据马上发送给客户端:
向流中写入大于8KB的数据; 调用response.flushBuffer()方法来手动刷新缓冲区;
负责向客户端(浏览器)发送响应头的相关方法
- addDateHeader(String name ,long date) 该方法是添加只有一个值且值的类型为long类型的响应头,例如expies响应头,表示过期时间
- addHeader(String name,String value) 该方法是添加有多个值的响应头,参数name表示响应头名称,参数value表示响应头的值
- addIntHeader(String name,int value) 该方法是添加有多个值且值的类型为int类型的响应头
- setHeader(String name,String value) 该方法是设置只有一个值的响应头,参数name表示响应头名称,参数value表示响应头的值
- setDateHeader(String name,long value) 该方法是设置只有一个值且值的类型为long类型的响应头,例如expies响应头,表示过期时间
- setIntHeader(String name,int value) 该方法是设置只有一个值且值的类型为int类型的响应头,例如Content-Length响应头,该响应头是代表响应内容有多少字节数
response.setHeader(“content-type”, “text/html;charset=utf-8”);
//设置content-type响应头,该头的作用是告诉浏览器响应内容为html类型,编码为utf-8。
而且同时会设置response的字符流编码为utf-8,即response.setCharaceterEncoding(“utf-8”);
response.setHeader("Refresh","5; URL=http://www.itcast.cn")://5秒后自动跳转到传智主页。
//设置浏览器禁止缓存
response.setDateHeader(“expries”, -1);
response.setHeader(“Cache-Control”, “no-cache”);
response.setHeader(“Pragma”, “no-cache”);
关于重定向的在上文HTTP协议中介绍了
这里总结
重定向是两次请求;
重定向的URL可以是其他应用,不局限于当前应用;
重定向的响应头为302,并且必须要有Location响应头;
重定向就不要再使用response.getWriter()或response.getOutputStream()输出数据,不然可能会出现异常;
HttpServletResponse对象常见应用
使用OutputStream流和PrintWriter流向客户端浏览器输出数据
@WebServlet("/ServletDemo5")
public class ServletDemo5 extends HttpServlet {
private static final long serialVersionUID = 4312868947607181532L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
outputData(response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
public void outputData(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 = "i miss guanshuqiao very much";
OutputStream outputStream = response.getOutputStream();//获取outputstream输出流
response.setHeader("content-type","text/html;charset=UTF-8");
byte[] dataByteArr = data.getBytes("UTF-8");//将字符转换成字节数组,指定以UTF-8编码进行转换
outputStream.write(dataByteArr);//使用OutputStream流向客户端输出字节数组
}
}
打开浏览器访问http://localhost:8080/ServletDemo5
@WebServlet("/ServletDemo6")
public class ServletDemo6 extends HttpServlet {
private static final long serialVersionUID = 4312868947607181532L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriterData(response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
public void PrintWriterData(HttpServletResponse response) throws IOException{
String data = "我很是想念 guanshuqiao";
response.setContentType("text/html;charset=utf-8");
/*
如果不使用response.setContentType()这个方法就要使用
response.setHeader("content-type", "text/html;charset=UTF-8"); //通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码
response.setCharacterEncoding("UTF-8");//设置将字符以"UTF-8"编码输出到客户端浏览器
*/
PrintWriter printWriter = response.getWriter();
printWriter.write(data);
}
}
访问http://localhost:8080/ServletDemo6
response.setContentType("text/html;charset=utf-8");等价于response.setHeader("content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
如果使用的是后者,则需要在获取printwrite输出流之前就要setContentType和setHeader,否则无法生效。
当需要向浏览器输出字符数据时,使用PrintWriter比较方便,省去了将字符转换成字节数组那一步。
在开发过程中,如果希望服务器输出什么浏览器就能看到什么,那么在服务器端都要以字符串的形式进行输出。如果使用PrintWriter流输出数字,那么也要先将数字转换成字符串后再输出
才疏学浅之处,切莫在意。
;——2019.7.12上午
参考博文:
HttpServletResponse对象(一)
一文看懂HttpServletResponse
javaweb学习总结(七)——HttpServletResponse对象(一)