【问题标题】:management sessions JSF 2.3 CDI管理会话 JSF 2.3 CDI
【发布时间】:2018-11-16 01:11:41
【问题描述】:

最近从2.2 升级到JSF 2.3,我注意到@ManagedBean 已被弃用,经过一些研究发现我应该使用CDI-2.0 托管bean 和@Named 注释。 我还将@javax.faces.bean.SessionScoped 迁移到@javax.enterprise.context.SessionScoped

但是我注意到我的 bean 是在服务器启动时创建的!

我使用用户“X”登录并更改了 bean 中的属性。之后我用另一个浏览器登录,我希望在我的属性中找到 null,但我在另一个浏览器中找到了用户“X”的最后一次更新。

我正在使用 myFaces 2.3、omnifaces 3.1,我还在我的 tomcat 中安装了 CDI。我参考了一些博客和一些响应stackoverflow,例如:

http://balusc.omnifaces.org/2013/10/how-to-install-cdi-in-tomcat.html

Migrate JSF managed beans to CDI managed beans

这是我的主要文件:

beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans 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
      http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>

pom.xml:

.....
<dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces</artifactId>
            <version>${primefaces.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.primefaces.extensions</groupId>
            <artifactId>all-themes</artifactId>
            <version>${primefaces.all.themes}</version>
            <scope>compile</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.omnifaces/omnifaces -->
        <dependency>
            <groupId>org.omnifaces</groupId>
            <artifactId>omnifaces</artifactId>
            <version>3.1</version>
        </dependency>

        <dependency>
            <groupId>net.bootsfaces</groupId>
            <artifactId>bootsfaces</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.myfaces.core</groupId>
            <artifactId>myfaces-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.myfaces.core/myfaces-impl -->
        <dependency>
            <groupId>org.apache.myfaces.core</groupId>
            <artifactId>myfaces-impl</artifactId>
            <version>2.3.1</version>
        </dependency>

        <!-- Oracle jstl -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/javax.enterprise/cdi-api -->
        <dependency>
            <groupId>javax.enterprise</groupId>
            <artifactId>cdi-api</artifactId>
            <version>2.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.el</groupId>
            <artifactId>javax.el-api</artifactId>
            <version>3.0.0</version>
            <scope>provided</scope>
        </dependency>
.....

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.webflow</groupId>
            <artifactId>spring-faces</artifactId>
            <version>2.4.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>${spring.version}</version>
        </dependency>

我做错了吗?

【问题讨论】:

  • “我也将@javax.enterprise.context.SessionScoped 迁移到@javax.faces.bean.SessionScoped” -> 你应该反过来。 CDI 版本是javax.entrerprise.context.SessionScoped,所以这是您要使用的版本。
  • @Siliarus:很可能是错字,因为它已被纠正
  • 试试stackoverflow.com/questions/32942876/…,你好像有旧的 beans.xml 定义(如果你需要的话)
  • 我也在使用 Spring,所以我认为问题出在 CDI + Spring

标签: spring jsf cdi tomcat8 myfaces


【解决方案1】:

我发现了问题并实施了解决方案,所以我想与您分享。 问题是spring框架的组件扫描,这里是我的解决方案:

XML:

<context:component-scan base-package="com.example">  
    <context:exclude-filter type="aspectj" expression="com.example.beans.*" />  
</context:component-scan> 

注释:

@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan(basePackages = { "com.example" },
    excludeFilters = @ComponentScan.Filter(type = FilterType.ASPECTJ, pattern = "com.example.beans.*"))
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

第二个问题是关于 Spring 的 bean 注入 CDI bean,所以我在 Spring 和 CDI 之间建立了一座桥梁。

我必须像这样创建一个新注释:

@Qualifier
@Inherited
@Documented
@Retention(RUNTIME)
@Target({ FIELD, TYPE, METHOD, PARAMETER })
public @interface SpringBean {

    String value() default "";
}

和一个制片人:

@SessionScoped
public class CdiBeanFactoryPostProcessor implements Serializable {

    private static final long serialVersionUID = -44416514616012281L;

    @Produces
    public PropertyResourceBundle getBundle() {
        FacesContext context = FacesContext.getCurrentInstance();
        return context.getApplication().evaluateExpressionGet(context, "#{msg}", PropertyResourceBundle.class);
    }

    @Produces
    @SpringBean("example")
    public Example example(InjectionPoint injectionPoint) {
        return (Example) findBean(injectionPoint);
    }


    protected Object findBean(InjectionPoint injectionPoint) {
        Annotated annotated = injectionPoint.getAnnotated();
        SpringBean springBeanAnnotation = annotated.getAnnotation(SpringBean.class);
        ServletContext ctx = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();

        String name = springBeanAnnotation.value();

        if(StringUtils.isNotBlank(name))
            return WebApplicationContextUtils.getRequiredWebApplicationContext(ctx).getBean(name);
        else 
            throw new NoSuchBeanDefinitionException(name, "not found in Context");

    }
}

然后我把它注入到我的 bean 中:

@Named
@SessionScoped
public class ExampleBean extends AbstractManagedBean  implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private static final Logger LOGGER = LogManager.getLogger(ExampleBean.class);

    @Inject
    @SpringBean("example")
    protected transient Example example;

    @Inject
    protected transient PropertyResourceBundle bundle;

..................

}

谢谢!

【讨论】:

  • 感谢分享...但实际上,标记和 çode' 都有些偏离...您使用 spring 的事实比您使用 Tomcat(或 JSF)更重要您添加了这些标签,但没有添加弹簧标签(请在问题中更正)。在“依赖项”中,Spring 也被“省略”了。请下次多注意这样的事情。创建一个minimal reproducible example。开始删除东西,直到找到缩小的原因(或解决方案)。节省您发布不清楚的问题和我们追逐“幽灵”的时间;-)。但是很好,您找到了解决方案。
猜你喜欢
  • 2011-08-01
  • 2011-06-12
  • 1970-01-01
  • 2020-03-08
  • 2017-10-19
  • 2018-10-10
  • 2013-07-22
  • 2014-07-17
  • 2022-08-22
相关资源
最近更新 更多