原文连接:http://liukai.iteye.com/blog/973717,仅供自己参考。
在教程中,我们将创建一个简单的Spring3MVC simple CRUD应用程序.

什么是@ModelAttribute 

Spring3关于@ModelAttribute的文档

引用

  1. @ModelAttribute has two usage scenarios in controllers. When you place it on a method parameter, @ModelAttribute maps a model attribute to the specific, annotated method parameter (see the processSubmit() method below). This is how the controller gets a reference to the object holding the data entered in the form.
  2.  
  3. You can also use @ModelAttribute at the method level to provide reference data for the model (see the populatePetTypes() method in the following example). For this usage the method signature can contain the same types as documented previously for the @RequestMapping annotation.
  4.  
  5. Note
  6. @ModelAttribute annotated methods are executed before the chosen @RequestMapping annotated handler method. They effectively pre-populate the implicit model with specific attributes, often loaded from a database. Such an attribute can then already be accessed through @ModelAttribute annotated handler method parameters in the chosen handler method, potentially with binding and validation applied to it.

大意就是: 
当你放置在方法参数,@ModelAttribute模型映射到具体属性; 
你也可以使用@ModelAttribute在方法级别上提供参考模型的数据.

英语不好.见谅

根据配合m2eclipse创建一个标准的maven web项目 
我们创建一个名为spring-jsp的web项目.并添加图下所示

为了开启SpringMVC,我们需要在web.xml添加以下内容

web.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app id="WebApp_ID" version="2.4"
  3. xmlns="http://java.sun.com/xml/ns/j2ee"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
  6. http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  7.  
  8. <servlet>
  9. <servlet-name>spring</servlet-name>
  10. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  11. <load-on-startup>1</load-on-startup>
  12. </servlet>
  13.  
  14. <servlet-mapping>
  15. <servlet-name>spring</servlet-name>
  16. <url-pattern>/</url-pattern>
  17. </servlet-mapping>
  18.  
  19. <listener>
  20. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  21. </listener>
  22.  
  23. </web-app>

在web.xml中我们定义servlet:spring. 
按照惯例,我们必须声明一个spring-servle.xml 
用springIDE插件创建一个配置xml. 
内容包含:

spring-servle.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
  6.  
  7. <!-- 定义一个视图解析器 -->
  8. <bean id="viewResolver"
  9. class="org.springframework.web.servlet.view.InternalResourceViewResolver"
  10. p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />
  11.  
  12. </beans>

这个XML配置声明一个视图解析器.在控制器中会根据JSP名映射到/ WEB-INF/jsp中相应的位置.

然后创建一个applicationContext.xml.

applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:mvc="http://www.springframework.org/schema/mvc"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  8. http://www.springframework.org/schema/context
  9. http://www.springframework.org/schema/context/spring-context-3.0.xsd
  10. http://www.springframework.org/schema/mvc
  11. http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
  12.  
  13. <!-- 激活spring的注解. -->
  14. <context:annotation-config />
  15.  
  16. <!-- 扫描注解组件并且自动的注入spring beans中.
  17. 例如,他会扫描org.liukai.tutorial下@Controller 和@Service下的文件.所以确保此base-package设置正确. -->
  18. <context:component-scan base-package="org.liukai.tutorial" />
  19.  
  20. <!-- 配置注解驱动的Spring MVC Controller 的编程模型.注:此标签只在 Servlet MVC工作! -->
  21. <mvc:annotation-driven />
  22.  
  23. </beans>

首先让我们定义两个简单的POJO

Address.java 

  1. package org.liukai.tutorial.domain;
  2.  
  3. import java.io.Serializable;
  4.  
  5. public class Address implements Serializable {
  6.  
  7. private static final long serialVersionUID = -8889854671283221397L;
  8.  
  9. private Integer id;
  10. private String street;
  11. private String zipCode;
  12. private String city;
  13.  
  14. ......getter/setter
  15. }

