JSF自定义组件错误+ ValueExpression

时间:2012-04-29 18:31:00

标签: jsf facelets el custom-component

我有两个大问题!

我正在尝试创建一个简单的JSF组件来扩展h:outputText的功能。

我已经尝试过这个guide并且我做了一些正确的事。

我可以成功导入我的taglib,一切似乎都很好,但是当我使用它时,我遇到了这个例外:

  

javax.servlet.ServletException:Expression Error:命名对象:找不到EmoticonOutputTextTag。

我该怎么做才能解决这个问题?

我附上了所有代码。

由于这个与我附加的代码有关,如何为ValueExpression属性启用inputText? Oracle的指南没有帮助:/

META-INF / EmoticonOutputText.tld

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" 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-jsptaglibrary_2_1.xsd">
  <tlib-version>1.0</tlib-version>
  <short-name>eot</short-name>
  <uri>com.unilife.emoticonOutputText</uri>
  <tag>
    <name>EmoticonOutputText</name>
    <tag-class>com.unilife.emoticonOutputText.EmoticonOutputTextTag</tag-class>
    <body-content>scriptless</body-content>
    <attribute>
      <name>style</name>
      <rtexprvalue>true</rtexprvalue>
      <type>java.lang.String</type>
    </attribute>
    <attribute>
      <name>styleClass</name>
      <rtexprvalue>true</rtexprvalue>
      <type>java.lang.String</type>
    </attribute>
    <attribute>
      <name>inputText</name>
      <required>true</required>
      <rtexprvalue>true</rtexprvalue>
      <type>java.lang.String</type>
    </attribute>
  </tag>
</taglib>

/META-INF/faces-config.xml

    <?xml version='1.0' encoding='UTF-8'?>
<faces-config version="1.2" 
                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_1_2.xsd">
    <component>
        <component-type>
            com.unilife.emoticonoutputtext
        </component-type>
        <component-class>
            com.unilife.emoticonOutputText.EmoticonOutputText
        </component-class>
    </component>

    <render-kit>
        <renderer>
            <description>
                OutputText che permette il rendering di emoticons al posto delle combinazioni di tasti
            </description>
            <component-family>
                javax.faces.Output
            </component-family>
            <renderer-type>
                com.unilife.emoticonoutputtext
            </renderer-type>
            <renderer-class>
                com.unilife.emoticonOutputText.EmoticonOutputTextRenderer
            </renderer-class>
        </renderer>
    </render-kit>  
</faces-config>

/META-INF/unilife.taglib.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE facelet-taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
"http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
    <namespace>http://unilife.it/tags</namespace>
    <tag>
        <tag-name>EmoticonOutputText</tag-name>
        <description>
            OutputText con la possibilità di mostrare Emoticons
        </description>
        <component>
            <component-type>EmoticonOutputTextTag</component-type>
            <renderer-type>EmoticonOutputTextRenderer</renderer-type>
        </component>
        <attribute>
            <name>style</name>            
            <type>java.lang.String</type>
        </attribute>
        <attribute>
            <name>styleClass</name>            
            <type>java.lang.String</type>
        </attribute>
        <attribute>
            <name>inputText</name>
            <required>true</required>            
            <type>java.lang.String</type>
        </attribute>
    </tag>
</facelet-taglib>

com.unilife.emoticonOutputText / EmoticonOutputText.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.unilife.emoticonOutputText;

import javax.faces.component.UIOutput;

/**
 *
 * @author stefano
 */
public class EmoticonOutputText extends UIOutput {

    private static final String COMP_FAMILY = "javax.faces.Output";

    /**
     * Get the value of COMPONENT_FAMILY
     *
     * @return the value of COMPONENT_FAMILY
     */
    @Override
    public String getFamily() {
        return COMP_FAMILY;
    }

    private static final String RENDERER_TYPE = "com.unilife.emoticonoutputtext";

    /**
     * Get the value of RENDERER_TYPE
     *
     * @return the value of RENDERER_TYPE
     */
    @Override
    public String getRendererType() {
        return RENDERER_TYPE;
    }


    private String style;

    /**
     * Get the value of style
     *
     * @return the value of style
     */
    public String getStyle() {
        return style;
    }

    /**
     * Set the value of style
     *
     * @param style new value of style
     */
    public void setStyle(String style) {
        this.style = style;
    }
    private String styleClass;

    /**
     * Get the value of styleClass
     *
     * @return the value of styleClass
     */
    public String getStyleClass() {
        return styleClass;
    }

    /**
     * Set the value of styleClass
     *
     * @param styleClass new value of styleClass
     */
    public void setStyleClass(String styleClass) {
        this.styleClass = styleClass;
    }
    private String inputText;

    /**
     * Get the value of inputText
     *
     * @return the value of inputText
     */
    public String getInputText() {
        return inputText;
    }

    /**
     * Set the value of inputText
     *
     * @param inputText new value of inputText
     */
    public void setInputText(String inputText) {
        this.inputText = inputText;
    }
}

com.unilife.emoticonOutputText / EmoticonOutputTextRenderer.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.unilife.emoticonOutputText;

import java.io.IOException;
import java.util.HashMap;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;
import javax.servlet.ServletContext;

/**
 *
 * @author stefano
 */
public class EmoticonOutputTextRenderer extends Renderer {

    //Contiene la corrispondenza tra la stringa da sostituire e il nome dell'emoticon
    private static final HashMap<String, String> emoticons = new HashMap<>();
    //Contiene il percorso dei files delle emoticon
    private final String basePath = ((ServletContext) (FacesContext.getCurrentInstance().getExternalContext().getContext())).getContextPath() + "/resources/images/emoticons/";

