0

在转换时,流重定向没有在 FacesContext 的当前实例中呈现 FacesMessage(与 MessageContext 相同的问题)我检查了 FacesContext 中 FacesMessage 的存在是正确的,但出于某种原因,即使上下文我也不会触摸重定向里面包含消息

春季应用程序上下文:

<faces:resources/>
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping"
      p:order="1"
      p:flowRegistry-ref="flowRegistry">
    <property name="defaultHandler">
        <!--If no flow match, map path to a view to render; e.g. the "/home" path
        would map to the view named "home" -->
        <bean class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
    </property>
</bean>
<bean id="faceletsViewResolver"
      class="org.springframework.web.servlet.view.UrlBasedViewResolver"
      p:viewClass="org.springframework.faces.mvc.JsfView"
      p:prefix="/WEB-INF/"
      p:suffix=".xhtml"/>
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<bean class="org.springframework.faces.webflow.JsfFlowHandlerAdapter"
      p:flowExecutor-ref="flowExecutor"/>
<webflow-config:flow-executor id="flowExecutor">
    <webflow-config:flow-execution-listeners>
        <webflow-config:listener ref="facesContextListener"/>
        <webflow-config:listener ref="jpaFlowExecutionListener"/>
        <webflow-config:listener ref="securityFlowExecutionListener"/>
    </webflow-config:flow-execution-listeners>
</webflow-config:flow-executor>
<webflow-config:flow-registry id="flowRegistry"
                              flow-builder-services="facesFlowBuilderServices" base-path="/WEB-INF/flows">
    <webflow-config:flow-location-pattern
            value="/**/*-flow.xml"/>
</webflow-config:flow-registry>
<faces:flow-builder-services id="facesFlowBuilderServices"
                             development="true"/>
<bean id="facesContextListener"
      class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener"/>
<bean id="jpaFlowExecutionListener"
      class="org.springframework.webflow.persistence.JpaFlowExecutionListener">
    <constructor-arg ref="entityManagerFactory"/>
    <constructor-arg ref="transactionManager"/>
</bean>
<bean id="securityFlowExecutionListener"
      class="org.springframework.webflow.security.SecurityFlowExecutionListener"/>

控制器 :

