重定向和请求分派
一. 重定向
1.HttpServletRequest接口提供的sendRedirect()方法用于生成302响应码和Location响应头,从而通知客户端去重新访问Location响应头中指定的URL,其完整的定义语法如下:
public void sendRedirect(String location)throws IOException;
2.其中的location参数指定了重定向的URL,它可以使用绝对URL和相对URL,Servlet容器会自动将相对URL转换成绝对URL后,再生成location头字段。
3.把这个Web应用程序部署到Web容器Tomcat中,启动Tomcat。然后按如图4.13所示在浏览器地址栏中输入:http://localhost:8080/jsp_04_servlet/servlet1?name=test
4.请求之后,服务器返回响应给客户端浏览器。
二. 请求分派
1.Servlet API中定义了一个RequestDispatcher接口,俗称请求分派器。它定义了如下两个方法:
public void forward(ServletRequest request,ServletResponse response)
throws ServletException,IOException;
public void include(ServletRequest request,ServletResponse response)
throws ServletException,IOException;
三. 获取RequestDispatcher实例的方式主要有两种:
1.调用ServletContext接口提供的getRequestDispatcher(String url)方法。
2.调用ServletRequest接口提供的getRequestDispatcher(String url)方法。
3.RequestDispatcher接口的forward()方法用于将请求转发到RequestDispatcher实例封装的资源,由新的资源对客户端作出响应,它的原理可以用图4.16来表示。
4.同样使用“http://localhost:8080/jsp_04_servlet/servlet1?name=test”路径访问这个Servlet1,客户端浏览器将得到如图4.17所示的效果。
四. 重定向和请求分派的比较
HttpServletResponse的sendRedirect()方法实现的重定向和RequestDispatcher的forward()方法实现的请求转发的比较:
1.请求分派只能将请求转发给同一个Web应用中的其他组件;而重定向不仅可以定向到当前应用程序中的其他资源,也可以重定向到其他站点的资源上。
2.重定向的访问过程结束后,浏览器地址栏中显示的URL会发生改变,由初始的URL地址变成重定向的目标URL;而请求转发过程结束后,浏览器地址栏保持初始的URL地址不变。
利用请求域属性传递对象数据
一HttpServletRequest接口中提供了几个方法用来操作请求实例中存储的对象:
1.public void setAttribute(String name,Object obj):将对象存储进HttpServletRequest实例中。
2.public Object getAttribute(String name):检索存储在HttpServletRequest实例中的对象。
3.public Enumeration getAttributeNames():返回包含HttpServletRequest实例中的所有属性名的Enumeration对象。
二publicvoid removeAttribute(String name):从HttpServletRequest实例中删除指定名称的属性。
ServletConfig和ServletContext
一ServletContext的其他用途
1.public void setAttribute(String name,Object obj):根据指定名name把对象obj存放到应用上下文范围中。
2.public Object getAttribute(String name):根据指定名从应用上下文范围中获取到该属性对象。
3.public void removeAttribut(String name):根据指定名从应用上下文范围中移除该属性。
Servlet的线程安全问题
一使用synchronized
使用synchronized关键字同步操作成员变量和共享数据的代码,就可以防止可能出现的线程安全问题。
二尽量少使用成员变量和共享数据
1.ServletContext是可以多线程同时读/写成员变量和共享数据的,线程是不安全的。
2.ServletRequest对象在service方法的范围内是有效的,不要试图在service方法结束后仍然保存请求对象的引用。
3.Servlet本身就是多线程的,在Servlet中再创建线程,将导致执行情况复杂化,出现多线程安全问题。