13

我的基于 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 应该在部署时扫描我的 War 中的 jar 并检测哪些类上有注释(并相应地自动配置应用程序)。我的问题是 JSF 显然没有检测到我拥有哪些运动注释的类。

War 项目有我所有的 .xhtml 文件以及项目的 faces-config.xml,我的 Jar 项目有我所有的 faces 相关 Java 代码(动作 bean、托管 bean、自定义转换器等)

4

2 回答 2

30

是的,我会立即回答我自己的问题,因为我已经花了一周的时间在桌子上敲打我的头,我只是在通过 JSF 2.0 RI (Mojarra) 调试后才发现我的问题,看看它在做什么。

基本上,注解扫描器只查阅 WAR 的 /WEB-INF/classes .class 文件以获取注解(假设您在 /WEB-INF 中有 faces-config.xml)。如果您将代码保存在单独的 Jar 文件中,并希望扫描 /WEB-INF/lib .jar 文件中的 .class 文件以查找注释,则该 Jar 的 META-INF 文件夹中必须有 faces-config.xml。您放入 jar 中的 faces-config.xml 可以是空的,它只需要存在即可,否则注释扫描器将跳过您的 jar,就像它是剩下的肉饼一样。

空的 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。所以,只是回顾一下。您的 War 中的 faces-config.xml 进入 WEB-INF。每个 Jar 文件中的可能为空的注释扫描器启用 faces-config.xml 进入该 Jar 的META -INF。

如果您想知道为什么行为必须如此疯狂,那是因为 JSF 配置可以通过这种方式分散在第一方和第三方库中。而且,如果您想知道 jar 中的 faces-config.xml 的全部存在是一个因素,那么我的观点是,这就是 Jar 对引擎感兴趣的标志 - 并且没有 faces-config .xml 意味着注释扫描器可以避免该 jar 并在部署时节省处理。如果在某处能更清楚地解释这些扫描仪语义,那会很好,<expletives deleted>!

以下博客文章对我理解代码的作用非常有用:

http://one-size-doesnt-fit-all.blogspot.com/2007/01/using-multiple-faces-configxml-files-in.html

我真的希望这可以使某人免于像我一样遭受一周的痛苦。

于 2010-06-07T05:46:47.947 回答
5

一个 JAR 包含 EJB 和 FacesBeans:

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

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

于 2011-06-30T15:41:26.210 回答