@Named("registrationController")
class RegistrationController implements Serializable {

@Inject
@LangServiceQualifier
ILangService langService
@Inject
@RegistrationServiceQualifier
IRegistrationService registrationService

void validate(RegistrationModel model) {
    model.user.profile.lang ?: model.user.profile.setLang(registrationLang())
    try {
        registrationService.validate(model)
        model.header = new RequestHelper(request: FacesUtils.request).header
    } catch (RegistrationException re) {
        FacesContext context = FacesUtils.context
        re.messages.each {
            switch (it) {
                case new UsernameAlreadyExistsException().message:
                    context.addMessage("register_form_username_inputText_id",
                            new FacesMessage(
                                    severity: FacesMessage.SEVERITY_ERROR,
                                    summary: FacesUtils.bundle.getString(it)))
                    break
                case new PrimaryEmailAlreadyExistsException().message:
                    context.addMessage("register_form_currentEmailValue_inputText_id",
                            new FacesMessage(
                                    severity: FacesMessage.SEVERITY_ERROR,
                                    summary: FacesUtils.bundle.getString(it)))
                    break
                case new EmailRetypeException().message:
                    context.addMessage("register_form_currentEmailValueRetype_inputText_id",
                            new FacesMessage(
                                    severity: FacesMessage.SEVERITY_ERROR,
                                    summary: FacesUtils.bundle.getString(it)))
                    break
                case new PasswordRetypeException().message:
                    context.addMessage("register_form_password_inputText_id",
                            new FacesMessage(
                                    severity: FacesMessage.SEVERITY_ERROR,
                                    summary: FacesUtils.bundle.getString(it)))
                    break
            }
        }
    }
}

spring web 流定义:

<flow xmlns="http://www.springframework.org/schema/webflow"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/webflow
    http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">

<on-start>
    <evaluate expression="requestParameters.contains('from')?requestParameters.get('from'):'home'"
              result="flowScope.from"/>
    <evaluate expression="registrationService.initModel()"
              result="flowScope.model"/>
</on-start>

<view-state id="enterRegistration" model="model">
    <transition on="cancelRegistrationAction" to="exitRegistrationAction"/>
    <transition on="validateRegistrationAction" to="reviewRegistration">
        <evaluate expression="registrationController.validate(model)"/>
    </transition>
</view-state>

<view-state id="reviewRegistration" model="model">
    <transition on="cancelRegistrationAction" to="exitRegistrationAction"/>
    <transition on="reviseRegistrationAction" to="enterRegistration"/>
    <transition on="confirmRegistrationAction" to="exitRegistrationAction">
        <evaluate expression="registrationService.register(model)"/>
    </transition>
</view-state>

<end-state id="exitRegistrationAction" view="externalRedirect:#{from}"/>

<on-end>
    <evaluate expression="registrationController.clearRegistrationModel(flowScope.model)"/>
</on-end>

JSF 页面:

<h:form id="register_form">
                            <p:messages id="register_form_messages_id"/>
                                <p:outputLabel for="register_form_username_inputText_id"
                                               value="#{msgs['user.username.label']}"/>
                                <p:inputText id="register_form_username_inputText_id"                                            
                                             label="#{msgs['user.username.label']}"
                                             value="#{model.username}"/>
                                <p:outputLabel for="register_form_currentEmailValue_inputText_id"
                                               value="#{msgs['user.currentEmailValue.label']}"/>
                                <p:inputText id="register_form_currentEmailValue_inputText_id"
                                             label="#{msgs['user.currentEmailValue.label']}"
                                             value="#{model.email}"/>
                                <p:outputLabel
                                    for="register_form_currentEmailValueRetype_inputText_id"
                                    value="#{msgs['user.currentEmailValueRetype.label']}"/>
                                <p:inputText
                                    id="register_form_currentEmailValueRetype_inputText_id"
                                    label="#{msgs['user.currentEmailValueRetype.label']}"
                                    value="#{model.emailRetype}"/>
                                <p:outputLabel for="register_form_password_inputText_id"
                                               value="#{msgs['user.password.label']}"/>
                                <p:password id="register_form_password_inputText_id"
                                            label="#{msgs['user.password.label']}"
                                            value="#{model.password}"/>
                                <p:outputLabel for="register_form_passwordRetype_inputText_id"
                                               value="#{msgs['user.passwordRetype.label']}"/>
                                <p:password id="register_form_passwordRetype_inputText_id"
                                            label="#{msgs['user.passwordRetype.label']}"
                                            value="#{model.passwordRetype}"/>
                                <p:commandButton
                                    id="exit_registration_cmd_btn_id"
                                    action="cancelRegistrationAction"
                                    value="#{msgs['cancel.button']}"
                                    immediate="true"/>


