CDI ViewScope& PrettyFaces:多次调用@PostConstruct(JSF 2.2)

时间:2015-05-21 16:04:51

标签: jsf-2.2 prettyfaces view-scope

我已经检查了类似的问题,这些问题声明JSF 2.1存在此错误,但我使用的是JSF 2.2详情:

我的环境:

  • CDI:1.1
  • 动态网络模块:3.0
  • Java:1.7
  • JSF:2.2
  • PrettyFaces:2.0.12.Final

我的豆子:

@Named(value = "home")
@javax.faces.view.ViewScoped
public class HomeBean implements Serializable {

  @Inject
  private HomeController controller;

  private List<Store> myPopularStores;

   @PostConstruct
   public void postConstruct() {
    myPopularStores = controller.getStores();
    LOG.log(Level.FINE, "HomeBean: initialized");
  }

  public String buttonClicked() {
     // whatever
  }
}

该控制器,现在只是一个返回单元素列表的模拟器。

@Named
public class HomeController implements Serializable {
  public List<Store> getStores() {
    // mocked
  }
}

我使用漂亮的面孔,pretty-config.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<pretty-config xmlns="http://ocpsoft.org/schema/rewrite-config-prettyfaces" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://ocpsoft.org/schema/rewrite-config-prettyfaces
                      http://ocpsoft.org/xml/ns/prettyfaces/rewrite-config-prettyfaces.xsd">

 <url-mapping id="Home">
    <pattern value="/" />
    <view-id value="/home.xhtml" />
  </url-mapping>

 <url-mapping id="cityIndex">
    <pattern value="/#{provinceName}" />
    <view-id value="/home.xhtml" />
 </url-mapping>

</pretty-config>

home.xhtml我将省略不相关的代码,但我说我将{strong> N 调用homeBean;例如#{home.buttonClicked()}

行;现在问题。

HomeBean的每一个引用都会创建一个新的 HomeBean 实例;如果我在@PostConstruct处使用断点调试它,其名称为 N 次;所以控制器被调用N次,日志行&#34; HomeBean:initialized&#34; 被打印N次。

它是一个@ViewScopped,所以我认为整个视图都会活着吗?

让我们说,最后它正确呈现主页...但控制器将成为数据库访问...我不希望每个图像都有新的数据库访问权限! O_O

[EDITED] 它与pretty-faces肯定有关,因为如果我将其删除,它的效果非常好。我已在web.xml

中将Pretty faces配置为以下内容
<filter>
    <filter-name>OCPsoft Rewrite Filter</filter-name>
    <filter-class>org.ocpsoft.rewrite.servlet.RewriteFilter</filter-class>
    <async-supported>true</async-supported>
</filter>
<filter-mapping>
    <filter-name>OCPsoft Rewrite Filter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ASYNC</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>

Pom依赖项是(prettyfaces.version是2.0.12.Final):

<dependency>
   <groupId>org.ocpsoft.rewrite</groupId>
   <artifactId>rewrite-servlet</artifactId>
   <version>${prettyfaces.version}</version>
</dependency>
<dependency>
   <groupId>org.ocpsoft.rewrite</groupId>
   <artifactId>rewrite-integration-faces</artifactId>
   <version>${prettyfaces.version}</version>
</dependency>
<dependency>
   <groupId>org.ocpsoft.rewrite</groupId>
   <artifactId>rewrite-config-prettyfaces</artifactId>
   <version>${prettyfaces.version}</version>
</dependency>

那里发生了什么?非常感谢。

1 个答案:

答案 0 :(得分:3)

问题是由此映射引起的:

<url-mapping id="cityIndex">
   <pattern value="/#{provinceName}" />
   <view-id value="/home.xhtml" />
</url-mapping>

此映射基本上匹配以/开头的每个网址。因此,它不仅匹配/foobar,还匹配/style.css/scripts.js以及/jquery.min.js等等。

基本上有两种方法可以解决这个问题。首先,您可以尝试使用custom regular expression来限制允许路径参数包含的内容。例如,您可以使用以下内容:

<url-mapping id="cityIndex">
   <pattern value="/#{ /[a-z]+/ provinceName }" />
   <view-id value="/home.xhtml" />
</url-mapping>

这告诉PrettyFaces省名必须只包含字母,但不能包含数字,句号等。这类似style.css不再匹配。

第二个选项是使用某种URL前缀:

<url-mapping id="cityIndex">
   <pattern value="/province/#{provinceName}" />
   <view-id value="/home.xhtml" />
</url-mapping>

这就是我通常推荐的,因为它是最简单直接的方式。 :)