在解析之前执行代码

时间:2017-09-06 20:48:43

标签: jsf jsf-2 localization

在jsf解析之前可以执行一些java代码吗?

我的用例:让我们说,我在外部属性文件中定义了几个outputText

<h:outputText value="#{msg['my.example.label']}"/>

在每个outputText之后我想要另一个值为msg的outputText(用于调试目的)。

<h:outputText value="#{msg['my.example.label']}"/>
<h:outputText value="my.example.label"/>

而且我不想在每个标签上添加手册,但要编写一些代码,可以检测#{msg[...]}个片段,提取密钥并在原始代码后添加。

JSF可以吗?

1 个答案:

答案 0 :(得分:0)

您可以创建扩展HtmlOutputText<h:outputText>)的自定义组件。这里有一个我用于类似的东西的例子,但显示所有表达式(bean,resurces和隐含对象),而不仅仅是资源变量:

自定义组件:

@FacesComponent("com.mycompany.component.CustomOutputText")
public class CustomOutputText extends HtmlOutputText {

    public static final String ATTRIBUTE_VALUE = "value";

    @Override
    public String getFamily() {
        return "com.mycompany.component.customFamily";
    }

    public String getValue() {
        return (String) getStateHelper().eval(ATTRIBUTE_VALUE);
    }

    public String getNotEvalValue() {
        return (String) getValueExpression(ATTRIBUTE_VALUE).getExpressionString();
    }

    public void setValue(String value) {
        getStateHelper().put(ATTRIBUTE_VALUE, value);
    }

    @Override
    public void encodeBegin(FacesContext context) throws IOException {
        ResponseWriter writer = context.getResponseWriter();

        writer.startElement("span", this);
        writer.append(getValue());
        writer.endElement("span");

        writer.startElement("p", this);
        writer.append("[expression: " + getNotEvalValue() + "]");
        writer.endElement("p");
    }
}

taglib:

<namespace>http://com.mycompany/custom-components</namespace>
<tag>
    <tag-name>customOutputText</tag-name>
    <component>
        <component-type>com.mycompany.component.CustomOutputText</component-type>
        <renderer-type>com.mycompany.component.CustomOutputText</renderer-type>
    </component>
    <attribute>
        <name>value</name>
        <required>true</required>
        <type>java.lang.String</type>
    </attribute>
</tag>

在web.xml中注册:

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

并且,测试一个简单的托管bean(在本例中为CDI)

@Named
@ViewScoped
public class MyBean implements Serializable {

    private static final long serialVersionUID = 1L;

    public String getSample() {
        return "sample text from bean";
    }   
}

在xhtml中包含taglib,并使用组件:

<custom:customOutputText value="#{myBean.sample}" />

输出是:

sample text from bean

[expression: #{myBean.sample}]

请注意,该组件将生成2个html标记,1个<span>和1个<p>,请考虑这适用于app css样式。