2017-10-16 3 views
0

Ich bin neu bei Builder-Mustern und versuche, einen Weg zu finden, Builder-Muster in meinen Spring-Modellen zu verwenden.Verwenden von Spring @ModelAttribute mit Builder-Mustern

Mein Vorgänger hatte alle Setter und Getter-Methoden, die ich mit Builder Methoden ersetzt und die nun der Code sieht ungefähr so ​​aus:

public class UserInterests { 
    private final String user; 
    private final int interestlevel; 

    private UserInterests(UserInterestBuilder builder) { 
     this.user = builder.user; 
     this.interestlevel = builder.interestlevel; 
    } 

    public String getUser() { 
     return user; 
    } 

    public static class UserInterestBuilder { 
     private String user; 
     private int interestlevel; 

     public UserInterestBuilder() { 
     } 

     public UserInterestBuilder user(final String userId) { 
      this.user = user; 
      return this; 
     } 

     public UserInterestBuilder interestLevel(final int interestLevel) { 
      this.interestLevel = interestLevel; 
      return this; 
     } 

     public UserInterests build() { 
      return new UserInterests(this); 
     } 
    } 
} 

Bisher ohne Bauherren ich den Benutzer interestlevel von der Benutzeroberfläche wurde unter (jsp) und verband es mit einem UserInterests-Modell. In der Steuerung habe ich @ModelAttribute verwendet, um die Instanz der UserInterests zu holen und benutzte sie.

Controller-Schnipsel:

@RequestMapping(value = "/addInterest", method = RequestMethod.POST) 
public ModelAndView addUserInterest(
     @ModelAttribute(USER_INTEREST) UserInterests userInterests, 
     BindingResult result, HttpSession session, ModelAndView model) { 
//do something here 
} 

JSP Snippet

<html> 
<head></head> 
<body> 
    <form:form modelAttribute="userInterests" action="addInterest" 
method="post"> 
<!-- Do more --> 
</body> 
</html>       

Aber da ich das Modell geändert Builder zu verwenden, kann ich nicht userInterests Modellinstanz als der Konstruktor dies ist privat nutzen. Ich kann die Benutzer- und interestlevel-Werte mit request.getParameter() separat abrufen und mit dem Build-Modell an das userInterests-Modell binden. Aber gibt es eine Möglichkeit, @ModelAttribute für Builder direkt zu verwenden, um Werte separat abrufen zu müssen.

Jede Hilfe wird sehr geschätzt.

Antwort

0

Die Annotation ModelAttribute wird von ModelAttributeMethodProcessor verarbeitet und Attribute werden über Datenbindung an Servlet-Anforderungsparameter aufgefüllt. Witthin der Eingeweide von Databindern wird Verfahren folgenden, die das

protected void applyPropertyValues(MutablePropertyValues mpvs) { 
     try { 
      // Bind request parameters onto target object. 
      getPropertyAccessor().setPropertyValues(mpvs, isIgnoreUnknownFields(), isIgnoreInvalidFields()); 
     } 
     catch (PropertyBatchUpdateException ex) { 
      // Use bind error processor to create FieldErrors. 
      for (PropertyAccessException pae : ex.getPropertyAccessExceptions()) { 
       getBindingErrorProcessor().processPropertyAccessException(pae, getInternalBindingResult()); 
      } 
     } 
    } 

Mit Blick auf BeanWrapperImpl Bindung tatsächlich tut, was die häufigste Eigenschaftenaccessor ist, ist es ein grundlegendes Merkmal hat Standard-Auto-Registrierung property editors von den Federpaketen zusätzlich zu die JDK-Standard-PropertyEditors, also im Grunde ist es vollständig mit JavaBeans (im Grunde Eigenschaften und ihre Accessoren mit speziellen Namenskonvention) verbunden, was bedeutet, dass es keine Unterstützung für andere Stil wie in Ihrem Fall Builder-Muster hat.

+0

Also, gibt es eine Möglichkeit, Builder-Muster mit meiner Abhängigkeitsinjektion zu verwenden. –

+0

Wenn Sie automatische Datenbindungseinrichtung wollen, dann können Sie nicht. Sie müssen das modelAtrribute mithilfe der Builder-API manuell in ein anderes Objekt konvertieren. – Shailendra

0

Wenn Sie Ihren Builder wirklich verwenden möchten, um UserInterests zu injizieren, können Sie Ihre eigene HandlerMethodArgumentResolver schreiben, die die Anfrage prüft und den UserInterestBuilder verwendet, um die Instanz von UserInterests bereitzustellen. Insbesondere finde ich es ein wenig erzwungen, und dieses Szenario könnte einfacher gemacht werden, indem Objekte erstellt werden, indem Command- oder Form-Objekte zum Binden von Parametern verwendet werden.

Verwandte Themen