【问题标题】:Access ViewScoped ManagedBean from Servlet从 Servlet 访问 ViewScoped ManagedBean
【发布时间】:2012-12-22 05:07:40
【问题描述】:

背景信息:我的jsf页面中有一个文件上传小程序。这个小程序需要一个可以发送它的 POST 请求的地址。 (我无法编辑此帖子请求以添加更多字段或其他内容)。然后我的 servlet 的 post 方法存储该文件。这项工作不能由托管 bean 完成,因为 servlet 必须使用 @MultiPartConfig 进行注释,并且我无法将此注释添加到 jsf 托管 bean。为了强制上传小程序使用相同的会话,我根据这个post 在发布请求中添加了一个名为 jsessionId 的 URL 属性。在我的 servlet 中,我现在可以访问会话范围的 bean。

现在我有一个 ViewScoped bean,我在其中存储了一些我想在 servlet 中使用的表单输入数据,因为将这些输入添加到 post 请求中不起作用(Applet 是第三方项目 (JUploadApplet) 并且对于某些原因添加额外的表单数据不起作用)。 现在是否可以从 servlet 中访问 ViewScoped bean?如果我将范围更改为 SessionScope,我可以处理输入,但使用 ViewScoped 如果我尝试像这样访问 bean,则会得到 NullPointerException: UploadBean uploadBean = (UploadBean)request.getSession().getAttribute("uploadBean");

【问题讨论】:

    标签: jsf jakarta-ee jsf-2 applet managed-bean


    【解决方案1】:

    这是不可能的。最好的办法是让视图范围的 bean 生成一个唯一键,通过该键将自身存储在会话范围中,并将该键作为附加参数传递给小程序,最后让 servlet 通过该键访问会话属性。

    例如

    private String sessionKey;
    
    @PostConstruct
    public void init() {
        sessionKey = UUID.randomUUID().toString();
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(sessionKey, this);
    }
    
    @PreDestroy
    public void destroy() {
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(sessionKey);
    }
    

    让小程序将sessionKey作为请求参数传递给servlet,这样servlet就可以做

    String sessionKey = request.getParameter("sessionKey");
    Bean bean = (Bean) request.getSession().getAttribute(sessionKey);
    // ...
    

    请注意,除了 bean 本身,您还可以只存储任意 bean/valueobject/等。

    【讨论】:

    • 好的,但我不完全知道如何将请求参数传递给 servlet。我尝试将它添加到 postURL 参数中,如下所示: 但这不会不工作
    • 您的 URI 语法错误。您需要 ? 字符将 URI 查询字符串与 URI 路径分开。 & 字符仅用于分隔查询字符串中的多个参数。
    • 您的解决方案几乎可以工作,但仍然存在一个(奇怪的)问题:如上所述,我将一个对象(一个 HashMap)放入 SessionMap 中。现在,当我上传一个文件时,一切正常,但是一旦我尝试上传第二个文件,就找不到该属性了。这可能与 PreDestroy 方法有关吗?我已经通过调试检查了是否创建了一个新的 ViewScoped Bean,因此我没有使用相同的视图,因此没有使用被破坏的 bean。
    • 起初我得到 NullPointerExceptions 但是当我现在尝试重现此错误时,我只收到警告警告:PWC4011:无法从上下文 /webschemex 将请求字符编码设置为 UTF-8,因为请求参数有已经被读取,或者 ServletRequest.getReader() 已经被调用
    • 重新创建视图范围的bean实际上是一个不同的问题。这可能与您的视图标记方式和/或导航方式有关。至于 PWC4011,请查看此答案:stackoverflow.com/questions/7643484/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-04
    • 2012-08-27
    • 2012-11-08
    • 2012-02-07
    • 2012-03-04
    • 2013-04-21
    • 2011-11-02
    相关资源
    最近更新 更多