Supplying parameters through p:remoteCommand to a Spring bean

百般思念 提交于 2019-12-11 08:18:16

问题


The following XHTML sets a selected value in <p:selectOneMenu> to a request scoped bean through <p:remoteCommand>.

<h:form id="languageForm" prependId="true">

    <pe:blockUI target=":body" widgetVar="blockBodyUIWidget">
        <h:panelGrid columns="2">
            <h:graphicImage library="default" name="images/ajax-loader1.gif" class="block-ui-image"/>
            <h:outputText value="#{messages['blockui.panel.message']}" class="block-ui-text"/>
        </h:panelGrid>
    </pe:blockUI>

    <p:selectOneMenu id="languages" value="#{localeBean.language}" onchange="changeLanguage([{name:'language', value:this.value}]);">
        <f:selectItem itemValue="en" itemLabel="#{messages['languages.english']}" />
        <f:selectItem itemValue="hi" itemLabel="#{messages['languages.hindi']}" />
    </p:selectOneMenu>

    <p:remoteCommand name="changeLanguage" process="@this" update="@none" onstart="PF('blockBodyUIWidget').block();" oncomplete="PF('blockBodyUIWidget').unblock();" action="#{intermediateLocaleBean.localeAction}"/>
</h:form>

The corresponding JSF managed bean:

@ManagedBean
@RequestScoped
public final class IntermediateLocaleBean
{
    @ManagedProperty("#{param.language}")
    private String language;
    @ManagedProperty("#{localeBean}")
    private LocaleBean localeBean;  //Injecting another session scoped bean here.

    public IntermediateLocaleBean() {}

    public void setLanguage(String language) {
        this.language = language;
    }

    public void setLocaleBean(LocaleBean localeBean) {
        this.localeBean = localeBean;
    }

    public String localeAction()
    {
        localeBean.setLocale(language.equals("hi")?new Locale(language, "IN"):new Locale(language));
        return FacesContext.getCurrentInstance().getViewRoot().getViewId() + "?faces-redirect=true";
    }
}

The language property is initialized to the selected language in <p:selectOneMenu>. This is all done as it is a JSF managed bean.


What if, the bean is maintained by Spring like as follows?

@Controller
@Scope("request")
public final class IntermediateLocaleBean
{
    //Do something to initialize the property - language.
    //@ManagedProperty would not work as this bean is managed by Spring.
    //It is not initialized to the selected language in <p:selectOneMenu>.
    //It is null.

    private String language;

    //The session scoped bean is injected using the @Autowired annotation as follows.

    @Autowired
    private final transient LocaleBean localeBean=null;

    public IntermediateLocaleBean() {}

    public void setLanguage(String language) {
        this.language = language;
    }

    public String localeAction()
    {
        localeBean.setLocale(language.equals("hi")?new Locale(language, "IN"):new Locale(language));
        return FacesContext.getCurrentInstance().getViewRoot().getViewId() + "?faces-redirect=true";
    }
}

How to initialize the language property to the selected language in <p:selectOneMenu> in this bean?


回答1:


Traditionally, the parameter value of language - a request parameter, could be made available using

FacesContext context = FacesContext.getCurrentInstance();
String language = context.getExternalContext().getRequestParameterMap().get("language");

like the following,

@Controller
@Scope("request")
public final class IntermediateLocaleBean
{
    @Autowired
    private final transient LocaleBean localeBean=null;

    public IntermediateLocaleBean() {}

    public void setLanguage(String language) {
        this.language = language;
    }

    public String localeAction()
    {
        String language = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("language");
        localeBean.setLocale(language.equals("hi")?new Locale(language, "IN"):new Locale(language));

        return FacesContext.getCurrentInstance().getViewRoot().getViewId() + "?faces-redirect=true";
    }
}

But I personally dislike exposing the entire request using FacesContext unless it is absolutely necessary.


There is an org.springframework.beans.factory.annotation.Value annotation in Spring that can be used with the Spring expression language to obtain request parameters as follows.

@Controller
@Scope("request")
public final class IntermediateLocaleBean
{
    @Value("#{request.getParameter('language')}") //Exposing the value of language.
    private String language;

    @Autowired
    private final transient LocaleBean localeBean=null;

    public IntermediateLocaleBean() {}

    public void setLanguage(String language) {
        this.language = language;
    }

    public String localeAction()
    {
        localeBean.setLocale(language.equals("hi")?new Locale(language, "IN"):new Locale(language));
        return FacesContext.getCurrentInstance().getViewRoot().getViewId() + "?faces-redirect=true";
    }
}

The value of language supplied by <p:remoteCommand> as a request parameter is now available in this bean using the @Value annotation (the getter method for language is not required in my case).

Please suggest or add another answer, if something else is available!



来源:https://stackoverflow.com/questions/22765022/supplying-parameters-through-premotecommand-to-a-spring-bean

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!