2015-01-12 1 views
0

Возможно ли записать только один атрибут на исходный сеанс без использования <private-session-attributes>false</private-session-attributes> с Liferay 6.2.10 и Liferay-Faces-Bridge 3.2.4?Как получить доступ к атрибутам сеанса сервлета в компоненте JSF внутри запроса портлета Liferay?

  • В JSF-bean/portlet мы настраиваем файл экспорта, который должен быть загружен через сервлет (внутри той же WAR).
  • Мы хотим поделиться одним конкретным объектом через сеанс, чтобы использовать некоторые JSTL-магии внутри портала.

Я не нашел другого выхода, кроме установки <private-session-attributes>false</private-session-attributes>, но загрязняет сессии с большим количеством JSF специфических и даже более портлетных конкретных объектов, которые никто не нуждается в пользовательской глобальной сессии. Поскольку большинство портлетов в этой войне необходимо связывать, мне придется либо переключать все на общедоступные атрибуты сеанса, либо использовать IPC.

Я пробовал несколько способов, которые дают только положительные результаты, не используя частные атрибуты сеанса.

ServiceContextThreadLocal.getServiceContext().getRequest().getSession().setAttribute("SERVICE_CONTEXT", true); 

ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext(); 
// Does not matter which way 
// PortletSession portletSession = (PortletSession)externalContext.getSession(false); 
PortletSession portletSession = ((PortletRequest) externalContext.getRequest()).getPortletSession(); 
portletSession.setAttribute("PORTLET_SESSION_PORTLET_SCOPE", true, PortletSession.PORTLET_SCOPE); 
portletSession.setAttribute("PORTLET_SESSION_APPLICATION_SCOPE", true, PortletSession.APPLICATION_SCOPE); 

HttpServletRequest httpServletRequest = PortalUtil.getHttpServletRequest((PortletRequest) externalContext.getRequest()); 
httpServletRequest.getSession().setAttribute("EXTERNAL_CONTEXT_SERVLET_REQUEST_SESSION", true); 

HttpServletRequest outerRequest = PortalUtil.getOriginalServletRequest(httpServletRequest); 
outerRequest.getSession().setAttribute("EXTERNAL_CONTEXT_SERVLETS_SERVLET_REQUEST", true); 

Другие варианты, которые я хотел бы избежать бы:

  • использовать javax.servlet.Filter с ThreadLocal
  • сохранить созданный документ (или конфигурации экспорта) в базу данных
  • транспорта конфигурации через клиента путем повторной отправки его в сервлет экспорта.

Этот answer предлагает использовать portletSession с переменными ApplicationScoped, но я не смог получить PortletSession.

С установкой <private-session-attributes>false</private-session-attributes> я получаю следующие атрибуты, установленные в оригинальной сессии:

  • TEST_WITH_EXTERNAL_CONTEXT_SERVLET_REQUEST_SESSION
  • TEST_WITH_PORTLET_SESSION_APPLICATION_SCOPE
  • TEST_WITH_SERVICE_CONTEXT
  • war_app_name_whatever TEST_WITH_PORTLET_SESSION_PORTLET_SCOPE

и множество других объектов (> 50), видимых в глобальных сеансах пользователей.

У кого-нибудь есть хорошая идея, как установить только один атрибут сеанса?

ответ

0

Развертывание запроса до достижения класса, который не распространяется javax.servlet.http.HttpServletRequestWrapper, решает проблему.

Запрос любезно сохранен Liferay и доступен через ServiceContextThreadLocal.getServiceContext().getRequest().

Liferays PortalUtil просто разворачивается, если оболочка запроса находится в пакете, который начинается с "com.liferay." и поэтому не работает, если используется специальная оболочка запроса.

public static <Type, ValueType extends Type> void setOnOriginalSession(Class<Type> type, ValueType value) { 

    HttpServletRequest request = ServiceContextThreadLocal.getServiceContext().getRequest(); 
    HttpServletRequest originalRequest = unwrapOriginalRequest(request); 
    HttpSession originalSession = originalRequest.getSession(); 

    String attributeNameForType = getAttributeNameForType(type); 
    originalSession.setAttribute(attributeNameForType, value); 
} 

private static HttpServletRequest unwrapOriginalRequest(HttpServletRequest request) { 

    while (request instanceof HttpServletRequestWrapper) { 
     HttpServletRequestWrapper httpServletRequestWrapper = (HttpServletRequestWrapper) request; 
     request = (HttpServletRequest) httpServletRequestWrapper.getRequest(); 
    } 
    return request; 
} 
Смежные вопросы