Create a CRUD Application with Java and JavaServer Faces

JavaServer Faces (JSF) is a Java framework for building Web applications, centered on components as the building blocks for the user interface. JSF benefits from a rich ecosystem of tools and vendors, as well as out of the box components and libraries that add even more power.

Why use JSF instead of JavaServer Pages (JSP)? There are two primary reasons: First, JSF has more templating capabilities, since it doesn’t write your view directly as it encounters the tag. Instead, you build a view as XML that can be preprocessed before output to HTML. This means you can reuse and better organize your code as your app grows. Second, JSF provides an entire MVC architecture for you, while JSP is just a scripting language that abstracts writing a Servlet by hand.

With that background, let’s create a simple application that shows the power of JSF. In this tutorial, we will build a simple web app to manage a list of your favorite books backed by a database and secure access to your app with Okta.

Create a CRUD Application With JSF

To begin, we will use the TomEE Maven archetype to generate the project:

$ mvn archetype:generate \
    -DarchetypeGroupId=org.apache.openejb.maven \
    -DarchetypeArtifactId=tomee-webapp-archetype \
    -DarchetypeVersion=1.7.1

Follow the interactive generation process, using these parameters to generate the app:

Define value for property 'groupId': com.okta.developer
Define value for property 'artifactId': jsf-crud
Define value for property 'version' 1.0-SNAPSHOT: : 1.0-SNAPSHOT
Define value for property 'package' com.okta.developer: : com.okta.developer
Confirm properties configuration:
groupId: com.okta.developer
artifactId: jsf-crud
version: 1.0-SNAPSHOT
package: com.okta.developer
Y: : Y

Then cd into the project, build and run to see it in action:

$ cd jsf-crud # or the artifactId you used to generate the project
$ mvn package
$ mvn tomee:run

Create A Book In Your JSF Application

Now point your preferred browser to http://localhost:8080/. You should see a form to create a book.

To add a book, just type the title and hit Add. You will land on a success page, and will be able to see a list of the books in the database. This form page is generated by src/main/webapp/book.xhtml, and the results page is generated by src/main/webapp/result.xhtml.

The book.xhtml is a simple form that connects its fields to the com.okta.developer.presentation.BookBean class. For example:

<h:inputText value='#{bookBean.bookTitle}'/>

For actions, like submitting the form, we bind directly to methods in the “bean” class. That specific form will trigger the add() method in the class:

<h:commandButton action="#{bookBean.add}" value="Add"/>

The BookBean.add() method creates a new Book instance and sets its title to what we have stored in bookTitle field (remember it was bound to the form’s input field):

public String add() {
    Book book = new Book();
    book.setBookTitle(bookTitle);
    bookService.addBook(book);
    return "success";
}

Then, it asks bookService to persist the book to the database as we can see in the com.okta.developer.application.BookService class:

public void addBook(Book book) {
  entityManager.persist(book);
}

But what about that "success" string being returned? It’s defined in the file src/main/webapp/WEB-INF/faces-config.xml:

<navigation-rule>
  <from-view-id>/book.xhtml</from-view-id>
  <navigation-case>
    <from-outcome>success</from-outcome>
    <to-view-id>/result.xhtml</to-view-id>
  </navigation-case>
</navigation-rule>

This means when a success happens on /book.xhtml file, JSF will send the user to the view /result.xhtml. In the result.xhtml file, we also see a button that binds to a method in the bean:

<h:commandButton action="#{bookBean.fetchBooks}" value="View books present"/>

This executes the method fetchBooks() in the class. In the src/main/java/com/okta/developer/presentation/BookBean.java file, we see fetchBooks() delegates to a method in bookService, which stores the results into the booksAvailable field, and then returns the string “success”.

public String fetchBooks() {
    booksAvailable=bookService.getAllBooks();
    return "success";
}

Read the books in your JSF Application

In the getAllBooks() method, the com.okta.developer.application.BookService class queries the database fetching all Book instances with no filters:

