2017-02-25 251 views
10

我是Spring中的新用戶,註冊了一個user.I的確如此。Spring:使用和不使用@ModelAttribute的綁定對象

@RequestMapping("/register") 
    public String register(@ModelAttribute User user,BindingResult result){ 
     if(!result.hasErrors()){ 
     userSerive.register(user); 
     } 
    return "welcome"; 
} 

這工作得很好,但這裏的問題是我不需要這個user對象在我welcome.jsp頁,何必讓模型對象heavier.So我嘗試沒有@ModelAttribute,這也是對我的作品像下面。

@RequestMapping("/register") 
    public String register(User user,BindingResult result){ 
     if(!result.hasErrors()){ 
     userSerive.register(user); 
     } 
    return "welcome"; 
} 

所以,我只是想知道什麼是優點的缺點&都和這是最好的做法,如果我真的不需要在jspuser對象。是否@ModelAttribute除了向Model添加對象之外還有其他的事情,哪些彈性隱式綁定不行。是否更安全的綁定方式呢?

我想我的類別在以下4種類型request.what的將是和不含@ModelAttribute如果我不需要考慮發送數據,我的要求是任何OF-

  1. 查詢字符串即查詢在GET形式的數據在POST
  2. 請求有效載荷或體即形式數據
  3. 在Ajax化JSON數據GET requst
  4. 在POST JSON數據requst-我想這不會是綁定在任何兩個。 @RequestBody是必需的。
+0

你不能在這個問題上開始賞金,因爲賞金每次都必須增加價值,下一個增量是100代表。 – Ryan

回答

0

如Spring MVC文檔中所述 - @ModelAttribute註釋可用於方法或方法參數。當然,我們可以同時在一個控制器中使用。

方法註解

@ModelAttribute("person") 
public Person getPerson(){ 
    return new Person(); 
} 

這種方法的目的是在模型中添加屬性。所以在我們的案例中,人物關鍵詞將人對象作爲模型中的值。在同一個控制器中的@RequestMapping方法之前調用控制器中的@ModelAttribute方法。

方法參數

public String processForm(@ModelAttribute("person") Person person){ 
    person.getStuff(); 
} 

見Spring文檔http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/mvc.html#mvc-ann-modelattrib-method-args

+0

你缺少上下文。根據我的用例,我不需要模型在視圖層,我可以綁定帶有和不帶'@ ModelAttribute'的java中的formdata,如果我們不需要jsp中的這個模型,兩種方法之間有什麼區別。 – TheCurious

3

有可能是(見下文......)在你的情況下,兩個方法簽名的行爲沒有什麼區別。

兩者都將請求參數綁定到user並將所得物添加到模型中作爲屬性user - 該屬性名從方法的參數,User的decapitalised類型名稱中導出。

@ModelAttribute可用於定製屬性的名稱,例如, @ModelAttribute("theUser"),或者向您的代碼的讀者提示此參數在視圖中使用。但正如你所說,這些都不適用於你的用例。

無論您是否使用@ModelAttribute註釋,Spring中完全相同的代碼都將用於填充參數 - 所涉及的代碼爲org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor

因此,我更願意在代碼中使用public String register(User user, BindingResult result)簽名。將@ModelAttribute註釋添加到模型中不需要的方法參數中可能會讓讀取代碼的人感到困惑。


稍長的答案是,有可能只是是針對你的情況,指定@ModelAttribute有原因的 - 但它是很神祕的,不可能。

Spring處理程序方法中的方法參數由HandlerMethodArgumentResolver實例填充。這些是可配置的,並依次嘗試每個參數。

的默認處理方法的參數解析器是這樣的(見RequestMappingHandlerAdapter):

resolvers.add(new ServletModelAttributeMethodProcessor(false)); 

... 

resolvers.add(new ServletModelAttributeMethodProcessor(true)); 

如果你要添加自己在中間,例如一個UserHandlerMethodArgumentResolver,然後你可以使用@ModelAttribute告訴Spring以默認方式處理特定的參數,而不是使用自定義參數解析器類。

