如何使用注释而不是XML在嵌入式Tomcat中创建自定义组件标记

时间:2015-02-16 21:00:55

标签: jsf annotations jsf-2.2 custom-component embedded-tomcat-8

编辑:重现此问题所需的唯一技术是JSF 2.2Spring Boot 1.2.1 +其嵌入式Tomcat 8.0.5服务器。此问题中列出的所有其他内容仅仅是为了说明我使用的技术背景。

  

更新#2:随着BalusC的想法,我将我的示例自定义组件移植到准系统Servlet 3.1 + JSF 2.2应用程序中。您可以在Github here.

上找到它的代码      

这个简单的案例没有表现出我在这里描述的问题。 @FacesComponent注释有效。这很大程度上意味着问题是由Spring 4.1.2Spring Boot本身造成的。它已经迟到了,所以明天我会进一步调查。

TL; DR:我想使用@FacesComponent及其属性来替换foundation-components-html.taglib.xml中的<component>faces-config.xml条目

我目前使用XML定义在我的项目中使用自定义组件。我最近了解到JSF 2.2引入了feature,它完全消除了对XML的需求。我很乐意使用它,但是当我纯粹使用注释时,JSF会忽略它们。原始标记显示在我的HTML中。

(即<custom:paragraph></custom:paragraph>

我已经在我的沙箱中演示了这个问题,我一直在Github上托管。如果你想解决这个问题,我将在这篇帖子的底部解释一下。

您需要做的就是删除foundation-components-html.taglib.xml,并注明faces-config.xml的{​​{1}}条目&gt;并运行应用程序以遇到问题。我把它留在了“功能”中。状态,以便任何希望提供帮助的人都有一个简单,可验证的正确起点。只需点击http://localhost:8080

即可
  

使用的技术:

     
      
  • Spring Boot 1.2.1

  •   
  • JSF 2.2来自Mojarra 2.2.6

  •   
  • 嵌入式Tomcat 8.0.5

  •   

注意:请记住,此设置目前有效,但它在taglib和faces-config条目上运行!我的问题是如何使用<component

中的最新功能删除这些依赖项

Full Project

Custom Component

JSF 2.2

Taglib Definition

package foundation.components;

import java.io.IOException;

import javax.faces.component.FacesComponent;

import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;

/**
 * The Paragraph Component
 * @author Seth Ellison
 */
@FacesComponent(value=UIParagraph.COMPONENT_TYPE, createTag=true, tagName="paragraph", namespace="http://www.blah.com/components/html")
public class UIParagraph extends UIComponentBase {

public static final String COMPONENT_TYPE = "foundation.components.Paragraph";

private String value;
private String styleClass;

@Override
public void encodeBegin(final FacesContext facesContext) throws IOException {

    // Encode Implementation Omitted for Brevity. 
}

@Override
public String getFamily() {        
    return "blah.components.family";
}

// Getters/Setters...

}

Faces Config

<facelet-taglib 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-facelettaglibrary_2_2.xsd">

    <namespace>http://www.blah.com/components/html</namespace>

    <tag>
        <tag-name>paragraph</tag-name>
        <component>
            <component-type>foundation.components.Paragraph</component-type>
        </component>
    </tag>
</facelet-taglib>

XHTML Template(为清晰起见而被删除)

<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" metadata-complete="false">

    <component>
        <component-type>foundation.components.Paragraph</component-type>
        <component-class>foundation.components.UIParagraph</component-class>
    </component>  
</faces-config>

如果你想运行它,最简单的方法是下载Spring Tool Suite,从Github获取代码,右键单击该项目,然后将其作为Spring Boot App运行。当JPA配置启动时,您将收到连接错误,因为您(可能)没有运行本地MySQL服务器。别担心这个。根本不需要访问索引页面并查看标签状态。我经常运行应用程序,没有数据库启动没有任何不良影响。最后,为了让PrettyFaces能够很好地使用Spring Boot,你必须创建一个符号链接或从目标/类到硬链接到WEB-INF / - PrettyFaces被编码为查看WEB-INF / classes或WEB-INF / lib扫描注释时。

BalusC的片段

此函数存在于标有<html xmlns="http://www.w3.org/1999/xhtml" xmlns:jsf="http://xmlns.jcp.org/jsf" xmlns:custom="http://www.blah.com/components/html"> <head jsf:id="head"></head> <body jsf:id="body"> <custom:paragraph value="This is a template for a simple marketing or informational website. It includes a large callout called a jumbotron and three supporting pieces of content. Use it as a starting point to create something more unique." /> </body> </html> 并实现@Configuration

的类中
ServletContextAware

1 个答案:

答案 0 :(得分:1)

好吧,我弄明白是什么导致了这个问题。

今天早上,我坐下来思考我的Servlet 3.1版代码和破碎的Spring Boot版本之间的差异。主要区别在于代码的运行方式。嵌入式服务器与独立服务器。

  

Spring Boot的嵌入式Tomcat服务器是原因。

当我按照this answer切换沙盒时,所有内容都正常打开,我的自定义组件完全不依赖于@FacesComponent注释!

我认为这与嵌入式服务器上启动后组织类的方式有关,而与Pivotal Tomcat服务器的离散部署有关。在这种情况下,JSF的注释扫描器似乎只是忽略了注释。