Java 如何将来自 RESTful api 的结果与 JSF 集成?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18296328/
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-12 00:12:31  来源:igfitidea点击:

How to integrate results from RESTful api with JSF?

javajsfrestjsf-2

提问by yisa

How to pass results from RESTful service to JSF components? I read many postings, but couldn't find a straightforward method. Using RESTful APIs wherever possible is the main requirement for my application. Performance is also a key as thousands of data elements will be processed in a day. If I can't find a solution in JSF, I might have to switch to another technology..

如何将结果从 RESTful 服务传递给 JSF 组件?我读了很多帖子,但找不到简单的方法。尽可能使用 RESTful API 是我的应用程序的主要要求。性能也是一个关键,因为一天将处理数千个数据元素。如果我在 JSF 中找不到解决方案,我可能不得不切换到另一种技术。

Therefore, I'm asking in case I'm missing something completely from other postings since I'm new. Here are a couple of simple scenarios.

因此,我想问一下,我是新手,以防万一我从其他帖子中完全遗漏了一些东西。这里有几个简单的场景。

On a JSF page, there is a datatable (Primefaces Checkbox based selection). The datatable displays records available (up to thousands). The datatable needs to be loaded through a RESTful api on the fly. Below is the code for my datatable.

在 JSF 页面上,有一个数据表(Primefaces Checkbox based selection)。数据表显示可用记录(最多数千)。数据表需要通过 RESTful api 即时加载。下面是我的数据表的代码。

    <p:dataTable id="addSampleTable" var="sample" value="#{testBean.sampleDataModel}"
            selection="#{testBean.selectedSamples}" >

    <p:column selectionMode="multiple" style="width:2%" /> 
    <p:column headerText="Sample">
        <h:outputText value="#{sample.name}" />
    </p:column>
</p:dataTable>

What's the best way to load the data? Is there a performance concern if every time I have to call the API from the server side (as opposed to client side using jquery and plain html)?

加载数据的最佳方式是什么?如果每次我必须从服务器端调用 API(而不是客户端使用 jquery 和纯 html),是否存在性能问题?

Second scenario, on the same page, there is also a button that allows user to add new record through another RESTful api. In turn, the newly added record should be displayed in the datatable.

第二种情况,在同一页面上,还有一个按钮,允许用户通过另一个 RESTful api 添加新记录。反过来,新添加的记录应显示在数据表中。

After I call the RESTful API to insert a record, the api also returns the record that was created. How can I insert this new record into my datamodel #{testBean.sampleDataModel} so that I don't have to load the entire table again? I suppose I can replace this datatable with plain html and append the new record to the table using jQuery, but then I can't leverage the selection table from JSF.

在我调用 RESTful API 插入记录后,该 API 还会返回创建的记录。如何将这条新记录插入到我的数据模型中 #{testBean.sampleDataModel} 以便我不必再次加载整个表?我想我可以用普通的 html 替换这个数据表,并使用 jQuery 将新记录附加到表中,但是我无法利用 JSF 中的选择表。

What are my options?

我有哪些选择?

采纳答案by perissf

Your question seems to be too broad, however I try to give some answers.

你的问题似乎太宽泛了,但我试着给出一些答案。

How to pass results from RESTful service to JSF components?

如何将结果从 RESTful 服务传递给 JSF 组件?

You can use the pattern implemented by NetBeans' guys. If you use this IDE, there is an option to automatically Build RESTful web services from database. Essentially, this pattern create all DAO basic functionalities in an abstract generic class called AbstractFacade. Then, for each concrete Entity class present in your JPA representation, it creates a Stateless class extending AbstractFacade, and adds jax-rs annotations to it in order to let it expose the Entity class through RESTful web service.

您可以使用 NetBeans 人员实现的模式。如果您使用此 IDE,则可以选择从数据库自动构建 RESTful Web 服务。本质上,这种模式在一个名为AbstractFacade. 然后,对于 JPA 表示中存在的每个具体实体类,它创建一个无状态类扩展AbstractFacade,并向其添加 jax-rs 注释,以便让它通过 RESTful Web 服务公开实体类。

You can then access the service directly by EJB injection. Just use @EJB annotation to inject your service in any container-managed class (in the same application, but also in other applications provided that you use portable JNDI naming rules). In particular, you'll be interested in injecting the facade classes in the managed beans backing your facelets components.

然后您可以通过 EJB 注入直接访问该服务。只需使用@EJB 批注将您的服务注入到任何容器管理的类中(在同一个应用程序中,但也可以在其他应用程序中使用,前提是您使用可移植的 JNDI 命名规则)。特别是,您会对在支持您的 facelets 组件的托管 bean 中注入外观类感兴趣。

What's the best way to load the data? Is there a performance concern if every time I have to call the API from the server side (as opposed to client side using jquery and plain html)?

加载数据的最佳方式是什么?如果每次我必须从服务器端调用 API(而不是客户端使用 jquery 和纯 html),是否存在性能问题?

Since you need to display thousands of records, your best bet is using Primefaces' lazy loadingin your datatable. Your application will then call the db only for retrieving the few tens of records displayed in the current page. Absolutely avoid displaying more than those records, otherwise the client browser will likely be negatively impacted.

由于您需要显示数千条记录,因此最好的办法是在数据表中使用 Primefaces 的延迟加载。然后,您的应用程序将仅调用数据库来检索当前页面中显示的几十条记录。绝对避免显示超过这些记录,否则客户端浏览器可能会受到负面影响。

