PrimeFaces & Spring Boot – część 1


PrimeFaces & Spring Boot – część 1

PrimeFaces jest udostępnianą na zasadach Apache 2.0 biblioteką komponentów dla JavaServer Faces w wersji 2.0, która umożliwia w szybki i łatwy sposób projektowanie aplikacji z użyciem graficznego interfejsu użytkownika – GUI. Autorem biblioteki jest firma Prime Teknoloji. Biblioteka PrimeFaces bazuje na bibliotece jQuery. Aplikacja w tym artykule wyświetlać będzie predefiniowaną za pomocą bloku statycznego listę produktów:

Niezbędne zależności do Mavena w pliku pom.xml:

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>
	<dependency>
		<groupId>org.apache.myfaces.core</groupId>
		<artifactId>myfaces-impl</artifactId>
		<version>2.2.12</version>
	</dependency>
	<dependency>
		<groupId>org.apache.myfaces.core</groupId>
		<artifactId>myfaces-api</artifactId>
		<version>2.2.12</version>
	</dependency>
	<dependency>
		<groupId>org.apache.tomcat.embed</groupId>
		<artifactId>tomcat-embed-jasper</artifactId>
	</dependency>
	<dependency>
		<groupId>org.ocpsoft.rewrite</groupId>
		<artifactId>rewrite-servlet</artifactId>
		<version>3.4.1.Final</version>
	</dependency>
	<dependency>
		<groupId>org.ocpsoft.rewrite</groupId>
		<artifactId>rewrite-integration-faces</artifactId>
		<version>3.4.1.Final</version>
	</dependency>
	<dependency>
		<groupId>org.ocpsoft.rewrite</groupId>
		<artifactId>rewrite-config-prettyfaces</artifactId>
		<version>3.4.1.Final</version>
	</dependency>
	<dependency>
		<groupId>org.primefaces</groupId>
		<artifactId>primefaces</artifactId>
		<version>6.2</version>
	</dependency>
	<dependency>
		<groupId>org.projectlombok</groupId>
		<artifactId>lombok</artifactId>
		<version>1.16.16</version>
	</dependency>
</dependencies>

<build>
	<outputDirectory>src/main/webapp/WEB-INF/classes</outputDirectory>
</build>

Konfiguracja SpringApplication – przepisywanie URLi, mapowanie URLi:

@EnableAutoConfiguration
@ComponentScan({"pl.javaleader.PrimeFacesSpringBoot"})
public class PrimeFacesSpringBootApplication {

	public static void main(String[] args) {
		SpringApplication.run(PrimeFacesSpringBootApplication.class, args);
	}


	@Bean
	public ServletRegistrationBean servletRegistrationBean() {
		FacesServlet servlet = new FacesServlet();
		return new ServletRegistrationBean(servlet, "*.jsf");
	}

	@Bean
	public FilterRegistrationBean rewriteFilter() {
		FilterRegistrationBean rwFilter = new FilterRegistrationBean(new RewriteFilter());
		rwFilter.setDispatcherTypes(EnumSet.of(DispatcherType.FORWARD, DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.ERROR));
		rwFilter.addUrlPatterns("/*");
		return rwFilter;
	}

}

./webapp/WEB-INF/faces-config.xml – w pliku faces-config.xml umieszczamy wszelkie informajce o konfiguracji JSF. W tym przypadku jest to użycie ziaren (beans) Springa jako ziaren JSF:

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

<faces-config 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"
              version="2.2">

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

</faces-config>

./webapp/WEB-INF/web.xml – deskryptor wdrożenia:

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

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" 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>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>

</web-app>

./webapp/layout.xhtml – główny layout strony:

<!DOCTYPE html>

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

      xmlns:p="http://primefaces.org/ui">

<f:view>

    <h:head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title>Product</title>
    </h:head>

    <h:body>
        <div class="ui-g">
            <div class="ui-g-12">
                <p:toolbar>
                    <f:facet name="left">
                        <p:button href="/" value="List of Products" />
                        <p:button href="/product" value="New Product" />
                    </f:facet>
                </p:toolbar>
            </div>

            <div class="ui-g-12">
                <ui:insert name="content" />
            </div>
        </div>
    </h:body>

