- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我将 spring-web (4.1.7) 与 spring-security-oauth2 (2.0.12) 和 hazelcast (3.3) 一起使用。
在测试时,用户(没有 session )访问该站点并单击链接以启动 OpenId Connect 登录。
我添加了一个 HttpSessionListener 来检查 session 何时创建。
OAuth2RestTemplate 用于执行身份验证并包含以下行:OAuth2AccessToken accessToken = context.getAccessToken();
上下文对象是一个具有 session 范围的 OAuth2ClientContext bean,似乎使用此对象(而不是实例化它)会触发 session 的创建(并且上下文存储在 session 中)。
到目前为止一切顺利,但我遇到的问题是我使用 Hazelcast 进行 session 复制,但没有创建 Hazelcast session 。这是一个问题,因为当请求完成并且没有找到 HttpSession 的 Hazelcast session 时,Hazelcast 过滤器将销毁 HttpSession。
我的问题是,如何触发 Hazelcast 过滤器的创建?创建 session 的堆栈跟踪显示我们没有调用 Hazelcast 来创建 session :
WebSessionListener.sessionCreated(HttpSessionEvent) line: 15
StandardSession.tellNew() line: 367
StandardSession.setId(String) line: 341
StandardManager(ManagerBase).createSession(String) line: 857
StandardManager.createSession(String) line: 291
Request.doGetSession(boolean) line: 2606
Request.getSession(boolean) line: 2316
RequestFacade.getSession(boolean) line: 841
ServletRequestAttributes.getSession(boolean) line: 111
ServletRequestAttributes.getSessionMutex() line: 244
SessionScope.get(String, ObjectFactory<?>) line: 91
DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class<T>, Object[], boolean) line: 337
DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line: 194
SimpleBeanTargetSource.getTarget() line: 35
JdkDynamicAopProxy.invoke(Object, Method, Object[]) line: 187
$Proxy322.getAccessToken() line: not available
OAuth2RestTemplate.getAccessToken() line: 169
我进行了一些黑客攻击,发现如果我调用电话request.getSession(true);这将创建两者
堆栈跟踪显示我们在创建 HttpSession 之前执行了 Hazelcast 方法 SpringAwareWebFilter.createNewSession。
所以我遇到的问题似乎是:
使用 RequestWrapper(HttpServletRequestWrapper).getSession() 时获取/创建 session ,这是 Hazelcast 感知的。
但是,当 spring 尝试创建 session (在使用 session 作用域 bean 时触发)时,它无法识别 Hazelcast。
这是预期的行为吗?即 spring 不知道创建 Hazelcast session ,我必须找到一些解决方法?或者有人可以推荐任何进一步的方法来调试这个吗?
在 web.xml 中,hazelcast 配置是:
<filter>
<filter-name>hazelcast-filter</filter-name>
<filter-class>com.hazelcast.web.spring.SpringAwareWebFilter</filter-class>
<init-param>
<param-name>map-name</param-name>
<param-value>sessions</param-value>
</init-param>
<init-param>
<param-name>sticky-session</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>cookie-name</param-name>
<param-value>hazelcast.session</param-value>
</init-param>
<init-param>
<param-name>cookie-secure</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>cookie-http-only</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>config-location</param-name>
<param-value>hazelcast-geneva.xml</param-value>
</init-param>
<init-param>
<param-name>shutdown-on-destroy</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hazelcast-filter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
作为引用,如果我强制调用 request.getSession 并且此调用经过 Hazelcast 过滤器 WebFilter 和 SpringAwareWebFilter,则堆栈链如下所示(与上面缺少 Hazelcast 过滤器的堆栈相比)
WebSessionListener.sessionCreated(HttpSessionEvent) line: 15
StandardSession.tellNew() line: 367
StandardSession.setId(String) line: 341
StandardManager(ManagerBase).createSession(String) line: 857
StandardManager.createSession(String) line: 291
Request.doGetSession(boolean) line: 2606
Request.getSession(boolean) line: 2316
RequestFacade.getSession(boolean) line: 841
WebFilter$RequestWrapper(HttpServletRequestWrapper).getSession(boolean) line: 255
WebFilter$RequestWrapper.getOriginalSession(boolean) line: 533
SpringAwareWebFilter(WebFilter).createNewSession(WebFilter$RequestWrapper, String) line: 307
SpringAwareWebFilter.createNewSession(WebFilter$RequestWrapper, String) line: 47
WebFilter$RequestWrapper.getSession(boolean) line: 605
WebFilter$RequestWrapper.getSession(boolean) line: 515
RequestWrapper(HttpServletRequestWrapper).getSession(boolean) line: 255
我发现,当在 session 作用域 bean 上调用方法时,它会触发对 ServletRequestAttributes.getSession(boolean) 的调用。
该对象有一个名为 request 的属性,在该属性上调用 getSession(boolean)。如果这个请求对象是 Hazelcast 过滤器创建的 WebFilter$RequestWrapper,我怀疑一切都会正常工作。
但是,在调用 Hazelcast 过滤器 doFilter 之前,ServletRequestAttributes 已使用 HttpServletRequest(未由 Hazelcast 包装)进行初始化。
似乎不可能更新 ServletRequestAttributes 中的请求属性,但也许有某种方法可以创建新的属性。
我使用的是 RequestContextListener,它在任何过滤器之前被触发,并在 Hazelcast 过滤器有机会包装请求对象之前在 ServletRequestAttributes 中设置请求对象。我删除了 RequestContextListener 并将其替换为 RequestContextFilter (似乎是他们在 spring boot 中所做的: https://github.com/spring-projects/spring-boot/issues/2637 )。这确保了当初始化 ServletRequestAttributes 时,它会获取 Hazelcast 请求对象。
最佳答案
Hazelcast WebFilter
(以及 SpringAwareFilter
)将请求包装在 RequestWrapper
中。当调用 request.getSession()
时,包装器会创建一个新的 HazelcastSession
,或者返回现有的(如果有)。
这就是为什么 WebFilter
需要在其他过滤器之前定义。来自 hazelcast-wm's README :
Make sure Hazelcast filter is placed before all the other filters if any; you can put it at the top.
Servlet 容器在过滤器之前处理 ServletRequestListener
实例(请参阅 this answer on SO )。因此,如果 ServletRequestListener
(或任何其他代码段)在 WebFilter
有机会包装请求之前调用 request.getSession()
,则不会HazelcastSession
将被创建, session 复制将不起作用。
确保 Hazelcast WebFilter
在调用 request.getSession()
解决问题之前包装请求。
关于java - 作用域 bean 应如何在 Hazelcast 中触发 session 创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41058183/
有什么区别 和 您能解释一下这两者之间有什么区别吗? 最佳答案 它是一个 XML 命名空间,用于分隔可能存在冲突的元素名称,因此没有真正的区别。 XML Namespaces 关于java -
我刚刚浏览了两个 Web 应用程序,在两个项目的“applicationContext.xml”文件中都有一个标记 ... 另一个是 ... 谁能给我解释一下有什么区别吗? 最佳答案 没有语
我一直在尝试了解 WebSphere Commerce 中的 Java bean,但我真的很困惑。请帮帮我。我需要知道: What is the difference between EntityBe
自从我们更新到 grails 2.0.1(从 2.0.0 开始)以来,通过 bean 字段显示的所有 bean 都错误地显示为“withBean”字段的第一个属性。在我下面发布的示例中,所有 [fir
我有一个 bean,我将另一个 beanlist 放入其中,并且我想访问该内部 bean。 我的第一个 Bean 是: public class FirstDTO { private String F
我正在尝试将 CSS 和 JS 添加到 spring MVC 项目中的 JSP 页面,以便我在 dispatcher-servlet.xml 中包含了 js/css 文件夹的引用,如下所示:
当我将请求传递给 RestController 时,出现以下错误。 org.springframework.beans.factory.xml.XmlBeanDefinitionStoreExcept
我看到很多示例将 bean 标记为实体 bean (@Entity) 和命名 bean (CDI),以避免创建 2 个类(托管 bean 和实体 bean)并利用 Bean 验证以便可以执行验证在客户
在我的理解中, session 总是意味着有状态。考虑 servlet session 对象, 想想 cookie。如果 session 是无状态的,我认为我们根本不需要 session 。 在jee
我完全是Spring框架的初学者。我当时正在玩一个创建对象实例的示例。因此需要您的帮助! 看看这个例子: MainApp.java: import org.springframework.contex
这个问题在这里已经有了答案: What is a JavaBean exactly? (23 个回答) 关闭 7 年前。 我已经阅读了有关 EJB、Java Beans 的内容,但是我仍然对“bea
我刚开始使用 Spring-Framework,实际上我正在使用 spring-boot 库。我有以下问题: 我知道在 @Configuration 类中使用 @Bean 注册的 bean 默认是单例
我对下面提到的场景中使用Spring Framework时会创建的实例数量有疑问: bean配置是这样的 or 默认情况下,bean "a"有 singleton scope .所以
在我的 Spring-Module.xml 中,我有两个 bean: ... ... 我像这样实例化我的类: Applicat
@Autowired private Map departments; 我的 spring 配置文件 只要使用 @Autowired 需要日期,它就可以正常工作 同样, 如何使用没有属性
我已经为 ComboBox 设置了 ContainerDataSource this.comboBox.setContainerDataSource(container)。这个容器是一个 BeanIt
为了支持流畅的编程风格,我最近修改了我们的 Java Beans setter 方法以返回 Bean 类。但是现在 Java Beans Activation Framework (rel 1.1)
有人可以告诉我在我的 ApplicationContext 中我必须使用 beans:bean 而不是 bean 的什么以及如何修复它。
我有如下配置: batch:job id="reconciliationJob" job-repository="jobRepository" restartable="true" 在应用程序上下文启
我已经为 Test_flow 创建了简单的测试套件,但是当我尝试运行该流程时出现错误。 java.lang.RuntimeException: org.mule.api.config.Configur
我是一名优秀的程序员,十分优秀!