Person.java 

  1. package org.liukai.tutorial.domain;
  2.  
  3. import java.io.Serializable;
  4.  
  5. public class Person implements Serializable {
  6.  
  7. private static final long serialVersionUID = -8333984959652704635L;
  8.  
  9. private Integer id;
  10. private String firstName;
  11. private String lastName;
  12. private String currency;
  13. private Double money;
  14.  
  15. ......getter/setter
  16.  
  17. }

然后实现2个简单的service层用于填充和处理业务逻辑.

AddressService.java 

  1. package org.liukai.tutorial.service;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.List;
  5.  
  6. import org.apache.log4j.Logger;
  7. import org.liukai.tutorial.domain.Address;
  8. import org.springframework.stereotype.Service;
  9. import org.springframework.transaction.annotation.Transactional;
  10.  
  11. /**
  12. * 同样用于显示.
  13. *
  14. * @author liukai
  15. *
  16. */
  17. @Service("addressService")
  18. @Transactional
  19. public class AddressService {
  20.  
  21. protected static Logger logger = Logger.getLogger("service");
  22.  
  23. /**
  24. * 获得所有的地址.
  25. *
  26. * @return
  27. */
  28. public List<Address> getAll() {
  29. logger.debug("Retrieving all addresses");
  30.  
  31. List<Address> addresses = new ArrayList<Address>();
  32.  
  33. // New address
  34. Address address = new Address();
  35. address.setId(1);
  36. address.setStreet("1 Street");
  37. address.setCity("City 1");
  38. address.setZipCode("11111");
  39.  
  40. // Add to list
  41. addresses.add(address);
  42.  
  43. // New address
  44. address = new Address();
  45. address.setId(2);
  46. address.setStreet("2 Street");
  47. address.setCity("City 2");
  48. address.setZipCode("22222");
  49.  
  50. // Add to list
  51. addresses.add(address);
  52.  
  53. // New address
  54. address = new Address();
  55. address.setId(3);
  56. address.setStreet("3 Street");
  57. address.setCity("City 3");
  58. address.setZipCode("33333");
  59.  
  60. // Add to list
  61. addresses.add(address);
  62.  
  63. // Return all addresses
  64. return addresses;
  65. }
  66.  
  67. }

PersonService.java

  1. package org.liukai.tutorial.service;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.HashMap;
  5. import java.util.List;
  6. import java.util.Map;
  7.  
  8. import org.apache.log4j.Logger;
  9. import org.liukai.tutorial.domain.Person;
  10. import org.springframework.stereotype.Service;
  11. import org.springframework.transaction.annotation.Transactional;
  12.  
  13. /**
  14. * 注意这个只是一个临时数据用于显示.
  15. *
  16. * @author liukai
  17. *
  18. */
  19. @Service("personService")
  20. @Transactional
  21. public class PersonService {
  22.  
  23. protected static Logger logger = Logger.getLogger("service");
  24.  
  25. private HashMap<Integer, Person> database = new HashMap<Integer, Person>();
  26.  
  27. /**
  28. * Initialize a list of persons
  29. */
  30. private void init() {
  31. // New person
  32. Person person = new Person();
  33. person.setId(1);
  34. person.setFirstName("John");
  35. person.setLastName("Smith");
  36. person.setCurrency("Dollar");
  37. person.setMoney(1500.00);
  38.  
  39. // Add to list
  40. database.put(1, person);
  41.  
  42. // New person
  43. person = new Person();
  44. person.setId(2);
  45. person.setFirstName("Jane");
  46. person.setLastName("Adams");
  47. person.setCurrency("Yen");
  48. person.setMoney(1000.00);
  49.  
  50. // Add to list
  51. database.put(2, person);
  52.  
  53. // New person
  54. person = new Person();
  55. person.setId(3);
  56. person.setFirstName("Mike");
  57. person.setLastName("Polaski");
  58. person.setCurrency("Euro");
  59. person.setMoney(2000.00);
  60.  
  61. // Add to list
  62. database.put(3, person);
  63. }
  64.  
  65. public PersonService() {
  66. // Initialize dummy database
  67. init();
  68. }
  69.  
  70. /**
  71. * 检索所有的 persons
  72. */
  73. public List<Person> getAll() {
  74. logger.debug("Retrieving all persons");
  75.  
  76. // Initialize our array
  77. List<Person> persons = new ArrayList<Person>();
  78.  
  79. // Iterate the database
  80. for (Map.Entry<Integer, Person> entry : database.entrySet()) {
  81. persons.add(entry.getValue());
  82. }
  83.  
  84. // Return all persons
  85. return persons;
  86. }
  87.  
  88. /**
  89. * 根据ID获得对应的Perosn
  90. */
  91. public Person get(Integer id) {
  92. logger.debug("Retrieving person based on his id");
  93. return database.get(id);
  94. }
  95.  
  96. /**
  97. * 修改Person
  98. */
  99. public void edit(Person person) {
  100. logger.debug("Editing existing person");
  101.  
  102. // Note this is not the best way to update a data!
  103.  
  104. // Delete existing user
  105. database.remove(person.getId());
  106. // Add updated user
  107. database.put(person.getId(), person);
  108. }
  109.  
  110. }

