用SpringBoot开发JSF应用程序(一)
—— Spring Boot可以支持构建很多类型的应用程序,而不仅仅是微服务。 让我们用Spring Boot构建一个JSF应用程序。原文:https://auth0.com/blog/developing-jsf-applications-with-spring-boot/Bruno Krebs May 09, 2017Spring Boot最初是应用于微服务相关应用程序,但是,由...
—— Spring Boot可以支持构建很多类型的应用程序,而不仅仅是微服务。 让我们用Spring Boot构建一个JSF应用程序。
原文:https://auth0.com/blog/developing-jsf-applications-with-spring-boot/
Bruno Krebs May 09, 2017
Spring Boot最初是应用于微服务相关应用程序,但是,由于它是基于Spring框架的,所以许多人开始想知道如何将JavaServer Faces(JSF)与Spring Boot集成。 在本文中,我们将把这些组合在一起,构建一个小应用程序,使用户能够将“产品信息”列出并保存到数据库中。
JSF是什么?
JavaServer Faces(JSF)是一种Java规范,它提供了一种以组件为中心的用户界面(UI)构建方法(从而简化了Java服务器端应用程序的开发。) JSF上的视图是通过称为视图模板的XML文件来描述的,通常依赖于服务器端会话来存储UI组件的状态。 例如,假设我们想要显示一个HTML“产品”表。 为此,我们需要一个包含以下内容的XML文件:
<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">
<ui:composition template="base-layout.xhtml">
<ui:define name="content">
<h:form id="form">
<h:dataTable id="table" var="product" value="#{productListController.products}">
<h:column>
<f:facet name="header">Name</f:facet>
<h:outputText value="#{product.name}" />
</h:column>
<h:column>
<f:facet name="header">Action</f:facet>
<h:commandButton id="delete" action="#{productListController.delete(product)}" label="Delete" />
</h:column>
</h:dataTable>
</h:form>
</ui:define>
</ui:composition>
</html>
在这种情况下,视图将通过使用h:dataTable组件在一个名为productListController的支持bean的帮助下进行呈现,该bean将为请求者生成HTML响应。 在呈现网页之后,JSF将保留服务器端的视图状态,以允许后续的交互。
JSF与SpringBoot的集成
首先,我们将fork或clone为本文专门创建的GitHub repo(https://github.com/auth0-blog/spring-boot-faces)。我们也可以使用Spring Initilizr网页(https://start.spring.io/),它简单直观。但是,由于我们要构建的应用程序将具有一些其他依赖项(如HSQLDB和Flyway),从fork开始会更容易。
JSF依赖项(基于Maven)
在派生存储库之后,打开您喜欢的IDE (Eclipse、IntelliJ IDEA、Netbeans等),并将初始项目作为Maven项目导入。在IDE上正确导入应用程序后,我们要做的第一件事是添加一些依赖项。让我们打开pom,添加嵌套在<dependecies></dependecies>元素中的以下元素:
<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.1</version>
</dependency>
从上到下,让我们揭开这些依赖关系的神秘面纱。 前两个依赖项myfaces-api和myfaces-impl是JSF接口规范(-api)和实现(-impl)。 需要第三个依赖项tomcat-embed-jasper,以便JVM可以在运行时解析并执行JSF视图。
之后,org.ocpsoft.rewrite作为groupId的值有三个依赖项。 这些依赖项与Rewrite相关,Rewrite是一种面向Servlet和Java Web框架的开源路由和URL重写解决方案。 使用JSF而不使用像Rewrite这样的工具会导致我们使用丑陋且非RESTful友好的URL,这种URL大量使用查询参数进行导航。 因此,我们将使用Rewrite来实现直观,可收藏和漂亮的URL。
添加的最后一个依赖项primefaces是一个JSF的开源UI框架,它包含一百多个组件,如数据表,拖放,叠加对话框等。这个框架将帮助我们轻松创建漂亮的用户界面。
现在,让我们打开pom.xml文件,通过向其添加以下行来更改构建过程:
<build>
<outputDirectory>src/main/webapp/WEB-INF/classes</outputDirectory>
<!-- plugins... -->
</build>
这种配置很重要,因为Rewrite不准备在非经典Web应用程序上扫描配置(即在Spring Boot等嵌入式应用程序上)。 所以我们需要稍微调整构建过程,以帮助Rewrite实现它的目标。
JSF配置
接下来,我们将创建两个XML文件。 第一个是web.xml,经验丰富的Java Web开发人员对它已经滚瓜烂熟了。 在常规的Spring Boot应用程序中,我们不需要此文件。 但是,由于我们将使用JSF,我们需要配置FacesServlet servlet和几个listener。 让我们在名为src / main / webapp / WEB-INF /的新目录下创建此文件,并添加以下内容:
<?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>
此文件中的前两个元素负责设置FacesServlet并对其进行配置。 servlet-mapping元素指示此servlet处理对* .jsf URL的请求,并在JSF的上下文中处理它们。 最后两个元素,listener元素,负责将JSF集成到Spring上下文中。
我们需要的第二个XML文件是faces-config.xml。 让我们在src / main / webapp / WEB-INF /文件夹下创建这个文件,其中包含以下内容:
<?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>
这个文件所做的就是注册一个ELResolver(即表达式语言解析器),它将解析名称引用的责任委托给Spring的WebApplicationContext上下文。有了它,我们可以在JSF上下文中使用Spring托管bean。
最后一步,我们需要更新项目的Application类以创建另外两个bean。 这是通过如下配置此类来完成的:
package com.auth0.samples.bootfaces;
import org.ocpsoft.rewrite.servlet.RewriteFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import javax.faces.webapp.FacesServlet;
import javax.servlet.DispatcherType;
import java.util.EnumSet;
@EnableAutoConfiguration
@ComponentScan({"com.auth0.samples.bootfaces"})
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.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;
}
}
创建了两个XML文件,正确导入了依赖项,并配置了Application类,我们已准备好开始在Spring Boot上开发JSF应用程序。
基于github工程的构建和配置(译者补充)
如果基于github工程fork出来,或者clone,使用eclipse导入会报错,可以通过以下方式进行解决。
问题一:转换成一个Maven工程
通过右键点击工程,选中“Configure”中的“Convert to Maven Project”,进行Maven工程转换。
构建成功以后,工程就会变成如下所示:
- src/main/java这样的目录就变成了Source Folder,而原来只是一个普通的文件目录。
- 出现JRE System Library
- 出现Maven Dependencies
解决错误
转换成Maven工程后,会出现一些错误,如图:
针对报错的是三个,在操作系统中添加对应的目录:
src/test/java
target/generated-sources/annotations
target/generated-test-sources/test-annotations
然后,刷新工程,错误就会消失。
包名无法识别
有可能会出现包名无法识别的异常,明明就在这个包下,但是报错:
解决方式:先把该类移到新包下,再重构包名,修改回来即可。
(未完待续)
用SpringBoot开发JSF应用程序系列文章:
更多推荐
所有评论(0)