Java 手动生成人脸上下文

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/592496/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 16:37:53  来源:igfitidea点击:

Generating a Faces Context manually

javajsfservletsicefaces

提问by Drew

I have two systems I'm trying to integrate. One is built on raw servlets, the new one is build on JSF with IceFaces. I'm trying to facilitate cross-system sign on. The idea is that I have a button in the old system that POSTs the appropriate information to the new site and logs them on.

我有两个系统要集成。一种是基于原始 servlet 构建的,新的一种是基于带有 IceFaces 的 JSF 构建的。我正在尝试促进跨系统登录。这个想法是我在旧系统中有一个按钮,可以将适当的信息发布到新站点并登录。

Well, ideally, I'd like to use just a regular old servlet to facilitate that on the new site. Go to the new site's Servlet, do what it needs to do and the forward onto the dashboard.

好吧,理想情况下,我只想使用一个常规的旧 servlet 来促进新站点上的实现。转到新站点的 Servlet,执行它需要执行的操作,然后转到仪表板。

Our security is handled via a managed bean. However, by the time you get to the Servlet, there is no faces context. So, how would I create a new faces context?

我们的安全性是通过托管 bean 处理的。但是,当您到达 Servlet 时,就没有faces 上下文了。那么,我将如何创建一个新的面孔上下文?

I have a back up plan in that I can always link to a dummy .iface page which will create the FacesContext for me and then create a backing bean that will do stuff when it gets instanciated and then forward onto the main page. But this feels very much like a hack.

我有一个备份计划,因为我总是可以链接到一个虚拟的 .iface 页面,该页面将为我创建 FacesContext,然后创建一个支持 bean,当它被实例化时会做一些事情,然后转发到主页。但这感觉非常像一个黑客。

Any help would be appreciated!

任何帮助,将不胜感激!

EDIT:I went with the back up way. Basically, I POST to a page like so:

编辑:我采用了备用方式。基本上,我 POST 到一个页面,如下所示:

<f:view>
   <ice:outputText value="#{EntryPoint}"/>
</f:view

The backing bean looking like so...

支撑豆看起来像这样......

public EntryPoint() {
      try {
         HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
         HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse(); 
         String loginID = request.getParameter("loginID");
         //Do some code to load the user/permissions
         response.sendRedirect(
            //The appropriate page
         );
      } catch (IOException ex) {
         logger.error(null, ex);
      } catch (SQLException ex) {
         logger.error(null, ex);
      }
   }

This still feels like a hack, but I'm not sure how to get around this. Ideally, I'd POST to a servlet, get the loginID, build the user and put it directly into the managed bean. But, the FacesContext does not exist at that point.

这仍然感觉像是一个黑客,但我不知道如何解决这个问题。理想情况下,我会 POST 到 servlet,获取 loginID,构建用户并将其直接放入托管 bean。但是,此时 FacesContext 不存在。

Any other ideas?

还有其他想法吗?

采纳答案by McDowell

I'm not sure what you mean by "site" in this context.

在这种情况下,我不确定您所说的“站点”是什么意思。

A couple of notes:

一些注意事项:

  • Managed beans will be never be available outside the web app (WAR) in which they are defined.
  • FacesContext object instances are ultimately created and disposed by FacesServlet.service, so requests should pass through this servlet. Attempting to create a context under other circumstances might lead to undefined behaviour.
  • 托管 bean 在定义它们的 Web 应用程序 (WAR) 之外将永远不可用。
  • FacesContext 对象实例最终由FacesServlet.service创建和处理,因此请求应该通过这个 servlet。尝试在其他情况下创建上下文可能会导致未定义的行为。


Bearing that in mind, you could create a request sequence like this:

记住这一点,您可以创建一个这样的请求序列:

FacesServlet (mapping: /faces/*)
 -> /faces/jsfPage.jsp (a JSP with JSF controls)
    -> DispatchBean (calls ExternalContext.dispatch("/AnotherServlet")
       -> AnotherServlet

jsfPage.jsp contains:

jsfPage.jsp 包含:

<f:view>
    <h:outputText value="#{dispatchBean.dispatch}" />
</f:view>

The "dispatch" property resolves to a bean method "getDispatch":

"dispatch" 属性解析为一个 bean 方法 "getDispatch":

public String getDispatch() {
    FacesContext context = FacesContext.getCurrentInstance();
    try {
        context.getExternalContext().dispatch("/FacesClientServlet");
    } catch (IOException e) {
        throw new FacesException(e);
    }
    return null;
}

Which dispatches to this servlet:

哪个调度到这个servlet:

public class FacesClientServlet extends javax.servlet.http.HttpServlet
        implements javax.servlet.Servlet {

    static final long serialVersionUID = 1L;

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

        FacesContext context = FacesContext.getCurrentInstance();
        ELContext elContext = context.getELContext();
        ExpressionFactory expressionFactory = context.getApplication()
                .getExpressionFactory();
        ValueExpression expression = expressionFactory.createValueExpression(
                elContext, "#{myBean.text}", Object.class);
        Object value = expression.getValue(elContext);

        ResponseWriter writer = context.getResponseWriter();
        writer.write("" + value);

    }

}

Which emits the value from a managed bean "myBean":

它从托管 bean “myBean”发出值:

public class MyBean {

    private final String text = "Hello, World!";

    public String getText() {
        return text;
    }

}

This is all very convoluted and I wouldn't willingly do any of it.

这一切都非常复杂,我不会心甘情愿地做任何事情。



An alternative, which may come with its own consequences, is to create your own context like this:

另一种可能会带来后果的替代方案是创建您自己的上下文,如下所示:

public class ContextServlet extends javax.servlet.http.HttpServlet implements
        javax.servlet.Servlet {
    static final long serialVersionUID = 1L;

    private FacesContextFactory facesContextFactory;
    private Lifecycle lifecycle;

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);

        LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder
                .getFactory(FactoryFinder.LIFECYCLE_FACTORY);
        facesContextFactory = (FacesContextFactory) FactoryFinder
                .getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
        lifecycle = lifecycleFactory
                .getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
    }

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

        FacesContext context = facesContextFactory.getFacesContext(
                getServletContext(), request, response, lifecycle);
        try {
            ELContext elContext = context.getELContext();
            ExpressionFactory expressionFactory = context.getApplication()
                    .getExpressionFactory();
            ValueExpression expression = expressionFactory
                    .createValueExpression(elContext, "#{myBean.text}",
                            Object.class);
            Object value = expression.getValue(elContext);

            PrintWriter pw = response.getWriter();
            try {
                pw.write("" + value);
            } finally {
                pw.close();
            }
        } finally {
            context.release();
        }
    }

}

Again, I would avoid this approach if possible.

同样,如果可能,我会避免这种方法。