2012-11-20 16 views
9

Ich bin neu bei Spring MVC. Ich schreibe eine App, die Spring, Spring MVC und JPA/Hibernate verwendet Ich weiß nicht, wie Spring MVC einen Wert aus einem Dropdown in ein Modellobjekt setzen. Ich kann dies ein sehr häufiges SzenarioDropdown-Wert Bindung im Frühjahr MVC

hier vorstellen, ist der Code:

Invoice.java

@Entity 
public class Invoice{  
    @Id 
    @GeneratedValue 
    private Integer id; 

    private double amount; 

    @ManyToOne(targetEntity=Customer.class, fetch=FetchType.EAGER) 
    private Customer customer; 

    //Getters and setters 
} 

Customer.java

@Entity 
public class Customer { 
    @Id 
    @GeneratedValue 
    private Integer id; 

    private String name; 
    private String address; 
    private String phoneNumber; 

    //Getters and setters 
} 

invoice.jsp

<form:form method="post" action="add" commandName="invoice"> 
    <form:label path="amount">amount</form:label> 
    <form:input path="amount" /> 
    <form:label path="customer">Customer</form:label> 
    <form:select path="customer" items="${customers}" required="true" itemLabel="name" itemValue="id"/>     
    <input type="submit" value="Add Invoice"/> 
</form:form> 

RechnungCon troller.java

@Controller 
public class InvoiceController { 

    @Autowired 
    private InvoiceService InvoiceService; 

    @RequestMapping(value = "/add", method = RequestMethod.POST) 
    public String addInvoice(@ModelAttribute("invoice") Invoice invoice, BindingResult result) { 
     invoiceService.addInvoice(invoice); 
     return "invoiceAdded"; 
    } 
} 

Wenn InvoiceControler.addInvoice() aufgerufen wird, eine Rechnung Instanz als Parameter erhalten. Die Rechnung hat einen erwarteten Betrag, aber das Kundeninstanzattribut ist null. Dies liegt daran, dass die http-Post die Kundennummer übermittelt und die Invoice-Klasse ein Customer-Objekt erwartet. Ich weiß nicht, was der Standard ist, um das zu konvertieren.

Ich habe über Controller.initBinder(), über Spring Type-Konvertierung (in http://static.springsource.org/spring/docs/current/spring-framework-reference/html/validation.html) gelesen, aber ich weiß nicht, ob das die Lösung für dieses Problem ist.

Irgendwelche Ideen?

+3

Ich habe ersetzt sie arbeiten by

Antwort

7

Der Trick, wie Sie bereits bemerkt haben, besteht darin, einen benutzerdefinierten Konverter zu registrieren, der die ID aus dem Dropdown in eine benutzerdefinierte Instanz konvertiert.

Sie können einen benutzerdefinierten Konverter auf diese Weise schreiben:

public class IdToCustomerConverter implements Converter<String, Customer>{ 
    @Autowired CustomerRepository customerRepository; 
    public Customer convert(String id) { 
     return this.customerRepository.findOne(Long.valueOf(id)); 
    } 
} 

Jetzt diesen Konverter mit Spring MVC registrieren:

<mvc:annotation-driven conversion-service="conversionService"/> 

<bean id="conversionService" 
    class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> 
    <property name="converters"> 
     <list> 
      <bean class="IdToCustomerConverter"/> 
     </list> 
    </property> 
</bean> 
+2

Was ich an einem solchen Ansatz nicht mag, ist, dass Sie das Datenobjekt mit dieser ID bereits aus der Datenbank geladen haben. Wenn Sie es jetzt von String in Objekt zurück konvertieren, holen Sie es erneut von db. –

+0

@Biju Kunjummen: Könnten Sie Ihre Antwort bitte auch mit dem Annotations- und Controller-Klassencode aktualisieren? –