2

I am trying to pass an object from one page to another page where each page is in a different view.

On the first page I have an input text, where myBean is a ViewScoped Bean and name is an object. <h:inputText value="#{myBean.name}"/>

The second page contains,
<f:metadata>
<f:viewParam name="userId" value="#{myBean.name}"/>
</f:metadata>

I get the error Conversion Error setting value mypackage.myBean@257100b' for 'null Converter'. Can we pass objects other than String values to view parameters?

user679526
  • 845
  • 4
  • 16
  • 39
  • By the way, having that value in an `` without a converter is pretty confusing. You would got exactly the same problem when submitting the POST form with that field. – BalusC Dec 22 '11 at 20:46

1 Answers1

11

Yes, you can. You just have to supply a converter which converts between the string representation of the object type behind #{myBean.name} and the real object. The string representation is usually the unique technical/natural identifier of the object in question. For example, the table's PK. It has got to be a string, simply because HTTP request parameters can be strings only. You can't pass complex Java objects around in URLs. URLs are just strings.

Here's a kickoff example:

E.g. the following in the initial view:

<h:link value="Edit" outcome="edit">
    <f:param name="id" value="#{personViewer.person.id}" />
</h:link>

(which generates an <a href="edit.xhtml?id=123">Edit</a>)

and the following in the linked view:

<f:metadata>
    <f:viewParam name="id" value="#{personEditor.person}"
        converter="#{personConverter}" converterMessage="Bad request. Unknown person."
        required="true" requiredMessage="Bad request. Please use a link from within the system."
    />
</f:metadata>
<h:messages />

with this converter

@ManagedBean
@RequestScoped
public class PersonConverter implements Converter {

    @EJB
    private PersonService personService;

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        return String.valueOf(((Person) value).getId());
    }

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        return personService.find(Long.valueOf(value));
    }

}

(oversimplified; all null/number checks omitted, but you got the idea)

See also:


Update as per the comments, you actually want to fire a POST request. You don't need a <f:viewParam> at all. It's for setting/validating/converting GET request parameters only. Attempting to serialize the whole object makes also no utter sense. Just use @ManagedProperty.

E.g.

@ManagedBean
@ViewScoped
public class PersonEditor implements Serializable {

    @ManagedProperty("#{personViewer.person}")
    private Person person;

    // ...
}

It's only not bookmarkable anymore and not SEO-friendly (but that's the nature of POST, you're probably already for long aware of this). Note that the #{personViewer} bean must by itself also be @ViewScoped (and thus not @ReqestScoped). You also need to make sure that you don't navigate back with a redirect, but just a forward.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks BaluCs for your quick reply. Can we set the recieved value to a managedProperty (another view scope bean) – user679526 Dec 22 '11 at 22:40
  • Only by a POST from another view scoped bean. You can't set request parameters in a view scoped bean by `@ManagedProperty`. See also the "See also" article link at bottom of the answer. – BalusC Dec 22 '11 at 22:44
  • We are trying to serialize and deserialize the object passed in the viewParam. But the issue is getAsObject is being called but not the getAsString. So, we added a separate toString method for myBean. And also the parameter value is being shown in the URL. Is there a way to hide this parameter? – user679526 Dec 22 '11 at 23:09
  • So you just want a POST? Then you don't need a `` at all. Serializing makes absolutely no sense. The `` is for setting GET request parameters. For POST, just use `@ManagedProperty` wherein you reference the initial bean. See also the updated answer. – BalusC Dec 22 '11 at 23:14
  • We need the values in the first page to be used in the second page.If we just do a post and have ManagedProperty for the initial bean as you have mentioned above, the person id is empty. If I add f:metadata tag and corresponding code on the second page and add the converters we can see the values in the second page. If we do not convert the class to toString , an error is occurred stating person cannot be set to personEditor bean. So, is there a way to call the toString method in the converter or any other better way? – user679526 Dec 23 '11 at 02:38
  • Just use POST the usual way. You can not send a GET request and hide the parameters without temporarily storing it in the session which is in turn possibly bad for user experience. – BalusC Dec 23 '11 at 04:28