【问题标题】:How to open JSF page using JAX-RS web service?如何使用 JAX-RS Web 服务打开 JSF 页面?
【发布时间】:2016-07-01 23:23:54
【问题描述】:

我希望其他 Web 应用程序(在 .net 或任何其他中)调用我的 JAX-RS Web 服务来设置和打开带有一些传递值的 JSF 页面。

例如

  • 另一个 Web 应用程序只需传递 userIdtoken 即可打开入口页面。
  • 用户将完成条目,服务将返回 uniqueId 以创建条目。

我很困惑如何设置 JSF 上下文参数并使用 JAX-RS 打开该 JSF 页面。谁能提供有关如何使用 Web 服务设置 JSF 会话范围托管 bean 的值的想法?

【问题讨论】:

  • JAX-RS 和 JSF 是互补的技术。您无法从 JAX-RS 打开 jsf 页面。如果你想从客户端打开一个jsf页面,你可以对jsf页面做一个http get,并将相关参数作为请求参数传入。或者,您可以在与 jsf 页面相同的 webapp 中调用单独的 JAX-RS service,通过它设置参数,然后在第二个请求中在 http get 中打开 JSF 页面而不传递参数.只需确保参数存储在足够长的范围内即可。
  • 好的,但现在的问题是如何设置长范围变量?例如。尝试使用 @Context 使用 JAX-RS 在 servlet 中设置会话变量。但它不起作用,因为其他 servlet 没有获取值
  • Servlet?将 jax-rs 与 cdi 一起使用,jsf 将其用于... 追求现代标准
  • 我正在尝试设置会话范围托管 bean 的值,但 FacesContext.getCurrentInstance() 在 webservice 中给出 null

标签: web-services rest jsf jsf-2 jax-rs


【解决方案1】:

在你的代码中试试这个,

return new Viewable("/index", "FOO");

或者,

RequestDispatcher rd = request.getRequestDispatcher("{url}");
rd.forward(request, response);

或者,

return Response.status(myCode).entity(new Viewable("/index", "FOO")).build();

【讨论】:

    【解决方案2】:

    尝试使用jersey 的这些示例,

    @GET
    public Response get() {
        URI uri=new URI("http://nohost/context");
        Viewable viewable=new Viewable("/index", "FOO");
        return Response.ok(viewable).build();
    }
    

    要返回不同的东西,请使用以下方法:

    @GET
    public Response get() {
        int statusCode=204;
        Viewable myViewable=new Viewable("/index","FOO");
        return Response.status(statusCode).entity(myViewable).build();
    }
    

    希望对你有所帮助

    【讨论】:

    • 那里的路径使用你的jsf文件路径
    • @Kukeltje 你能给我一个可以使用 JSF 和 Jersey 的例子吗?
    • 我在 Jersey 文档 jersey.java.net/documentation/latest/… 上找到了,但我仍然对如何使用它感到困惑
    【解决方案3】:

    首先,这个问题总体上表明对“REST Web 服务”的目的存在误解。该问题具体要求使用 REST Web 服务执行两个相当不寻常的任务:

    1. 操纵与请求关联的 HTTP 会话。
    2. 重定向到由有状态 MVC 框架管理的 HTML 页面作为响应。

    两者都与 REST 的 stateless 本质完全矛盾。这些任务不应该由 REST Web 服务执行。此外,REST Web 服务主要供编程客户端(例如 JavaScript 或 Java 代码)使用,而不是供使用 HTML 页面的 Web 浏览器使用。您通常不会在浏览器的地址栏中输入 REST Web 服务的 URL 来查看 HTML 页面。您通常在浏览器的地址栏中输入 HTML 页面的 URL。该 HTML 页面又可以由基于 HTML 表单的 MVC 框架(例如 JSF)生成。

    在您的具体情况下,在程序化客户端检索到唯一 来自 REST Web 服务的 ID,然后程序化客户端应该依次向 JSF Web 应用程序发出一个新请求。例如。在基于 Java 的客户端中如下所示(下面的示例假设它是一个普通的 servlet,但它可以是您自己所说的任何其他内容):

    String uniqueId = restClient.getUniqueId(userId, token);
    String url = "http://example.com/context/login.xhtml?uniqueId=" + URLEncoder.encode(uniqueId, "UTF-8");
    response.sendRedirect(url);
    

    在目标 JSF Web 应用程序中,只需按照通常的方式使用 <f:viewParam>/<f:viewAction> 即可获取唯一 ID 并基于该 ID 执行业务操作。例如。如下login.xhtml:

    <f:metadata>
        <f:viewParam name="uniqueId" value="#{authenticator.uniqueId}" />
        <f:viewAction action="#{authenticator.check}" />
    </f:metadata>
    

    @ManagedBean
    @RequestScoped
    public class Authenticator {
    
        private String uniqueId;
    
        @EJB
        private UserService service;
    
        public String check() {
            FacesContext context = FacesContext.getCurrentInstance();
            User user = service.authenticate(uniqueId);
    
            if (user != null) {
                context.getExternalContext().getSessionMap().put("user", user);
                return "/somehome.xhtml?faces-redirect=true";
            }
            else {
                context.addMessage(null, new FacesMessage("Invalid token"));
                return null; // Or some error page.
            }  
        }
    
        // Getter/setter.
    }
    

    也许为了方便起见,REST Web 服务甚至可以返回包含唯一 ID 的完整 URL,这样客户端就不必担心目标 URL。

    String uniqueIdURL = restClient.getUniqueIdURL(userId, token);
    response.sendRedirect(uniqueIdURL);
    

    另一方面,您很有可能只是误解了功能需求,您可以直接在 JSF Web 应用程序中处理用户 ID 和令牌,如果它与 REST Web 运行在同一台服务器上,则更有可能服务,也使用 HTTPS。只需添加一个额外的&lt;f:viewParam&gt; 并在&lt;f:viewAction&gt; 方法中执行与JAX-RS 资源相同的业务服务逻辑。

    <f:metadata>
        <f:viewParam name="userId" value="#{authenticator.userId}" />
        <f:viewParam name="token" value="#{authenticator.token}" />
        <f:viewAction action="#{authenticator.check}" />
    </f:metadata>
    

    另见:

    【讨论】:

    • 感谢@BalusC。我在等你的回复。但我的问题是传递一些参数(例如用户、组织单位、位置等)并在此基础上打开 JSF 应用程序页面
    • 即使我尝试了@Kukeltje 评论,也得到了 url,但我无法设置更高范围的变量。那么有没有其他方法可以做到这一点?
    • 如果 JAX-RS 和 JSF 在同一台服务器上运行并且基本上共享相同的后端,那么只需将这些参数传递给 JSF 页面,而不是如上所示。另见答案的最后一段。看起来您过度考虑了解决方案,并且 JAX-RS 在需求中是不必要的。它仅对程序化客户端有用,对常规网络浏览器无效。
    • 但是想传递参数而不显示在URL中
    • 然后只在检索后发送重定向?当前的f:viewAction 示例已经成功地做到了这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-29
    • 1970-01-01
    相关资源
    最近更新 更多