为什么JSF 2.0 RI(Mojarra)没有扫描我的班级注释?

时间:2010-06-07 05:32:05

标签: jsf jsf-2 annotations

我在基于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,自定义转换器等)

2 个答案:

答案 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)

JAR包含EJB和&amp; FacesBeans:

如果包含Faces Beans的JAR已经捆绑在一个耳中(因为它包含EJB),那么你还必须将相同的JAR放在战争的WEB-INF / lib中(在META-INF目录中添加faces-config.xml之上),以便容器识别JSF 2.0 Annotations。

  

在这种情况下,最好创建两个JARS,一个用于EJB,一个用于FacesBeans。