jsf - Performing a redirect, when conversion / validation associated with query parameters fails -


the following simple use case of <f:viewaction>.

<f:metadata>     <f:viewparam name="id" value="#{testmanagedbean.id}" maxlength="20"/>     <f:viewaction action="#{testmanagedbean.viewaction}"/> </f:metadata> 

the managed bean involved.

@managedbean @viewscoped public final class testmanagedbean implements serializable {      private static final long serialversionuid = 1l;     private long id; //getter , setter.      public void viewaction() {         system.out.println("viewaction() called : " + id);     } } 

the parameter id passed through url. there conversion error, when non-numeric value xxx passed through url in question , viewaction() method associated listener of <f:viewaction> not invoked.

the value of id null in case. redirect page, when id not convertible desired target type (like in case) or id not validated against specified validation criteria avoid potential exceptions thrown in lazydatamodel#load() method of primefaces or somewhere else in associated managed bean whenever access these parameters attempted in corresponding managed bean. so, viewaction() method should invoked.

how proceed this? should use

<f:event type="prerenderview"> 

in conjunction <f:viewaction>?

this specified behavior. when process_validations phase ends validation failure, both update_model_values , invoke_application phases skipped. in "regular" forms <h:form>. think of <f:viewparam> <h:inputtext> , <f:viewaction> <h:commandbutton> , become more clear.

for particular requirement, performing redirect when conversion/validation has failed, there @ least 3 solutions:

  1. as found out, add <f:event listener>. i'd rather hook on postvalidate event instead better self-documentability.

    <f:metadata>     <f:viewparam name="id" value="#{bean.id}" maxlength="20" />     <f:event type="postvalidate" listener="#{bean.redirectifnecessary}" />     <f:viewaction action="#{bean.viewaction}" /> </f:metadata> 
    public void redirectifnecessary() throws ioexception {     facescontext context = facescontext.getcurrentinstance();      if (!context.ispostback() && context.isvalidationfailed()) {         context.getexternalcontext().redirect("some.xhtml");     } } 

    the check on facescontext#ispostback() prevents redirect being performed on validation failures of "regular" forms in same view (if any).


  2. extend builtin longconverter whereby perform redirect in getasobject() (a validator insuitable default converter long fail on non-numeric inputs; if converter fails, validators never fired). poor design (tight-coupling).

    <f:metadata>     <f:viewparam name="id" value="#{bean.id}" converter="idconverter" />     <f:viewaction action="#{bean.viewaction}" /> </f:metadata> 
    @facesconverter("idconverter") public class idconverter extends longconverter {      @override     public object getasobject(facescontext context, uicomponent component, string value) {         if (value == null || !value.matches("[0-9]{1,20}")) {             try {                 context.getexternalcontext().redirect("some.xhtml");                 return null;             }             catch (ioexception e) {                 throw new facesexception(e);             }         }         else {             return super.getasobject(context, component, value);         }     }  } 

    you if necessary play around <f:attribute> inside <f:viewparam> "pass" parameters converter.

    <f:viewparam name="id" value="#{bean.id}" converter="idconverter">     <f:attribute name="redirect" value="some.xhtml" /> </f:viewparam> 
    string redirect = (string) component.getattributes().get("redirect"); context.getexternalcontext().redirect(redirect); 

  3. create custom taghandler same <f:event listener> without need additional backing bean method.

    <html ... xmlns:my="http://example.com/ui">  <f:metadata>     <f:viewparam name="id" value="#{bean.id}" maxlength="20" />     <my:viewparamvalidationfailed redirect="some.xhtml" />     <f:viewaction action="#{bean.viewaction}" /> </f:metadata> 

    com.example.taghandler.viewparamvalidationfailed

    public class viewparamvalidationfailed extends taghandler implements componentsystemeventlistener {      private string redirect;      public viewparamvalidationfailed(tagconfig config) {         super(config);         redirect = getrequiredattribute("redirect").getvalue();     }      @override     public void apply(faceletcontext context, uicomponent parent) throws ioexception {         if (parent instanceof uiviewroot && !context.getfacescontext().ispostback()) {             ((uiviewroot) parent).subscribetoevent(postvalidateevent.class, this);         }     }      @override     public void processevent(componentsystemevent event) throws abortprocessingexception {         facescontext context = facescontext.getcurrentinstance();          if (context.isvalidationfailed()) {             try {                 context.getexternalcontext().redirect(redirect);             }             catch (ioexception e) {                 throw new abortprocessingexception(e);             }         }     }  } 

    /web-inf/my.taglib.xml

    <?xml version="1.0" encoding="utf-8"?> <facelet-taglib     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/web-facelettaglibrary_2_0.xsd"     version="2.0" >     <namespace>http://example.com/ui</namespace>      <tag>         <tag-name>viewparamvalidationfailed</tag-name>         <handler-class>com.example.taghandler.viewparamvalidationfailed</handler-class>     </tag>   </facelet-taglib> 

    /web-inf/web.xml

    <context-param>     <param-name>javax.faces.facelets_libraries</param-name>     <param-value>/web-inf/my.taglib.xml</param-value> </context-param> 

    true, it's bit of code, ends in clean , reusable <my:viewparamvalidationfailed> tag , fit new omnifaces feature.


Comments

Popular posts from this blog

apache - Remove .php and add trailing slash in url using htaccess not loading css -

javascript - jQuery show full size image on click -