接下来就是@ModelAttribute的两种使用方法.

模式1:method级(作用于方法上)

引用
  1. You can also use @ModelAttribute at the method level to provide reference data for the model (see the populatePetTypes() method in the following example). For this usage the method signature can contain the same types as documented previously for the @RequestMapping annotation.

来源:spring3文档

我们在controller里用注解@ModelAttribute 定义一个method.

AddressController.java 

  1. package org.liukai.tutorial.controller;
  2.  
  3. import java.util.List;
  4.  
  5. import javax.annotation.Resource;
  6.  
  7. import org.apache.log4j.Logger;
  8. import org.liukai.tutorial.domain.Address;
  9. import org.liukai.tutorial.service.AddressService;
  10. import org.springframework.stereotype.Controller;
  11. import org.springframework.ui.Model;
  12. import org.springframework.web.bind.annotation.ModelAttribute;
  13. import org.springframework.web.bind.annotation.RequestMapping;
  14. import org.springframework.web.bind.annotation.RequestMethod;
  15.  
  16. @Controller
  17. @RequestMapping("/address")
  18. public class AddressController {
  19.  
  20. protected static Logger logger = Logger.getLogger("controller");
  21.  
  22. @Resource(name = "addressService")
  23. private AddressService addressService;
  24.  
  25. /**
  26. * 获得所有Addresses,并使他们成为一个model.
  27. * 注意@ModelAttribute作用于method级别上时.会在@Controller执行时加载
  28. * method里的方法.即在@Controller执行时@ModelAttribute添加参数.
  29. * 返回于该@Controller返回的所有JSP页面.
  30. */
  31. @ModelAttribute("addresses")
  32. public List<Address> getAllAddresses() {
  33. return addressService.getAll();
  34. }
  35.  
  36. /**
  37. * 处理和检索一个包含addresses 的JSP Page .
  38. */
  39. @RequestMapping(value = "list1", method = RequestMethod.GET)
  40. public String getAllUsingModelAttribute() {
  41. logger.debug("Received request to show all addresses page");
  42.  
  43. // 他会解析 /WEB-INF/jsp/addressespage.jsp
  44. return "addressespage";
  45. }
  46.  
  47. /**
  48. * 处理和检索一个包含addresses 的JSP Page .
  49. *
  50. * @return the name of the JSP page
  51. */
  52. @RequestMapping(value = "list2", method = RequestMethod.GET)
  53. public String getAllUsingModel(Model model) {
  54. logger.debug("Received request to show all addresses page");
  55.  
  56. // 检索所有的address并装入model返回addressespage.jsp
  57. model.addAttribute("addresses", addressService.getAll());
  58. model.addAttribute("greetings", "I came from Model not ModelAttribute");
  59.  
  60. // This will resolve to /WEB-INF/jsp/addressespage.jsp
  61. return "addressespage";
  62. }
  63.  
  64. }

Controller中有一个注解为@ModelAttribute("addresses")的getAllAddresses的method 
表示在JSP Page中的参数名称为addresses.

