【问题标题】:Access a ViewScoped Managedbean in a Servlet在 Servlet 中访问 ViewScoped Managedbean
【发布时间】:2012-09-01 12:48:09
【问题描述】:

有人知道在 Servlet 中访问 ViewScoped ManagedBean 的方法吗?

例如,我可以通过这种方式访问​​ SessionScoped ManagedBean:

MyBean bean = (MyBean) request.getSession().getAttribute("myBean");

但如果我将范围设置为 ViewScoped,它会返回 null。我知道原因是 Servlet 尝试尽早访问 bean。但是我该如何解决这个问题?

支持 bean:

@ManagedBean(name = "statistikHandler")
@SessionScoped //or ViewScoped
public class StatistikHandler {

    private Object someAttribute

    //Do something nice here
    //getter and setter

}

小服务程序:

public class ImageStreamServlet extends HttpServlet {

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        System.out.println("+++++ CALL THE IMAGESERVLET +++++");

        //try to "inject" the Bean here

        StatistikHandler handler = (StatistikHandler) request.getSession().getAttribute("statistikHandler");

        try {
            if (handler != null) {
                //Do something with the ManagedBean
            } else {
                System.out.println("HANDLER NOT FOUND");
            }

        } finally {
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }
}

就是这样。如果我将 StatistikHandler 设置为 SessionScope 它工作正常。如果我将 Handler 设置为 ViewScoped,它将不起作用。


首先:感谢您的遮阳篷。

阿扬·蒂姆斯:

第二件事是视图范围仅在有视图正在处理时才存在。它不能凭空出现。

这是有道理的,我知道。我试图解释流程,希望你能理解我。我的英语不是最好的,但我认为已经足够了。所以让我们试试吧:

我设置了对视图的请求,因此设置了视图范围 bean 的实例。所以视图和 bean 存在,但 servlet 不是必需的。

现在我与视图交互并且必须渲染另一部分。现在这部分需要 servlet,我设置了对 servlet 的请求。

所以:视图和 bean 作为实例存在,然后(在部分重新加载之后)我请求 servlet。

阿扬·蒂姆斯:

您必须有一些代码将引用存储在请求范围内,Servlet 可以在其中找到并获取它。

恕我直言,这是重要的部分。正如你所说,我不能将视图范围的 bean 作为会话属性。我非常感谢你这个事实,因为我以前不知道。

现在我可以继续思考解决方案了。

感谢和问候

【问题讨论】:

  • 请分享您的托管 bean 代码,它是导入部分。
  • 你的[cdi] 标签有点搞笑。使用 CDI @Inject 是可能的,但您根本没有在 backing bean 上使用 CDI。为什么这个[cdi] 标签?
  • 因为我认为 CSI 可能是我的问题的解决方案。 :D

标签: servlets jsf-2 cdi


【解决方案1】:

有两点需要注意。

首先,您无法通过请求会话属性来获取视图范围 bean 的实例。这些 bean 根本不(直接)存储在那里。

第二件事是视图范围仅在有视图被处理时才存在。它不能凭空出现。

Java 代码示例来说明最后一条语句:

// How to access i here???

while (foo) {
    int i = 1;
    // ...
}

由于i 是在while 循环中声明的,因此在该循环之前访问它是没有意义的。

在 Servlet 的情况下,如果您的 Servlet 在同一个请求中分派给 Faces Servlet,那么您只能在之后访问视图范围的 bean,并且仍然不能直接访问。您必须有一些代码将引用存储在请求范围内,Servlet 可以在其中找到并获取它。

再次使用 Java 类比,如下所示:

int bar = 0;

while (foo) {
    int i = 1;
    // ...
    bar = i;
}

// use bar here

如果您需要 Servlet 设置视图范围 bean 使用的某些内容,则将该内容存储在请求范围中并让视图范围 bean 在那里提取它。再次与 Java 类比:

int bar = 23;

while (foo) {
    int i = bar;
    // ...
}

换句话说,使用一个共同的“通道”让这两者相互交流。

【讨论】:

    猜你喜欢
    • 2012-12-22
    • 1970-01-01
    • 2011-04-04
    • 2012-08-27
    • 2012-11-08
    • 2012-02-07
    • 2011-12-07
    • 2012-03-04
    • 2011-11-02
    相关资源
    最近更新 更多