+0

這是OP問題的答案。 – John

1

除了將對象添加到模型之外,Spring MVC還使用它將綁定對象提供給Controller方法,您可以在其中使用它,以便「註冊」。

是的@ModelAtttribute是Spring MVC中最安全和最好的方法,可將傳入的發佈數據綁定到對象。

0

檢查這個職位here。它涵蓋了ModelAttribute的大量細節。

ModelAttribute只能與表單編碼的請求數據一起使用。它不能將json/xml請求數據與數據對象綁定。爲此,您將不得不使用RequestBody。

1

這個問題是非常有用的,但我沒有看到答覆在這裏正確回答問題。

我通過計算器多線程讀取,並發現這是非常有用的: https://stackoverflow.com/a/26916920/1542363

對於自己如何決定使用哪一個,如果我只需要綁定,並且不希望存儲參數對象在模型中,則不要使用@ModelAttribute

除了@ryanp的完美的答案
+0

我發現任何原因存儲模型參數對象除了發送到像jsp.yes這樣的意見我的問題是關於是否有任何其他原因相同。 – TheCurious

0

,我想補充:

現代Spring MVC的項目,這是最保險的人會使用像@Controller和@RequestMapping等註釋,提供請求處理程序在內部,Spring MVC使用RequestMappingHandlerAdapter.invokeHandlerMethod()來處理用戶提供的HandlerMethod的請求。如果您查看RequestMappingHandlerAdapter,它將設置一個參數解析器集合以準備HandlerMethod參數,通過查看該集合,您可以瞭解Spring MVC如何以及以何種順序解析請求並填充用戶提供的參數。所以這裏的源代碼:

```Java的

/** 
* Return the list of argument resolvers to use including built-in resolvers 
* and custom resolvers provided via {@link #setCustomArgumentResolvers}. 
*/ 
private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() { 
    List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>(); 

    // Annotation-based argument resolution 
    resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false)); 
    resolvers.add(new RequestParamMapMethodArgumentResolver()); 
    resolvers.add(new PathVariableMethodArgumentResolver()); 
    resolvers.add(new PathVariableMapMethodArgumentResolver()); 
    resolvers.add(new MatrixVariableMethodArgumentResolver()); 
    resolvers.add(new MatrixVariableMapMethodArgumentResolver()); 
    resolvers.add(new ServletModelAttributeMethodProcessor(false)); 
    resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice)); 
    resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice)); 
    resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory())); 
    resolvers.add(new RequestHeaderMapMethodArgumentResolver()); 
    resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory())); 
    resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory())); 
    resolvers.add(new SessionAttributeMethodArgumentResolver()); 
    resolvers.add(new RequestAttributeMethodArgumentResolver()); 

    // Type-based argument resolution 
    resolvers.add(new ServletRequestMethodArgumentResolver()); 
    resolvers.add(new ServletResponseMethodArgumentResolver()); 
    resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice)); 
    resolvers.add(new RedirectAttributesMethodArgumentResolver()); 
    resolvers.add(new ModelMethodProcessor()); 
    resolvers.add(new MapMethodProcessor()); 
    resolvers.add(new ErrorsMethodArgumentResolver()); 
    resolvers.add(new SessionStatusMethodArgumentResolver()); 
    resolvers.add(new UriComponentsBuilderMethodArgumentResolver()); 

    // Custom arguments 
    if (getCustomArgumentResolvers() != null) { 
     resolvers.addAll(getCustomArgumentResolvers()); 
    } 

    // Catch-all 
    resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true)); 
    resolvers.add(new ServletModelAttributeMethodProcessor(true)); 

    return resolvers; 
} 

```

什麼值得指出的是在底部無限別名解析器。 Spring MVC使用兩個相同的處理@RequestParam和@ModelAttribute的解析器分別處理未註釋的簡單類型和pojo類型參數。這就是爲什麼在OP的測試中,不管是否有@ModelAttribute都沒關係。

令人遺憾的是,在Spring MVC的參考文獻中,它並沒有被弄清楚。

相關問題