2

我正在尝试将Objectfrom传递给 JSF 的Servletaction方法。但我无法做到这一点。doPost()Managed bean

我试图将值设置Servlet为:

request.getSession().setAttribute(key, "JYM");

并尝试将其检索Managed bean为:

FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(key)

它正在回归null

这也是nullManaged bean

((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getSession().getAttribute(key);

Managed bean由此返回null

((HttpSession)FacesContext.getCurrentInstance().getExternalContext().getSession(false)).getAttribute(key)

我将密钥传递为:

'${pageContext.request.contextPath}/uploadservlet;jsessionid=${pageContext.session.id}?key=<h:outputText value="#{uploadBean.key}" />'

uploadBean是的名称Managed beankey生成为:

key = UUID.randomUUID().toString();

keyServlet 和托管 bean 中都保持不变。我打印的是检查。

我怎样才能传递ObjectfromServletAction?任何指针都会非常有帮助。

更新

Managed bean会话范围内。

更新

通过使用ServletContext我能够传递值:

这是我所做的: 在 Servlet 中:

String key = request.getParameter("key");

if (getServletContext().getAttribute(key) == null) {
    List<FileItem> fileFields = new ArrayList<FileItem>();
    fileFields.add(fileField);
    getServletContext().setAttribute(key, fileFields);
} else {
    List<FileItem> fileFields = (List<FileItem>)getServletContext().getAttribute(key);
    fileFields.add(fileField);
}

从会话范围的bean:

ServletContext servletContext = ((ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext());
List<FileItem> fileFields = (List<FileItem>)servletContext.getAttribute(key);
servletContext.setAttribute(key, null);

现在fileFields不再为空。我理解的是ServletContext行为类似于 Application Scoped 变量。

更新

HttpSessionListener的实现:

这是我写的课程:

public class UploadListener implements HttpSessionListener {
    private HttpSession session = null;

    public void sessionCreated(HttpSessionEvent event) {
        session  = event.getSession();
        session.setMaxInactiveInterval(10);
    }

    public void sessionDestroyed(HttpSessionEvent event) {
        session  = event.getSession();
        Set<String> keys = (Set<String>) session.getAttribute("key");
        Map<String, Object> data = (Map<String, Object>) session.getServletContext().getAttribute("key");
        data.keySet().removeAll(keys);
    }
}

我将值设置ServletContext为:

String key = request.getParameter("key");

List<FileItem> fileFields = (List<FileItem>)getServletContext().getAttribute(key);

if (fileFields == null) {
    fileFields = new ArrayList<FileItem>();
    getServletContext().setAttribute(key, fileFields);
}

fileFields.add(fileField);

这就是我调用 Servlet: 的方式'${pageContext.request.contextPath}/uploadservlet?key=<h:outputText value="#{uploadBean.key}" />'

4

1 回答 1

2

如果 servletcontainer 不支持通过jsessionidURL 片段识别 HTTP 会话,则此构造将失败。这是默认支持的,但可以通过 servletcontainer 特定配置来关闭它。到目前为止,不幸的是,您的 Weblogic 服务器似乎是这样配置的。

您最好的选择是在应用程序范围内交换数据。的随机性UUID足够强,不会引起冲突。您只需要确保在销毁会话时清除与会话相关的数据。否则内存会泄漏。为此,您可以使用HttpSessionListener. 如果您将密钥存储在应用程序范围(引用共享数据)和会话范围(引用到目前为止使用的所有密钥)中,那么sessionDestroyed()实现可以如下所示:

public void sessionDestroyed(HttpSessionEvent event) {
    Set<String> keys = (Set<String>) event.getSession().getAttribute("keys");
    Map<String, Object> data = (Map<String, Object>) event.getSession().getServletContext().getAttribute("data");
    data.keySet().removeAll(keys);
}

根据您的更新进行更新,获取/设置它们的更优雅的方法是:

String key = request.getParameter("key");
List<FileItem> fileFields = (List<FileItem>) getServletContext().getAttribute(key);

if (fileFields == null) {
    fileFields = new ArrayList<FileItem>();
    getServletContext().setAttribute(key, fileFields);
}

fileFields.add(fileField);

List<FileItem> fileFields = (List<FileItem>) FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().remove(key);
// ...
于 2013-01-11T14:47:24.380 回答