当Web服务器收到客户端的http请求,(在程序继承HttpServlet的前提下)容器在调用Servlet的doGet()或doPost()方法时,会针对每一次请求创建一个HttpServletRequest接口的实例和一个HttpServletResponse接口的实例,封装成参数传给doGet()或doPost()方法。
request和response分别代表客户端对Web服务器的请求 和 服务器对客户端的响应。
HttpServlet的继承结构如下:
ServletResponse的常用方法:
getOutputStream():返回一个ServletOutputStream对象,它被用于发送对客户端的响应(二进制的形式)
//回送字符数据的方法
//ServletOutputStream sos = response.getOutputStream();
//sos.write(“hello,focus”.getBytes());
public ServletOutputStream getOutputStream()
throws java.io.IOException
//getWriter():返回将字符文本发送到客户端的PrintWriter对象,
public java.io.PrintWriter getWriter()
throws java.io.IOException
//设置响应到客户端的编码方式
//如:response.setCharacterEncoding(“utf-8”);
public void setCharacterEncoding(java.lang.String charset)
//设置响应到客户端时的类型
//如:response.setContentType(“text/html”);
public void setContentType(java.lang.String type)
HttpServletResponse的方法:
(1)模拟使用getOutputStream和getWriter两个方法输出字符到浏览器。
创建一个Servlet(demo3.java)
代码如下:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class demo3 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType(“text/html;charset=utf-8”);
PrintWriter out = response.getWriter();
out.println(“hello focus”);
//当执行到sos.write(“hello focus”) 时,把hello focus字符封装后返回给web服务器
//把response的内容进行拆解后返回给浏览器,
//查看该流的还有没有输出的内容,如果没有了,检测该流是否关闭,如果没有关闭,
则关闭该流。
ServletOutputStream sos = response.getOutputStream();
sos.write(“hello focus_18”.getBytes());
}
}
抛出异常:
java.lang.IllegalStateException: getWriter() has already been called for this response
这个response的getWriter()方法已经在访问。
总结:
1.getOutputStream和getWriter方法分别用于得到输出二进制数据、输出文本数据的ServletOutputStream、Printwriter对象。
2.在同一个response对象中getOutputStream或getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一个方法。
3.Servlet程序向ServletOutputSream或PintWrite对象中写入的数据将被Servlet引擎(Web服务器)从response里面获取,Servlet引擎将这些数据当作响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端。
4.Servlet的service方法结束后,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经使用过close()方法,如果没有,Servlet引擎将调用close()方法关闭该输出流对象。
(2)灵活使用 重定向
在Servlet类的请求处理方法中,可以获取客户端提交的参数数据,也可以编写逻辑代码对请求数据进行处理,最后进行对客户端进行响应。
有时该Servlet类处理不了你的请求或不能独立处理完毕这个请求,需要其他Servlet类进行辅助处理,这时就需要用到“重定向”或“请求分派”了。
重定向
HttpServletRequest接口提供的sendRedirect()方法用于生成302响应吗和Location响应头,从而通知客户端去重新访问Location响应头中指定的URL,语法如下:
public void sendRedirect(java.lang.String location)
throws java.io.IOException
其中,Location参数指定了重定向的URL,它可以使用绝对URL和相对URL,Servlet容器会自动将相对URl转换成绝对URL后,在生成Location头字段。
sendRedirect()不仅可重定向到本地容器的资源,也可以重定向到网络站点。
例子:
demo3.java代码如下:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class demo3 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.sendRedirect(“/demo/demo4”);//重定到指定的路劲的资源
}
}
demo4.java代码如下:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class demo4 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
request.setCharacterEncoding("utf-8");
out.println("用户名为:");
out.println(request.getParameter("name"));
}
}
当在浏览中输入:
http://localhost:8080/demo/demo3?name=focus
显示效果如下:
服务器调用demo4实例的相应方法来处理demo3这个方法时,HttpServletRequest实例不会再包含第一次请求中的参数了,request和response都是全新的,所以参数name的值为null。
而通过下面的这种方式,就可获得name的值。
response.sendRedirect(“/demo/demo4?name=focus”);
当username是用户提交过来的值,即可这样设置
String username = request.getParameter(“username”);
response.sendRedirect(“/demo/demo4?name=”+username);
总结:
sendRedirect(“URL?username=focus”);
优点:传送信息的速度比较快
缺点:它只能传送字符串,而不能传送一个对象
注意:
(1)Servlet的url名和变量之间有?号
(2)如果传递两个以上的值,它们间要用&号分开:
如:sendRedirect(“Servlet地址?参数名=参数值&参数名=参数值…”);
总结:
1.通过HttpServletResponse可回送最基本的字符,控制浏览器的显示。
2.通过HttpServletResponse回送的http头,可以控制浏览器的行为。
3.通过HttpServletResponse提供的函数,可以完成相应的功能(比如下载文件,生成随机验证码)