How can I insert this new record into my datamodel #{testBean.sampleDataModel} so that I don't have to load the entire table again?

如何将这条新记录插入到我的数据模型中 #{testBean.sampleDataModel} 以便我不必再次加载整个表?

Please distinguish between loading from dband loading in jsf. You can program your backing bean in order to call the db (which is usually the most expensive operation) only when you think it's necessary. As far as I know, both JSF's and PrimeFaces' dataTable implementations don't give you the possibility to manage the table contents at a row level: at every ajax update, the entire table will be reloaded. However, as already said, this won't impact your application's performances as long as you have correctly programmed your backing bean (i.e. choosing the right bean scopeand avoid calling the db service in getters).

请区分从 db加载jsf 加载。您可以对您的支持 bean 进行编程,以便仅在您认为必要时调用 db(这通常是最昂贵的操作)。据我所知,JSF 和 PrimeFaces 的 dataTable 实现都不能让您在行级别管理表内容:在每次 ajax 更新时,整个表都将被重新加载。但是,正如已经说过的,只要您正确编程了支持 bean(即选择正确的 bean 范围避免在 getters 中调用数据库服务),这不会影响应用程序的性能。

Useful Links:

有用的链接:

回答by gabor_the_kid

What's the best way to load the data? Is there a performance concern if every time I have to call the API from the server side (as opposed to client side using jquery and plain html)?

加载数据的最佳方式是什么?如果每次我必须从服务器端调用 API(而不是客户端使用 jquery 和纯 html),是否存在性能问题?

Yes, there is a performance concern. The best way is to load your collection once into page context and operate on the list in this context. Then once you have done all your changes you synchronize with the stateless REST service.

是的,存在性能问题。最好的方法是将您的集合加载到页面上下文中并在此上下文中对列表进行操作。完成所有更改后,您将与无状态 REST 服务同步。

How can I insert this new record into my datamodel #{testBean.sampleDataModel} so that I don't have to load the entire table again?I suppose I can replace this datatable with plain html and append the new record to the table using jQuery, but then I can't leverage the selection table from JSF.

如何将这条新记录插入到我的数据模型中 #{testBean.sampleDataModel} 以便我不必再次加载整个表?我想我可以用纯 html 替换这个数据表并使用 jQuery 将新记录附加到表中,但是我无法利用 JSF 中的选择表。

No, you don't have to do that! There are several JSF datatable implementations which use AJAX partial submit, the datatable code already includes the logic you describe above. Your collection in page scope is extended with the new element without rerendering the whole list again.

不,你不必那样做!有几个 JSF 数据表实现使用 AJAX 部分提交,数据表代码已经包含您上面描述的逻辑。您在页面范围内的集合会使用新元素进行扩展,而无需再次重新呈现整个列表。

回答by kalamar

Although this question is a little bit old, it's still a current issue. I'm not happy with the anwsers above because the both technologies mentioned above are together a missmatch.

虽然这个问题有点老了,但它仍然是一个当前的问题。我对上面的回答不满意,因为上面提到的两种技术都是不匹配的。

The most important question here is: Does the given RESTful API actually act as a ...

这里最重要的问题是:给定的 RESTful API 是否真的充当...

  • service/buisness layer or ...
  • ... does it provide CRUD operations only? If it only provides typical CRUD operations, it acts as a persistance layer and there is a need for a service layer.
  • 服务/业务层或...
  • ...它是否只提供 CRUD 操作?如果它只提供典型的 CRUD 操作,那么它充当一个持久层,并且需要一个服务层。

In the second case, you can implement your service layer in a technology of your choice, JSF backed beans or even EJBs are a good choice. In the Java EE context the JAX-RS specification is a good choice, Jersey is an implementation of this specification. You can use this client API to access the RESTful API from Java: [1]

在第二种情况下,您可以使用您选择的技术实现服务层,JSF 支持的 bean 甚至 EJB 都是不错的选择。在 Java EE 上下文中,JAX-RS 规范是一个不错的选择,Jersey 是该规范的一个实现。您可以使用此客户端 API 从 Java 访问 RESTful API:[1]

But...

但...

When you design a complete new application, ensure your RESTful api provides not just CRUD operations but also provide higher leven service layer operations (accessed by https POST method) and deal with security concerns.

当您设计一个完整的新应用程序时,请确保您的 RESTful api 不仅提供 CRUD 操作,还提供更高级别的服务层操作(通过 https POST 方法访问)并处理安全问题。

In this case heterogeneous systems like webapplications, mobile webapps, native mobile apps and so on can access the service layer directly and the particular view (the REST service consumer) is loosly coupled with the service layer (wich is a good thing in software engineering in general).

在这种情况下,像 web 应用程序、移动 web 应用程序、原生移动应用程序等异构系统可以直接访问服务层,并且特定视图(REST 服务消费者)与服务层松散耦合(这在软件工程中是一件好事)一般的)。

My opinion: forget old fashioned server side web frameworks like JSF, Struts and so on, provide a RESTful API with service layer operations and use JavaScript frameworks like AngularJS in order to access the RESTful operations directly... mobile apps are the next step. The complete Java EE technology stack is a little bit rusty ;-)

我的观点:忘记JSF、Struts等老式的服务器端Web框架,提供带有服务层操作的RESTful API并使用AngularJS等JavaScript框架直接访问RESTful操作......移动应用程序是下一步。完整的 Java EE 技术栈有点生疏了 ;-)

[1] https://jersey.java.net/documentation/latest/user-guide.html#client

[1] https://jersey.java.net/documentation/latest/user-guide.html#client