public List<Book> getAllBooks() {
    CriteriaQuery<Book> cq = entityManager.getCriteriaBuilder().createQuery(Book.class);
    cq.select(cq.from(Book.class));
    return entityManager.createQuery(cq).getResultList();
}

Cool. But how does the page actually display the book information? In the result.xhtml file, find the ui:repeat tag:

<ui:repeat value="#{bookBean.booksAvailable}" var="book">
    #{book.bookTitle} <br/>
</ui:repeat>

The <ui:repeat> tag iterates over each value, in this case #{bookBean.booksAvailable} is the field we just assigned from the fetchBooks() method. Each element of the collection can be referenced by the name in the var attribute of the tag (in this case book).

Whatever is inside the <ui:repeat> tag will be repeated for each of the elements in the collection. Here, it simply outputs the book title by using the interpolation notation #{book.bookTitle} followed by a line break tag (<br/>).

We just covered both the Create and Read methods of our CRUD application. Awesome! Now let’s try to Update a book.

Update A Record

Create an edit.xhtml file in src/main/webapp folder to contain the form to update a Book in the database. It looks very similar to the Create form:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html">

<h:body bgcolor="white">
    <f:view>
        <h1>Update book</h1>
        <h:form>
            <h:panelGrid columns="2">
                <h:outputText value='Enter book title'/>
                <h:inputText value='#{bookBean.bookTitle}'/>
                <h:outputText value='Update'/>
                <h:commandButton action="#{bookBean.update}" value="Update"/>
            </h:panelGrid>
            <input type="hidden" name="bookId" value='#{param.bookId}'/>
        </h:form>
    </f:view>
</h:body>
</html>

Now add a link to this page from the book list in file src/main/webapp/result.xhtml by changing the content of <ui:repeat> tag:

<ui:repeat value="#{bookBean.booksAvailable}" var="book">
    <h:link value="#{book.bookTitle}" outcome="edit">
        <f:param name="bookId" value="#{book.bookId}"/>
    </h:link>
    <br/>
</ui:repeat>

Now each book in the list is a link to that book’s edit page.

However, if you try to click on that link, you’ll see that the form shows empty on page load. Let’s fix that and load the book’s title before the form renders. To fetch the bookId from the URL in our bean, include the following dependency in the pom.xml file:

<dependencies>
  ...
  <dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-web-api</artifactId>
    <version>6.0</version>
    <scope>provided</scope>
  </dependency>
  ...
</dependencies>

Edit the src/main/java/com/okta/developer/application/BookService.java file and add the following method to BookService class to load the book from the database:

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Root;

...

public Book getBook(Integer bookId) {
    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<Book> cq = cb.createQuery(Book.class);
    Root<Book> book = cq.from(Book.class);
    cq.select(book);
    cq.where(cb.equal(book.get("bookId"), bookId));
    return entityManager.createQuery(cq).getSingleResult();
}

And add the following logic to BookBean to load the book before page render:

import javax.annotation.PostConstruct;
import javax.faces.context.FacesContext;

...

private Integer bookId;
private Book book;

@PostConstruct
public void postConstruct() {
    String bookIdParam = FacesContext.getCurrentInstance()
        .getExternalContext().getRequestParameterMap().get("bookId");
    if (bookIdParam != null) {
        bookId = Integer.parseInt(bookIdParam);
        book = bookService.getBook(bookId);
        bookTitle = book.getBookTitle();
    }
}

Now let’s create a method that will persist the changes to the database, with the following method in the BookService class:

public void update(Book book) {
    entityManager.merge(book);
}

Also, add the update method to BookBean class:

public String update() {
    book.setBookTitle(bookTitle);
    bookService.update(book);
    return "success";
}

And to properly redirect the user to the list page, add the following navigation rule to the file src/main/webapp/faces-config.xml:

<navigation-rule>
  <from-view-id>/edit.xhtml</from-view-id>
  <navigation-case>
    <from-outcome>success</from-outcome>
    <to-view-id>/result.xhtml</to-view-id>
  </navigation-case>
