如何在Tomcat上安装和使用CDI?

Rog*_*tes 30 jsf tomcat cdi jsf-2.2

我正在创建我的第一个项目Java EE 7,但我遇到了麻烦.感谢任何帮助.

  • Tomcat 7.0.34
  • JSF 2.2
  • Primefaces 3.5
  • JavaEE的-API-7.0.jar

应用程序启动时,Tomcat日志显示以下消息:

"validateJarFile (C:\...\build\web\WEB-INF\lib\javaee-api-7.0.jar)-jar not loaded. See Servlet 2.3 Spec, section 9.7.2. Offending class: javax/servlet/Servlet .class"
Run Code Online (Sandbox Code Playgroud)

当我点击调用托管bean的按钮时,我收到错误:

Advertência: /index.xhtml @18,66 value="#{indexMB.user}": Target Unreachable, identifier 'indexMB' resolved to null
javax.el.PropertyNotFoundException: /index.xhtml @18,66 value="#{indexMB.user}": Target Unreachable, identifier 'indexMB' resolved to null
Run Code Online (Sandbox Code Playgroud)

IndexMB

@Named("indexMB")
@RequestScoped
public class IndexMB {

private String password;
private String user;

public String loginTest(){
    return (this.user.equals("admin") ? "adminPage" : "inOutPage");
}

// getters and setters
}
Run Code Online (Sandbox Code Playgroud)

的index.xhtml

<html ...>

<f:loadBundle basename="i18n" var="bundle" />
<h:head>
    <title>#{bundle['index_title']}</title>
</h:head>
<h:body>
    #{bundle['index_appname']}
    <br />
    <h:form id="frmIndex">
        <p:panelGrid columns="2">
            <p:outputLabel for="user" value="#{bundle['lblUser']}" />
            <p:inputText id="user" value="#{indexMB.user}" />

            <p:outputLabel for="password" value="#{bundle['lblPassword']}" />
            <p:password id="password" value="#{indexMB.password}" />
        </p:panelGrid>
        <p:commandButton action="#{indexMB.loginTest}" value="#{bundle['btn_login']}" />
    </h:form> 
</h:body>
Run Code Online (Sandbox Code Playgroud)

faces-config.xml中

<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">

<application>
    <locale-config>
        <default-locale>pt_BR</default-locale>
        <supported-locale>en</supported-locale>
        <supported-locale>fr</supported-locale>
    </locale-config>
</application>
Run Code Online (Sandbox Code Playgroud)

这些主题对我没有帮助:

Bal*_*usC 65

Tomcat作为一个准系统JSP/Servlet容器不支持CDI开箱即用.你是怎么安装CDI的?你真的降javaee-api.jar/WEB-INF/lib只是为了让你的代码编译?哦,请不,这不是正确的方法.Java EE API JAR仅包含API类,而不包含具体实现.摆脱整个JAR.它可能导致许多其他可移植性问题,如本答案中所述:如何在Eclipse项目中导入javax.servlet API?您应该实际安装具体的实现以及特定的API.

你有2个选择:

  1. 删除Tomcat并寻找真正的Java EE容器.当您使用Tomcat时,请转到TomEE.这非常简单,下载TomEE Web配置文件zip文件,将其解压缩并将其集成到Eclipse中,与Tomcat完全相同.不要忘记从webapp中删除Java EE JAR文件,并将项目属性中的Targeted Runtime属性从Tomcat更改为TomEE,以便正确解析Java EE依赖项.

    无需额外的JAR或配置.您甚至可以从webapp中删除JSF JAR.TomEE作为一个真正的Java EE容器已经提供了JSF和CDI.如果你正在使用Maven,下面的坐标就足够了.

    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <version><!-- 8.0 or 7.0 or 6.0 --></version>
        <scope>provided</scope>
    </dependency>
    
    Run Code Online (Sandbox Code Playgroud)

    请注意其重要性provided及其含义,如"目标运行时已提供此功能".另请参见如何通过Maven正确安装和配置JSF库?.


  2. 在Tomcat上安装真正的CDI实现.Weld是可用的CDI实现之一.在Weld安装指南中,您可以找到如何将其集成到Tomcat中的说明.为了完整性和未来参考,以下是步骤:

    1. 放入weld-servlet-shaded.jarwebapp /WEB-INF/lib.如果您正在使用Maven,请使用此坐标:

      <dependency>
          <groupId>org.jboss.weld.servlet</groupId>
          <artifactId>weld-servlet-shaded</artifactId>
          <version>3.0.5.Final</version>
      </dependency>
      
      Run Code Online (Sandbox Code Playgroud)
    2. /META-INF/context.xml使用以下内容在webapp中创建文件:

      <Context>
          <Resource name="BeanManager" 
              auth="Container"
              type="javax.enterprise.inject.spi.BeanManager"
              factory="org.jboss.weld.resources.ManagerObjectFactory"/>
      </Context>
      
      Run Code Online (Sandbox Code Playgroud)

      请注意,当您使用Mojarra 2.2.11或更新版本时,此步骤并非绝对必要,因为它可以ServletContext在JNDI中缺席时找到它.

    3. /WEB-INF/beans.xml在webapp中创建一个空文件.

    就是这样(注意:在较旧的Weld Servlet版本中,你需要显式注册CDI bean管理器和Weld监听器web.xml,但这对当前版本来说是不必要的).

    如果您更喜欢Weld上面的OpenWebBeans作为CDI实现,请访问此博客以获取详细的Maven安装说明:如何在Tomcat中安装CDI?


具体问题无关,Tomcat 7的JSP/Servlet API 符合Java EE 7的API,而是符合Java EE 6(Servlet 3.0/JSP 2.2).如果您希望Tomcat等效于Java EE 7(Servlet 3.1/JSP 2.3),那么您应该查看Tomcat 8.另请参阅Apache Tomcat版本矩阵.

  • 至于TomEE,它已经捆绑了JSF (MyFaces)。如果您仍然在您的 web 应用程序中捆绑另一个 JSF impl,那么您就会得到这个异常。只需从您的 Web 应用程序中删除 JSF JAR。至于 GlassFish 4,不确定,但这也可能是由脏类路径引起的。 (2认同)

归档时间:

查看次数:

29316 次

最近记录:

7 年 前