java - Servlet 如何通过一般请求参数传递 SessionID
天蓬老师
天蓬老师 2017-04-17 17:57:18
0
2
828

我有个项目,希望在 REST 接口使用 SessionID 作为 Token,这样能简化和用熟悉的方式处理会话数据,在 URL 附加 ;jsessionid= 太丑,传递 Cookie 的话 APP 开发又嫌麻烦,就想通过普通的 GET/POST 参数或自定义 HTTP BODY 来传递 SessionID。

现在的 Servlet 都不再支持通过 ID 获取 Session,搜到的一些方案,比如用监听器来记录 Session,但我不喜欢这种方式,1是我觉得冗余,2是不想自己存储更不想放在内存里;SessionManager 的话就是自定存储了,目前 tomcat,jetty 等的 session 已经满足我的需求了,没必要找这个麻烦。

我查了下 Tomcat 的源码找到了他的 Request 里有 setRequestedSessionId 的方法,只要在 getSession 之前调用就行,但这不是 ServletRequest 接口里的方法,我的项目不一定运行在 Tomcat 里。

来问问有什么简单的方式解决这个问题没?

天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

reply all(2)
Peter_Zhu

Done, I checked the respective Request (implementation of HttpServletRequest) of Tomcat and Jetty, and both set the session id through a setRequestedSessionId(String). If I use reflection to obtain and call this method, set the sessionId before getSession. After the experiment works on Jetty, I will try Tomcat again. These two containers are what I commonly use, and I will check them out when I encounter other containers.

The code is simple:

    try {
        request.getClass ()
             .getMethod("setRequestedSessionId", String.class)
             .invoke   (request , id);
    } catch ( NoSuchMethodException ex) {
        // Log
    } catch (IllegalAccessException |
           IllegalArgumentException |
          InvocationTargetException ex) {
        // Log
    }

Haha!

It should be noted that it must be executed before the current request calls getSession for the first time. Pay special attention to whether there is a Filter in the upper layer that uses Session


2016/05/21 Updated experimental results

The SessionID can be replaced in the above method, but the Session cannot be taken out, because the Session will be verified when taking it out, and the source code of Jetty will be tracked to find out that the Session object is set when the Request is initialized, as shown below:

At this time, I haven’t progressed to Servlet and Filter yet, so I can’t start, so it seems that resetting is not that simple.

The above was only tested on Jetty, and the result failed. There is no experiment on Tomcat. If you look at the source code, there is a changeSessionId(String) method. It should be possible based on the logic.


Results updated again on 2016/05/21

After constant tossing, the sessionId was successfully reset using the following code:

    try {
        Object obj;
        obj = req.getClass ()
           .getMethod("getSessionManager")
           .invoke   (req);
        obj = obj.getClass ()
           .getMethod("getHttpSession" , String.class)
           .invoke   (obj, sid);
        req.getClass ()
           .getMethod("setSession", HttpSession.class)
           .invoke   (req, (HttpSession) obj);
    } catch ( NoSuchMethodException ex ) {
        // Log
    } catch (IllegalAccessException  |
           IllegalArgumentException  |
          InvocationTargetException ex ) {
        // Log
    }

Nothing needs to be changed in the program executed after this. You can use request.getSession() to read and write the Session normally. This method is written for Jetty.


2015/05/22 Tomcat actual measurement update

I was bored after breakfast, so I tracked the Tomcat code, using Tomcat 7 and 8 versions, and found that the Request object handed to the user Servlet is a proxy class called RequestFacade, which only implements the methods of the HttpServletRequest interface. , hiding his Request object, so methods such as setRequestedSessionId of org.apache.catalina.connector.Request cannot be called.

It seems that this Hack can only be implemented for Jetty.


Although the results are not optimistic, and Jetty may hide those methods in future versions, this experimental process has given us a better understanding of these two application containers. Whether it's Cookie, URL Path Parameter, or GET/POST parameters, they just carry Session Token in different locations of the request data. It may be more convenient to simply encapsulate the connection on the client side.

Ty80

Use token and put the token in the request header. The front-end is required to bring this token when making requests

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template