</navigation-rule>

Now that we are done updating the book, let’s move on to the Delete part.

Delete A Record

The previous section covers the hard part - loading a book inside the bean. Adding the delete button will be easier.

Add a delete link for each entry in the list to the edit page in file src/main/webapp/result.xhtml:

<ui:repeat value="#{bookBean.booksAvailable}" var="book">
    <h:link value="#{book.bookTitle}" outcome="edit">
        <f:param name="bookId" value="#{book.bookId}"/>
    </h:link>

    <!-- Delete link: -->
    <h:outputText value=" ("/>
    <h:link value="Delete" outcome="delete">
        <f:param name="bookId" value="#{book.bookId}"/>
    </h:link>
    <h:outputText value=")"/>
    <br/>
</ui:repeat>

Now,create the delete confirmation page at src/main/webapp/delete.xhtml:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html">

<h:body bgcolor="white">
    <f:view>
        <h1>Delete book?</h1>
        <h:form>
            <h:panelGrid columns="2">
                <h:outputText value='Book title'/>
                <h:inputText value='#{bookBean.bookTitle}' readonly="true"/>
                <h:outputText value='Delete'/>
                <h:commandButton action="#{bookBean.delete}" value="Confirm Delete"/>
            </h:panelGrid>
            <input type="hidden" name="bookId" value='#{param.bookId}'/>
        </h:form>
    </f:view>
</h:body>
</html>

And add the proper delete handler in the BookBean class:

public String delete() {
    bookService.delete(book);
    return "success";
}

Next, handle the delete in the BookService class:

import javax.persistence.Query;

...

public void delete(Book book) {
    Query query = entityManager.createQuery("DELETE FROM Book b WHERE b.bookId = :bookId");
    query.setParameter("bookId", book.getBookId());
    query.executeUpdate();
}

And don’t forget to redirect your user back to the list after deletion by adding the following to src/main/webapp/faces-config.xml:

<navigation-rule>
    <from-view-id>/delete.xhtml</from-view-id>
    <navigation-case>
        <from-outcome>success</from-outcome>
        <to-view-id>/result.xhtml</to-view-id>
    </navigation-case>
</navigation-rule>

Done! I told you delete would be easier.

So now we can Create, Update, Read and Delete our Books CRUD application.

Improve The User Interface

The CRUD app works fine, but the app doesn’t look nice. Let’s improve our app user interface a bit with PrimeFaces.

First, add it as a dependency in our pom.xml:

<dependencies>
    ...
    <dependency>
        <groupId>org.primefaces</groupId>
        <artifactId>primefaces</artifactId>
        <version>7.0</version>
    </dependency>
    ...
</dependencies>

Now we can use any PrimeFaces component in our views by declaring its namespace to our html tag, like so:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui">

For a deeper overview, read about each PrimeFaces component in their site.

First, let’s remove the book list from our BookBean class and create a BookList class instead. This will load the book list as soon as the page loads. Create the file src/main/java/com/okta/developer/presentation/BookList.java with the following content:

package com.okta.developer.presentation;

import com.okta.developer.application.BookService;
import com.okta.developer.entities.Book;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
import java.util.List;

@Named
public class BookList {

    @Inject
    private BookService bookService;
    private List<Book> booksAvailable;

    @PostConstruct
    public void postConstruct() {
        booksAvailable = bookService.getAllBooks();
    }

    public List<Book> getBooksAvailable() {
        return booksAvailable;
    }
}

Remove the following blocks of code related to the booksAvailable field from BookBean class:

private List<Book> booksAvailable;

public List<Book> getBooksAvailable() {
    return booksAvailable;
}

public void setBooksAvailable(List<Book> booksAvailable) {
    this.booksAvailable = booksAvailable;
}

public String fetchBooks() {
    booksAvailable=bookService.getAllBooks();
    return "success";
}

Let’s also change our landing page. Instead of adding a Book through the form, let’s present the book list. For that, edit index.jsp to change the redirect to result.jsf:

