Search code examples
javajsf-2portletliferay-6

Viewscoped Managed beans and Portlets


I am creating a portlet where in the view and edit modes apply. I want a situation whereby and update switches the portlet from the edit mode to the view mode. Below is my code snippet

@ManagedBean(name = "portletBackingBean")
@ViewScoped
public class FirstPortlet extends GenericFacesPortlet implements Serializable {


private transient Logger logger = LoggerFactory.getLogger(getClass());

private void doActionResponse(PortletMode mode){
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext =
    facesContext.getExternalContext();
    ActionResponse actionresponce = (ActionResponse) externalContext.getResponse();
    try {
        actionresponce.setPortletMode(mode);
    } catch (PortletModeException e) {
        // TODO Auto-generated catch block
        LiferayFacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Error setting property"));
    }
}


private String userName;

/**
 * @return the userName
 */
public String getUserName() {
    return userName;
}

/**
 * @param userName the userName to set
 */
public void setUserName(String userName) {
    this.userName = userName;
}


//submitting the values
public void doSubmit(){
    if(this.userName != null) {
        logger.debug("value of property in backing bean set to " + getUserName());
        doActionResponse(PortletMode.VIEW);
    }


}

So far all is well, but then the portlet renders in view mode, the value of #{portletBackingBean.userName} is null.

Please is there a more elegant way of doing this

Thanks in advance


Solution

  • There are some serious defects in this code.

    @ManagedBean(name = "portletBackingBean")
    @ViewScoped
    public class FirstPortlet extends GenericFacesPortlet implements Serializable {
    //...
      private String userName;
    

    The portlet...

    • Is always application scoped
    • Must be thread-safe
    • Cannot be a managed bean
    • Cannot have per-user state (e.g. userName)

    Whenever the portletBackingBean is resolved it will cause the JSF framework to create a new instance of the FirstPortlet class. It will not return a reference to the portlet instance that contains it.

    In addition, if you use different views for the edit and view portlet modes @ViewScoped is not an appropriate scope for this state.

    In short, I think you need to look again at your model design and figure out how you're going to separate state from portlet functionality.