【问题标题】:Custom JSF1 component doesn't work in JSF2自定义 JSF1 组件在 JSF2 中不起作用
【发布时间】:2013-01-02 13:33:06
【问题描述】:

我用 JSF1 编写了一个简单的自定义组件,它运行良好。 但是当我在 JSF2 中使用它时,它不起作用。以下是我的使用方法:

<?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:d="http://jsftutorials.com/"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">
    <h:body>
        <f:view>
          <d:ticker>Hello World!</d:ticker>
        </f:view>
    </h:body>
</html>

下面是为 JSF1 创建组件的方式:

faces-config.xml

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

<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
    version="2.0">
    <component>
        <component-type>ticker</component-type>
        <component-class>ticker.UITicker</component-class>
    </component>
</faces-config>

ticker.tld

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
                          "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
    <tlib-version>1.0</tlib-version>
    <jsp-version>1.2</jsp-version>
    <short-name>d</short-name>
    <uri>http://jsftutorials.com/</uri>
    <tag>
        <name>ticker</name>
        <tag-class>ticker.TickerTag</tag-class>
        <body-content>JSP</body-content>
    </tag>
</taglib>

TickerTag.java

package ticker;

import javax.faces.component.UIComponent;
import javax.faces.webapp.UIComponentTag;

@SuppressWarnings("deprecation")
public class TickerTag extends UIComponentTag {

    public void release() {
        super.release();
    }

    protected void setProperties(UIComponent component) {
        super.setProperties(component);

    }

    public String getComponentType() {
        return "ticker";
    }

    public String getRendererType() {
        return null;
    }
}

UITicker.java

package ticker;

import java.io.IOException;

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

public class UITicker extends UIOutput {

    public void encodeBegin(FacesContext context) throws IOException {
        ResponseWriter writer = context.getResponseWriter();
        writer.startElement("div", this);
    }

    public void encodeEnd(FacesContext context) throws IOException {
        ResponseWriter writer = context.getResponseWriter();
        writer.endElement("div");
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    <display-name></display-name>

    <welcome-file-list>
        <welcome-file>index.xhtml</welcome-file>
    </welcome-file-list>

    <context-param>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>server</param-value>
    </context-param>

    <context-param>
        <param-name>javax.faces.CONFIG_FILES</param-name>
        <param-value>/WEB-INF/faces-config.xml</param-value>
    </context-param>

    <listener>
        <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
    </listener>

    <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>*.faces</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
</web-app>

我应该改变什么才能让它在 JSF2 中工作?

【问题讨论】:

    标签: jsf-2 custom-component


    【解决方案1】:

    这是一个 JSP 标签。 JSP 在 JSF 2.0 中已被弃用,后来被 Facelets (XHTML) 取代。您确实在使用 Facelets 而不是 JSP。只有当您将 JSF2 与旧版 JSP 而不是 Facelets 一起使用时,您的组件才能工作。您需要将旧的 JSP 标记更改为 Facelets 标记。

    以下是您需要进行的更改:

    • faces-config.xml:完全删除&lt;component&gt;

    • ticker.tld:将其重命名为ticker.taglib.xml,并将内容替换为:

      <?xml version="1.0" encoding="UTF-8"?>
      <facelet-taglib 
          xmlns="http://java.sun.com/xml/ns/javaee"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
          version="2.0">
          <namespace>http://jsftutorials.com</namespace>
          <tag>
              <tag-name>ticker</tag-name>
              <component>
                  <component-type>ticker</component-type>
              </component>
          </tag>
      </facelet-taglib>
      
    • TickerTag.java:完全删除它。 Facelets 不需要它。

    • UITicker.java:在类上添加以下注解(这将替换faces-config.xml 中的&lt;component&gt; 条目)

      @FacesComponent("ticker")
      public class UITicker extends UIOutput {
      

      (注意:注解值必须匹配 taglib XML 文件中的&lt;component-type&gt;,而不是&lt;tag-name&gt;

      由于UIOutput 默认情况下不允许文本子级,因此表示&lt;div&gt; 组件基本上是错误的选择。你最好改为扩展UIPanel

      @FacesComponent("ticker")
      public class UITicker extends UIPanel {
      

      (请注意,标准的 &lt;h:panelGroup layout="block"&gt; 组件已经像这样渲染了 &lt;div&gt;;我知道您只是在学习 JSF,但为了确定您确实在寻找 JSF 组件的情况呈现一个 div)

    • web.xml:添加以下上下文参数:

      <context-param>
          <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
          <param-value>/WEB-INF/ticker.taglib.xml</param-value>
      </context-param>
      

      (注意:当您在/WEB-INF/lib 中将taglib 作为JAR 文件提供并且在JAR 的/META-INF 中有.taglib.xml 文件时,这是不必要的)

    在阅读/学习有关 JSF 的内容时,请确保您阅读的是针对 JSF2 而不是针对 JSF1 的正确教程/资源。很多很多事情都是以不同的方式完成的。

    另见:

    【讨论】:

    • 非常感谢,我按照你说的改变了我的项目。但它不再起作用:(。我应该定义 d:ticker 吗?我删除了 TickerTag.java,我添加了 @FacesComponent 并删除了 faces-config.xml 配置,我在 web.xml 中添加了 context-param 配置,但它没有不行!
    • 啊,这又是一个与扩展UIOutput 相关的特定问题。默认情况下,它不允许文本子项(&lt;div&gt; 肯定在生成的 HTML 输出中,但文本“Hello World”根本就没有)。你最好扩展UIPanel。我会编辑答案。
    • 谢谢,我将 UIOutput 更改为 UIPanel 但它不再起作用了,我认为我的问题不是那个。这是我运行后的页面源 -> dpaste.com/861112。 d:ticker 和命名空间未转换为 html!
    • 嗯,你有没有按照ticker.tld修改步骤?您在第一条评论中没有说明任何内容。没有正确的 taglib.xml 文件会导致这个问题。
    • 我在 WEB-INF 中有ticker.taglib.xml 和这个来源 -> dpaste.com/861113
    猜你喜欢
    • 2017-10-10
    • 1970-01-01
    • 2011-09-03
    • 1970-01-01
    • 1970-01-01
    • 2012-12-07
    • 2012-01-29
    • 1970-01-01
    • 2011-12-05
    相关资源
    最近更新 更多