<%@ page session="false" %>
<%
    response.sendRedirect("result.jsf");
%>

Here is what my files now look like. Feel free to adapt yours as you browse the PrimeFaces component library.

File: src/main/webapp/book.xhtml using a p:panel and p:panelGrid:

<?xml version="1.0" encoding="UTF-8"?>
<!-- File: book.xhtml -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body>
    <h:form>
        <p:panel header="Create Book">
            <p:panelGrid columns="1" layout="grid">
                <p:outputLabel for="book-title" value="Enter book title"/>
                <p:inputText id="book-title" value='#{bookBean.bookTitle}'/>
                <p:commandButton value="Create" action="#{bookBean.add}" ajax="false"/>
            </p:panelGrid>
            <!-- We will use this later
            <input type="hidden" value="${_csrf.token}" name="${_csrf.parameterName}"/>
            -->
        </p:panel>
    </h:form>
</h:body>
</html>

File: src/main/webapp/delete.xhtml using a p:panel and p:panelGrid:

<?xml version="1.0" encoding="UTF-8"?>
<!-- File: delete.xhtml -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body>
    <h:form>
        <p:panel header="Delete Book?">
            <p:panelGrid columns="1" layout="grid">
                <p:outputLabel for="book-title" value="Book title"/>
                <p:inputText id="book-title" value='#{bookBean.bookTitle}' readonly="true"/>
                <p:commandButton value="Confirm Delete" action="#{bookBean.delete}" ajax="false"/>
            </p:panelGrid>
            <input type="hidden" name="bookId" value='#{param.bookId}'/>
            <!-- We will use this later
            <input type="hidden" value="${_csrf.token}" name="${_csrf.parameterName}"/>
            -->
        </p:panel>
    </h:form>
</h:body>
</html>

File: src/main/webapp/edit.xhtml using a p:panel and p:panelGrid:

<?xml version="1.0" encoding="UTF-8"?>
<!-- File: edit.xhtml -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body>
    <h:form>
        <p:panel header="Update Book">
            <p:panelGrid columns="1" layout="grid">
                <p:outputLabel for="book-title" value="Enter new book title"/>
                <p:inputText id="book-title" value='#{bookBean.bookTitle}'/>
                <p:commandButton value="Update" action="#{bookBean.update}" ajax="false"/>
            </p:panelGrid>
            <input type="hidden" name="bookId" value='#{param.bookId}'/>
            <!-- We will use this later
            <input type="hidden" value="${_csrf.token}" name="${_csrf.parameterName}"/>
            -->
        </p:panel>
    </h:form>
</h:body>
</html>

File: src/main/webapp/result.xhtml using a p:dataList instead of ui:repeat:

<?xml version="1.0" encoding="UTF-8"?>
<!-- File: result.xhtml -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body>
    <h:link outcome="book" value="Create Book"/>
    <p:dataList value="#{bookList.booksAvailable}" var="book" type="ordered">
        <f:facet name="header">
            Book List
        </f:facet>
        #{book.bookTitle}
        <h:outputText value=" ("/>
        <p:link value="Edit" outcome="edit">
            <f:param name="bookId" value="#{book.bookId}"/>
        </p:link>
        <h:outputText value=" | "/>
        <p:link value="Delete" outcome="delete">
            <f:param name="bookId" value="#{book.bookId}"/>
        </p:link>
        <h:outputText value=")"/>
    </p:dataList>
</h:body>
</html>

Run the Application with PrimeFaces Enabled

Restart the app with mvn package tomee:run. The app will look a bit better now! Check out the book list:

Book list with PrimeFaces

Secure Your Application With Okta

At the moment, anyone can access our awesome Book application and change the database. To prevent that, let’s add a security layer to our application with the Spring Security library and authenticate users through Okta.

First, register for a forever-free developer account today! When you’re finished, complete the steps below to create an OIDC app.

  1. Log in to your developer account at developer.okta.com
  2. Navigate to Applications and click on Add Application
  3. Select Web and click Next
  4. Give the application a name (.e.g., Java JSF Secure CRUD)
  5. Add the following as Login redirect URI:
    • http://localhost:8080/login/oauth2/code/okta
  6. Click Done

