Причина этого вопроса
- @ SessionObj с автопроводкой в OtherFilter
- @ SessionObj с автопроводкой в контроллере после OtherFilter
Обе ситуации выше, источником DI является запрос # getsession (), который привязан к объекту [requestAttributes].
org.springframework.web.context.request.ServletRequestAttributes
protected final HttpSession getSession(boolean allowCreate) {
if (isRequestActive()) {
HttpSession session = this.request.getSession(allowCreate);
this.session = session;
return session;
}
}
Ниже приведены основные этапы во время одного запроса:
последовательность от а до е
а. В RequestContextListner
объект [requestAttributes] связан с экземпляром
HttpServletRequestImpl (без информации о сеансе из БД)
org.springframework.web.context.request.RequestContextListener
public void requestInitialized(ServletRequestEvent requestEvent) {
if (!(requestEvent.getServletRequest() instanceof HttpServletRequest)) {
throw new IllegalArgumentException(
"Request is not an HttpServletRequest: " + requestEvent.getServletRequest());
}
HttpServletRequest request = (HttpServletRequest) requestEvent.getServletRequest();
ServletRequestAttributes attributes = new ServletRequestAttributes(request);
request.setAttribute(REQUEST_ATTRIBUTES_ATTRIBUTE, attributes);
LocaleContextHolder.setLocale(request.getLocale());
RequestContextHolder.setRequestAttributes(attributes);
}
б. В SessionRepositoryFilter
- запрос заключен в SessionRepositoryRequestWrapper (с сеансом
информация из БД)
но объект [requestAttributes] не переименован
с экземпляром SessionRepositoryRequestWrapper
org.springframework.session.web.http.SessionRepositoryFilter
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
request.setAttribute(SESSION_REPOSITORY_ATTR, this.sessionRepository);
SessionRepositoryRequestWrapper wrappedRequest = new SessionRepositoryRequestWrapper(
request, response);
SessionRepositoryResponseWrapper wrappedResponse = new SessionRepositoryResponseWrapper(
wrappedRequest, response);
try {
filterChain.doFilter(wrappedRequest, wrappedResponse);
}
}
с. В другом фильтре
- SessionObj внедряется через [requestAttributes], связанный с
экземпляр HttpServletRequestImpl (без информации о сеансе из БД), поэтому
пусто
* * +1058 д. В FrameworkServlet
объект [requestAttributes] повторно привязан с экземпляром
SessionRepositoryRequestWrapper (с информацией о сеансе из БД), который был
завернутый в предыдущий процесс b
org.springframework.web.servlet.FrameworkServlet
protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);
initContextHolders(request, localeContext, requestAttributes);
}
private void initContextHolders(HttpServletRequest request,
@Nullable LocaleContext localeContext, @Nullable RequestAttributes requestAttributes) {
if (requestAttributes != null) {
RequestContextHolder.setRequestAttributes(requestAttributes, this.threadContextInheritable);
}
}
е. В контроллере после OtherFilter
- SessionObj внедряется через [requestAttributes], связанный с
экземпляр SessionRepositoryRequestWrapper (с информацией о сеансе из
БД), так что отлично работает
Одно решение для этого вопроса
Добавление фильтра получения сеанса между springSessionRepositoryFilter
и другой фильтр
<bean class="org.springframework.web.filter.CompositeFilter" name="springChainFilter">
<property name="filters">
<list>
<bean id="springSessionRepositoryFilter" class="org.springframework.session.web.http.SessionRepositoryFilter">
</bean>
<!--Session Retrieve Filter -->
<bean id="sessionRetrieveFilter" class="xxx.xxx.SessionRetrieveFilter">
<!--Other Later Filter -->
<bean id="otherFilter" class="xxx.xxx.OtherFilter">
</bean>
</list>
</property>
</bean>
В Session Retrieve Filter свяжите [requestAttributes] с
экземпляр SessionRepositoryRequestWrapper (сделать что-то вроде
FrameworkSevlet сделать в будущем)
xxx.xxx.SessionRetrieveFilter
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
RequestAttributes wrappedAttributes = new ServletRequestAttributes(request, response);
RequestContextHolder.setRequestAttributes(wrappedAttributes);
filterChain.doFilter(request, response);
}