根据URL评估jsf bean属性

时间:2012-11-11 14:21:41

标签: url jsf java-ee jsf-2

有没有办法根据请求URL显示特定的JSF页面?

假设我有一个JSF页面“details.xhtml”。托管bean“detailsBean”具有一个对象列表,其中每个对象都有自己的ID。现在,如果用户请求页面“../details.xhtml?id=1”,则应查询ID为1的对象的列表,并显示该对象的结果详细信息页面。

我已经编写了一个转换器实现类,它可以从对象转换为ID,反之亦然,但我不知道如何正确使用它。我是否必须通过JAX-RS规范来实现这一目标,还是有更简单的解决方案?

2 个答案:

答案 0 :(得分:4)

在JSF中,您可以使用所谓的视图参数来完成此操作。您在Facelet的metadata部分声明了这些内容:

<f:metadata>         
    <f:viewParam name="id" value="#{yourBean.yourObject}" label="id" 
        converter="yourObjectConverter" 
    />
</f:metadata>

这将从请求网址中获取网址参数id。例如。如果您使用localhost:8080/mypage.jsf?id=1请求显示此页面,则1将被移至yourObjectConverter,此转换器返回的内容将在yourBean.yourObject中设置。

您的支持bean将获得转换后的对象。不需要使用相同的查询代码一遍又一遍地污染您的支持bean。

@ManagedBean
public class YourBean {

    private SomeObject someObject;

    public void setYourObject(SomeObject someObject) {
        this.someObject = someObject;
    }
}

如果你的支持bean是视图范围的,你可能想要使用viewParam {{1}}变体,因为否则它会在每次回发后不必要地转换(如果你的转换器进行数据库查询,你绝对不想要这个。)

完整的例子:

进一步阅读:

答案 1 :(得分:-1)

您可以使用以下步骤使用普通JSF实现此目的

  1. 捕获请求中的ID,以确定请求参数中DetailsBean中正在查询的对象。有很多方法可以实现这一点,其中一种方法是向托管bean添加以下注释(目前只允许@RequestScoped bean使用,请参阅here)。

       @ManagedProperty(value="#{param.id}")
       int requiredObjectId;
    

    上面的注释将捕获请求中的id参数,并将其分配给requiredObjectId变量。

  2. 使用捕获的Id,使用@PostConstruct方法

    在bean中设置对象
       @PostConstruct
       public void queryForObject(){
    
       //use the requiredObjectId variable to query and setup the object in the backing bean
    
       }
    

    检索到的对象应该被指定为托管bean的实例变量

  3. 在您的视图中,您可以引用已在辅助bean中设置的查询对象

      <h:panelGrid columns="2">
         <h:outputText value="Title"/>
         <h:outputText value="#{detailsBean.selectedObject.title}"/>
      </h:panelGrid>
    
  4. 如果您的bean位于比请求范围更广的范围内,那么在视图呈现之前,您需要一组构造来干净地提取该请求参数。

    1. 使用

      捕获在JSF视图中的请求参数
      <f:metadata>
       <f:viewParam name="id" value="#{detailsBean.requiredObjectId}" required="true" requiredMessage="You must provide an Object Id"/>         
      </f:metadata>
      
          **OR**
      
    2. 由于JSF生命周期处理的性质,单独执行上述操作可能无法使值及时用于对象设置。您可以改用以下内容。

       <f:metadata>
          <f:event type="preRenderView" listener="#{detailsBean.setObjectId}" />         
      </f:metadata>
      

      我们在这里完成的是指定一个方法(捕获id),该方法必须在呈现视图之前执行,以确保id参数可用于你需要它的时间。仅当您使用上面的<f:event/>时才继续执行步骤3.

    3. 在辅助bean中,您现在可以定义setObjectId方法

        public void setObjectId(){
      
        Map<String,String> requestParams =      FacesContext.getExternalContext().getRequestParameterMap();
        requiredObjectId =  Integer.parseInt(requestParams.get("id"));
      
        }
      
    4. 请注意,上述选项通常是一种解决方法/黑客,而不是一个干净的解决方案