JSF - A few beginner questions (from a PHP developer)

I am learning Java Server Faces for a school project and because I am a PHP developer, I cannot understand the general concept of JSF.

In the usual PHP MVC structure, the requested URL is connected using a routing system using the called methods of the class (controller life cycle) and the rendered template, so I can call some logic before any output is sent to the browser, for example. d. redirect.

Correct me if I am wrong - I could not recognize this template in JSF. The URL is bound to the rendered template (faces / index.xhtml → index.xhtml in my source code), and if I want to call some method in bean support (the JSF equivalent for the controller), I can call any getter in template (# {bean. property}), but, for example, I don’t know how to redirect when requesting a URL. I was able to execute some kind of custom method in my bean support after clicking on <h:commandLink> or <h:commandButton> , but looking at the generated HTML (which always looked like a submit form), I don't think this is the only way do it.

I also looked at faces-config.xml, which looks like a good way to configure multi-stage form wizards, but I don’t know how to use this mechanism to determine the structure of the entire network. What is it primarily used for? Defining URLs?

In addition, I would like to learn something about the dependency injection system. I don't know what introduces my facades to the supported attributes of the bean class when I comment on them using @EJB. I don’t know which mechanism injects EntityManager into my facades if I annotate the "em" attribute with a PersistenceContext. And how can I change these mechanisms in unit tests that work without this DI container (Glassfish?).

Please, can someone clarify for me how these things work in some kind of PHP-friendly way? Thanks!:)

+4
source share
3 answers

From the age of two, I had planned to write a blog post on the topic “JSF for PHP programmers” and never got around to doing this ... but some thoughts gathered during this time: (I understand, you know most of this):

  • Switching between PHP and JSF is painful - in both directions. Get ready for bitterness and frustration - I'm serious. The problem is that you do not need to ask "how to make X using JSF", but "does it make sense to do X in JSF or should I do Y".

  • The template used in most PHP frameworks (Cake, CI, ZF) is not simple MVC - it is Front Controller (and friends): you work with requests, route them, send them to actions, actions read request parameters, talk to the model, transfer data to the view, view the received answers and use some helpers to render the fragments that are used repeatedly, the answer ends, ends. A form in a typical PHP MVC application may result in a different action than the one it provided. The controller calls the view and has the ability to act until the view is displayed. Routing is important because actions are tied to URLs.

    There is no such thing in JSF. Routing and redirection (at least what happens before the view is processed) are not part of the JSF, they are one level of abstraction below the JSF. You can add routing and forwarding using some other libraries or your own code, it's quite simple. The mechanism in faces-config.xml is not actually routed, and yes, you're right, it depends on the magic script. You do not use it to structure your web application (if only because it applies only to POST requests).

    Actions in the JSF are not selected by the centralized router / dispatcher, but by components. In most cases, you don’t even need an action because the view and model are sufficient. You can imagine that JSF treats each page component as its own MVC stack. The component itself (for example, text input, a drop-down list) is responsible for returning data from the request, converting and validating data, displaying HTML and transmitting data to controllers (and other components) by placing them in the right place in the model.

    Because of this, things that require an action controller, such as the Zend Framework, such as pagination, search, editing multi-page forms with custom presentation logic, etc., usually do not require more than a view and model in JSF (possibly validators or converters). Components trigger actions only when data is stored in the database or when data processing is complicated. Even then, the action is launched after the view has read all the data from the request, so sending the action is in no way connected with routing. Each commandlink or commandbutton must return to the exact page displaying the original form, because only the components on this page can understand the request and update the model. Since routing has nothing to do with shelling actions, it is left out of the box (you can do pretty URLs and pretty routing using libraries like PrettyFaces , but it's not part of JSF).

    JSF redirects are performed as the result of actions (based on the string returned by the actions), therefore, although redirection and some logic can be performed before it, the template must be processed before redirection.

    In PHP, it is customary to think of reading data from a database as an "action that needs to be done before the view is displayed." In JSF, this is not an action, but part of the initialization of your model; as such, it belongs to a method inside your bean-driven model — such a method must be annotated using @PostConstruct and it will be executed by the DI JSF container before you get the bean reference, and after all the dependencies have been entered.

    If you really think you need to run an action before the page displays, use event listeners - but be careful: you might be doing something wrong.

    The hidden assumption underlying the Cake / Zend structure is that "there is one main thing on every HTML page, and the display relates mainly to this one thing." JSF's hidden assumption is that "as far as we can tell, the whole application is just one page with control states"

  • By definition, injection is performed by the container - since your managed beans are not produced by you, but are passed to the JSF components by some EL resolver. JSF contains a simple standalone container, and in Java EE 5 you also get an EJB container. Java EE 6 begins DI consolidation by introducing CDI (Contexts and Dependency Injection, JSR 299) and redefining EJB as a special type of CDI bean. Also in Java EE 6, you can skip the JSF DI container and use CDI beans. CDI implementation used by Glassfish, Weld .

    Despite the fact that you can use the built-in Glassfish to run the test, the whole idea of ​​the Injection of Dependency unit test is the ability to test classes outside the container (this is why they are UNIT tests, not INTEGRATION tests). Dependencies should be mocked and inserted manually.

  • If you have not invested too much time in JSF, you can first switch to JSR-311. This is a new alternative presentation layer for Java EE that focuses on a calm approach: quiet URLs, routing, resources, etc. It has pluggable templates, and its RI has a beautiful MVC level. If you like Zend Framework, you will like it. You can use JSR-311 to practice EJB, JPA, and other Java EE materials, and then return to JSF when you are already familiar with Injection Dependency, transaction management, etc., and can focus on stateful web presentations. An example code in Jersey (jsr-311 RI, you linked it to your glass fish / netbeans) might look like this:

     @EJB UsersDao usersDao; @Path("/users/detail/{userId}") public void userDetail(@PathParam("userId") int userId){ return new Viewable("users/template.jsp", usersDao.getById(userId)); } 

    Warning: jsr-311 is service-oriented (json, xml), not a web application, and the template engine is connected, so there are no helpers of the jsr-311 type (when recovering URLs, you use it to a large extent yourself)

+20
source

If you need some kind of friendly behavior, I suggest you start with PrettyFaces .

It is built on top of JSF 2, allows you to use URLs, friendly URLs and saves a lot of time. Just include the bank in your web application, and you're done.

A great extension, it is not a replacement for JSF, it just simplifies the internal structure of JSF and adds humanity to your JSF projects.

+1
source

First of all, Here is a good introduction to JSF.

Secondly, the way your jsf pages go from page to page is the navigation mechanism that you configure in your faces-config.xml file, for example:

 <faces-config> <navigation-rule> <from-view-id>/pages/inputname.jsp</from-view-id> <navigation-case> <from-outcome>greeting</from-outcome> <to-view-id>/pages/greeting.jsp</to-view-id> </navigation-case> </navigation-rule> </faces-config> 

As for DI, the JSF specification defines a very simple rather than a simple primitive DI mechanism, you can also define this in the faces-config.xml file, for example:

  <managed-bean> <managed-bean-name>iteration</managed-bean-name> <managed-bean-class>net.dbyrne.agile.Iteration</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> <managed-property> <!-- setStart called first --> <property-name>start</property-name> <value>#{projectBean.currentStart}</value> </managed-property> <managed-property> <property-name>end</property-name> <value>#{projectBean.currentEnd}</value> </managed-property> <managed-property><!-- setLast called last --> <property-name>last</property-name> <value>hack</value> </managed-property> </managed-bean> 

Yours faithfully,

0
source

Source: https://habr.com/ru/post/1334550/


All Articles