Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Servlets 如何在Liferay portlet请求中访问JSFbean中的servlet会话属性?_Servlets_Jsf 2_Liferay_Portlet - Fatal编程技术网

Servlets 如何在Liferay portlet请求中访问JSFbean中的servlet会话属性?

Servlets 如何在Liferay portlet请求中访问JSFbean中的servlet会话属性?,servlets,jsf-2,liferay,portlet,Servlets,Jsf 2,Liferay,Portlet,对于Liferay 6.2.10和Liferay Faces Bridge 3.2.4,是否可以只向原始会话写入一个属性,而不使用false 在JSFbean/portlet中,我们配置了一个导出文件,该文件必须可以通过servlet下载(在同一个WAR中) 我们希望通过会话共享一个特定对象,以供门户中的一些JSTL魔术使用 除了设置false,我没有找到其他方法,但是这会污染会话,因为在用户全局会话中没有人需要大量特定于JSF甚至更多特定于portlet的对象。由于这场战争中的大多数Por

对于Liferay 6.2.10和Liferay Faces Bridge 3.2.4,是否可以只向原始会话写入一个属性,而不使用
false

  • 在JSFbean/portlet中,我们配置了一个导出文件,该文件必须可以通过servlet下载(在同一个WAR中)
  • 我们希望通过会话共享一个特定对象,以供门户中的一些JSTL魔术使用
除了设置
false
,我没有找到其他方法,但是这会污染会话,因为在用户全局会话中没有人需要大量特定于JSF甚至更多特定于portlet的对象。由于这场战争中的大多数Portlet需要通信,我要么将所有端口都切换到公共会话属性,要么使用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
  • 将生成的文档(或导出配置)保存到数据库
  • 通过将配置重新发布到导出servlet,通过客户端传输配置
这建议对ApplicationScoped变量使用portletSession,但我无法获得portletSession

通过设置
false
我可以在原始会话中设置以下属性:

  • 使用外部上下文SERVLET请求会话测试
  • 使用\u PORTLET \u会话\u应用程序\u范围测试\u
  • 使用\u服务\u上下文测试\u
  • war\u应用程序\u名称\u无论什么?使用\u PORTLET\u会话\u PORTLET\u范围测试\u
以及在全局用户会话中可见的大量其他对象(>50)


有人知道如何只设置一个会话属性吗?

解包请求,直到到达一个不扩展
javax.servlet.http.HttpServletRequestWrapper的类,解决了这个问题

请求由Liferay存储,可通过
ServiceContextThreadLocal.getServiceContext().getRequest()
获取

如果请求包装器位于以“
”com.liferay.”
开头的包中,则Liferays
PortalTil
仅会展开,因此,如果使用自定义请求包装器,则Liferays不起作用

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;
}
publicstaticvoidsetonoriginalsession(类类型,值类型值){
HttpServletRequest请求=ServiceContextThreadLocal.getServiceContext().getRequest();
HttpServletRequest originalRequest=取消原始请求(请求);
HttpSession originalSession=originalRequest.getSession();
字符串attributeNameForType=getAttributeNameForType(类型);
setAttribute(attributeNameForType,值);
}
私有静态HttpServletRequest unwrapOriginalRequest(HttpServletRequest请求){
while(HttpServletRequestWrapper的请求实例){
HttpServletRequestWrapper HttpServletRequestWrapper=(HttpServletRequestWrapper)请求;
request=(HttpServletRequest)httpServletRequestWrapper.getRequest();
}
返回请求;
}

此方法在Liferay 7.0+中可能不起作用,因为您将无法再直接访问应用服务器的
HttpServletRequest
。如果您试图在Portlet之间共享数据,则应尝试my blog中的一种方法:。如果您试图在servlet应用程序和portlet之间共享数据,您可能应该为servlet和portlet使用外部数据源,如数据库或restapi。