    public EmoticonOutputTextRenderer() {
        parseEmoticons();
    }

    private void parseEmoticons(){
        emoticons.put(":)", basePath + "smile");
        emoticons.put(":-)", basePath + "smile");
        emoticons.put("=)", basePath + "smile");
        emoticons.put(":(", basePath + "frown");
        emoticons.put(":-(", basePath + "frown");
        emoticons.put("=(", basePath + "frown");
        emoticons.put(":p", basePath + "tongue");
        emoticons.put(":-p", basePath + "tongue");
        emoticons.put("=p", basePath + "tongue");
        emoticons.put(":D", basePath + "grin");
        emoticons.put(":-D", basePath + "grin");
        emoticons.put("=D", basePath + "grin");
        emoticons.put(":o", basePath + "gasp");
        emoticons.put(":-o", basePath + "gasp");
        emoticons.put(";)", basePath + "wink");
        emoticons.put(";-)", basePath + "wink");
        emoticons.put("8)", basePath + "glasses");
        emoticons.put("8-)", basePath + "glasses");
        emoticons.put("8|", basePath + "sunglasses");
        emoticons.put("8-|", basePath + "glasses");
        emoticons.put(">:(", basePath + "grumpy");
        emoticons.put(">:-(", basePath + "grumpy");
        emoticons.put(":\\", basePath + "unsure");
        emoticons.put(":-\\", basePath + "unsure");
        emoticons.put(":/", basePath + "unsure");
        emoticons.put(":-/", basePath + "unsure");
        emoticons.put(":'(", basePath + "cry");
        emoticons.put("3:)", basePath + "devil");
        emoticons.put("3-:)", basePath + "devil");
        emoticons.put("O:)", basePath + "angel");
        emoticons.put("O-:)", basePath + "angel");
        emoticons.put(":*", basePath + "kiss");
        emoticons.put(":-*", basePath + "kiss");
        emoticons.put("<3", basePath + "heart");
        emoticons.put("^_^", basePath + "kiki");
        emoticons.put("-_-", basePath + "squint");
        emoticons.put("o.O", basePath + "confused");
        emoticons.put("O.o", basePath + "confused");
        emoticons.put(">:O", basePath + "upset");
        emoticons.put(">:-O", basePath + "upset");
        emoticons.put(":v", basePath + "pacman");
        emoticons.put(":3", basePath + "colonthree");
    }

    @Override
    public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
        EmoticonOutputText eot = (EmoticonOutputText) component;
        ResponseWriter writer = context.getResponseWriter();
        //Aggiungiamo l'eventuale stile CSS o direttamente la classe
        writer.startElement("span", null);
        if(eot.getStyle()!=null && !eot.getStyle().isEmpty()){
            writer.writeAttribute("style", eot.getStyle(), null);
        }
        if(eot.getStyleClass()!=null && !eot.getStyleClass().isEmpty()){
            writer.writeAttribute("class", eot.getStyleClass(), null);
        }
        //Andiamo ad effettuare il parse vero e proprio, sostituendo le emoticons come le immagini
        for(String str : eot.getInputText().split(" ")){
            if(emoticons.containsKey(str)){ //Se riconosco l'emoticon allora scrivo l'immagine
                writer.startElement("img", null);
                writer.writeAttribute("src", emoticons.get(str) + ".gif", null);
                writer.endElement("img");
                writer.writeText(" ", null);
            } else { //Altrimenti aggiungo semplicemente la parola
                writer.writeText(str + " ", null);
            }
        }
    }
}

com.unilife.emoticonOutputText / EmoticonOutputTextTag.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.unilife.emoticonOutputText;

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

/**
 *
 * @author stefano
 */
public class EmoticonOutputTextTag extends UIComponentELTag {

    private static final String COMP_TYPE = "com.unilife.emoticonoutputtext";
    private static final String RENDERER_TYPE = "com.unilife.emoticonoutputtext";
    private String style;
    private String styleClass;
    private String inputText;

    public void setStyle(String style) {
        this.style = style;
    }

    public void setStyleClass(String styleClass) {
        this.styleClass = styleClass;
    }

    public void setInputText(String inputText) {
        this.inputText = inputText;
    }

    @Override
    public String getComponentType() {
        return COMP_TYPE;
    }

    @Override
    public String getRendererType() {
        return RENDERER_TYPE;
    }

    @Override
    protected void setProperties(UIComponent component) {
        super.setProperties(component);
        EmoticonOutputText eot = (EmoticonOutputText)component;
        if(style != null){
            eot.setStyle(style);
        }
        if(styleClass != null){
            eot.setStyleClass(styleClass);
        }
        if(inputText != null){
            eot.setInputText(inputText);
        }
    }
}

正如你所看到的,代码非常简单(实际上我甚至不知道我哪里错了,因为我无法测试它,这是我第一次使用自定义组件!)

有没有人可以帮助我?

1 个答案:

答案 0 :(得分:0)

  

表达式错误:命名对象:未找到EmoticonOutputTextTag。

这意味着找不到给定的“组件类型”。标记的getComponentType()返回com.unilife.emoticonoutputtext,但您在标记类名称上错误地注册了它:

<component-type>EmoticonOutputTextTag</component-type>

相应地修复它。我在命名约定方面也会更加一致。我也开始按照完全开始学习本教程,并使用一个工作示例,而不是采用与本教程中提到的不同的方式。