大きな質問が 2 つあります。
h:outputText の機能を拡張する単純な JSF コンポーネントを作成しようとしています。
このガイドに従ってみましたが、どういうわけか正しいことをしました。
taglib を正常にインポートでき、すべて問題ないように見えますが、それを使用すると、次の例外が発生しました。
javax.servlet.ServletException: 式エラー: 名前付きオブジェクト: EmoticonOutputTextTag が見つかりません。
これを解決するにはどうすればよいですか?
すべてのコードを添付しています。
ValueExpression
これは添付するコードに関連しているため、inputText
プロパティを有効にするにはどうすればよいですか? オラクルのガイドは役に立ちませんでした:/
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);
}
}
}
ご覧のとおり、コードは非常に単純です (実際には、テストすることができず、カスタム コンポーネントを使用するのは初めてなので、どこが間違っているのかさえわかりません!)
私を助けることができる人はいますか?