Now, create the file src/main/resources/application.properties with your Client ID and Client Secret, you can find these on the General tab of the app you just created.

okta.client-id={clientId}
okta.client-secret={clientSecret}
okta.issuer-uri=https://{yourOktaDomain}/oauth2/default

Let’s add Spring Security as a dependency in your pom.xml file:

<properties>
    ...
    <spring-security.version>5.1.6.RELEASE</spring-security.version>
    <spring.version>5.1.6.RELEASE</spring.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-framework-bom</artifactId>
            <version>${spring.version}</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-bom</artifactId>
            <version>${spring-security.version}</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    ...
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-oauth2-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-oauth2-resource-server</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-oauth2-jose</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.9.9</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.9.3</version>
    </dependency>
</dependencies>

For Spring Security to correctly control your app security, it needs to know which requests need authentication. For that, we will create the file src/main/java/com/okta/developer/SecurityConfiguration.java to tell Spring Security to secure all URLs and to use a CSRF token to secure forms:

package com.okta.developer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.client.InMemoryOAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.registration.ClientRegistrations;
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;

@Configuration
@EnableWebSecurity
@PropertySource("classpath:application.properties")
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    private final String clientSecret;
    private final String clientId;
    private final String issuerUri;

    @Autowired
    public SecurityConfiguration(@Value("${okta.issuer-uri}") String issuerUri,
                                 @Value("${okta.client-id}") String clientId,
                                 @Value("${okta.client-secret}") String clientSecret) {
        this.issuerUri = issuerUri;
        this.clientId = clientId;
        this.clientSecret = clientSecret;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .sessionManagement() // Always create a session
                .sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
                .and()
            .csrf() // Use CSRF token
                .csrfTokenRepository(new CookieCsrfTokenRepository())
                .and()
            .authorizeRequests() // Require all requests to be authenticated
                .anyRequest().authenticated()
                .and()
            .oauth2Login();
    }

    /* Following methods instruct Spring Security to use 
       Okta as user/authentication provider 
    */

    @Bean
    public OAuth2AuthorizedClientService authorizedClientService() {
        return new InMemoryOAuth2AuthorizedClientService(clientRegistrationRepository());
    }

    @Bean
    public ClientRegistrationRepository clientRegistrationRepository() {
        ClientRegistration okta = getRegistration();
        return new InMemoryClientRegistrationRepository(okta);
    }

    private ClientRegistration getRegistration() {
        return ClientRegistrations.fromOidcIssuerLocation(this.issuerUri)
                .registrationId("okta")
                .clientId(this.clientId)
                .clientSecret(this.clientSecret)
                .build();
    }
}

Next, create the file src/main/java/com/okta/developer/SecurityWebApplicationInitializer.java class to enable Spring Security in the app:

package com.okta.developer;

import org.springframework.security.web.context.*;

public class SecurityWebApplicationInitializer
   extends AbstractSecurityWebApplicationInitializer {

   public SecurityWebApplicationInitializer() {
       super(SecurityConfiguration.class);
   }
}

Since we have enabled CSRF protection, we need to add the token to each <h:form> tag. Just add that line within the forms (I left those commented out on my files that use PrimeFaces):

<input type="hidden" value="${_csrf.token}" name="${_csrf.parameterName}"/>

Done! Go to http://localhost:8080 and you will be redirected to an Okta login form and will only be able to use the application after you are successfully authenticated.

Want to share the app with a friend? Cool, go to the Okta developer console page, go to Users and create an account for them. You now have a fully functional security administration tool as well, where you can enable/disable users, check when they are logging to your app, reset their passwords, etc.

Enjoy your new, secure Book app!

#java #programming

What is GEEK

Buddha Community

Create a CRUD Application with Java and JavaServer Faces
Tyrique  Littel

Tyrique Littel

1600135200

How to Install OpenJDK 11 on CentOS 8

What is OpenJDK?

OpenJDk or Open Java Development Kit is a free, open-source framework of the Java Platform, Standard Edition (or Java SE). It contains the virtual machine, the Java Class Library, and the Java compiler. The difference between the Oracle OpenJDK and Oracle JDK is that OpenJDK is a source code reference point for the open-source model. Simultaneously, the Oracle JDK is a continuation or advanced model of the OpenJDK, which is not open source and requires a license to use.

In this article, we will be installing OpenJDK on Centos 8.

#tutorials #alternatives #centos #centos 8 #configuration #dnf #frameworks #java #java development kit #java ee #java environment variables #java framework #java jdk #java jre #java platform #java sdk #java se #jdk #jre #open java development kit #open source #openjdk #openjdk 11 #openjdk 8 #openjdk runtime environment

A Lightweight Face Recognition and Facial Attribute Analysis

deepface

Deepface is a lightweight face recognition and facial attribute analysis (age, gender, emotion and race) framework for python. It is a hybrid face recognition framework wrapping state-of-the-art models: VGG-Face, Google FaceNet, OpenFace, Facebook DeepFace, DeepID, ArcFace and Dlib.

Experiments show that human beings have 97.53% accuracy on facial recognition tasks whereas those models already reached and passed that accuracy level.

Installation

The easiest way to install deepface is to download it from PyPI. It's going to install the library itself and its prerequisites as well. The library is mainly based on TensorFlow and Keras.

pip install deepface

Then you will be able to import the library and use its functionalities.

from deepface import DeepFace

Facial Recognition - Demo

A modern face recognition pipeline consists of 5 common stages: detect, align, normalize, represent and verify. While Deepface handles all these common stages in the background, you don’t need to acquire in-depth knowledge about all the processes behind it. You can just call its verification, find or analysis function with a single line of code.

Face Verification - Demo

This function verifies face pairs as same person or different persons. It expects exact image paths as inputs. Passing numpy or based64 encoded images is also welcome. Then, it is going to return a dictionary and you should check just its verified key.

result = DeepFace.verify(img1_path = "img1.jpg", img2_path = "img2.jpg")

Face recognition - Demo

Face recognition requires applying face verification many times. Herein, deepface has an out-of-the-box find function to handle this action. It's going to look for the identity of input image in the database path and it will return pandas data frame as output.

df = DeepFace.find(img_path = "img1.jpg", db_path = "C:/workspace/my_db")

Face recognition models - Demo

Deepface is a hybrid face recognition package. It currently wraps many state-of-the-art face recognition models: VGG-Face , Google FaceNet, OpenFace, Facebook DeepFace, DeepID, ArcFace and Dlib. The default configuration uses VGG-Face model.

models = ["VGG-Face", "Facenet", "Facenet512", "OpenFace", "DeepFace", "DeepID", "ArcFace", "Dlib"]

#face verification
result = DeepFace.verify(img1_path = "img1.jpg", img2_path = "img2.jpg", model_name = models[1])

#face recognition
df = DeepFace.find(img_path = "img1.jpg", db_path = "C:/workspace/my_db", model_name = models[1])

FaceNet, VGG-Face, ArcFace and Dlib are overperforming ones based on experiments. You can find out the scores of those models below on both Labeled Faces in the Wild and YouTube Faces in the Wild data sets declared by its creators.

ModelLFW ScoreYTF Score
Facenet51299.65%-
ArcFace99.41%-
Dlib99.38 %-
Facenet99.20%-
VGG-Face98.78%97.40%
Human-beings97.53%-
OpenFace93.80%-
DeepID-97.05%

Similarity

Face recognition models are regular convolutional neural networks and they are responsible to represent faces as vectors. We expect that a face pair of same person should be more similar than a face pair of different persons.

Similarity could be calculated by different metrics such as Cosine Similarity, Euclidean Distance and L2 form. The default configuration uses cosine similarity.

metrics = ["cosine", "euclidean", "euclidean_l2"]

