using f:viewParam with required attribute and comm

2019-02-17 08:33发布

问题:

I want to share my experience using primefaces, f:viewParam and p:commandButton, and ask a few questions.Take a look at this page:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui">
  <h:head></h:head>
  <h:body>  
    <f:metadata>
      <f:viewParam required="true" name="id_file" value="#{bean.idFile}" />
    </f:metadata>
    <h:form id="tableform" prependId="false">              
      <p:commandButton actionListener="#{bean.myMethod())}" icon="ui-icon-search" title="View" />
    </h:form>
    <p:messages id="messages" showDetail="true" autoUpdate="true" closable="true" />      
  </h:body>
</html>

The backing bean have a "myMethod()" method that does nothing. When you enter the page it expects the "id_file" parameter and put it in the idFile property of the backing bean. Then you click the button and the myMethod is called. Then you click again and you get an obscure validation error and myMethod is never called:

j_idt1: Validation Error: Value is required.j_idt1: Validation Error: Value is required.

First of all, remember that without p:messages you can't see this message, you have to dig the XML that primefaces send on ajax calls. Secondly, after 4 hours of debugging I've tried to change the f:viewParam like this:

<f:viewParam name="id_file" value="#{bean.idFile}" />

without "required": magically everything start working, I can click 1,2,3,etc and myMethod is called every time. So, the problem is that the ajax submit validate the parameter specified with f:viewParam, it sounds silly to me, but ok, I can live with it.

My questions are:

  • why this validation error doesn't appear the first time button is clicked? If you look at the ajax POSTs they are identical

  • it is supposed to be ok to validate the view parameters (that, in my idea, belongs to the view) on a partial ajax call?

  • is there a way to tell to primefaces not to validate on particular ajax request (process="@this" does not resolve)?

Thank you, I hope that my experience will allow you to avoid spending hours doing debugging!

回答1:

  1. The viewParam is a UIComponent. That means it's semantically no different from a <h:commandButton/> or a <h:inputText/> and it's liable to go thru every prescribed JSF request processing lifecycle phase, up to and including validation and conversion. In fact, the tag itself causes any given view to go into the full processing of any given page, just by being there

  2. The <p:commandButton/> is going to do a postback, meaning, it's going to be re-requesting the same view, using a POST. So to solve your current problem, you need to base your required condition on that fact:

    <f:viewParam  required="#{!facesContext.postback}" name="id_file" value="{bean.idFile}"/>
    

    What you get from the new condition is that the parameter will be required only on the first request. Subsequent postbacks will not trigger the condition. Just be sure you don't have any logic (maybe in a @PostConstruct that's built around that expectation