</f:view>

</html>

./webapp/product-list.xhtml – przykładowa witryna wyświetlająca listę produktów:

<?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:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:p="http://primefaces.org/ui">

    <ui:composition template="layout.xhtml">
        <ui:define name="content">
            <h:form id="form">
                <p:panel header="Products List">
                    <p:dataTable id="table" var="product" value="#{productList.products}">
                        <p:column>
                            <f:facet name="header"># Id</f:facet>
                            <h:outputText value="#{product.id}" />
                        </p:column>

                        <p:column>
                            <f:facet name="header">Name</f:facet>
                            <h:outputText value="#{product.name}" />
                        </p:column>

                        <p:column>
                            <f:facet name="header">Price</f:facet>
                            <h:outputText value="#{product.price}">
                                <f:convertNumber type="currency" currencySymbol="$ " />
                            </h:outputText>
                        </p:column>

                    </p:dataTable>
                </p:panel>
            </h:form>
        </ui:define>
    </ui:composition>

</html>

Kontroler wyświetlający przykładowe dane – kolekcja produktów ze względu na wydajność aplikacji powinna być załadowana przed wyrenderowaniem interfejsu GUI:

@Scope     ( value          = "session")
@Component ( value          = "productList")
@ELBeanName( value          = "productList")
@Join(       path = "/", to = "/product-list.jsf")
public class ProductListController {

    private List<Product> products;

    @Autowired
    ProductServiceApi productServiceApi;

    @Deferred
    @RequestAction
    @IgnorePostback
    public void loadData() {
        products = productServiceApi.getAllProducts();
    }

    public List<Product> getProducts() {
        return products;
    }

}

Klasa modelu – Produkt:

package pl.javaleader.PrimeFacesSpringBoot.model;

import java.math.BigDecimal;

public class Product {

    private Long id;
    private String name;
    private BigDecimal price;

    public Product() {
    }

    public Product(Long id, String name, BigDecimal price) {
        this.id    = id;
        this.name  = name;
        this.price = price;
    }

    public Product(String name, BigDecimal price) {
        this.name  = name;
        this.price = price;
    }

    // getters & setters

}

API – port:

package pl.javaleader.PrimeFacesSpringBoot.service;

import pl.javaleader.PrimeFacesSpringBoot.model.Product;
import java.util.List;

public interface ProductServiceApi {
    List<Product> getAllProducts();
}

Implementacja – adapter:

package pl.javaleader.PrimeFacesSpringBoot.service;

import pl.javaleader.PrimeFacesSpringBoot.model.Product;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Service;

@Service
public class ProductService implements  ProductServiceApi {

    static List<Product> products = new ArrayList();

    static {
        Product product1 = new Product(1L, "p1", new BigDecimal(200));
        Product product2 = new Product(2L, "p2", new BigDecimal(300));
        Product product3 = new Product(3L, "p3", new BigDecimal(400));
        Product product4 = new Product(4L, "p4", new BigDecimal(500));
        Product product5 = new Product(5L, "p5", new BigDecimal(600));

        products.add(product1);
        products.add(product2);
        products.add(product3);
        products.add(product4);
        products.add(product5);

    }

    public List<Product> getAllProducts() {
        return products;
    }
}

Biblioteka PrimeFaces udostępnia rozbudowaną listę gotowych szablonów. Aby zmienić szablon należy dodać parametr kontekstu:

	@Bean
	public ServletContextInitializer initializer() {
		return new ServletContextInitializer() {
			@Override
			public void onStartup(ServletContext servletContext) throws ServletException {
				servletContext.setInitParameter("primefaces.THEME", "omega");
			}
		};
	}

oraz w pom.xml repozytorium:

	<repositories>
		<repository>
			<id>prime-repo</id>
			<name>PrimeFaces Maven Repository</name>
			<url>http://repository.primefaces.org</url>
			<layout>default</layout>
		</repository>
	</repositories>

i zależność:

<dependency>
	<groupId>org.primefaces.themes</groupId>
	<artifactId>all-themes</artifactId>
	<version>1.0.10</version>
</dependency>

 

 


Leave a comment

Your email address will not be published.


*