创建一个JSP页面:addressespage.jsp 
addressespage.jsp 

  1. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
  2. <%@ page language="java" contentType="text/html; charset=UTF-8"
  3. pageEncoding="UTF-8"%>
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  8. <title>Insert title here</title>
  9. </head>
  10. <body>
  11.  
  12. <h1>Addresses</h1>
  13.  
  14. <table>
  15. <tr>
  16. <td width="100">Id</td>
  17. <td width="150">Street</td>
  18. <td width="150">City</td>
  19. <td width="150">Zip Code</td>
  20. </tr>
  21. <c:forEach items="${addresses}" var="address">
  22. <tr>
  23. <td><c:out value="${address.id}" />
  24. </td>
  25. <td><c:out value="${address.street}" />
  26. </td>
  27. <td><c:out value="${address.city}" />
  28. </td>
  29. <td><c:out value="${address.zipCode}" />
  30. </td>
  31. </tr>
  32. </c:forEach>
  33. </table>
  34.  
  35. <p>${greetings}</p>
  36. </body>
  37. </html>

根据controller里的@RequestMapping.我们的访问路径为: 
http://localhost:8080/spring-jsp/address/list1 
http://localhost:8080/spring-jsp/address/list2 
下面是根据address/list1得到的截图. 

而根据address/list2得到的截图是:

比较一下他们有什么区别? 
后者是不是多了一行文字? 
然后回过头看看代码.

引用
  1. @ModelAttribute annotated methods are executed before the chosen @RequestMapping annotated handler method. They effectively pre-populate the implicit model with specific attributes, often loaded from a database.

来源:spring3文档

大意是:@ModelAttribute是在所选择的@RequestMapping 处理方法之前执行的. 
他们有效的填充数据,经常用于从database加载数据.

所以你可以用@ModelAttribute遍历你的List. 
如果你在controller中做一些update操作.你可以先获得旧的List一直到你获得新数据后覆盖以前的数据.

模式2:method parameter级(即方法里所带的参数)

引用
  1. When you place it on a method parameter, @ModelAttribute maps a model attribute to the specific, annotated method parameter (see the processSubmit() method below). This is how the controller gets a reference to the object holding the data entered in the form.rameters in the chosen handler method, potentially with binding and validation applied to it.

来源:spring3文档

