@ModelAttribute ใน Spring MVC คืออะไร


372

วัตถุประสงค์และการใช้งาน@ModelAttributeใน Spring MVC คืออะไร



40
ฉันคิดว่านี่เป็นคำถามที่มีประโยชน์เพราะช่วยให้ผู้อ่านได้รับข้อมูลเพิ่มเติม (รวมถึงตัวอย่าง) กว่าเอกสารทางการของ Spring
anton1980

3
ตรวจสอบการเขียนนี้ที่นี่ thespringthing.blogspot.com/2010/11/…
praveenj

คำตอบ:


399

@ModelAttributeอ้างถึงคุณสมบัติของ Model object (M ใน MVC;) สมมติว่าเรามีรูปแบบที่มีวัตถุสำรองฟอร์มที่เรียกว่า "บุคคล" จากนั้นคุณสามารถให้ Spring MVC จัดหาวัตถุนี้ให้กับวิธีการควบคุมโดยใช้@ModelAttributeคำอธิบายประกอบ :

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

ในทางกลับกันคำอธิบายประกอบจะใช้ในการกำหนดวัตถุที่ควรเป็นส่วนหนึ่งของแบบจำลอง ดังนั้นหากคุณต้องการให้มีการอ้างอิงวัตถุบุคคลในโมเดลคุณสามารถใช้วิธีการต่อไปนี้:

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

วิธีการใส่คำอธิบายประกอบนี้จะช่วยให้การเข้าถึงวัตถุบุคคลในมุมมองของคุณเนื่องจากมันจะถูกเพิ่มโดยอัตโนมัติไปยังรุ่นตามฤดูใบไม้ผลิ

ดู"การใช้ @ModelAttribute"


8
@fasseg คุณไม่จำเป็นต้องใช้@ModelAttributeในกรณีแรกของคุณ
Neil McGuigan

@Neil คุณจำเป็นต้องใช้@ModelAttributeในแอตทริบิวต์วิธีเมื่อใด
Ryan


1
คุณควรรวมถึงวิธีการบรรจุบุคคลและวิธีการนี้เรียกว่า
Philip Rego

134

ฉันรู้ว่านี่เป็นด้ายเก่า แต่ฉันคิดว่าฉันโยนหมวกของฉันในแหวนและดูว่าฉันสามารถโคลนน้ำอีกเล็กน้อย :)

ฉันพบว่าการต่อสู้ครั้งแรกของฉันเพื่อทำความเข้าใจ@ModelAttributeเป็นผลมาจากการตัดสินใจของ Spring ในการรวมคำอธิบายประกอบหลาย ๆ อย่างเข้าด้วยกัน มันชัดเจนขึ้นเมื่อฉันแบ่งเป็นหมายเหตุประกอบขนาดเล็กหลายรายการ:

สำหรับคำอธิบายประกอบพารามิเตอร์ให้คิดว่า@ModelAttributeเทียบเท่า@Autowired + @Qualifierคือพยายามดึงข้อมูล bean ด้วยชื่อที่กำหนดจากโมเดลที่จัดการโดย Spring หากไม่พบ bean ที่ระบุชื่อแทนที่จะโยนข้อผิดพลาดหรือส่งคืนnullจะมีบทบาทในการ@Beanสร้างอินสแตนซ์ใหม่โดยใช้ Constructor เริ่มต้นและเพิ่ม bean เข้ากับโมเดล

สำหรับคำอธิบายประกอบวิธีคิด@ModelAttributeเป็นเทียบเท่า@Bean + @Beforeคือมันทำให้ถั่วสร้างโดยรหัสของผู้ใช้ในรูปแบบและมันมักจะเรียกว่าก่อนวิธีการจัดการคำขอ

เปรียบเปรยฉันเห็น@ModelAttributeดังต่อไปนี้ (โปรดอย่าใช้มันอย่างแท้จริง !!)

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

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

อย่างที่คุณเห็นสปริงทำการตัดสินใจอย่างถูกต้องเพื่อให้@ModelAttributeคำอธิบายประกอบที่ครอบคลุมทั้งหมด ไม่มีใครต้องการเห็นคำอธิบายประกอบ smorgasbord


2
Hm, @Bean เป็น singleton ตามค่าเริ่มต้น ฉันไม่แน่ใจว่าใช้แนวคิดเดียวกันนี้ได้ที่นี่
ซอมบี้

10
ไม่ได้อย่างแน่นอน. ฉันแค่ใช้คำอธิบายประกอบที่ง่ายขึ้นเพื่ออธิบายคำอธิบายประกอบที่ซับซ้อนนี้ โปรดอธิบายแนวคิดของฉันไม่ใช่อย่างแท้จริง
Christopher Yang

4
@ ซอมบี้เพิ่ม@Scope("request")แล้ว :)
OrangeDog

28

