Full Web Application Tomcat JSF Primefaces JPA Hibernate – Part 3
Primefaces AutoComplete, JSF Converter
This post continues from part 1 and part 2.
The JSF has the Converter tool that helps us get some data from the user view and transform into an object loaded from the database or a cache.
In the “com.converter” package create the following class:
package com.converter; import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.convert.*; import com.facade.DogFacade; import com.model.Dog; @FacesConverter(forClass = com.model.Dog.class) public class DogConverter implements Converter { @Override public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) { DogFacade dogFacade = new DogFacade(); int dogId; try { dogId = Integer.parseInt(arg2); } catch (NumberFormatException exception) { throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, 'Type the name of a Dog and select it (or use the dropdow)', 'Type the name of a Dog and select it (or use the dropdow)')); } return dogFacade.findDog(dogId); } @Override public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) { if (arg2 == null) { return ''; } Dog dog = (Dog) arg2; return String.valueOf(dog.getId()); } }
About the above code:
- In the @Converter annotation there is an attribute named “forClass”. This attribute indicates to the de JSF that all classes of the specified in the “forClass” will invoke the Converter. The DogConverter is annotated with “forClass = com.model.Dog.class”, every time the JSF needs a Converter for a Dog class the JSF will invoke the DogConverter. It was not necessary to write any code in the “web.xml” file.
The Converter code is required in the Primefaces AutoComplete. Bellow you see how easy is to use the AutoComplete:
personUpdateDialog.xhtml
PersonMB.java
About the above code:
- The AutoComplete function has several options like minimum query length, delay to start a query, dropdown to display all values and more. It is worth to see all the options: http://primefaces.org/showcase/ui/autoCompleteBasic.jsf and http://primefaces.org/showcase/ui/autocompleteHome.jsf
- The “complete” method has a cache of the values found in the database. The method goes to each object of the List<Dog> and keeps the matches.
- Notice that the Converter will always be called because the “itemValue=”#{dog}”” that you will find in the AutoComplete component.
You can see bellow the AutoComplete working:
CSS/javascript/images with JSF
Take a look at the pictures bellow, it will display how that the application of this post handles resources:
“master.xhtml”
“index.xhtml”
With JSF it is very easy to handle this kind of resources. The developer does not need to use the file relative path anymore. To use your resources like that create your files like bellow:
The JSF will map all resources found in the folder “/WebContent/resources” and the developer will be able to use the resources like displayed above.
“web.xml” configurations
In the folder “WebContent/WEB-INF/” create the files bellow:
“web.xml”
<?xml version='1.0'?> <web-app version='3.0' xmlns='http://java.sun.com/xml/ns/javaee' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd'> <display-name>JSFCrudApp</display-name> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.xhtml</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>/pages/protected/index.xhtml</welcome-file> </welcome-file-list> <context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param> <filter> <filter-name>LoginCheckFilter</filter-name> <filter-class>com.filter.LoginCheckFilter</filter-class> <init-param> <param-name>loginActionURI</param-name> <param-value>/JSFCrudApp/pages/public/login.xhtml</param-value> </init-param> </filter> <filter-mapping> <filter-name>LoginCheckFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>AdminPagesFilter</filter-name> <filter-class>com.filter.AdminPagesFilter</filter-class> </filter> <filter-mapping> <filter-name>AdminPagesFilter</filter-name> <url-pattern>/pages/protected/admin/*</url-pattern> </filter-mapping> <filter> <filter-name>DefaultUserPagesFilter</filter-name> <filter-class>com.filter.DefaultUserPagesFilter</filter-class> </filter> <filter-mapping> <filter-name>DefaultUserPagesFilter</filter-name> <url-pattern>/pages/protected/defaultUser/*</url-pattern> </filter-mapping> </web-app>
“faces-config.xml”
<?xml version='1.0' encoding='UTF-8'?> <faces-config xmlns='http://java.sun.com/xml/ns/javaee' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd' version='2.0'> <application> <resource-bundle> <base-name>messages</base-name> <var>bundle</var> </resource-bundle> <message-bundle>messages</message-bundle> </application> </faces-config>
About the above code:
- All security filters you will find mapped in the web.xml file. You could also use the @Filter annotations that would work the same.
- The property “javax.faces.PROJECT_STAGE” has the value DEVELOPMENT. One of the advantages of this configurations is that the JSF will append a “h:message” if none is found in the screen. If some exception happens and there is no component to display it the JSF will append a h:message component in the page.
- Inside the “faces-config” exist a tag named “message-bundle”. This tag allows the developer to override the JSF default messages, the value of this tag will point to a file with the default JSF messages key. In the “message.properties” file (page 08) has the key “javax.faces.component.UIInput.REQUIRED”, any value you write in this key will affect all the “required field” messages displayed in the application.
Increasing the security of your application
Do not concatenate the queries
Do not use the usual “where id =” + id sql code. This kind of code allows the “SQL Injection” hacker attack. A developer that works with ORM is also vulnerable to this kind of attack but with different name: “HQL Injection”. The best way of doing a query you may find in the Person and User class:
It does not matter if you use JPA or not, never concatenate your query with strings.
The developer must be aware that “SQL Injection may happen in any query of your application”, and not only in the login query. If a user has a valid login to your application, this user is able to do “SQL Injection” in all your queries.
AutoComplete Off
In the page “login.xhtml” there is the following code:
The tag “autocomplete” off tells to the browser that this field should not be saved. The great browsers (Firefox, Chrome, IE) respect this tag and it helps to protect your application.
If you allow the browser to keep the password the browser must keep this password stored somewhere. If a hacker finds out where this key is stored he may try to crack it.
Validate all incoming requests
If the application was required just to validate if the user is or is not logged the user class would not need the role Enum.
If there was no role validation a regular user could access any area of the system, like the admin pages. Notice that this application has filters that always validate the user role for all requests. “Hiding a link is not a protection measure. The developer should always validate all incoming requests”. A developer may hide a URL or a button, but a user could access any screen of your application if he types the URL in the browser or simulating get/post calls.
Always use the h:outputText component
An easy way to avoid the Cross-Site Scripting is using the h:outputText component to display data from the database. Notice that in this post that all the values displayed to de user that comes from the database are using the h:outputText component. A situation that the h:outputText component can be avoided is when the application will display system messages from a file like “message.properties”.
Running the application
Start the Tomcat and check the database; notice that there is no table inside the database yet.
Type the following URL in the browser: http://localhost/JSFCrudApp/ .
The following screen will be displayed:
Type any value that you want and press the login button, do not bother if there is no user or tables. Just click on it. You will see an error message like this:
Check your database again and you will see that all tables were created. The applications is controlling all transaction manually that is the reason for the JPA/Hibernate just create the table when is first invoked.
You need to create a user with the role ADMIN (I named this user Real Madrid) and another user with the USER role (I named it Barcelona). The ADMIN user will have access to all system under all folders but the user with the USER role will have access to the pages under the folder defaultUser.
If you log in with the ADMIN user you will see:
Log in now with the user that has the USER role:
The Dogs button were hidden. Even without the button a user could access the URL of the Dogs and the Dogs screen should be allowed only to ADMIN roles.
To see how the application would behave with and illegal access, keep logged in with the USER role and try to access the following link: http://localhost/JSFCrudApp/pages/protected/admin/adminIndex.xhtml
The next screen will be displayed:
This screen will be displayed because the AdminPagesFilter check if the request comes from a ADMIN user. I the user is not in the ADMIN role our Ninja Cat will get it! [=
Reference: Full Web Application with Tomcat JSF Primefaces JPA Hibernate from our JCG partner Hebert Coelho at the uaiHebert blog.
could you share the source code of project
hello, please, share the source code. tx..
I am beginner in java .could you able to send source code of this application at address ashu17188@gmail.com
Good evening, very interesting tutorial, but I am not able to find where to download the souce code.
I’m studying these technologies and would be very helpful.
Thanks in advance
Where can i find and download the source code of project ?
Tanks in advance Vince
https://github.com/tuxied/JSFCrudApp
Hi,
This is very nice tutorial to start learning JSF..but as you mentioned in part1 i did not get the source code/all required resources with .jars file required.
Can you please provide the complete source code for this Nice Application.
Thanks in Advance Vinod
One of the best article/tutorial about primefaces,jsf,hibernate. Thank you very much.
Only one thing is missed, a 4th page for telling web pages.
Thanks anyway, i like it so much.
Could you please share the source code