<f:param sends id null and is released java.lang.Numberformatexception

Asked

Viewed 1,539 times

2

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

I noticed that the exception is released when the edit link is clicked! and the data goes to inputText to be edited. When the name is changed and clicked on the save button the name returns to the original and does not save anything there changes the name again and click save there the name is changed! that is to do more than once to change a given.

Gave a System.out.println(params.get("id") + "+ params.containsValue("id")); before the line that raises the exception and returned null, false .

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

It is as if the "id" coming from the view through the param attribute is always sending null!

How can I fix 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
  • I didn’t understand one thing in that CommandLink is calling the method preparaAlteracao of your Bean? In addition it is inside a dataTable? Could include the most complete code?

  • Yes. by clicking on commandLink the <f:param should take the id of the selected line and send to the method preparaAlteracao() which receives the id and makes a parseint since it receives a String and has to convert to Integer

  • posted the column code edit. The detail is that to remove a row from the datatable I do it the same way and no problem.

3 answers

3

After 5 months finding the solution to a problem that tormented me:

Solution:

  • Disable Ajax from link edit.
  • In the registration form had the attribute required = "true" to avoid empty values. With required = "true" the record item was not sent to the field to be changed and the required completion message was called (after disabling Ajax on link edit). When placing required = "false" the record item goes to the field to be changed and change the item to another name this is edited first. Does not happen but to go back to the previous item and put the new name again to edit.

Now as not everything is flowers, the form can register empty values! Then I had to treat this in MB.

1

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

In case, you can use the f:ajax to add the functionality of Ajax, but keeping the action in the commandLink and use the object localidade by the scope that the 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 the dataTable has a var with name "locality". I also made the exchange for action, you can use the actionListener no problem.

The f:ajax by default will use the main event of commandLink which is the 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()));
    }
}

It is still possible to avoid calling your Facade to search for the object, using only the object passed by parameter. Only that there depends on the origin of the object and if it has the data you need further.

0

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

first <f:param>

2nd <f:attribute>

<f:setPropertyActionListener>

4th Passage of Parametro: <h:commandLink actionListener="#{localidadeBean.atualiza(localidade)}">

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

The second option in the bean takes as parameter an Actionevent should be AJAX although on the page is not passing anything(I do not understand this) and on the page is underlined red. (ERROR)

The 3rd 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 but I had to create a method with the same body as the set of the object and on the page it is underlined in red. (ERROR).

They all work, but the user has to do the operation twice to change the item. I don’t know why.

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

  • Still, I wonder why it doesn’t change the record as soon as I click save on the first try and returns the current name of the record in inputText, then I have to delete the current name type again the name I want and click again save to the name in the field be changed.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.