大意是:如果你的方法参数里带有@ModelAttribute的参数.表示从JSP Page传回的参数并自动的转化为java对象

  1. package org.liukai.tutorial.controller;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.List;
  5.  
  6. import javax.annotation.Resource;
  7.  
  8. import org.apache.log4j.Logger;
  9. import org.liukai.tutorial.domain.Person;
  10. import org.liukai.tutorial.service.PersonService;
  11. import org.springframework.stereotype.Controller;
  12. import org.springframework.ui.Model;
  13. import org.springframework.web.bind.annotation.ModelAttribute;
  14. import org.springframework.web.bind.annotation.PathVariable;
  15. import org.springframework.web.bind.annotation.RequestMapping;
  16. import org.springframework.web.bind.annotation.RequestMethod;
  17.  
  18. @Controller
  19. @RequestMapping("/main")
  20. public class MainController {
  21.  
  22. protected static Logger logger = Logger.getLogger("controller");
  23.  
  24. @Resource(name = "personService")
  25. private PersonService personService;
  26.  
  27. /**
  28. * 获得所有Person,并使他们成为一个model.
  29. */
  30. @ModelAttribute("persons")
  31. public List<Person> getAllPersons() {
  32. logger.debug("Retrieving all persons and adding it to ModelAttribute");
  33. // Delegate to PersonService
  34. return personService.getAll();
  35. }
  36.  
  37. /**
  38. * 获得所有的货币类型,并使他们成为一个model.
  39. */
  40. @ModelAttribute("currencies")
  41. public List<String> getAllCurrencies() {
  42. logger.debug("Retrieving all currencies and adding it to ModelAttribute");
  43.  
  44. // Prepare data
  45. List<String> currencies = new ArrayList<String>();
  46. currencies.add("Dollar");
  47. currencies.add("Yen");
  48. currencies.add("Pound");
  49. currencies.add("Euro");
  50. currencies.add("Dinar");
  51.  
  52. return currencies;
  53. }
  54.  
  55. /**
  56. * 处理和检索一个包含Perosn 的JSP Page
  57. */
  58. @RequestMapping(method = RequestMethod.GET)
  59. public String getAllPage(Model model) {
  60.  
  61. logger.debug("Received request to show all persons page");
  62.  
  63. // personsage.jsp会引用一个名叫persons的model attribute
  64. // 我们不需要手动添加这个model
  65. // 前面他已经自动的通过@ModelAttribute("persons")进行了添加.
  66.  
  67. // 他会解析 /WEB-INF/jsp/personspage.jsp
  68. return "personspage";
  69. }
  70.  
  71. /**
  72. * 检索修改页面
  73. */
  74. @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
  75. public String getEdit(@PathVariable Integer id, Model model) {
  76. /*
  77. * @PathVariable表示指定@RequestMapping的URL模板中{}里的值
  78. * 相当于以前我们URL后面传的参数如XX?id=XXXX .
  79. * 但是现在我们可以用 XX/id/XX来代替.
  80. * 这个就是REST风格的URL,我们可以实现非常复杂的URL模板
  81. */
  82.  
  83. logger.debug("Received request to show edit page");
  84.  
  85. /*
  86. * 根据ID检索出对应的Person,然后把检索出来的Person放入一个叫
  87. * "personAttribute"的model中.
  88. * 这样editpage.jsp就会接收一个 名为personAttribute的参数.
  89. * 相当于request.setAttribute("XX",XX)
  90. */
  91. model.addAttribute("personAttribute", personService.get(id));
  92.  
  93. // This will resolve to /WEB-INF/jsp/editpage.jsp
  94. return "editpage";
  95. }
  96.  
  97. /**
  98. * 保存修改结果
  99. */
  100. @RequestMapping(value = "/edit/{id}", method = RequestMethod.POST)
  101. public String saveEdit(@ModelAttribute("personAttribute") Person person,
  102. @PathVariable Integer id, Model model) {
  103. logger.debug("Received request to update person");
  104.  
  105. // 我们从页面接收到了一个名为"personAttribute"的model并命名为person
  106. // 同样我们也获得了指定的id.
  107. person.setId(id);
  108.  
  109. // 更新person
  110. personService.edit(person);
  111.  
  112. // 在更新后我们重新显示所有Person 的页面
  113. model.addAttribute("persons", personService.getAll());
  114.  
  115. // This will resolve to /WEB-INF/jsp/personspage.jsp
  116. return "personspage";
  117. }
  118.  
  119. }

这个controller里定义了两个method级别的@ModelAttribute方法:getAllPersons和getAllCurrencies 
我们已经了解了他们的用法和意义. 
然后在saveEdit方法中,有个一个参数是用@ModelAttribute注解的.

  1. @RequestMapping(value = "/edit/{id}", method = RequestMethod.POST)
  2. public String saveEdit(@ModelAttribute("personAttribute") Person person,
  3. @PathVariable Integer id, Model model) {
  4. ...
  5. }

表示从JSP 页面返回的一个叫"personAttribute"的值.并自动的转化为Person对象. 
这样和以前我们用的request.getParameters("personAttribute")效果一样. 
但是一个是操作参数对象.一个是处理请求.两者的实现思想不同.

在此controller中我们有3个映射: 
/main  - 检索所有的Person

/main/edit/{id} - (GET)根据ID进行检索和edit

/main/edit/{id} - (POST) 根据ID进行更新

注:后两者的URL虽然一样, 
但一个是GET方法,一般用于检索. 
一个是POST方法,一般用于提交表单. 
如果大家有注意@RequestMapping中的method方法其实有四种. 
GET 
POST 
PUT 
DELETE

每个方法对应一个逻辑操作.对于REST风格的编程是一个相当好的补充. 
关于这点感兴趣的同学可以看看springsource一篇官方BLOG:REST in Spring 3: @MVC

让我们继续完成其他的JSP 

