Domanda

I would like to modularize my JSF 2.1 / Java EE application. I have a page that consists of several modules. Each module should use a separate JSF backing bean. Some of these modules need to show and change some data from/on the same entity.

I've already tried some approaches but I am not satisfied so far. I ask myself what the best way to do this would be?

All modules use the same entity and they (probably) need to notify the other backing beans if some data has changed.

Comments to some approaches that I've already tried:

  • Passing the entity to my component (XHTML) via interface will not pass it to the backing bean as well
  • Loading the entity in the bean's postContruct method by reading an id from the request paramters is commonly discouraged in favour of using the "viewParam" approach
  • Using "viewParam" is IMHO not as good as having the entity after bean creation (in my postConstruct). I'm not sure when the bean's setter is invoked.
È stato utile?

Soluzione

Despite it being "commonly discouraged" (by whom?), I'm using something one of the following techniques in my JSF-2.2 backing beans (depending on whether I need personId for something else):

@ViewScoped
public class BeanConverter {
    @Inject @Param(name = "personId")
    private ParamValue<Person> curPerson;
}

@ViewScoped
public class BeanConstruct {
    @PersistenceContext
    private EntityManager em;

    @Inject @Param
    private ParamValue<Long> personId;

    private Person curPerson;

    @PostConstruct
    public void init() {
        curPerson = em.find(Person.class, personId.getValue());
    }
}

This uses the excellent CDI support of Omnifaces. I then use merge() to update the entity, but in my case only one bean gets to save changes to the entity, so YMMV. When beans need to communicate updates or entity creations among themselves, I usually go for javax.enterprise.Events where the event gets the entity as a constructor argument:

public class BeanSending {
    @Inject
    private Event<PersonCreated> personCreatedEvent;

    public void constructPerson() {
        Person person = makePerson();
        personCreatedEvent.fire(new PersonCreated(person));
    }
}

public class BeanUpdater {
    public void updatePerson(@Observes PersonCreated evt) {
        doStuffWithPerson(evt.getPerson());
    }
}

Altri suggerimenti

I think what you need is the CDI - Context & Dependency Injection. Just chop up your page into a number of smaller CDI beans and inject them into each other as you need.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top