5.4.5 通过重写URL跟踪Session

优质
小牛编辑
144浏览
2023-12-01

如果用户把浏览器的Cookie功能关闭,或者浏览器不支持Cookie功能,那么SessionId就不能通过Cookie向服务端发送了。Servlet规范为了弥补这个不足,允许通过URL请求参数来发送SessionId。这样当浏览器的Cookie功能关闭时,在浏览器中仍然可以通过由URL请求参数发送的SessionId在服务端找到相应的HttpSession对象。

在下面的例子演示了如何通过URL的请求参数来发送SessionId,读者可以从该例子中学到如何通过重写URL的方式来跟踪Session对象。

例子 : 通过重写URL跟踪Session

1. 实例说明

本例使用HttpResponseServlet接口的encodeURL方法重写了URL,发在浏览器未关闭Cookie和关闭Cookie的情况下测试本例中的Servlet。当关闭浏览器的Cookie功能时,encodeURL方法会在URL后面加一个jsessionid参数,该参数的值就是SessionId。

2. 编写RewriteURL类

public class RewriteURL extends HttpServlet
{
    public void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        HttpSession session = request.getSession();
        response.setContentType("text/html; charset=UTF-8");           
        RequestDispatcher rd = request.getRequestDispatcher("HeaderInfo");
        //  包含HeaderInfo的内容
        rd.include(request, response);
        PrintWriter out = response.getWriter();
        //  重写URL
        out.println("<br/><br/><a href='" +response.encodeURL("RewriteURL?param=value") + "'>RewriteURL</a>");       
    }
}

在上面的代码中包含了HeaderInfo,以显示请求消息头的内容。重写URL可以使用HttpResponseServlet接口中的encodeURL方法,在本例中,使用encodeURL方法将访问RewriteURL的URL进行了重写。

3. 配置RewriteURL类

RewriteURL类的配置代码如下:

<servlet-mapping>
    <servlet-name>CookieSession</servlet-name>
    <url-pattern>/CookieSession</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>RewriteURL</servlet-name>
    <servlet-class>chapter5.RewriteURL</servlet-class>
</servlet>

4. 测试浏览器在未关闭Cookie功能的情况下使用Session

假设本机的IP是192.168.18.212,在浏览器地址栏中输入如下的URL:

http://192.168.18.212:8080/demo/RewriteURL

在第一次访问上面的URL时,encodeURL方法在重写URL时会加入jsessionid参数,这是因为当第一次访问这个URL时,HTTP请求消息头的Cookie字段中并没有叫JSESSIONID的Cookie,所以encodeURL会在URL中加入jsessionid参数,如图5.18所示。

18

图5.18 第一次访问RewriteURL,在URL后添加了jsessionid参数

当在同一个浏览器窗口再次访问上面的URL时, jsessionid参数就不会在URL中出现了,这是由于浏览器已经在HTTP请求消息头的Cookie字段中加入了叫JSESSIONID的Cookie,就不需要在URL中传递SessionId了,如图5.19所示。

19

图5.19 再次访问RewriteURL时,重写URL时不再添加jsessionid参数

从这一点可以看出,encodeURL方法将根据HTTP请求消息头中是否有叫JSESSIONID的Cookie来决定是否在被重写的URL中加入jsessionid参数。

5. 测试关闭Cookie功能的情况

在IE中单击【工具】>【Internet 选项】命令,打开【Internet 选项】对话框,选中【隐私】页面 ,单击【高级】按钮,打开【高级隐私策略对话框】对话框,并按着如图5.20所示来设置。

20

图5.20 关闭Cookie功能

在浏览器地址栏中输入如下的URL:

http://192.168.18.212:8080/demo/RewriteURL

无论访问多少次上面的URL,在URL上都会加上一个jsessionid参数,也就是说,效果都会和5.18一样。

5. 程序总结

如果要使用URL参数来传递SessionId,不要选中图5.20所示的【总是允许会话cookie】复选框。如果选中,虽然Cookie被禁止,但却可以保存临时Cookie,由于JSESSIONID也是临时Cookie,所以在这种情况下,JSESSIONID仍然可以在客户端和服务端之间传递。

还要提一点的是jsessionid并不是请求参数,这个参数和RewriteURL使用了分号分隔(;)分隔,它是请求URL的一部分,可以使用HttpServletRequest的getRequestURI方法获得。如果URL含有请求参数,格式类似下面的形式:

http://192.168.18.212:8080/demo/RewriteURL;jsessionid=AB130896860CD37902CDEDEB63A372B5?param=value

如果使用localhost访问RewriteURL,就算关闭了Cookie功能,仍然可以使用临时Cookie,因此,用localhost来访问RewriteURL时,无论Cookie功能是否被关闭,都可以使用Cookie来传递SessionId,如下面的URL所示:

http://localhost:8080/demo/RewriteURL