2015-07-24 3 views
3

Je rencontre un comportement étrange avec une action jsf en utilisant p: commandButton. La page correspondante prend en charge certaines tâches de création et de mise à jour. Je peux donc accéder à la page avec un formulaire vierge ou continuer avec certaines données déjà sauvegardées qui sont chargées dans le formulaire. Le bouton qui ne fonctionne pas comme prévu déclenche les actions de sauvegarde pour conserver les informations de formulaires.Action JSF non appelée (une case fonctionne alors que la seconde ne l'est pas)

Maintenant, voici mon problème: Lorsque je continue avec des données déjà sauvegardées et que je clique sur "sauvegarder" tout fonctionne correctement. L'action est appelée et les données sont conservées ou des erreurs de validation sont affichées. Voici quelques instructions que j'ai obtenues en me connectant à MyPhaseListener.afterPhase(). J'ai coupé quelques lignes de journal qui confirment réellement mes données ont été persistées.

10:43:53,959 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:43:53,960 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) AFTER PHASE RESTORE_VIEW 1 
10:43:53,960 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) Method expression of the action being invoked: #{tollRegistrationBean.saveRegistration('CUSTOMER_DATA')} 
10:43:53,960 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:43:53,961 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:43:53,961 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) AFTER PHASE APPLY_REQUEST_VALUES 2 
10:43:53,962 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) Method expression of the action being invoked: #{tollRegistrationBean.saveRegistration('CUSTOMER_DATA')} 
10:43:53,962 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:43:53,963 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:43:53,964 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) AFTER PHASE PROCESS_VALIDATIONS 3 
10:43:53,964 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) Method expression of the action being invoked: #{tollRegistrationBean.saveRegistration('CUSTOMER_DATA')} 
10:43:53,964 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:43:53,965 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:43:53,965 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) AFTER PHASE UPDATE_MODEL_VALUES 4 
10:43:53,965 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) Method expression of the action being invoked: #{tollRegistrationBean.saveRegistration('CUSTOMER_DATA')} 
10:43:53,966 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:43:54,041 INFO [com.egrima.cockpit.beans.toll.TollRegistrationBean] (http-localhost/127.0.0.1:8080-1) WEB: TOLL_REGISTRATION_SAVE "registrationId:210001-2783,registrationStatus:OPEN" 
10:43:54,081 DEBUG [com.egrima.cockpit.beans.toll.TollRegistrationBean] (http-localhost/127.0.0.1:8080-1) Registration saved by user [email protected] and customer number 210001 
10:43:54,081 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:43:54,082 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) AFTER PHASE INVOKE_APPLICATION 5 
10:43:54,083 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) Method expression of the action being invoked: #{tollRegistrationBean.saveRegistration('CUSTOMER_DATA')} 
10:43:54,083 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:43:54,121 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:43:54,121 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) AFTER PHASE RENDER_RESPONSE 6 
10:43:54,121 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) Method expression of the action being invoked: #{tollRegistrationBean.saveRegistration('CUSTOMER_DATA')} 
10:43:54,121 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 

Maintenant la partie Stange est quand je fais l'enregistrer de nouvelles données il n'y a pas d'action appelée. L'objectif n'est donc pas de mettre à jour les données existantes mais d'insérer de nouvelles données, mais cette différence est plus intéressante pour ma couche JPA que pour le bean JSF. Le cycle de vie est traité normalement mais aucune action n'est appelée.

10:51:10,813 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:51:10,813 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) AFTER PHASE RESTORE_VIEW 1 
10:51:10,813 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:51:10,813 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:51:10,813 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) AFTER PHASE APPLY_REQUEST_VALUES 2 
10:51:10,814 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:51:10,814 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:51:10,814 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) AFTER PHASE PROCESS_VALIDATIONS 3 
10:51:10,814 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:51:10,814 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:51:10,814 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) AFTER PHASE UPDATE_MODEL_VALUES 4 
10:51:10,814 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:51:10,814 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:51:10,815 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) AFTER PHASE INVOKE_APPLICATION 5 
10:51:10,815 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:51:10,825 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 
10:51:10,825 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) AFTER PHASE RENDER_RESPONSE 6 
10:51:10,825 INFO [com.egrima.cockpit.server.LifeCycleListener] (http-localhost/127.0.0.1:8080-1) -------------------------------------------------------------------- 

En dehors de l'appel de l'action, il semble assez similaire. Et c'est ce que je ne peux pas comprendre. Je clique exactement sur le même bouton et appelle exactement la même action.

Voici mon fichier xhtml complet avec le formulaire h:. Je l'ai raccourci légèrement. Le fichier entier contient plus de champs de saisie (ils suivent tous le même modèle) et quelques balises supplémentaires qui ne sont importantes que pour le stylisme.

<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:fn="http://java.sun.com/jsp/jstl/functions" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:p="http://primefaces.org/ui" 
    xmlns:ui="http://java.sun.com/jsf/facelets"> 
    <h:form id="tollCustomerForm"> 

     <h:panelGrid columns="3" cellpadding="0" styleClass="width-100" columnClasses="width-50 valign-top, width-50 valign-top"> 

      <h:panelGrid columns="2" columnClasses="width-30, width-70 space-right" rendered="#{tollRegistrationBean.registration.customerData.company.visible}"> 
       <h:panelGroup> 
        <h:outputLabel for="inputCompany" value="#{msg.toll_registration_customerData_company}" /> 
        <h:outputLabel value=" #{msg.gloabl_required_field_sign}" rendered="false" /> 
       </h:panelGroup> 
       <h:inputText id="inputCompany" value="#{tollRegistrationBean.registration.customerData.company.value}" 
        styleClass="#{!component.valid ? 'errorInputText' : 'dkv-inputText'}" readonly="true" disabled="#{tollRegistrationBean.registrationSent}" 
        label="#{msg.toll_registration_accordion_tab_customer_data} - #{msg.toll_registration_customerData_company}" required="false" /> 
      </h:panelGrid> 
      <h:panelGrid columns="2" columnClasses="width-30, width-70 space-right" rendered="#{tollRegistrationBean.registration.customerData.addressAddition.visible}"> 
       <h:panelGroup> 
        <h:outputLabel for="inputCountry" value="#{msg.toll_registration_customerData_country}" /> 
        <h:outputLabel value=" #{msg.gloabl_required_field_sign}" rendered="false" /> 
       </h:panelGroup> 
       <h:inputText id="inputCountry" value="#{tollRegistrationBean.getCountryName(tollRegistrationBean.registration.customerData.country.value)}" 
        styleClass="#{!component.valid ? 'errorInputText' : 'dkv-inputText'}" readonly="true" disabled="#{tollRegistrationBean.registrationSent}" 
        label="#{msg.toll_registration_accordion_tab_customer_data} - #{msg.toll_registration_customerData_country}" required="false" /> 
      </h:panelGrid> 
      <h:panelGrid columns="2" columnClasses="space-left width-30, width-70" rendered="#{customerBean.renderCustomernumbers}"> 
       <h:panelGroup> 
        <h:outputLabel for="inputCustomerNumber" value="#{msg.toll_registration_customerData_customerNumber}" /> 
        <h:outputLabel value=" #{msg.gloabl_required_field_sign}" rendered="false" /> 
       </h:panelGroup> 
       <h:inputText id="inputCustomerNumber" value="#{customerBean.customernumber}" 
        styleClass="#{!component.valid ? 'errorInputText' : 'dkv-inputText'}" readonly="true" disabled="#{tollRegistrationBean.registrationSent}" 
        label="#{msg.toll_registration_accordion_tab_customer_data} - #{msg.toll_registration_customerData_customerNumber}" required="false" /> 
      </h:panelGrid> 
      <h:panelGrid columns="2" columnClasses="space-left width-30, width-70" rendered="#{tollRegistrationBean.registration.customerData.email.visible}"> 
       <h:panelGroup> 
        <h:outputLabel for="inputEmail" value="#{msg.toll_registration_customerData_email}" /> 
        <h:outputLabel value=" #{msg.gloabl_required_field_sign}" rendered="false" /> 
       </h:panelGroup> 
       <h:inputText id="inputEmail" value="#{tollRegistrationBean.registration.customerData.email.value}" 
        styleClass="#{!component.valid ? 'errorInputText' : 'dkv-inputText'}" readonly="true" disabled="#{tollRegistrationBean.registrationSent}" 
        label="#{msg.toll_registration_accordion_tab_customer_data} - #{msg.toll_registration_customerData_email}" required="false" /> 
      </h:panelGrid> 

     </h:panelGrid> 

     <!-- ########## THE STRANGE SAVE BUTTON ########## --> 
     <p:commandButton value="#{msg.toll_registration_accordion_save_step_button}" id="saveRegBtn" update=":tollAccordion :tollSelectionForm:globalMessages :tollSelectionForm:registrationProgressBar" 
      action="#{tollRegistrationBean.saveRegistration('CUSTOMER_DATA')}" disabled="#{tollRegistrationBean.registrationSent}" styleClass="dkv-button" > 
       <p:resetInput target=":tollAccordion:tollCustomerForm" /> 
     </p:commandButton> 
     <!-- ########## THE STRANGE SAVE BUTTON ########## --> 

     <!-- preValidation method only executed, if submit button is pressed (not called, if save-button is clicked) --> 
     <h:panelGroup rendered="#{param['tollAccordion:tollCustomerForm:saveAndNextStepRegBtn']!=null}"> 
      <f:event listener="#{tollRegistrationBean.listenNextAccordionStep}" type="preValidate" /> 
      <f:attribute name="currentAccordionStep" value="CUSTOMER_DATA" /> 
     </h:panelGroup> 

    </h:form> 
</ui:composition> 

Cette composition ui: est incluse dans un autre fichier xhtml avec des informations de mise en page. Ce modèle de présentation est plutôt non-spectaculaire et n'inclut pas de formulaire h: il n'y a donc pas de formulaires imbriqués.

et mon (raccourci) haricot jsf

@Component 
@Scope("view") 
public class TollRegistrationBean implements Serializable { 

    ... 

    @PostConstruct 
    public void init() { 

     // get registrationId by param and load registration 
     RequestContext context = RequestContext.getCurrentInstance(); 
     String registrationId = (String)context.getCallbackParams().get(TollRegistrationMainBean.CALLBACK_PARAM_SELECTED_REGISTRATION_ID); 
     if (registrationId != null && !registrationId.isEmpty()) { 
      registration = tollPersistingService.loadRegistrationAndCheckFields(registrationId); 
     } 

     if (registration != null) { 
      createAccordionOrder(); 
      selectedTolls = registration.getTollTypes(); 

      // update saved customer data, read from DB, with data from crm 
      tollCustomerBean.loadCustomerDataFromCRM(registration); 
     } 

     activeIndex = 0; 
     registrationSent = false; 
    } 

    public void saveRegistration(String currentAccordionStep) { 
     log.info("TollRegistrationBean.saveRegistration()"); 

     try { 
      tollPersistingService.saveRegistration(registration, customerBean.getCustomernumber()); 
      activeIndex = accordionOrder.indexOf(currentAccordionStep); 
      registration.getStepByStepName(StepName.valueOf(currentAccordionStep)).setCssAccordionIcon(""); 

      FacesContext.getCurrentInstance().addMessage(null, 
        new FacesMessage(FacesMessage.SEVERITY_INFO, MessageUtils.getMessage("toll_registration_info_saved_successfully"), "")); 

      String userEmail = UserUtils.getCurrentUser().getEmailAddress(); 
      log.database(AdvancedLoggerUtils.Actions.TOLL_REGISTRATION_SAVE.name(), registration.toDatabaseLogString(), userEmail, 
        AdvancedLoggerUtils.System.WEB.name()); 
      log.debug("Registration saved by user " + userEmail + " and customer number " + customerBean.getCustomernumber()); 
     } catch (Exception e) { 
      log.error(e.getMessage(), e); 
     } 
    } 

} 

J'utilise JSF 2.2, 5.2 et Primefaces printemps 4.1.4.RELEASE.

Quelqu'un a-t-il déjà éprouvé le même problème ou un problème similaire? Je serais vraiment reconnaissant pour toute aide ou indice. Je suis un peu coincé avec ça.

Merci et salutations Sebastian

+0

Et vous utilisez Spring ... pourquoi ne pas ajouter que les balises? – Kukeltje

+0

Pourriez-vous ajouter le formulaire entier à votre message? – javahippie

+0

J'ai mis à jour les informations du printemps et l'étiquette ci-dessus (merci pour l'indice) et posté mon fichier xhtml ci-dessous. –

Répondre

2

Bonjour Sébastien,

la forme ne peut pas être submited si p: remoteCommand est toujours en cours d'exécution. Vous devez le placer sous une forme séparée ...

Meilleures salutations

+0

Comment saviez-vous que OP utilisait remoteCommand? Cela n'est indiqué nulle part dans la question (que je peux voir de toute façon). Y a-t-il de la documentation qui indique cette information que vous avez ici comme réponse? – kolossus