簡體   English   中英

Spring MVC 中的@ModelAttribute 是什么?

[英]What is @ModelAttribute in Spring MVC?

Spring MVC中@ModelAttribute的用途和用途是什么?

@ModelAttribute指的是 Model 對象的一個​​屬性(MVC 中的 M ;)所以假設我們有一個表單,它帶有一個名為“Person”的表單支持對象然后你可以讓 Spring MVC 使用這個對象提供給 Controller 方法@ModelAttribute注釋:

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

另一方面,注釋用於定義應該是模型一部分的對象。 因此,如果您想在 Model 中引用 Person 對象,可以使用以下方法:

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

這個帶注釋的方法將允許訪問視圖中的 Person 對象,因為它會被 Spring 自動添加到模型中。

請參閱“使用@ModelAttribute”

我知道這是一個舊線程,但我想我把我的帽子扔進戒指,看看我是否可以再把水弄混一點:)

我發現我最初難以理解@ModelAttribute是因為 Spring 決定將多個注解合二為一。 一旦我把它分成幾個更小的注釋,它就變得更清晰了:

對於參數注釋,將@ModelAttribute視為@Autowired + @Qualifier的等價物,即它嘗試從 Spring 管理的模型中檢索具有給定名稱的 bean。 如果沒有找到指定的 bean,它不會拋出錯誤或返回null ,而是隱式地扮演@Bean的角色,即使用默認構造函數創建一個新實例並將 bean 添加到模型中。

對於方法注釋,將@ModelAttribute視為@Bean + @Before的等價物, @Bean + @Before用戶代碼構造的bean 放入模型中,並且它始終在請求處理方法之前調用。

形象地說,我看到@ModelAttribute如下(請不要從字面上理解!!):

@Bean("person")
@Before
public Person createPerson(){
  return new Person();
}

@RequestMapping(...)
public xxx handlePersonRequest( (@Autowired @Qualifier("person") | @Bean("person")) Person person, xxx){
  ...
}

如您所見,Spring 做出了正確的決定,使@ModelAttribute成為一個包羅萬象的注解; 沒有人想看到注釋大雜燴。

對於我的風格,我總是使用 @ModelAttribute 從 spring 表單 jsp 中捕獲對象。 例如,我在jsp頁面上設計表單,該表單與commandName一起存在

<form:form commandName="Book" action="" methon="post">
      <form:input type="text" path="title"></form:input>
</form:form>

我使用以下代碼捕獲控制器上的對象

public String controllerPost(@ModelAttribute("Book") Book book)

並且書的每個字段名稱必須與表單子元素中的路徑匹配

所以我會嘗試用更簡單的方式來解釋它。 讓我們:

public class Person {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        this.name = name;
    }
}

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

1.方法注解

@ModelAttribute(“cities”)
 public List<String> checkOptions(){
 return new Arrays.asList(new[]{“Sofia”,”Pleven","Ruse”});//and so on
}

這種方法的目的是在模型中添加屬性。 因此,在我們的例子中,城市鍵將具有列表new Arras.asList(new[]{“Sofia”,”Pleven","Ruse”})作為模型中的值(您可以將模型視為 map(key:value) )。 控制器中的@ModelAttribute方法在同一控制器內的@RequestMapping方法之前調用。

在這里,我們要向模型添加公共信息,這些信息將在表單中使用以顯示給用戶。 例如,它可用於填充 HTML 選擇:

在此處輸入圖片說明

2.方法參數

public String findPerson(@ModelAttriute(value="person") Person person) {
    //..Some logic with person
    return "person.jsp";
}

方法參數上的 @ModelAttribute 表示應該從模型中檢索參數。 因此,在這種情況下,我們希望 Model 中的person對象作為鍵,我們希望獲取它的值並將其放入方法參數Person person 中 如果這樣不存在或(有時您拼錯了 (value="persson")),那么 Spring 將不會在模型中找到它,並將使用其默認值創建空的 Person 對象。 然后將獲取請求參數並嘗試使用它們的名稱將它們數據綁定到 Person 對象中。

