0

我正在尝试在已弃用的 ManagedBean/ManagedProperty 注释上使用 CDI,并在一个非常简单的 Web 应用程序中遇到此异常:

Error creating bean with name 'navigationController': Unsatisfied dependency expressed through field 'message'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type 'java.lang.String' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject(), @org.omnifaces.cdi.Param(validatorAttributes=[], validatorMessage=, validators=[], converter=, pathIndex=-1, converterAttributes=[], converterClass=interface javax.faces.convert.Converter, label=, overrideGlobalBeanValidationDisabled=false, required=false, disableBeanValidation=false, name=, validatorClasses=[], converterMessage=, requiredMessage=)}

我正在尝试在http://showcase.omnifaces.org/cdi/Param的 OmniFaces 展示中遵循 @Param 的示例。

我把http://localhost:8080/jsfSpringBootApp/nav.xhtml?message=My+message+from+MessageSource放到一个页面上。我的理解是 NavigationController bean 应该在导航到 nav.xhtml 时创建,并且消息字段将填充从请求参数中获取的值。

IntellliJ 还抱怨 @Param 注释:

找不到使用@Param 限定的bean

感谢您的任何帮助。我被困在接下来要尝试的事情上。

整个项目位于https://david_maffitt@bitbucket.org/david_maffitt/jsfspringbootapp.git

nav.xhtml 的内容是

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:p="http://primefaces.org/ui">

<h:body >
<f:view>

    <p:panel id="myPanelId" header="My Panel" style="margin-bottom:20px">
        <h:outputText value="My text output." />
        <h:outputText value="My text output from params: #{navigationController.action}" />
    </p:panel>

</f:view>
</h:body>
</html>

NavigationController.java 的内容是包 org.nrg.cap.jsfWebApp;

import org.omnifaces.cdi.Param;

import javax.enterprise.context.RequestScoped;
import javax.faces.annotation.ManagedProperty;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.Serializable;

//@Component
//@Scope("request")
@Named
@RequestScoped
public class NavigationController implements Serializable {

    @Inject @Param
    private String message;


    public String showPage() {
        return ("fubar".equals(message))? "fubar": "snafu";
    }

    public void setAction(String message) {
        this.message = message;
    }
    public String getAction() {
        return message;
    }
}

pom.xml 是

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.nrg.cap</groupId>
    <artifactId>jsfSpringBootApp</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>JSF Spring Boot WebApp</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>

        <joinfaces.version>4.0.0</joinfaces.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.1.RELEASE</version>
        <relativePath/>
    </parent>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.joinfaces</groupId>
                <artifactId>joinfaces-dependencies</artifactId>
                <version>${joinfaces.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.joinfaces</groupId>
            <artifactId>primefaces-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.joinfaces</groupId>
            <artifactId>omnifaces3-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.enterprise</groupId>
            <artifactId>cdi-api</artifactId>
            <version>2.0.SP1</version>
        </dependency>
    </dependencies>

</project>

我发现我必须添加 cdi-api 的依赖项,因为我正在部署到没有 cdi 的 tomcat 9.0.13。pom 来自 joinfaces 项目。

4

3 回答 3

0

OmniFaces@Param注释是基于 CDI(实现)的注释。尽管 Spring 可以使用@Namedand@Inject来替代Spring Framework 中 @Inject@Component和@Autowired@Autowired区别是什么?在什么条件下使用哪一种?, (你确实需要添加一个'CDI'api)它仍然不能使 Spring 成为一个真正的 CDI DI 容器。

这意味着@ParamSpring 不会像 OmniFaces/CDI 所预期的那样使用/解释它,并且 Spring 会尝试找到一个带有@Param注释的真实 bean,该注释当然不存在。因此你会得到你得到的错误。

最好的解决方案超出了这个问题的范围,因为它“主要基于意见”,但基本上它们归结为两个选项。

我不会在这里说第一个有我的偏好......嗯,刚刚做了......

于 2018-12-17T11:37:47.910 回答
-1

您应该在 bean.xml 集bean-discovery-mode="all"> https://github.com/armdev/reactive-javaserver-faces/blob/master/reactive-jsf/src/main/webapp/WEB-INF/beans.xml中进行更改

于 2018-12-16T18:01:58.277 回答
-1

我看得更深:基于Joinfaces的项目,这意味着项目的基础是Spring boot。因此,在将 CDI 用于 DI 之后。将 CDI 注释更改为 Spring DI - @Inject 更改为 @Autowired。加入两个不同的 DI 原则并不是一个好主意。

于 2018-12-16T21:10:59.810 回答