personspage.jsp
 

  1. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
  2. <%@ page language="java" contentType="text/html; charset=UTF-8"
  3. pageEncoding="UTF-8"%>
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  8. <title>Insert title here</title>
  9. </head>
  10. <body>
  11.  
  12. <h1>Persons</h1>
  13.  
  14. <table>
  15. <tr>
  16. <td width="50">Id</td>
  17. <td width="150">First Name</td>
  18. <td width="150">Last Name</td>
  19. <td width="100">Money</td>
  20. <td width="50">Currency</td>
  21. </tr>
  22. <c:forEach items="${persons}" var="person">
  23. <tr>
  24. <td><c:out value="${person.id}" /></td>
  25. <td><c:out value="${person.firstName}" /></td>
  26. <td><c:out value="${person.lastName}" /></td>
  27. <td><c:out value="${person.money}" /></td>
  28. <td><c:out value="${person.currency}" /></td>
  29. </tr>
  30. </c:forEach>
  31. </table>
  32.  
  33. </body>
  34. </html>

这个主要是映射 /main.

editpage.jsp

  1. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
  2. <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
  3. <%@ page language="java" contentType="text/html; charset=UTF-8"
  4. pageEncoding="UTF-8"%>
  5. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  6. <html>
  7. <head>
  8. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  9. <title>Insert title here</title>
  10. </head>
  11. <body>
  12.  
  13. <h1>Edit Person</h1>
  14.  
  15. <c:url var="saveUrl" value="/main/edit/${personAttribute.id}" />
  16.  
  17. <form:form modelAttribute="personAttribute" method="POST" action="${saveUrl}">
  18. <table>
  19. <tr>
  20. <td><form:label path="id">Id:</form:label></td>
  21. <td><form:input path="id" disabled="true"/></td>
  22. </tr>
  23.  
  24. <tr>
  25. <td><form:label path="firstName">First Name:</form:label></td>
  26. <td><form:input path="firstName"/></td>
  27. </tr>
  28.  
  29. <tr>
  30. <td><form:label path="lastName">Last Name</form:label></td>
  31. <td><form:input path="lastName"/></td>
  32. </tr>
  33.  
  34. <tr>
  35. <td><form:label path="money">Money</form:label></td>
  36. <td><form:input path="money"/></td>
  37. </tr>
  38.  
  39. <tr>
  40. <td><form:label path="currency">Currency:</form:label></td>
  41. <td><form:select path="currency" items="${currencies}"/></td>
  42. </tr>
  43. </table>
  44.  
  45. <input type="submit" value="Save" />
  46. </form:form>
  47.  
  48. </body>
  49. </html>

此页面返回以下controller中的方法:

  1. @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
  2. public String getEdit(@PathVariable Integer id, Model model) {
  3. ...
  4. }

我们可以通过类似 
http://localhost:8080/spring-jsp/main/edit/1 
的链接进行编辑. 
下面是编辑页面

当我们编辑完提交表格,执行了下面的方法

  1. @RequestMapping(value = "/edit/{id}", method = RequestMethod.POST)
  2. public String saveEdit(@ModelAttribute("personAttribute") Person person,
  3. @PathVariable Integer id, Model model) {
  4. ...
  5. }

整个项目的目录结构如下


总结:我们完成一个基于spring3MVC的应用程序. 
并且了解了@ModelAttribute的两种使用模式. 
一个是作用于method级别, 
一个是用作method里的参数. 

BTW:附件为本次教程源码.你可以下载后直接在tomcat或其他web服务器启动.也可以自行添加 
maven插件启动.

 

(转)Spring3MVC 在JSP中使用@ModelAttribute的更多相关文章

  1. 浅谈JSP中include指令与include动作标识的区别

    JSP中主要包含三大指令,分别是page,include,taglib.本篇主要提及include指令. include指令使用格式:<%@ include file="文件的绝对路径 ...

  2. java web学习总结(二十八) -------------------JSP中的JavaBean

    一.什么是JavaBean JavaBean是一个遵循特定写法的Java类,它通常具有如下特点: 这个Java类必须具有一个无参的构造函数 属性必须私有化. 私有化的属性必须通过public类型的方法 ...

  3. jsp中的@include与jsp:include区别详解

    1 前言 搞java开发的人也许都知道在jsp中引入项目中其他文件有如下两种方式 <%@include file="xxx.jsp"%> <jsp:include ...

  4. bootstrap在jsp中的应用

    http://www.bootcss.com/ 下载bootstrap的js,css文件: 在jsp中的应用: 第一步: 新建一个web项目 将bootstrap下载下来的文件放入WEB-INF下面的 ...

  5. jsp中超链接路径的写法

    主题 超链接不就是一个地址字符串吗?这能有什么花头? LZSB! 曾经我也是这么想的.... 最近对apache的学习让我对网页中超链接,CSS,js的路径的写法有了一些新的认识. 所以这篇文章主要分 ...

  6. jsp中头的导入两种方式区别

    1.<jsp:include page="top.jsp">先将top.jsp中的java脚本和jsp指令执行完毕以后再讲top.jsp页面加入面中 2.<%@ ...

  7. Spring MVC:在jsp中引入css

    为了将css引入jsp中,今天可真是踩了好多坑,最后在stackoverflow上找到了解决方法,不多说贴出代码. 在web.xml中添加以下代码: <servlet-mapping> & ...

  8. 使用Maven构建Java Web项目时,关于jsp中引入js、css文件路径问题。

    今天有点闲,自己动手搭建一个Java Web项目,遇到jsp中引入js.css文件时路径不正确的问题,于是在网上查阅了很多资料,最终都无法解决问题,于是,上stackoverflow找到了解决方法,这 ...

  9. jsp中jstl标签的类似 if - else 语句 的语法

    在jsp中引入jstl的标签库和函数库 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c&q ...

随机推荐

  1. node.js零基础详细教程(6):mongodb数据库操作

    第六章 建议学习时间4小时  课程共10章 学习方式:详细阅读,并手动实现相关代码 学习目标:此教程将教会大家 安装Node.搭建服务器.express.mysql.mongodb.编写后台业务逻辑. ...

  2. 利用angular控制元素的显示和隐藏

    <!DOCTYPE html> <html lang="en" ng-app="myapp"> <head> <met ...

  3. Hibernate入门(二)

    一 Hibernate使用注解 可以使用注解创建Hibernate程序,使用注解的优点是不用创建映射文件,直接创建对象的关联. 使用hibernate注解需要导入注解相关的JAR包. 1.下载JAR包 ...

  4. C#的命名管道(named pipe)

    命名管道是一种从一个进程到另一个进程用内核对象来进行信息传输.和一般的管道不同,命名管道可以被不同进程以不同的方式方法调用(可以跨权限.跨语言.跨平台).只要程序知道命名管道的名字,发送到命名管道里的 ...

  5. 不小心用js重做了一遍贪吃蛇

    贪吃蛇游戏想必没人会感到陌生,这个游戏的js版本在网上也是一搜一大把,今天我要介绍的仍然是如何用js做一个贪吃蛇游戏,但在关键一步,蛇的运动的实现上略有不同. 贪吃蛇的js版本通常用连续的方块元素来实 ...

  6. 如何在linux如何安装nginx服务器

    1.进入命令窗口: 2.进入nginx.org 网站 下载安装包nginx-1.8.0.tar.gz 3.进入下载的文件夹 4.加压下载的压缩包 tar  -zxvf nginx-1.8.0.tar. ...

  7. VisualSVN 5.1.7破译License Key

    前面手敲一些简要的软件说明:visualSVN server大家都不陌生,服务器上的版本控制系统,一般配套Tortoisesvn(小乌龟)使用.本次介绍的这个visualsvn属于VisualStud ...

  8. php Base64编码文件二进制流主要使用

    <?php header( "Content-type: image/jpeg"); //$filename='1.jpg'; //$content=file_get_con ...

  9. 门控开关项目--使用Multism仿真

    可以修改桥式整流电路的电容,发现容值不合适的时候,直流不平稳.

  10. AngularJS数据双向绑定

    <body ng-app> <div ng-controller="myCtrl"> <input ng-model="abc" ...