我在基于Eclipse的JSF项目中有一个War and Jar项目。我决定使用注释来声明我的FacesConverter(在众多其他事物中),而不是使用我的faces-config.xml声明它。
@FacesConverter(value="passwordFieldStringConverter")
public class PasswordFieldStringConverter implements Converter {
public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) throws ConverterException {
try {
return arg2.getBytes("UTF-16BE");
}
catch(UnsupportedEncodingException uee) {
Assert.impossibleException(uee);
}
return(null);
}
public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) throws ConverterException {
try {
return new String((byte[]) arg2, "UTF-16BE");
}
catch(UnsupportedEncodingException uee) {
Assert.impossibleException(uee);
}
return(null);
}
}
然后我直接在我的.xhtml中使用 passwordFieldStringConverter :
<?xml version="1.0" encoding="UTF-8" ?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:sec="http://www.springframework.org/security/facelets/tags">
<ui:composition>
<f:view>
<f:loadBundle basename="landingPage.bundle" var="bundle" />
<ui:decorate template="/WEB-INF/jsf_helpers/htmlShell.xhtml">
<ui:param name="PageTitleParam" value="#{bundle.pageTitle}" />
<h:form>
<h:dataTable var="rowVar" value="#{userListContainer.users}">
<f:facet name="header"><h:outputText value="Users you are currently managing:" /></f:facet>
<h:column>
<f:facet name="header">
<h:outputText value="Screen Name" />
</f:facet>
<h:outputText value="#{rowVar.screenName}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Password" />
</f:facet>
<h:outputText value="#{rowVar.password}">
<f:converter converterId="passwordFieldStringConverter" />
</h:outputText>
</h:column>
</h:dataTable>
</h:form>
</ui:decorate>
</f:view>
</ui:composition>
</html>
JSF应该在部署时扫描我的战争中的jar并检测哪些类具有注释(并相应地自动配置应用程序)。我的问题是,JSF显然没有检测到我所拥有的带有注释的类。
War项目包含我的所有.xhtml文件以及项目的faces-config.xml,我的Jar项目有我所有面孔相关的Java代码(动作bean,托管bean,自定义转换器等)
答案 0 :(得分:29)
是的,我现在正在回答我自己的问题,因为我已经花了一个星期的时间在桌子上敲我的头,我只是在通过JSF 2.0 RI(Mojarra)进行调试之后才发现我的问题,看看它在做什么。 / p>
基本上,注释扫描程序仅查询WAR的/ WEB-INF / classes .class文件以获取注释(假设您在/ WEB-INF中有faces-config.xml)。如果您将代码保存在单独的Jar文件中,并且希望扫描/ WEB-INF / lib .jar文件中的.class文件以进行注释,那么必须在Jar的META中有faces-config.xml- INF文件夹。你插入罐子里的faces-config.xml可能是空的,它只需要在那里,否则注释扫描器会像你的剩余肉饼一样调制你的罐子。
清空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 /WEB-INF/schema/web-facesconfig_2_0.xsd"
version="2.0" metadata-complete="false">
<!-- This file must be present with our jar, even if it is empty. Otherwise, our Java annotations won't get scanned! -->
</faces-config>
我知道在那里抛出了很多-INF。所以,回顾一下。你战争中的faces-config.xml在WEB-INF中。您的每个Jar文件中可能为空的注释扫描器启用faces-config.xml都在Jar的 META -INF中。
如果你想知道为什么这种行为必须如此坚定,那是因为JSF配置可以通过这种方式分散和分散在第一方和第三方库中。如果你想知道jar中的faces-config.xml的整体存在是一个因素,那么,我的意见是,这标志着Jar对引擎很有趣 - 并且没有faces-config .xml表示注释扫描程序可以避免该jar并在部署时节省处理。如果那些扫描仪语义在某处更清楚地解释,那就好了,&lt; expletives deleted&gt;!
以下博客文章对我理解代码的作用非常有用:
http://one-size-doesnt-fit-all.blogspot.com/2007/01/using-multiple-faces-configxml-files-in.html
我真的希望这可以拯救像我一样痛苦一周的人。
答案 1 :(得分:4)
如果包含Faces Beans的JAR已经捆绑在一个耳中(因为它包含EJB),那么你还必须将相同的JAR放在战争的WEB-INF / lib中(在META-INF目录中添加faces-config.xml之上),以便容器识别JSF 2.0 Annotations。
在这种情况下,最好创建两个JARS,一个用于EJB,一个用于FacesBeans。