name="Dmitrij"&countries=Lesoto&sponsor.organization="SilkRoad"&authorizedFunds=&authorizedHours=&

所以我們有了名字,它將使用 setName(String name) 綁定到 Person.name。 所以在

//..Some logic with person

我們可以訪問這個值為“Dimitrij”的填充名稱。

當然,Spring 可以綁定更復雜的對象,如列表、地圖、地圖集列表等,但在幕后,它使數據綁定變得神奇。

  1. 我們可以同時使用帶有 @ModelAttribute 參數的模型注釋方法和請求方法處理程序。 然后我們必須聯合規則。

  2. 當然,我們有很多不同的情況——@ModelAttribute 方法也可以在@ControllerAdvice 中定義,等等......

我知道我參加聚會遲到了,但我會引用他們所說的“遲到總比不到好”。 那我們開始吧,每個人都有自己的解釋方式,我試着總結一下,舉個例子,分幾步給大家簡單介紹一下; 假設您有一個簡單的表單 form.jsp

<form:form action="processForm" modelAttribute="student">
First Name : <form:input path="firstName" /> 
<br><br>
Last Name : <form:input path="lastName" />
<br><br>
<input type="submit" value="submit"/>
</form:form>

path="firstName" path="lastName" 這些是當表單被調用時 StudentClass 中的字段/屬性,它們的 getter 被調用,但是一旦提交,它們的 setter 就會被調用,它們的值在 modelAttribute= 中指示的 bean 中設置表單標簽中的“學生”。

我們有包含以下方法的 StudentController;

@RequestMapping("/showForm")
public String showForm(Model theModel){ //Model is used to pass data between 
//controllers and views
    theModel.addAttribute("student", new Student()); //attribute name, value
return "form";
}

@RequestMapping("/processForm")
public String processForm(@ModelAttribute("student") Student theStudent){
    System.out.println("theStudent :"+ theStudent.getLastName());
return "form-details";
}

//@ModelAttribute("student") Student theStudent
//Spring automatically populates the object data with form data all behind the 
//scenes 

現在我們終於有了一個 form-details.jsp

<b>Student Information</b>
${student.firstName}
${student.lastName}

那么回到 Spring MVC 中的 @ModelAttribute 是什么的問題? 來自源代碼的示例定義, http://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation @ModelAttribute是將方法參數或方法返回值綁定到命名模型屬性的注釋然后將其公開給 Web 視圖。

實際發生的是,它獲取表單提交的所有值,然后保存它們以供您綁定或分配給對象。 它的工作原理與@RequestParameter 一樣,我們只獲取一個參數並將值分配給某個字段。 唯一的區別是@ModelAttribute保存所有表單數據而不是單個參數。 它為您創建一個 bean,用於保存表單提交的數據,供開發人員稍后使用。

回顧整個事情。 第 1 步:發送一個請求,我們的方法 showForm 運行,一個模型,一個名為 student 的臨時 bean 被轉發到表單。 theModel.addAttribute("student", new Student());

第 2 步:表單提交模型上的modelAttribute="student"更改了學生,現在它保存了表單的所有參數

第 3 步: @ModelAttribute("student") Student theStudent我們獲取@ModelAttribute保存的值並將整個 bean/對象分配給 Student。

第 4 步:然后我們在出價時使用它,就像我那樣在頁面上展示它一樣

我希望它可以幫助您理解這個概念。 謝謝

以任何網絡應用程序為例,無論是 Gmail、Facebook、Instagram 還是任何其他網絡應用程序,都是關於在最終用戶與應用程序或 UI 與后端應用程序之間交換數據或信息。 即使在 Spring MVC 世界中,也有兩種交換數據的方式:

  1. 從控制器到用戶界面,以及
  2. 從 UI 到控制器。

我們在這里感興趣的是數據是如何從 UI 傳送到控制器的。 這也可以通過兩種方式完成:

  1. 使用 HTML 表單
  2. 使用查詢參數。

使用 HTML 表單:考慮以下場景,

表單提交代表

當我們從 Web 瀏覽器提交表單數據時,我們可以在 Controller 類中作為對象訪問該數據。 當我們提交一個 HTML 表單時,Spring Container 會做四件事。 它會,

  1. 首先使用request.getParameter方法讀取請求中提交的所有數據。
  2. 一旦它讀取它們,它將使用integer.parseIntdouble.parseDouble和所有其他基於數據的數據類型可用的解析方法將它們轉換為適當的 Java 類型。
  3. 解析后,它將創建我們創建的模型類的對象。 例如,在這個場景中,提交的是用戶信息,我們創建了一個名為 User 的類,Container 將創建一個對象,並將自動輸入的所有值設置到該對象中。
  4. 然后它將通過將值設置到控制器來移交該對象。

為了讓這整個事情發揮作用,我們必須遵循某些步驟。

內部工作

我們首先需要定義一個模型類,比如 User,其中字段的數量應該與 HTML 表單中的字段數量完全匹配。 此外,我們在 HTML 表單中使用的名稱應該與我們在 Java 類中的名稱相匹配。 這兩個非常重要。 名稱應該匹配,表單中的字段數應該與我們創建的類中的字段數匹配。 一旦我們這樣做,容器將自動讀取傳入的數據,創建此模型的對象,設置值並將其移交給控制器。 為了在控制器中讀取這些值,我們在方法參數上使用@ModelAttribute注釋。 當我們在 Controller 中創建方法時,我們將使用 @ModelAttribute 並向其添加一個參數,該參數將自動由 Container 提供此對象。

以下是注冊用戶的示例代碼:

@RequestMapping(value = "registerUser", method = RequestMethod.POST)
public String registerUser(@ModelAttribute("user") User user, ModelMap model) {
    model.addAttribute("user", user);
    return "regResult";
}

希望這個圖解解釋有幫助!

@ModelAttribute 可以用作方法參數/參數或方法聲明之前。 此注解的主要目標是將請求參數或表單字段綁定到模型對象

參考 http://www.javabeat.net/modelattribute-spring-mvc/

將方法參數或方法返回值綁定到命名模型屬性的注釋,暴露給 Web 視圖。

public String add(@ModelAttribute("specified") Model model) {
    ...
}

這用於 Spring MVC數據綁定目的。 讓你有一個包含表單元素的jsp,例如

JSP

<form:form action="test-example" method="POST" commandName="testModelAttribute"> </form:form>

(Spring Form方法,也可以使用Simple form element)

在控制器端

@RequestMapping(value = "/test-example", method = RequestMethod.POST)
public ModelAndView testExample(@ModelAttribute("testModelAttribute") TestModel testModel, Map<String, Object> map,...) {

}

現在,當您提交表單時,表單字段值將可供您使用。

@ModelAttribute將使用您指定的名稱創建一個屬性(@ModelAttribute("Testing") Test test) as Testing給定示例中的(@ModelAttribute("Testing") Test test) as Testing ,Test 是 bean 測試是對 bean 的引用,而 Testing 將在模型中可用,以便您可以進一步在 jsp 頁面上使用它來檢索您存儲在ModelAttribute的值。

@ModelAttribute 只是將來自 jsp 字段的值綁定到 Pojo 類來執行我們在控制器類中的邏輯。 如果您熟悉 struts,那么這就像在提交時填充 formbean 對象。

ModelAttribute 注解用作 Spring MVC Web 應用程序的一部分,可用於兩種場景。

首先,它可以用於將數據注入到 JSP 之前的加載模型中。 這對於確保需要 JSP 來顯示所有數據本身特別有用。 通過將一種方法連接到模型來獲得注入。

其次,它可用於從現有模型中讀取數據並將其分配給教練方法的參數。

參考https://dzone.com/articles/using-spring-mvc%E2%80%99s

在方法層面

1.在方法級別使用注解時,它表明該方法的目的是添加一個或多個模型屬性

@ModelAttribute
public void addAttributes(Model model) {
model.addAttribute("india", "india");
}

在方法參數處 1. 當用作方法參數時,它表示應從模型中檢索該參數。 當不存在並且應該首先實例化然后添加到模型中並且一旦出現在模型中時,參數字段應該從具有匹配名稱的所有請求參數中填充因此,它將表單數據與 bean 綁定。

 @RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
  public String submit(@ModelAttribute("employee") Employee employee) {
  return "employeeView";
  }

首先,模型在 MVC Spring 中使用(MVC = Model,視圖,控制器)。 這就是說,模型與“視圖”一起使用

這些觀點是什么? 視圖可以是“由我們的后端框架(在我們的例子中為 Spring)生成的 html 頁面,在 html 頁面的某些部分中包含一些可變數據”。

所以我們有 model,它是一個包含數據的實體,確實被“注入”到視圖中。

您可以使用幾個“視圖”庫 Spring:其中,JSP、Thymeleaf、Mustache 等。

For example, let us assume we are using Thymeleaf (they are all similar. What's more, Spring does not even know, except for JSP, with which view libraries he is working with. All the models are served through the Servlet of Spring. This意味着 Spring 代碼對於所有這些視圖庫都是相同的。您唯一需要更改的是此類 html 頁面的語法,這些頁面位於資源/靜態/模板中)

resources/static/templates   //All our view web pages are here

Controller 負責路線。 例如,假設我們的網站托管在 localhost:8080 上。 我們想要一個向我們展示學生的路線(URL)。 假設這可以在 localhost:8080/students 獲得。 將執行此操作的 controller 是 StudentController:

@Controller  //Not @RestController
   public class StudentController {

   @GetMapping(/students)
   public String getStudentView() {
       return "student";
   }
}

這段代碼的作用是說,如果我們要

本地主機:8080/學生

然后調用 getStudentView() 方法。 但請注意它應該返回一個字符串。 但是,當使用視圖庫時,controller 使用@Controller(而不是@RestController)進行注釋,spring 所做的是尋找 ZFC35FDC70D5FC69D2698883A822C7A5 的 ZFC35FDC70D5FC69D26988883A822C7A5 頁面的名稱。尋找視圖

/resources/static/templates/student.html

這對於沒有數據的 static 頁面來說已經足夠了。 然而,如果我們需要一個包含一些數據的動態頁面,Spring 提供了另一個很大的優勢:上面的方法 getStudentView() 也將在后台傳遞一個 model 到我們的視圖“student.html”。 我們的 model 將包含我們可以使用視圖庫中的特定語法在文件“student.html”中訪問的數據。 例如,對於 thymeleaf:

<div th:text="${attribute1}"> </div>

這將訪問我們的 model 的屬性“attribute1”。 我們可以通過我們的 model 傳遞不同的數據。 這是通過為其分配各種屬性來完成的。 使用@ModelAttribute 有多種分配屬性的方法:

@Controller  //Not @RestController
   public class StudentController {

   @ModelAttribute(name = "attribute1")
   public int assignAttribute1() {
      return 123454321
   }   // Think it as "model.attribute1 = 123454321"

   @GetMapping(/students)
   public String getStudentView() {
       return "student";
   }
}

上面的代碼將分配給 model(在后台創建),一個名為“attribute1”的屬性(認為它是一個鍵),值為 12354321。類似於“model.attribute1 = 123454321”。

最后我們把model傳給視圖的時候我們把go傳給url

本地主機:8080/學生

注意:所有帶有@ModelAttribute 注解的方法都會在視圖返回之前被調用。 創建完所有屬性后,model 將傳遞給我們的視圖。 簡單的說,getStudentView()方法被調用后,所有帶有@ModelAttribute的方法都會被調用。

話雖如此,上面編寫的 html 代碼將從瀏覽器中查看為:

<div> 123454321 </div> // th:text is a command of 
//THymeleaf, and says to substitute the text
// between the tags with the attribute "attribute1" 
// of our model passed to this view.

這是@ModelAttribute 的基本用法。

還有另一個重要的用例:

model 可能需要在相反的方向:即從視圖到 controller。 在上述情況下,model 從 controller 傳遞到視圖。 但是,假設用戶從我們的 html 頁面發回一些數據。 我們可以在沒有 model 屬性 @ModelAttribute 的情況下捕獲它。 這已經被其他人描述過了

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM