CDI ViewScope和PrettyFaces:多次调用@PostConstruct(JSF 2.2) [英] CDI ViewScope & PrettyFaces: Multiple calls to @PostConstruct (JSF 2.2)

查看:133
本文介绍了CDI ViewScope和PrettyFaces:多次调用@PostConstruct(JSF 2.2)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经检查过类似的问题,这些问题声明JSF 2.1存在此错误,但我使用的是JSF 2.2,让我们详细介绍:

I'v already check similar questions which declare that JSF 2.1 had this bug, but I'm using JSF 2.2 Let's detail:

我的环境:

  • CDI:1.1
  • 动态Web模块: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
  }
}

该控制器现在只是一个模拟,它返回一个元素列表.

That controller, right now is just a mock which returns a one-element list.

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

我正在使用漂亮的脸蛋,pretty-config.xml如下:

I'm using pretty faces, the pretty-config.xml is the following:

<?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中,我将省略无关的代码,但要说我是 N 乘以homeBean的次数.例如#{home.buttonClicked()}

In the home.xhtml I'm going to omit irrelevant code but say that I call N times the homeBean; for example #{home.buttonClicked()}

好;现在的问题.

其中每个对HomeBean的引用都创建一个新的 HomeBean 实例;如果我在@PostConstruct处使用断点调试它,则称为 N 次;因此,控制器被调用了N次,并且日志行"HomeBean:已初始化" 被打印了N次.

Each one of those references to the HomeBean, creates a new HomeBean instance; If I debug it with a breakpoint at the @PostConstruct it's called N times; so the controller is called N times and the log line "HomeBean: initialized" is printed N times.

这是一个@ViewScopped,所以我认为它对于整个视图都是有效的,不是吗?

It's a @ViewScopped, so I assume it will be alive for the entire view isn't it?

比方说,最终它可以正确呈现主页...但是控制器将成为数据库访问对象...我不希望每个图像都有新的数据库访问权限! O_O

Let's say, finally it renders the home page correctly... but the controller is going to be a DB access... I don't want a new DB access per image! O_O

它肯定与pretty-faces有关,因为如果我删除它,它就可以很好地工作.我已经在web.xml

It's definitely related with pretty-faces because if I remove it, it works perfectly fine. I've configured Pretty faces as the following in the web.xml

<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):

And the Pom dependencies are (prettyfaces.version is 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>

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

What's going on there? Thx very much.

推荐答案

问题是由以下映射引起的:

The problem is caused by this mapping:

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

此映射基本上匹配每个以/开头的URL.因此,它不仅与/foobar匹配,而且还与/style.css/scripts.js/jquery.min.js等匹配.

This mapping is basically matching every URL beginning with a /. So it doesn't just match /foobar but also /style.css and /scripts.js and /jquery.min.js and so on.

基本上有两种方法可以解决此问题.首先,您可以尝试使用

There are basically two ways to fix this. First you could try to use a custom regular expression to restrict what the path parameter is allowed to contain. You could for example use something like this:

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

这告诉PrettyFaces,省名只能包含字母,而不能包含数字,句点等.这与style.css类似,将不再匹配.

This tells PrettyFaces that the province name must only contain letters, but no number, periods, etc. This was something like style.css won't be matched any more.

第二个选择是使用某种URL前缀,如下所示:

The second option is to use some kind of URL prefix like this:

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

我通常建议这样做,因为这是最简单直接的方法. :)

That's what I usually recommend as it is the most simply and straight forward way. :)

这篇关于CDI ViewScope和PrettyFaces:多次调用@PostConstruct(JSF 2.2)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