Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Bootiful Enterprise Applications Powered by Spring Boot and Hosted on Payara Micro

DZone's Guide to

Bootiful Enterprise Applications Powered by Spring Boot and Hosted on Payara Micro

Learn how to take popular modules from Java EE, such as JPA and JSF, develop an application with them in Spring Boot, and then deploy the app on Payara Micro.

· Java Zone
Free Resource

Bitbucket is for the code that takes us to Mars, decodes the human genome, or drives your next car. What will your code do? Get started with Bitbucket today, it's free.

We have already introduced Spring Boot to Payara Micro, the new fish on the block!, by implementing Spring Boot based RESTful web services and hosted on Payara Micro. While implementing it, we didn’t deal with any of the XML configurations or dependency management needed for the Spring framework with the help of  the Spring Boot.

With this article, we will take it one step further by introducing new modules from Java EE like JPA, JSF and many others. Spring Boot will ease the development yet again for us with its bootstrapping methodology. After building our sample application containing simple user interface and persistency, we will deploy it onto Payara Micro, the application server that offers running Java EE applications on a cluster with a small footprint (~60mb) and directly from the console.

It’s worth to mention that Payara Micro is fully compatible with the Java EE 7 Web Profile - you will see for yourself how easy it is to create a CRUD page that integrates with an embedded database provided by Payara Micro.

All of the examples in this article are based on Spring Boot version 1.2.6.RELEASE and Payara Micro version 4.1.153, which are the latest available versions at the time of writing. The complete source code given in the article is available here.

Project Structure and Dependencies

Let’s start our development by taking our Spring Boot REST example as a code basis. The only dependencies that we are going to add are: JSF + PrimeFaces for the user interface and Spring boot starter JPA for the persistency. They are given as follows.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
    <groupId>org.primefaces</groupId>
    <artifactId>primefaces</artifactId>
    <version>5.2</version>
</dependency>

Payara Micro already ships with Mojarra v2.2.11, which is the JSF implementation from Oracle, so providing the PrimeFaces dependency only will suffice on the UI side. Spring Boot’s starter for JPA bundles all the necessary dependencies for Hibernate so we don’t need to provide a persistency provider either. Spring Boot can also auto-configure embedded databases like H2, HSQL or Derby. Since Payara Micro ships with an embedded Derby database already, we don’t even need to write one line of code to connect to that database, other than only extending our repository classes from the class, JpaRepository. We’ll get to that soon, just stick with us!

Implementing a CRUD page

First we should define our domain object as a JPA managed entity. Person class definition that achieves this is given below.

@Entity
public class Person implements Serializable {

    @Id
    @GeneratedValue
    private int id;
    @NotNull
    @Size(min = 2, max = 20)
    private String name;
    @Size(min = 3, max = 50)
    private String lastName;
    @Email
    private String email;

    // getters & setters
}

As you can also notice, entity contains bean validation annotations like @Size, @NotNull and@Email, which apply constraints on the properties of the domain object. These validations will be automatically integrated on the JSF input field components.

Spring Data module provides standardized repository implementation model based on JPA. It maps an interface per managed domain object and the corresponding person repository definition is given below.

public interface PersonRepository extends 
JpaRepository<Person, Integer> {
}

For populating the DB, we need to implement a Spring bean with a method annotated by@PostConstruct, so that it inserts sample person objects into in memory database while getting up application.

@Service
public class DbInitService {

    @Autowired
    private PersonRepository repository;

    @PostConstruct
    public void init() {
        Person person1 = new Person(1, "Mert", "Caliskan", "emailaddress@gmail.com");
        repository.save(person1);
        Person person2 = new Person(2, "Steve", "Millidge", "emailaddress1@c2b2.co.uk");
        repository.save(person2);
        Person person3 = new Person(3, "Andrew", "Pielage", "emailaddress2@c2b2.co.uk");
        repository.save(person3);
    }
}

As the last step of implementation, the person.xhtml page and its corresponding managed bean definition are listed below. The page consists of 2 sections that contain a grid for inputting a new person and a data table for listing the saved persons by retrieving from the database. Table also supports editing and deleting a person from the list with a button and a link.

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