                                <p:commandButton
                                    id="validate_registration_cmd_btn_id"
                                    action="validateRegistrationAction"
                                    value="#{msgs['register.label']}"
                                    update="@form"
                                    ajax="false"/>
                    </h:form>

我在 openjdk7 tomcat7 mojarra primefaces 下运行,问题与 glassfish 3.1.2、groovy 2.0.5 和 groovy eclipse 编译器、spring 3.2、spring webflow 2.3.1 相同

4

1 回答 1

0

好的,我找到了一种解决方法,但仍然不知道 JSF 生命周期中的“法院电路”是什么,不让消息显示在转换的评估中,所以我不得不使用决策状态来阻止转换并更改控制器方法签名,并使验证过程返回一个布尔值以指示环境验证的天气,并且这种方式强制使用相同的填充请求映射留在此视图上。

import javax.faces.application.FacesMessage
import javax.faces.context.FacesContext
import javax.inject.Inject
import javax.inject.Named
import javax.servlet.http.HttpServletRequest

@Named("registrationController")
class RegistrationController {

static final Logger log = LoggerFactory.getLogger(RegistrationController)

Logger getLog() { return log }

@Inject
@LangServiceQualifier
ILangService langService
@Inject
@RegistrationServiceQualifier
IRegistrationService registrationService


Lang registrationLang() {
    return langService.supportedLangs.find {
        it.code == FacesContext
                .currentInstance
                .externalContext
                .requestLocale
                .language
    } as Lang ?: langService.defaultLang
}

Boolean validateModel(RegistrationModel registrationModel) {
    FacesContext context = FacesContext.currentInstance
    ResourceBundle bundle = ResourceBundle.getBundle(
            II18nConfigService.BUNDLE_BASE_NAME_VALUE,
            context.viewRoot.locale,
            Thread.currentThread().contextClassLoader)
    registrationModel.user.profile.lang ?: registrationModel.user.profile.setLang(registrationLang())
    try {
        registrationService.validate(registrationModel)
        registrationModel.header = new RequestHelper(
                request: context
                        .externalContext
                        .request as HttpServletRequest).header
    } catch (RegistrationException re) {
        assert !re.messages.empty
        re.messages.each {
            switch (it) {
                case new UsernameAlreadyExistsException().message:
                    context.addMessage "register_form_username_inputText_id",
                            new FacesMessage(
                                    severity: FacesMessage.SEVERITY_ERROR,
                                    summary: bundle.getString(it))
                    break
                case new PrimaryEmailAlreadyExistsException().message:
                    context.addMessage "register_form_currentEmailValue_inputText_id",
                            new FacesMessage(
                                    severity: FacesMessage.SEVERITY_ERROR,
                                    summary: bundle.getString(it))
                    break
                case new EmailRetypeException().message:
                    context.addMessage "register_form_currentEmailValueRetype_inputText_id",
                            new FacesMessage(
                                    severity: FacesMessage.SEVERITY_ERROR,
                                    summary: bundle.getString(it))
                    break
                case new PasswordRetypeException().message:
                    context.addMessage "register_form_password_inputText_id",
                            new FacesMessage(
                                    severity: FacesMessage.SEVERITY_ERROR,
                                    summary: bundle.getString(it))
                    break
            }
        }
        return Boolean.FALSE
    }
    return Boolean.TRUE
}
}

流定义

<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/webflow
    http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<on-start>
    <evaluate expression="requestParameters.contains('from')?requestParameters.get('from'):'home'"
              result="flowScope.from"/>
    <evaluate expression="registrationService.initModel()"
              result="flowScope.registrationModel"/>
</on-start>

<view-state id="enterRegistration" model="registrationModel">
    <transition on="validateRegistrationAction" to="isValidModelDecision">
        <evaluate expression="registrationController.validateModel(registrationModel)"
                  result="flowScope.isValidModel"/>
    </transition>
    <transition on="cancelRegistrationAction" to="exitRegistrationAction" history="discard"/>
</view-state>

<decision-state id="isValidModelDecision">
    <if test="isValidModel" then="reviewRegistration" else="enterRegistration"/>
</decision-state>

<view-state id="reviewRegistration" model="registrationModel">
    <transition on="reviseRegistrationAction" to="enterRegistration"/>
    <transition on="confirmRegistrationAction" to="exitRegistrationAction">
        <evaluate expression="registrationService.register(registrationModel)" />
    </transition>
    <transition on="cancelRegistrationAction" to="exitRegistrationAction"     history="discard"/>
</view-state>

<end-state id="exitRegistrationAction" view="externalRedirect:#{from}"/>
</flow>

这只是一种解决方法,而不是解释我的代码有什么问题,只是我的黑客继续。

于 2013-01-29T01:36:42.273 回答