f: param sends id null and java.lang.NumberFormatException is thrown

2

I use the same registration form to update a datatable record. when clicking update it sends to the inputText the name to be updated so far so well, the problem is when the name is changed and the button is clicked. the inputText returns to the previous name and the change does not occur.

I noticed that the exception is thrown when the edit link is clicked! and the data goes to the inputText to be edited. When the name is changed and clicked on the save the name back to original and save nothing button there changes the name again and click save there the name is changed! or you have to do more than once to change a given.

I gave a System.out.println (params.get ("id") + "" + params.containsValue ("id")); before the line raising the exception and returned null, false.

Then <f:param is not sending the id value to the MangedBean.

It's as if the "id" that comes from the view through the param attribute was always sending null!

How can I resolve this?

Page

     <h:column>
            <f:facet name="header">
                <h:outputText value="Editar" />
            </f:facet>

            <f:ajax event="click" render="@all"
                listener="#{localidadeBean.preparaAlteracao}">

                <h:commandLink>
                    <f:param name="id" value="#{localidade.codLocalidade}" />
                    <h:graphicImage title="editar" library="imagens" name="editar.png"
                        style="float:right;" />
                </h:commandLink>

            </f:ajax>               

        </h:column>

ManagedBean

public void preparaAlteracao() {
    Map<String, String> params = FacesContext.getCurrentInstance()
            .getExternalContext().getRequestParameterMap();

    Integer id = Integer.parseInt(params.get("id"));// Linha que levanta a Exceção

    facade = new Facade(this.getManager());
    try {
        this.localidade = facade.procuraLocalidade(id);
    } catch (RepositorioException e) {
        BaseBean.addErrorMessage("localidade", e.getMessage());
        throw new ValidatorException(new FacesMessage("localidade", e.getMessage()));
    }
}

Stacktrace

    Out 17, 2014 5:56:12 PM com.sun.faces.lifecycle.InvokeApplicationPhase execute
Advertência: /lista-de-localidades.xhtml @34,53 listener="#    {localidadeBean.preparaAlteracao}": java.lang.NumberFormatException: null
javax.el.ELException: /lista-de-localidades.xhtml @34,53 listener="#{localidadeBean.preparaAlteracao}": java.lang.NumberFormatException: null
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:111)
at com.sun.faces.facelets.tag.jsf.core.AjaxBehaviorListenerImpl.processAjaxBehavior(AjaxHandler.java:447)
at javax.faces.event.AjaxBehaviorEvent.processListener(AjaxBehaviorEvent.java:113)
at javax.faces.component.behavior.BehaviorBase.broadcast(BehaviorBase.java:106)
at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:760)
at javax.faces.component.UIData.broadcast(UIData.java:1092)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:795)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1260)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at br.com.sescpe.scontratos.controle.filtro.JPAFilter.doFilter(JPAFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at br.com.sescpe.scontratos.controle.filtro.ControleAcesso.doFilter(ControleAcesso.java:37)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:409)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1044)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.NumberFormatException: null
at java.lang.Integer.parseInt(Integer.java:454)
at java.lang.Integer.<init>(Integer.java:677)
at br.com.sescpe.scontratos.controle.managedbean.localidade.LocalidadeBean.preparaAlteracao(LocalidadeBean.java:94)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.el.parser.AstValue.invoke(AstValue.java:278)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
... 36 more
    
asked by anonymous 18.10.2014 / 22:15

3 answers

3

After 5 months I discovered the solution to a problem that plagued me:

Solution:

  • Disable Ajax from link edit.
  • In the registration form, it had the required = "true" attribute to avoid registering empty values. With required = "true" the registry item was not sent to the field to be changed and the required message was called (after disabling Ajax in the link edit). By putting required = "false" the record item goes to the field to be changed and changing the item to another name is edited first. It does not happen but go back to the previous item and put the new name again to edit.

Now since not everything is flowers, the form can register empty values! So I had to deal with this in MB.

    
31.03.2015 / 23:10
1

I suggest a restructuring, not to depend on requisition attributes, which can easily be lost or forgotten.

In this case, you can use f:ajax to add the Ajax functionality, but keep action in commandLink and use localidade object for the scope that dataTable creates instead of using a% f:param .

The organization would look like this:

Facelets

<h:column>
    <f:facet name="header">
        <h:outputText value="Editar" />
    </f:facet>

    <h:commandLink action="#{localidadeBean.preparaAlteracao(localidade)}">
        <f:ajax render="@all" />
        <h:graphicImage title="editar" library="imagens" name="editar.png" style="float:right;" />
    </h:commandLink>
</h:column>

I believe that dataTable has a var named "location". Also I made the exchange for action , if you want you can use actionListener without problem.

The f:ajax by default will use the main event of commandLink which is click .

Managed Bean

public void preparaAlteracao(Localidade localidade) {
    Integer id = localidade.getCodLocalidade();

    facade = new Facade(this.getManager());

    try {
        this.localidade = facade.procuraLocalidade(id);
    } catch (RepositorioException e) {
        BaseBean.addErrorMessage("localidade", e.getMessage());
        throw new ValidatorException(new FacesMessage("localidade", e.getMessage()));
    }
}

You can still avoid calling your Facade to fetch the object, using only the object passed by parameter. But that depends on the source of the object and if it has the data you need later.

    
19.10.2014 / 17:47
0

I was testing the alternatives for passing the page value to the bean:

1st <f:param>

2nd <f:attribute>

3rd <f:setPropertyActionListener>

4th Parameter Pass: <h:commandLink actionListener="#{localidadeBean.atualiza(localidade)}">

The first option is the one that generates the exception and was what I was using.

The second option in the bean receives as an parameter an ActionEvent must be AJAX although the page is not passing anything (I do not understand this) and the page is underlined in red.

The third option I can pass the object (line) and set the object in the bean and do not need to access the database:)

The 4th option is similar to the 3rd one, but I had to create a method with the same object set body and the page is underlined in red.

All work, but the user has to do the operation 2 times to change the item. I do not know why.

I chose 3rd because it is the most advantageous in implementation.

    
21.10.2014 / 22:12