#face verification
result = DeepFace.verify(img1_path = "img1.jpg", img2_path = "img2.jpg", distance_metric = metrics[1])

#face recognition
df = DeepFace.find(img_path = "img1.jpg", db_path = "C:/workspace/my_db", distance_metric = metrics[1])

Euclidean L2 form seems to be more stable than cosine and regular Euclidean distance based on experiments.

Facial Attribute Analysis - Demo

Deepface also comes with a strong facial attribute analysis module including age, gender, facial expression (including angry, fear, neutral, sad, disgust, happy and surprise) and race (including asian, white, middle eastern, indian, latino and black) predictions.

obj = DeepFace.analyze(img_path = "img4.jpg", actions = ['age', 'gender', 'race', 'emotion'])

Age model got ± 4.65 MAE; gender model got 97.44% accuracy, 96.29% precision and 95.05% recall as mentioned in its tutorial.

Streaming and Real Time Analysis - Demo

You can run deepface for real time videos as well. Stream function will access your webcam and apply both face recognition and facial attribute analysis. The function starts to analyze a frame if it can focus a face sequantially 5 frames. Then, it shows results 5 seconds.

DeepFace.stream(db_path = "C:/User/Sefik/Desktop/database")

Even though face recognition is based on one-shot learning, you can use multiple face pictures of a person as well. You should rearrange your directory structure as illustrated below.

user
├── database
│   ├── Alice
│   │   ├── Alice1.jpg
│   │   ├── Alice2.jpg
│   ├── Bob
│   │   ├── Bob.jpg

Face Detectors - Demo

Face detection and alignment are important early stages of a modern face recognition pipeline. Experiments show that just alignment increases the face recognition accuracy almost 1%. OpenCV, SSD, Dlib, MTCNN and RetinaFace detectors are wrapped in deepface.

All deepface functions accept an optional detector backend input argument. You can switch among those detectors with this argument. OpenCV is the default detector.

backends = ['opencv', 'ssd', 'dlib', 'mtcnn', 'retinaface']

#face verification
obj = DeepFace.verify(img1_path = "img1.jpg", img2_path = "img2.jpg", detector_backend = backends[4])

#face recognition
df = DeepFace.find(img_path = "img.jpg", db_path = "my_db", detector_backend = backends[4])

#facial analysis
demography = DeepFace.analyze(img_path = "img4.jpg", detector_backend = backends[4])

#face detection and alignment
face = DeepFace.detectFace(img_path = "img.jpg", target_size = (224, 224), detector_backend = backends[4])

Face recognition models are actually CNN models and they expect standard sized inputs. So, resizing is required before representation. To avoid deformation, deepface adds black padding pixels according to the target size argument after detection and alignment.

RetinaFace and MTCNN seem to overperform in detection and alignment stages but they are much slower. If the speed of your pipeline is more important, then you should use opencv or ssd. On the other hand, if you consider the accuracy, then you should use retinaface or mtcnn.

The performance of RetinaFace is very satisfactory even in the crowd as seen in the following illustration. Besides, it comes with an incredible facial landmark detection performance. Highlighted red points show some facial landmarks such as eyes, nose and mouth. That's why, alignment score of RetinaFace is high as well.

You can find out more about RetinaFace on this repo.

API - Demo

Deepface serves an API as well. You can clone /api/api.py and pass it to python command as an argument. This will get a rest service up. In this way, you can call deepface from an external system such as mobile app or web.

python api.py

Face recognition, facial attribute analysis and vector representation functions are covered in the API. You are expected to call these functions as http post methods. Service endpoints will be http://127.0.0.1:5000/verify for face recognition, http://127.0.0.1:5000/analyze for facial attribute analysis, and http://127.0.0.1:5000/represent for vector representation. You should pass input images as base64 encoded string in this case. Here, you can find a postman project.

Tech Stack - Vlog, Tutorial

Face recognition models represent facial images as vector embeddings. The idea behind facial recognition is that vectors should be more similar for same person than different persons. The question is that where and how to store facial embeddings in a large scale system. Herein, deepface offers a represention function to find vector embeddings from facial images.