<f:view>
    <h:head>
        <title>JSF on Payara Micro</title>
    </h:head>
    <h:body>
        <h:form id="form">
            <p:messages id="messages" />
            <p:panelGrid id="newPerson" columns="2">
                <p:outputLabel for="txt_name" value="Name" />
                <p:inputText id="txt_name" value="#{personView.person.name}" />
                <p:outputLabel for="txt_lastname" value="Last name" />
                <p:inputText id="txt_lastname" value="#{personView.person.lastName}" />
                <p:outputLabel for="txt_email" value="E-mail" />
                <p:inputText id="txt_email" value="#{personView.person.email}" />
                <p:commandButton id="btn_save" value="Save" action="#{personView.savePerson}"
                                 process=":form:newPerson"
                                 update=":form:newPerson :form:personList :form:messages">
                </p:commandButton>
            </p:panelGrid>
            <p:dataTable id="personList" value="#{personView.personList}" var="p">
                <p:column>
                    <f:facet name="header">
                        <h:outputText value="Id" />
                    </f:facet>
                    <h:outputText value="#{p.id}" />
                </p:column>
                <p:column>
                    <f:facet name="header">
                        <h:outputText value="Name" />
                    </f:facet>
                    <h:outputText value="#{p.name}" />
                </p:column>
                <p:column>
                    <f:facet name="header">
                        <h:outputText value="Last name" />
                    </f:facet>
                    <h:outputText value="#{p.lastName}" />
                </p:column>
                <p:column>
                    <f:facet name="header">
                        <h:outputText value="E-mail" />
                    </f:facet>
                    <h:outputText value="#{p.email}" />
                </p:column>
                <p:column>
                    <f:facet name="header">
                        <h:outputText value="Edit" />
                    </f:facet>
                    <p:commandButton value="Edit" process="@this" update=":form:newPerson">
                        <f:setPropertyActionListener value="#{p}" target="#{personView.person}" />
                    </p:commandButton>
                </p:column>
                <p:column>
                    <f:facet name="header">
                        <h:outputText value="Delete" />
                    </f:facet>
                    <p:commandLink action="#{personView.deletePerson(p)}" process="@this" update=":form:personList">
                        <h:outputText value="X" />
                    </p:commandLink>
                </p:column>
            </p:dataTable>
        </h:form>
    </h:body>
</f:view>
</html>

PersonView managed bean class is a Spring bean and the person repository is injected into it with the @Autowired annotation.

@Controller
public class PersonView implements Serializable {

    @Autowired
    private PersonRepository personRepository;

    private Person person = new Person();

    public List<Person> getPersonList() {
        return personRepository.findAll();
    }

    public void savePerson() {
        personRepository.save(person);
        person = new Person();
    }

    public void deletePerson(Person person) {
        personRepository.delete(person);
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public Person getPerson() {
        return person;
    }
}

Wrapping it up

To integrate Spring beans into JSF pages, we need to define an EL Resolver in JSF configuration file, which is the faces-config.xml. The file should be placed under WEB-INF folder.

<faces-config version="2.2"
              xmlns="http://xmlns.jcp.org/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
              http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">

    <application>
        <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
    </application>
</faces-config>

The web.xml, web application deployment descriptor file, should also be placed under WEB-INFfolder in order to package the application as a war file. This file is also needed to correctly deploy our application onto Payara Micro.  The configuration file should contain the FacesServlet definition, which is the gateway servlet for handling all of our JSF requests.

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
     http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <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>*.jsf</url-pattern>
    </servlet-mapping>

</web-app>

As a last step, executing mvn clean install command within the application folder should create a war archive out of it. 

Getting it up and Running

With Payara Micro it’s so easy to deploy a war archive through the console. Download Payara Micro v4.1.153 from here first and then just execute the command given below.

java -jar payara-micro-4.1.153.jar --deploy %PATH_TO%/ spring-boot-jpa-jsf-example-1.0-SNAPSHOT.war

When you request for the person JSF page as http://localhost:8080/spring-boot-jpa-jsf-example-1.0-SNAPSHOT/person.jsf, you should be seeing a visual output as follows:

Image title

The Bean Validation will be automatically integrated to JSF components so inputting malformed data to the input fields will lead to visual notifications on the page as given below.

Image title


Are you using Bitbucket to accomplish your company's mission? Share your company’s mission with #Forthecode for a chance to be featured on our homepage, our social media channels, or win a free t-shirt!

Topics:
spring boot ,payara ,microservices ,java ee ,crud ,jsf

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}