1

I found some reference JSF Parameter Passing.

But, It is not ok for my requirement. I would pass the object(Student) one backing bean to another bean as below.

studentTable.xhtml                              updateStudent.xhtml
                        pass student object
                        (not `StudentID` string)
                        ==================> 
StudentTableBean.java                           UpdateStudnetBean.java

Both of backing bean may be RequestScope or ViewScope, not Session. When I click a link(a row of datatable) at studentTable.xhtml, I would like to pass the student object to updateStudent.xhtml.

Is it possible? Could you provide some reference or providing?

Community
  • 1
  • 1
Zaw Than oo
  • 9,651
  • 13
  • 83
  • 131

3 Answers3

3

HTTP and HTML doesn't understand complex Java objects. In Java perspective, they only understand strings. You'd better convert the complex Java object to an unique identifier in string flavor, usually its technical ID (the autogenerated database PK, for example) and in turn use that identifier as HTTP request parameter in the HTML link.

Given a List<Student> which is represented as a table with links as follows,

<h:dataTable value="#{studentTable.students}" var="student">
    <h:column>
        <h:link value="Edit" outcome="updateStudent.xhtml">
            <f:param name="id" value="#{student.id}" />
        </h:link>
    </h:column>
</h:dataTable>

you can in the target view updateStudent.xhtml use <f:viewParam> to convert the passed student ID back to Student as follows,

<f:metadata>
    <f:viewParam name="id" value="#{updateStudent.student}" converter="#{studentConverter}" />
</f:metadata>

with

private Student student;

and

@ManagedBean
@ApplicationScoped
public class StudentConverter implements Converter {

    @EJB
    private StudentService studentService;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (value == null || value.isEmpty()) {
            return null;
        }

        if (!value.matches("[0-9]+")) {
            throw new ConverterException("The value is not a valid Student ID: " + value);
        }

        long id = Long.valueOf(value);
        return studentService.getById(id);
    }

    @Override    
    public String getAsString(FacesContext context, UIComponent component, Object value) {        
        if (value == null) {
            return "";
        }

        if (!(value instanceof Student)) {
            throw new ConverterException("The value is not a valid Student instance: " + value);
        }

        Long id = ((Student)value).getId();
        return (id != null) ? String.valueOf(id) : null;
   }

}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Pass `ID String`, retrieve from DB again. Otherwise, use `SessionScope` or `ApplicationScope`. Am I right? Thanks for your providing. – Zaw Than oo Jan 20 '14 at 09:14
  • Don't abuse the scope or you will kill the threadsafety and user experience. Further reading: http://stackoverflow.com/q/7031885 and http://stackoverflow.com/a/15523045 More helpful links: https://jsf.zeef.com/bauke.scholtz – BalusC Jan 20 '14 at 09:19
0

How would you think that'd be possible? Viewscope ends when you leave the page and all beans in that scope are destroyed - and so are the objects they are holding.

updateStudent.xhtml creates a new view and gets it's own set of Viewscoped beans. If you want to keep objects between pages, either start a new, long-running conversation or push the objects into session scope.

For using conversation scope, see this tutorial.

mabi
  • 5,279
  • 2
  • 43
  • 78
  • I use `Jboss Seam` in my project. Now I am considering to remove `Jboss Seam`. That's why, I am trying to research like `Conversation`. – Zaw Than oo Jan 20 '14 at 08:41
  • @CycDemo I was in the same position and chose ViewScoped beans with converters as BalusC illustrated below (ConversationScoped is a JEE7 addition that I'm not sure of, yet). Since all lookups are by PK, they are very cache-friendly and should be lightning fast compared to all the other stuff JSF needs to do. – mabi Jan 20 '14 at 09:50
0

You can do this by putting the student's object in the session map of the current instance of the request: You pass the id of the student in question from studentTable.xhtml to the backing-bean UpdateStudnetBean.java, then you search for the object instance from the resource (list, DB, etc.), then you put it in the session map object above. This way you can get it in the view updateStudent.xhtml by the implicit object sessionScope.

Omar
  • 1,430
  • 1
  • 14
  • 31