使用Maven实施自定义JSF 2.0组件

前一段时间,我编写了自己的定制JSF组件。 但是在那个时候,JSF 1.0仍然是最新的,并且该项目没有使用maven作为构建系统。 因此,我一直想用maven编写一个自定义JSF2组件。 因此,让我们开始:

首先,我们设置一个带有两个模块的Maven项目。 这是父项目的pom.xml文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>martins-developer-world</groupId>
	<artifactId>jsf-component</artifactId>
	<packaging>pom</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>jsf-component Maven Webapp</name>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>javax.faces</groupId>
			<artifactId>jsf-api</artifactId>
			<version>2.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>com.sun.faces</groupId>
			<artifactId>jsf-impl</artifactId>
			<version>2.2.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>
	<build>
		<finalName>jsf-component</finalName>
	</build>
	<modules>
		<module>jsf-component-webapp</module>
		<module>jsf-component-impl</module>
	</modules>
</project>

如您所见,我们在顶级pom.xml中添加了JSF依赖关系,以便我们在子模块中继承它们。 因为我们将使用JBoss Application Server测试我们的Web应用程序,所以我们必须设置要提供的Maven依赖项的范围,以便我们的war文件和组件jar不会部署它们。 我们组件的实现将驻留在jsf-component-impl中,因此我们选择jar作为此模块的包装类型:

<?xml version="1.0"?>
<project
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>martins-developer-world</groupId>
		<artifactId>jsf-component</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<artifactId>jsf-component-impl</artifactId>
	<name>jsf-component-impl</name>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	<dependencies>
	</dependencies>
</project>

现在,让我们实现一个扩展UIOutput的Java类。 之所以选择UIOutput是因为,第一步,我只想实现一个简单的helloWorld标签,该标签将在span元素中打印作为属性给出的名字和姓氏。 由于此组件未收到任何输入,因此UIOutput适当:

package martins.developer.world.jsf.component.impl;

import java.io.IOException;

import javax.faces.application.ResourceDependencies;
import javax.faces.application.ResourceDependency;
import javax.faces.component.FacesComponent;
import javax.faces.component.UIOutput;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;

@ResourceDependencies({ @ResourceDependency(name = "css/jsf-component.css", target = "head") })
@FacesComponent("HelloWorld")
public class HelloWorldComponent extends UIOutput {
	private static final String COMPONENT_FAMILY = "martins.developer.world.jsf.component.helloWorld";

	private enum PropertyKeys {
		firstName, lastName
	};

	@Override
	public String getFamily() {
		return COMPONENT_FAMILY;
	}

	@Override
	public void encodeBegin(FacesContext context) throws IOException {
		ResponseWriter writer = context.getResponseWriter();
		writer.startElement("span", this);
		writer.writeAttribute("class", "helloWorldClass", "");
		writer.writeText(String.format("Hello %s %s!", getFirstName(), getLastName()), "");
		writer.endElement("span");
	}

	public String getFirstName() {
		return (String) getStateHelper().eval(PropertyKeys.firstName, "???firstName???");
	}

	public void setFirstName(String firstName) {
		getStateHelper().put(PropertyKeys.firstName, firstName);
	}

	public String getLastName() {
		return (String) getStateHelper().eval(PropertyKeys.lastName, "???lastName???");
	}

	public void setLastName(String lastName) {
		getStateHelper().put(PropertyKeys.lastName, lastName);
	}
}

getFamily()方法是我们必须实施的唯一方法。 这里有趣的是encodeBegin()方法。 这是我们实现span标签的地方。 因为它应该具有CSS类属性,所以我们使用Writer的writeAttribute()方法添加它。 使用getter和setter方法将所得JSF标记的两个属性建模为简单属性。 这些getter和setter的实现使用JSF 2.0中提供的StateHelper。 在encodeBegin()中,我们使用吸气剂来检索用户给定的值。

有趣的是@ResourceDependencies注释。 有了这个注释,我们可以告诉JSF框架,我们有一些依赖的文件。 在这种情况下,这是一个CSS文件,位于文件夹src / main / resources / META-INF / resources / css中。
注释@FacesComponent在JSF框架的引导过程中注册了此组件。 给定名称在taglib文件中用于引用此类:

<?xml version="1.0"?>
<facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee">
	<namespace>http://martinsdeveloperworld.wordpress.com</namespace>
	<tag>
		<tag-name>helloWorld</tag-name>
		<component>
			<component-type>HelloWorld</component-type>
		</component>
	</tag>
</facelet-taglib>

在src / main / resources / META-INF下的这个taglib文件中,我们定义了可用的组件,这里仅是helloWorld标签。 标签的属性是从Java类的属性派生的。

最后,我们要测试我们新创建的组件。 为此,我们设置了一个简单的JSF2 webapp项目,并将以下代码段添加到web.xml中,以声明我们要使用自定义组件:

<context-param>
		<param-name>facelets.FACELETS_LIBRARIES</param-name>
		<param-value>/META-INF/jsf-component.taglib.xml</param-value>
	</context-param>

现在,我们可以编写一个简单的JSF页面,该页面引用我们的新标记:

<!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:mdw="http://martinsdeveloperworld.wordpress.com">
<h:head>
<title>Hello JSF 2!</title>
</h:head>
<h:body>
	<h2>Hello World!</h2>
	<mdw:helloWorld firstName="Martin" lastName="Developer"/>
</h:body>
</html>

当我们将此应用程序部署到JBoss Application Server并调用相应的URL时,我们将获得以下HTML输出:

<!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">
<head>
	<title>Hello JSF 2!</title>
	<link type="text/css" rel="stylesheet" href="/jsf-component-webapp/faces/javax.faces.resource/css/jsf-component.css" />
</head>
<body>
	<h2>Hello World!</h2>
	<span class="helloWorldClass">Hello Martin Developer!</span>
</body>
</html>

显然,我们可以看到带有CSS类和输出的span标签。 CSS文件在HTML文档的开头引用。


翻译自: https://www.javacodegeeks.com/2013/11/implementing-a-custom-jsf-2-0-component-with-maven.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值