Last active
April 26, 2017 14:48
-
-
Save AndrienkoAleksandr/699d7432aed16799410bd809d9ac6b02 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<!-- | |
JBoss, Home of Professional Open Source | |
Copyright 2015, Red Hat, Inc. and/or its affiliates, and individual | |
contributors by the @authors tag. See the copyright.txt in the | |
distribution for a full listing of individual contributors. | |
Licensed under the Apache License, Version 2.0 (the "License"); | |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, software | |
distributed under the License is distributed on an "AS IS" BASIS, | |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
See the License for the specific language governing permissions and | |
limitations under the License. | |
--> | |
<cheatsheet title="This quickstart shows off all the new features of Java EE, and makes a great starting point for your project."> | |
<intro> | |
<description> | |
The kitchensink application shows off a number of Java EE technologies such as CDI, JSF, EJB, JTA and JAX-RS. It does this by providing a member registration database, available via JSF and JAX-RS. | |
</description> | |
</intro> | |
<item title="Deployment Descriptors"> | |
<description>Let's start by looking at the necessary deployment descriptors. By now, we're very used to seeing <b>beans.xml</b> and <b>faces-config.xml</b> in <b>WEB-INF/</b> (which can be found in the <b>src/main/webapp</b> directory of the example). Notice that, once again, we don't need a web.xml. There are two configuration files in the <b>src/main/resources</b> directory of the example — <b>META-INF/persistence.xml</b>, which sets up JPA, and <b>import.sql</b> which Hibernate, the JPA provider in JBoss EAP, will use to load the initial users into the application when the application starts.</description> | |
</item> | |
<item title="JSF Templates"> | |
<description> | |
Next, let's take a look at the JSF view the user sees. As usual, we use a template to provide the sidebar and footer. This one lives in <b>WEB-INF/templates/default.xhtml</b>: | |
<br/><br/> | |
The <head> element starting on line 22 is where we define styles and more. | |
<br/><br/> | |
This application defines a common sidebar, putting them in the template means we only have to define them once. You can see the sidebar <div> from lines 37 to 43. | |
<br/><br/> | |
Finally we have a common footer defined in the <div> from lines 44 to 49. | |
<br/><br/> | |
That leaves the main page, <b>index.xhtml</b>, in which we place the content unique to the main page. The JSF form allows us to register new users. There should be one already created when the application started by lines 31 to 60. | |
<br/><br/> | |
The application uses Bean Validation to validate data entry. The error messages from Bean Validation are automatically attached to the relevant field by JSF, and adding a messages JSF component will display them. | |
<br/><br/> | |
Name validation: 36 to 38. | |
<br/> | |
Email validation: 40 to 42. | |
<br/> | |
Phone number validation: 44 to 47. | |
<br/><br/> | |
This application exposes REST endpoints for each registered member. The application helpfully displays the URL to the REST endpoint on this page (lines 90 to 91). | |
</description> | |
</item> | |
<item title="Member Entity"> | |
<description> | |
Next, let's take a look at the Member entity, before we look at how the application is wired together in <b>/src/main/java/org/jboss/as/quickstarts/kitchensink/model/Member.java</b> | |
<br/><br/> | |
As usual with JPA, we define that the class is an entity by adding @Entity (line 37). | |
<br/><br/> | |
Members are exposed as a RESTful service using JAX-RS. We can use JAXB to map the object to XML and to do this we need to add @XmlRootElement (line 38). | |
<br/><br/> | |
Bean Validation allows constraints to be defined once (on the entity) and applied everywhere. On lines 46 to 48 we constrain the person's name to a certain size and regular expression. @Digits, @NotNull and @Size are further examples of constraints. | |
<br/><br/> | |
The Hibernate Validator also offers some extra validations, such as @Email on line 53. | |
</description> | |
</item> | |
<item title="Interacting with Persistence"> | |
<description> | |
Next, let’s take a look at <b>/src/main/java/org/jboss/as/quickstarts/kitchensink/data/MemberRepository.java</b>, which is responsible for interactions with the persistence layer. On line 29 you can see that the bean is application scoped, as it is a singleton. | |
<br/><br/> | |
First, the entity manager is injected on line 32 to allow interaction with JPA, then the JPA criteria API is used to load a member by his or her unique identifier, email address - see lines 40 to 47 The criteria API can also be used to load a list of entities as shown on lines 51 to 58. | |
</description> | |
</item> | |
<item title="Building Member Lists"> | |
<description> | |
Next, let's take a look at <b>/src/main/java/org/jboss/as/quickstarts/kitchensink/data/MemberListProducer.java</b>, which is responsible for building the list of members, ordered by name. It uses JPA 2 criteria to do this. | |
<br/><br/> | |
This bean is request scoped (line 30), meaning that any fields (such as members) will be stored for the entire request. The MemberRepository is responsible for interactions with the persistence layer on lines 33 - 34. | |
<br/><br/> | |
The list of members is exposed as a producer method on line 40 to 41. It's also available via EL. The observer method on lines 46 - 48 is notified whenever a member is created, removed, or updated. This allows us to refresh the list of members whenever they are needed. This is a good approach as it allows us to cache the list of members, but keep it up to date at the same time. | |
</description> | |
</item> | |
<item title="Creating New Members"> | |
<description> | |
Let's now look at <b>/src/main/java/org/jboss/as/quickstarts/kitchensink/service/MemberRegistration.java</b>, the class that allows us to create new members from the JSF page. This bean requires transactions as it needs to write to the database. Making this a stateless EJB (see line 28) gives us access to declarative transactions - much simpler than manual transaction control! | |
<br/><br/> | |
On line 31 we inject a JDK logger, defined in the Resources class. An event is sent every time a member is updated. This allows other pieces of code (in this quickstart the member list is refreshed) to react to changes in the member list without any coupling to this class - see line 43. | |
</description> | |
</item> | |
<item title="Utilities"> | |
<description> | |
Now, let's take a look at the <b>/src/main/java/org/jboss/as/quickstarts/kitchensink/util/Resources.java</b> class, which provides resources such as the entity manager. CDI recommends using "resource producers", as we do in this example, to alias resources to CDI beans, allowing for a consistent style throughout our application. | |
<br/><br/> | |
We use the 'resource producer' pattern, from CDI, to 'alias' the old fashioned @PersistenceContext injection of the entity manager to a CDI style injection. This allows us to use a consistent injection style (@Inject) throughout the application. | |
<br/><br/> | |
We expose a JDK logger for injection. In order to save a bit more boiler plate, we automatically set the logger category as the class name! See line 47. | |
<br/><br/> | |
We expose the FacesContext (line 52) via a producer method, which allows it to be injected. If we were adding tests, we could also then mock it out. | |
<br/><br/> | |
If you want to define your own datasource, take a look at the <a href="https://access.redhat.com/documentation/en/jboss-enterprise-application-platform/" target="_blank">Configuration Guide for Red Hat JBoss Enterprise Application Platform</a>. | |
</description> | |
</item> | |
<item title="Member Controller"> | |
<description> | |
Of course, we need to allow JSF to interact with the services. The <b>/src/main/java/org/jboss/as/quickstarts/kitchensink/controller/MemberController.java</b> class is responsible for this. | |
<br/><br/> | |
The MemberController class uses the @Model stereotype, which adds @Named and @RequestScoped to the class on line 34. The FacesContext is injected on line 37 so that messages can be sent to the user, then the MemberRegistration bean is injected on line 40 to allow the controller to interact with the database. | |
<br/><br/> | |
The Member class is exposed using a named producer field on lines 43 to 45, which allows access from JSF. Note that the named producer field has dependent scope, so every time it is injected, the field will be read. | |
<br/><br/> | |
The @PostConstruct annotation on line 47 causes a new member object to be placed in the newMember field when the bean is instantiated. | |
<br/><br/> | |
When the register method is called on line 54, the newMember object is passed to the persistence service. We also send a message to the user on line 56, to give them feedback on their actions. | |
<br/><br/> | |
Finally, we replace the newMember with a new object on line 57, thus blanking out the data the user has added so far. This works as the producer field is dependent scoped. | |
</description> | |
</item> | |
<item title="JAX-RS"> | |
<description> | |
Before we wrap up our tour of the kitchensink example application, let's take a look at how the JAX-RS endpoints are created. We start with the <b>/src/main/java/org/jboss/as/quickstarts/kitchensink/rest/JaxRSActivator.java</b> class, which extends <b>Application</b> and is annotated with <b>@ApplicationPath</b>, is the Java EE <b>no XML</b> approach to activating JAX-RS. | |
<br/><br/> | |
The real work goes in <b>/src/main/java/org/jboss/as/quickstarts/kitchensink/rest/MemberResourceRESTService.java</b>, which produces the endpoint. The @Path annotation on line 52 tells JAX-RS that this class provides a REST endpoint mapped to rest/members (concatenating the path from the activator with the path for this endpoint). The bean is request scoped on line 53, as JAX-RS interactions typically don't hold state between requests. | |
<br/><br/> | |
JAX-RS endpoints are CDI enabled, and can use CDI-style injection. CDI allows us to inject a Bean Validation Validator instance (line 59), which is used to validate the POSTed member before it is persisted. | |
<br/><br/> | |
MemberRepository is injected on line 62 to allow us to query the member database, then MemberRegistration is injected on line 65 to allow us to alter the member database. | |
<br/><br/> | |
The listAllMembers() method (lines 68 - 72) is called when the raw endpoint is accessed and offers up a list of endpoints. Notice that the object is automatically marshalled to JSON by RESTEasy (the JAX-RS implementation included in Red Hat JBoss Enterprise Application Platform). | |
<br/><br/> | |
The lookupMemberById() method (lines 74 - 83) is called when the endpoint is accessed with a member ID parameter appended (for example rest/members/1). Again, the object is automatically marshalled to JSON by RESTEasy. | |
<br/><br/> | |
createMember() on lines 89 - 120 is called when a POST is performed on the URL. Once again, the object is automatically unmarshalled from JSON. In order to ensure that the member is valid, we call the validateMember method (lines 136 - 148), which validates the object, and adds any constraint violations to the response. These can then be handled on the client side, and displayed to the user. The object is then passed to the MemberRegistration service to be persisted on line 100. We then handle any remaining issues with validating the object (lines 104 - 117), which are raised when the object is persisted. | |
</description> | |
</item> | |
<item title="Run and Deploy the Application"> | |
<description> | |
You can run and deploy the application in a single step by clicking the “play” button in the command toolbar and choosing the “build-start-deploy” command. This will build the app using maven, start JBoss EAP and deploy the built artifact to the correct location in JBoss to run. A preview URL is automatically generated and shown in the command window (along with the log outputs) at the bottom of the IDE. Clicking the preview URL will open a new browser tab showing you the running app that you’ve edited and built. | |
</description> | |
</item> | |
</cheatsheet> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment