2015-07-01 25 views
8

Ich lerne Spring-MVC 4 kommend von asp.net MVC und ich suchte nach einer Möglichkeit, Daten an die Ansicht zu übergeben, ohne ein Modell Atrribute in jedem Anruf zu deklarieren.Zugriff auf aktuelles Modell im Frühjahr-mvc

Zum Beispiel, jetzt habe ich das.

public class BaseController { 
    public void AddMessage(Model model, String m) { 
     Model.addAttribute("msg", m); 
    } 
} 

public class PersonController extends BaseController{ 
     @RequestMapping("details/{Id}") 
     public String details(@PathVariable int Id, Model model) { 
      Person p = service.LoadById(Id); 

      if(p == null) { 
       AddMessage(model, "Record not found..."); 
      } else { 
       model.addAttribute("bean", q); 
      } 

      return "person/details"; 
     } 
} 

Aber was ich wirklich mag, ist, einen Weg zu haben, dass die Modell-Instanz in meinen Basis-Controller Methoden Acess, ohne sie auf als Argument passieren zu müssen. Ähnlich der Verwendung von ViewData oder TempData in asp.net MVC.

Ist es möglich, Daten auf diese Weise an die Ansicht weiterzugeben? http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/ModelAttribute.html

Nur mit Anmerkungen versehen, das Verfahren und Spring automatisch hinzufügen, was die Methode:

Danke

+0

Was möchten Sie mit dem Modell machen? –

Antwort

1

Ich habe es geschafft, dieses Problem mit einem Anfrage Interceptor zu umgehen. Im Wesentlichen:

Auf meiner Basis-Controller-Klasse:

public abstract class BaseController { 

    protected List<UserViewMessage> viewMessages; 

    public List<UserViewMessage> getViewMessages() { 
     if (viewMessages == null) { 
      viewMessages = new ArrayList<UserViewMessage>(); 
     } 

     return viewMessages; 
    } 

    public void addMessage(String message, UserViewMessageType type) { 
     getViewMessages().add(new UserViewMessage(message, type)); 
    } 

    public void clearMessages() { 
     if (viewMessages != null) { 
      viewMessages.clear(); 
     } 
    } 
} 

Dann fügte ich einen Abfangjäger die Nachrichten-Sammlung auf das Modell zu kopieren:

public class RequestInterceptor extends HandlerInterceptorAdapter { 

    private static String MODEL_MESSAGES_KEY = "ModelMessageList_"; 

    @Override 
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 
      throws Exception { 

     if (handler instanceof org.springframework.web.method.HandlerMethod) { 

      HandlerMethod handlerMethod = (HandlerMethod) handler; 

      if (handlerMethod != null) { 
       Object bean = handlerMethod.getBean(); 

       if (bean != null && bean instanceof BaseController) { 

        BaseController bc = (BaseController) bean; 
        bc.clearMessages(); 
       } 
      } 
     } 

     return super.preHandle(request, response, handler); 
    } 

    @Override 
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, 
      ModelAndView modelAndView) throws Exception { 

     if (handler instanceof org.springframework.web.method.HandlerMethod) { 

      HandlerMethod handlerMethod = (HandlerMethod) handler; 

      if (handlerMethod != null && modelAndView != null) { 
       Object bean = handlerMethod.getBean(); 

       if (bean != null && bean instanceof BaseController) { 

        BaseController bc = (BaseController) bean; 

        if (bc.getViewMessages() != null) { 
         modelAndView.addObject(MODEL_MESSAGES_KEY, bc.getViewMessages()); 
        } 
       } 
      } 
     } 

     super.postHandle(request, response, handler, modelAndView); 
    } 
} 

, die auf PreHandle, löscht auf alle Nachrichten die Basis-Controller-Sammlung. Nach der Anfrage (PostHandle) und da das Modell verfügbar ist, kopiere ich die Nachricht Sammlung an das Modell, so dass es auf meinen Ansichten zur Verfügung wie folgt:

<div class="row"> 
    <div class="col-lg-12"> 
     <c:forEach var="messageItem" items="${_ModelMessageList_}"> 
      <div class="alert alert-info"><c:out value="${messageItem.message}" /></div> 
     </c:forEach> 
    </div> 
</div> 

Es ist nicht optimal, aber es funktioniert.

0

Wenn Sie das Modell vorbei als Methodenparameter vermeiden möchten, können Sie ModelAttribute Anmerkung in einer Methode verwenden, kehrt zum Modell zurück.

@ModelAttribute 
public Stuff addStuffToModel() { 
     Stuff stuff = new Stuff("dummy data"); 
     return stuff; // stuff is added to the model 
} 
+0

Gibt es einen anderen Weg? Wie Sie sich vorstellen könnten, dem Modell Fehlermeldungen hinzuzufügen (zum Beispiel), müssen Sie eine Liste aus dem Modell abrufen und dann etwas hinzufügen. Also muss ich wirklich auf die Model-Instanz zugreifen – tggm

+0

@TiagoMatias Denken Sie in AOP oder ähnlichem? –

Verwandte Themen