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