embedding = DeepFace.represent(img_path = "img.jpg", model_name = 'Facenet')

Tech stack is vast to store vector embeddings. To determine the right tool, you should consider your task such as face verification or face recognition, priority such as speed or confidence, and also data size.

Contribution

Pull requests are welcome. You should run the unit tests locally by running test/unit_tests.py. Please share the unit test result logs in the PR. Deepface is currently compatible with TF 1 and 2 versions. Change requests should satisfy those requirements both.

Support

There are many ways to support a project - starring⭐️ the GitHub repo is just one 🙏

You can also support this work on Patreon

 

Citation

Please cite deepface in your publications if it helps your research. Here are its BibTeX entries:

@inproceedings{serengil2020lightface,
  title        = {LightFace: A Hybrid Deep Face Recognition Framework},
  author       = {Serengil, Sefik Ilkin and Ozpinar, Alper},
  booktitle    = {2020 Innovations in Intelligent Systems and Applications Conference (ASYU)},
  pages        = {23-27},
  year         = {2020},
  doi          = {10.1109/ASYU50717.2020.9259802},
  url          = {https://doi.org/10.1109/ASYU50717.2020.9259802},
  organization = {IEEE}
}
@inproceedings{serengil2021lightface,
  title        = {HyperExtended LightFace: A Facial Attribute Analysis Framework},
  author       = {Serengil, Sefik Ilkin and Ozpinar, Alper},
  booktitle    = {2021 International Conference on Engineering and Emerging Technologies (ICEET)},
  pages        = {1-4},
  year         = {2021},
  doi          = {10.1109/ICEET53442.2021.9659697},
  url.         = {https://doi.org/10.1109/ICEET53442.2021.9659697},
  organization = {IEEE}
}

Also, if you use deepface in your GitHub projects, please add deepface in the requirements.txt.

Author: Serengil
Source Code: https://github.com/serengil/deepface 
License: MIT License

#python #machine-learning 

How to Develop Mobile Applications with Java?

Do you want to develop mobile apps with Java? AppClues Infotech has the best expertise to develop a mobile app with Java. We have a highly talented team of developers that can help to create a secure, elegant & high-performance Java mobile app for your business.

Our Java Mobile App Development Service
• Custom Java Android App Development
• Java Web-based Applications
• Java Android Game Development
• Java Android App UI/UX Design
• Java App Migrations and Platform Porting
• QA Testing, Maintenance & Support of Java Android Apps

For more info:
Website: https://www.appcluesinfotech.com/
Email: info@appcluesinfotech.com
Call: +1-978-309-9910

#create mobile app with java #create mobile app with java #create mobile app with java #java android app development #top java app development company #best java app development services

Create Android Application with Java

Do you want to create Android mobile applications with Java for your startup or business? We at AppClues Infotech is one of the leading Java app development company in USA that will help to create a secure & successful mobile app with the most advanced features & technologies.

For more info:
Website: https://www.appcluesinfotech.com/
Email: info@appcluesinfotech.com
Call: +1-978-309-9910

#java android app development company usa #java application development services usa #java mobile app development #java for mobile app development #create android app with java #best java app development company in usa

Joseph  Murray

Joseph Murray

1623302550

Top 5 Java Web Application Technologies You Should Master in 2021

Web Development in Java

Java is a commonly used language for web development, especially on the server-side. Java web applications are distributed applications that run on the internet. Web development with Java allows us to create dynamic web pages where users can interact with the interface.

There are various ways through which you can create dynamic web pages in Java. The Java EE (Enterprise Edition) platform provides various Java technologies for web development to developers. Services like distributed computing, web services, etc. are provided by Java EE. Applications can be developed in Java without using any additional scripting language. Let us see how web applications are made via Java.

**Java Web Application **

Java Web Application Technologies

#software development #java #java web applications #web applications #java web application technologies #top 5 java web application technologies you should master