สำหรับสไตล์ของฉันฉันมักใช้ @ModelAttribute เพื่อจับวัตถุจากสปริงรูปแบบ 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)

และชื่อฟิลด์ของหนังสือทุกเล่มจะต้องตรงกับเส้นทางในองค์ประกอบย่อยของแบบฟอร์ม


4
catchคำกริยาว่าอธิบายการทำงานที่@ModelAttributeได้ทำ ดี
Eddy

3
คำตอบที่ดีที่สุดของปี
ดาวพฤหัสบดี Cls

4
แต่จำเป็นหรือไม่ ยังคงใช้งานได้โดยไม่ต้องใช้คำอธิบายประกอบ @ModelAttribute

23

ดังนั้นฉันจะพยายามอธิบายด้วยวิธีที่ง่ายกว่า มามี:

public class Person {
    private String name;

    public String getName() {
        return name;
    }

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

ตามที่อธิบายไว้ในเอกสารฤดูใบไม้ผลิ MVC - The @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”})เป็นค่าในรูปแบบ (คุณสามารถคิดว่ารูปแบบเป็นแผนที่ (คีย์: ค่า)) @ModelAttributeวิธีในตัวควบคุมจะถูกเรียกก่อนวิธีการ@RequestMappingภายในตัวควบคุมเดียวกัน

ที่นี่เราต้องการเพิ่มข้อมูลทั่วไปของโมเดลซึ่งจะใช้ในแบบฟอร์มเพื่อแสดงต่อผู้ใช้ ตัวอย่างเช่นมันสามารถใช้ในการกรอก HTML เลือก:

ป้อนคำอธิบายรูปภาพที่นี่

2. วิธีการโต้แย้ง

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

@ModelAttribute ในการโต้แย้งวิธีบ่งชี้ว่าอาร์กิวเมนต์ควรดึงจากรูปแบบ ดังนั้นในกรณีนี้เราคาดหวังว่าเรามีในรุ่น บุคคลวัตถุเป็นกุญแจสำคัญและเราต้องการที่จะได้รับความคุ้มค่าและนำไปใช้วิธีการโต้แย้งคนบุคคล หากไม่มีอยู่หรือ (บางครั้งคุณสะกดคำผิดพลาด (value = "persson")) Spring จะไม่พบมันใน Model และจะสร้างวัตถุ Person ที่ว่างโดยใช้ค่าเริ่มต้น จากนั้นจะใช้พารามิเตอร์คำขอและพยายามผูกข้อมูลในวัตถุบุคคลโดยใช้ชื่อของพวกเขา

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

ดังนั้นเรามีชื่อและมันจะผูกกับ Person.name โดยใช้ setName (ชื่อ String) ดังนั้นค่ะ

//..Some logic with person

เราสามารถเข้าถึงชื่อที่กรอกแล้วด้วยค่า "Dimitrij"

แน่นอนว่า Spring สามารถผูกกับวัตถุที่ซับซ้อนมากขึ้นเช่นรายการ, แผนที่, รายการชุดของแผนที่และอื่น ๆ แต่เบื้องหลังมันทำให้ข้อมูลมีความผูกพัน

  1. เราสามารถมีวิธีหมายเหตุประกอบแบบจำลองในเวลาเดียวกันและตัวจัดการวิธีการร้องขอด้วย @ModelAttribute ในอาร์กิวเมนต์ จากนั้นเราต้องรวมกฎ

  2. แน่นอนว่าเรามีสถานการณ์ที่แตกต่างกันมากมาย - @ModelAttribute ยังสามารถกำหนดวิธีการใน @ControllerAdvice และอื่น ๆ ...


13

ฉันรู้ว่าฉันไปงานปาร์ตี้สาย แต่ฉันจะพูดเหมือนพวกเขาพูดว่า "ดีกว่าจะสายไม่เคย" ดังนั้นให้เราไปทุกคนมีวิธีของตัวเองในการอธิบายสิ่งต่าง ๆ ให้ฉันลองสรุปผลรวมและทำให้มันง่ายขึ้นสำหรับคุณในไม่กี่ขั้นตอนด้วยตัวอย่าง; สมมติว่าคุณมีแบบฟอร์มอย่างง่าย 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 เมื่อฟอร์มถูกเรียกว่า getters จะถูกเรียกใช้ แต่เมื่อส่ง setters แล้วจะถูกเรียกและค่าจะถูกตั้งค่าใน bean ที่ระบุใน modelAttribute = "นักเรียน" ในแท็กแบบฟอร์ม

เรามี 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}

ดังนั้นกลับไปที่คำถาม @ModelAttribute ใน Spring MVC คืออะไร? ความหมายตัวอย่างจากแหล่งที่มาสำหรับคุณ http://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation @ModelAttributeเป็นคำอธิบายประกอบที่ผูกวิธีพารามิเตอร์หรือค่าตอบแทนวิธีการในการแอตทริบิวต์รูปแบบการตั้งชื่อ จากนั้นแสดงเป็นมุมมองเว็บ

สิ่งที่เกิดขึ้นจริงคือมันได้รับค่าทั้งหมดในแบบฟอร์มของคุณที่ส่งมาจากนั้นให้พวกเขาผูกหรือกำหนดให้กับวัตถุ มันทำงานเหมือนกับ@RequestParameterโดยที่เราได้รับพารามิเตอร์และกำหนดค่าให้กับบางฟิลด์เท่านั้น ความแตกต่างเพียงอย่างเดียวคือ@ModelAttributeเก็บข้อมูลฟอร์มทั้งหมดแทนที่จะเป็นพารามิเตอร์เดียว มันสร้าง bean สำหรับคุณที่เก็บข้อมูลที่ส่งแบบฟอร์มเพื่อใช้งานโดยนักพัฒนาในภายหลัง

เพื่อสรุปสิ่งทั้งหมด ขั้นตอนที่ 1: มีการส่งคำขอและวิธีการของเราจะแสดงการเรียกใช้และแบบจำลองถั่วชั่วคราวจะถูกตั้งค่าด้วยชื่อนักเรียนจะถูกส่งต่อไปยังแบบฟอร์ม theModel.addAttribute ("นักเรียน", นักศึกษาใหม่ ());

ขั้นตอนที่ 2: modelAttribute = "นักเรียน" ในรูปแบบการส่งแบบฟอร์มเปลี่ยนนักเรียนและตอนนี้มันถือพารามิเตอร์ทั้งหมดของแบบฟอร์ม

ขั้นตอนที่ 3: @ModelAttribute ("นักเรียน") นักเรียนนักศึกษา เราเรียกค่าที่ถูกเก็บไว้โดย@ModelAttributeและกำหนดถั่ว / วัตถุทั้งหมดให้กับนักเรียน

ขั้นตอนที่ 4: จากนั้นเราใช้มันตามที่เราเสนอราคาเช่นเดียวกับการแสดงบนหน้าเว็บ ฯลฯ อย่างที่ฉันทำ

ฉันหวังว่ามันจะช่วยให้คุณเข้าใจแนวคิด ขอบคุณ


9

ใช้เว็บแอปพลิเคชันใด ๆ ไม่ว่าจะเป็น Gmail หรือ Facebook หรือ Instagram หรือเว็บแอปพลิเคชันอื่น ๆ มันคือทั้งหมดที่เกี่ยวกับการแลกเปลี่ยนข้อมูลหรือข้อมูลระหว่างผู้ใช้กับแอปพลิเคชันหรือ UI และแอปพลิเคชันด้านหลัง แม้แต่ใน Spring MVC โลกมีสองวิธีในการแลกเปลี่ยนข้อมูล:

  1. จาก Controller ไปยัง UI และ
  2. จาก UI ไปยังตัวควบคุม

สิ่งที่เราสนใจที่นี่คือวิธีการสื่อสารข้อมูลจาก UI ไปยังตัวควบคุม วิธีนี้สามารถทำได้ 2 วิธี:

  1. ใช้แบบฟอร์ม HTML
  2. การใช้พารามิเตอร์การสืบค้น

ใช้แบบฟอร์ม HTML: พิจารณาสถานการณ์ด้านล่าง

แบบฟอร์มการส่งผลงาน

เมื่อเราส่งข้อมูลฟอร์มจากเว็บเบราว์เซอร์เราสามารถเข้าถึงข้อมูลนั้นในคลาสควบคุมของเราเป็นวัตถุ เมื่อเราส่งแบบฟอร์ม HTML Spring Container จะทำสี่สิ่ง มันจะ,

  1. ก่อนอื่นให้อ่านข้อมูลทั้งหมดที่ส่งมาในคำขอโดยใช้เมธอดrequest.getParameter
  2. เมื่อพวกเขาอ่านก็จะแปลงให้เป็นชนิด Java ที่เหมาะสมโดยใช้Integer.parseInt , double.parseDoubleและทุกวิธีการแยกอื่น ๆ ที่มีขึ้นอยู่กับชนิดข้อมูลของข้อมูล
  3. เมื่อแยกวิเคราะห์แล้วมันจะสร้างวัตถุของคลาสโมเดลที่เราสร้างขึ้น ตัวอย่างเช่นในสถานการณ์นี้มันเป็นข้อมูลผู้ใช้ที่จะถูกส่งและเราสร้างคลาสที่เรียกว่าผู้ใช้ซึ่งคอนเทนเนอร์จะสร้างวัตถุและมันจะตั้งค่าทั้งหมดที่เข้ามาโดยอัตโนมัติในวัตถุนั้น
  4. จากนั้นจะส่งมอบวัตถุนั้นโดยการตั้งค่าให้กับคอนโทรลเลอร์

ในการทำให้สิ่งทั้งหมดนี้ทำงานเราจะต้องทำตามขั้นตอนบางอย่าง

ทำงานภายใน

อันดับแรกเราต้องกำหนดคลาสโมเดลเช่นผู้ใช้ซึ่งจำนวนฟิลด์ควรตรงกับจำนวนฟิลด์ในแบบฟอร์ม HTML นอกจากนี้ชื่อที่เราใช้ในรูปแบบ HTML ควรตรงกับชื่อที่เรามีในคลาส Java สองสิ่งนี้สำคัญมาก ชื่อควรตรงกับจำนวนฟิลด์ในแบบฟอร์มควรตรงกับจำนวนฟิลด์ในคลาสที่เราสร้าง เมื่อเราทำเช่นนั้นคอนเทนเนอร์จะอ่านข้อมูลที่เข้ามาโดยอัตโนมัติสร้างวัตถุของรุ่นนี้ตั้งค่าและส่งมอบให้กับคอนโทรลเลอร์ ในการอ่านค่าเหล่านั้นภายใน Controller เราใช้ @ModelAttributeคำอธิบายประกอบบนพารามิเตอร์ method เมื่อเราสร้างเมธอดในคอนโทรลเลอร์เราจะใช้ @ModelAttribute และเพิ่มพารามิเตอร์เข้าไปซึ่งมันจะมีออบเจ็กต์นี้ที่กำหนดโดยคอนเทนเนอร์โดยอัตโนมัติ

นี่คือตัวอย่างรหัสสำหรับการลงทะเบียนผู้ใช้:

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

หวังว่าคำอธิบายแบบแผนภาพนี้ช่วยได้!


4

MVCนี้จะใช้สำหรับการผูกข้อมูลวัตถุประสงค์ในฤดูใบไม้ผลิ ให้คุณมี jsp ที่มีองค์ประกอบของฟอร์มเช่น

บน JSP

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

(วิธีการแบบฟอร์มสปริงองค์ประกอบแบบฟอร์มที่เรียบง่ายยังสามารถนำมาใช้)

บนตัวควบคุม

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

}

ตอนนี้เมื่อคุณจะส่งแบบฟอร์มค่าเขตข้อมูลฟอร์มจะพร้อมใช้งานสำหรับคุณ


4

คำอธิบายประกอบที่ผูกพารามิเตอร์วิธีการหรือค่าตอบแทนวิธีการที่มีชื่อรุ่นแอตทริบิวต์เปิดเผยกับมุมมองเว็บ

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

3

@ModelAttribute สามารถใช้เป็นอาร์กิวเมนต์วิธี / พารามิเตอร์หรือก่อนที่จะประกาศวิธีการ วัตถุประสงค์หลักของคำอธิบายประกอบนี้เพื่อผูกพารามิเตอร์คำขอหรือเขตข้อมูลฟอร์มกับวัตถุแบบจำลอง

อ้าง http://www.javabeat.net/modelattribute-spring-mvc/


1

@ModelAttributeจะสร้างแอททริบิวที่มีชื่อที่คุณระบุ(@ModelAttribute("Testing") Test test) as Testing ในตัวอย่างที่กำหนดการทดสอบคือการทดสอบบีนเป็นการอ้างอิงถึงบีนและการทดสอบจะพร้อมใช้งานในแบบจำลองเพื่อให้คุณสามารถใช้งานได้ในหน้า jsp เพื่อดึงค่าที่คุณเก็บไว้ ModelAttributeในตัวคุณ


1

@ModelAttribute เพียงผูกค่าจากเขตข้อมูล jsp กับ Pojo calss เพื่อดำเนินการตรรกะของเราในระดับควบคุม หากคุณคุ้นเคยกับ struts นี่เป็นเหมือนการเติมวัตถุ formbean เมื่อส่ง


0

หมายเหตุประกอบ ModelAttribute ใช้เป็นส่วนหนึ่งของเว็บแอปพลิเคชัน Spring MVC และสามารถใช้งานได้ในสองสถานการณ์

ประการแรกสามารถใช้ฉีดข้อมูลลงในโมเดลโหลด JSP ล่วงหน้า สิ่งนี้มีประโยชน์อย่างยิ่งในการตรวจสอบว่าจำเป็นต้องมี JSP เพื่อแสดงข้อมูลทั้งหมดเอง ได้รับการฉีดโดยเชื่อมต่อหนึ่งวิธีกับแบบจำลอง

ประการที่สองมันสามารถใช้ในการอ่านข้อมูลจากรูปแบบที่มีอยู่และกำหนดให้กับพารามิเตอร์ของวิธีการโค้ช

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


0

ในระดับวิธีการ

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";
  }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.