2012-09-09 17 views
7

Non sono sicuro che si tratti di un problema complesso, ma come persona di partenza mi sembra un po 'complesso. Ho un oggetto in base al quale ho bisogno di mostrare alcuni valori sull'interfaccia utente e lasciare che l'utente ne selezioni alcuni, ho bisogno di inviare i dati a un altro controller quando l'utente fa clic sul pulsante di invio.Qui è la struttura del mio oggetto datiAssociazione di una mappa di liste in Spring MVC

public class PrsData{ 
private Map<String, List<PrsCDData>> prsCDData; 
} 

public class PrsCDData{ 
    private Map<String, Collection<ConfiguredDesignData>> configuredDesignData; 
} 

public ConfiguredDesignData{ 
    // simple fields 
} 

ho impostare l'oggetto nel modello prima mostra la vista simile

model.addAttribute("prsData", productData.getPrData()); 

nella forma ho seguenti impostazioni

<form:form method="post" commandName="prsData" action="${addProductToCartAction}" > 
<form:hidden path="prsCDData['${prsCDDataMap.key}'] 
    [${status.index}].configuredDesignData['${configuredDesignDataMap.key}'] 
    [${configuredDesignDataStatus.index}].code"/> 

<form:hidden path="prsCDData['${prsCDDataMap.key}'] 
    [${status.index}].configuredDesignData['${configuredDesignDataMap.key}'] 
    [${configuredDesignDataStatus.index}].description"/> 

</form:form> 

Questo è quello che ho a AddProductToCartController

public String addToCart(@RequestParam("productCodePost") final String code, 
@ModelAttribute("prsData") final PrsData prsData, final Model model, 
@RequestParam(value = "qty", required = false, defaultValue = "1") final long qty) 

Sulla inviando il modulo che sto ottenendo seguente eccezione

org.springframework.beans.NullValueInNestedPathException: Invalid property 'prsCDData[Forced][0]' 
of bean class [com.product.data.PrsData]: 
Cannot access indexed value of property referenced in indexed property path 'prsCDData[Forced][0]': returned null 

Sembra che il suo tentativo di accedere ai valori di questo controller, mentre sto cercando di trasmettere il valore a tale controller e cercando di creare lo stesso oggetto con valori selezionati

uno può dire dove sto facendo male e che cosa ho bisogno di prendersi cura di

Modifica

ho fatto qualche ricerca ed è venuto a sapere che la primavera non supportano auto-popolamento elenco/carta per oggetti personalizzati e in base alla risposta che ho cercato di cambiare implementazione come

public class PrsData{ 
    private Map<String, List<PrsCDData>> prsCDData; 
    // lazy init 
    public PrsData() 
    { 
      this.prsCDData = MapUtils.lazyMap(new HashMap<String, List<PrsCDData>>(), 
       FactoryUtils.instantiateFactory(PrsCDData.class)); 
     } 
    } 

    public class PrsCDData{ 
     private Map<String, Collection<ConfiguredDesignData>> configuredDesignData; 
     public PrsCDData() 
    { 

     this.configuredDesignData = MapUtils.lazyMap(new HashMap<String, 
             List<ConfiguredDesignData>>(), 
      FactoryUtils.instantiateFactory(ConfiguredDesignData.class)); 

    } 
    } 

ma sto ottenendo seguente eccezione

org.springframework.beans.InvalidPropertyException: 
Invalid property 'prsCDData[Forced][0]' of bean class [com.data.PrsData]: 
Property referenced in indexed property path 'prsCDData[Forced][0]' 
is neither an array nor a List nor a Set nor a Map; 
returned value was [[email protected]] 

non sono sicuro che cosa sto facendo male, sembra che sia la mia espressione JSTL non è giusto

+0

Un'altra cosa a cui prestare attenzione in questo scenario è classi nidificate. Rendere 'PrsCDData' una classe di alto livello potrebbe evitare questo problema. –

risposta

7

Spiegazione: se nel controller è presente @ModelAttribute("user") User user e si carica una pagina corrispondente contenente <form:form commandName="user">, viene creato un Utente vuoto.

Tutti gli attributi sono nulli o vuoti in caso di elenco o mappa. Inoltre, le sue liste/mappe vuote sono state istanziate con un'implementazione di crescita automatica. Cosa significa ? Diciamo che abbiamo un autogrowing vuoto List<Coconut> coconuts. Se faccio coconuts.get(someIndex).setDiameter(50), funzionerà invece di lanciare un'eccezione, perché l'elenco auto cresce e crea un'istanza di una noce di cocco per l'indice specificato.
Grazie a questo aumento automatico, presentando un modulo con l'ingresso di seguito funzionerà come un fascino:

<form:input path="coconuts[${someIndex}].diameter" /> 

Ora torna al tuo problema: Spring MVC l'aumento automatico funziona abbastanza bene con una catena di oggetti, ognuno contenente una mappa/elenco (see this post). Ma data la tua eccezione, sembra che Spring non aumenti automaticamente i possibili oggetti contenuti nella lista/mappa a crescita automatica.In Map<String, List<PrsCDData>> prsCDData, lo List<PrsCDData> è una semplice lista vuota senza radiazioni automatiche, che porta quindi all'eccezione.

Quindi la soluzione deve utilizzare una sorta di Apache Common LazyList o Spring's AutoPopulatingList.
È necessario implementare la propria mappa di crescita automatica che crea un'istanza di LazyList/AutoPopulatingList per un dato indice. Da zero o utilizzando una sorta di implementazione di Apache Common LazyMap/MapUtils.lazyMap (finora non ho trovato un equivalente Spring per LazyMap).

Esempio di soluzione, utilizzando Apache Commons Collezioni:

public class PrsData { 

    private Map<String, List<PrsCDData>> prsCDData; 

    public PrsData() { 
     this.prsCDData = MapUtils.lazyMap(new HashMap<String,List<Object>>(), new Factory() { 

      public Object create() { 
       return LazyList.decorate(new ArrayList<PrsCDData>(), 
          FactoryUtils.instantiateFactory(PrsCDData.class)); 
      } 

     }); 
    } 

} 
+0

Bella spiegazione! Proveremo come da te suggerito e aggiorneremo –

+0

cercando il primo approccio dando la seguente eccezione 'org.springframework.beans.NullValueInNestedPathException: Proprietà non valida 'prsBTOData' di classe bean [data.data.PrsData]: Impossibile istanziare il tipo di proprietà [org .springframework.util.AutoPopulatingList] per auto-crescere percorso proprietà nidificata: java.lang.IllegalArgumentException: Impossibile istanziare Tipo di raccolta: org.springframework.util.AutoPopulatingList' –

+0

puoi spiegare il secondo approccio più come non è molto chiaro a me. –

Problemi correlati