1.请求处理方法签名:
SpringMVC通过分析处理方法的签名,将HTTP请求信息绑定到处理方法的相应入参中。
SpringMVC对控制器处理方法签名的限制很宽松。
必要时可以对方法及方法入参相应的注解(@PathVariable、@RequestParam、@RequestHeader等)SpringMVC框架会将HTTP请求的信息绑定到相应的方法入参中,并根据方法的返回值类型做出相应的后续处理。
1.1 @RequestParam:
在处理方法入参处使用RequestParam可以把请求参数传递给请求方法:
value:参数名;
required:是否必须。默认为true。
@RequestMapping(value = "/testRequestParam")public String testRequestParam(@RequestParam(value = "username") String un,@RequestParam(value = "age", required = false, defaultValue = "0") int age) {System.out.println("testRequestParam, username: " + un + ", age: "+ age);return SUCCESS;}
1.2 @RequestHeader:
请求头包含了若干个属性,服务器可以根据此获知客户端的信息。
@RequestMapping("/testRequestHeader")public String testRequestHeader(@RequestHeader(value = "Accept-Language") String al) {System.out.println("testRequestHeader, Accept-Language: " + al);return SUCCESS;}
1.3 @CookieValue:
@CookieValue可以让处理方法入参绑定某个Cookie值。
@RequestMapping("/testCookieValue")public String testCookieValue(@CookieValue("JSESSIONID") String sessionId) {System.out.println("testCookieValue: sessionId: " + sessionId);return SUCCESS;}
1.4 POJO作为参数:
Spring MVC会按请求参数名和POJO属性名进行自动匹配,自动为对象填充属性值。支持级联属性。
package com.atguigu.springmvc.entities;public class User {private Integer id;private String username;private String password;private String email;private int age;private Address address;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;}// @Override
// public String toString() {
// return "User [username=" + username + ", password=" + password
// + ", email=" + email + ", age=" + age + ", address=" + address
// + "]";
// }@Overridepublic String toString() {return "User [id=" + id + ", username=" + username + ", password="+ password + ", email=" + email + ", age=" + age + "]";}public User(String username, String password, String email, int age) {super();this.username = username;this.password = password;this.email = email;this.age = age;}public User(Integer id, String username, String password, String email,int age) {super();this.id = id;this.username = username;this.password = password;this.email = email;this.age = age;}public User() {}
}
package com.atguigu.springmvc.entities;public class Address {private String province;private String city;public String getProvince() {return province;}public void setProvince(String province) {this.province = province;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}@Overridepublic String toString() {return "Address [province=" + province + ", city=" + city + "]";}}
@RequestMapping("/testPojo")public String testPojo(User user) {System.out.println("testPojo: " + user);return SUCCESS;}
1.5 Servlet API作为参数:
MVC的Handler方法可以接受的Servlet API类型的参数:
HttpServletRequest
HttpServletResponse
HttpSession
java.security.Principal? Locale
InputStream
OutputStream
Reader
Writer
@RequestMapping("/testServletAPI")public void testServletAPI(HttpServletRequest request,HttpServletResponse response, Writer out) throws IOException {System.out.println("testServletAPI, " + request + ", " + response);out.write("hello springmvc");
// return SUCCESS;}
2.处理模型数据:
SpringMVC提供了以下几种途径输出模型数据:
ModelAndView:处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据。
Map及Model:入参为org.springframework.ui.Model、org.springframework.ui. ModelMap或java.uti.Map时,处理方法返回时,Map中的数据会自动添加到模型中。
@SessionAttributes:将模型中的某个属性暂存到HttpSession中,已便多个请求之间可以共享这个属性。
@ModelAttribute:方法入参标注该注解之后,入参的对象就会放到数据模型中。
2.1 ModelAndView:
控制器处理方法的返回值如果位ModelAndView,则其既包含视图信息又包含模型数据信息。
添加模型数据:
– MoelAndView addObject(String attributeName, Object attributeValue)
– ModelAndView addAllObject(Map<String, ?> modelMap)
设置视图:
– void setView(View view)
– void setViewName(String viewName)
@RequestMapping("/testModelAndView")public ModelAndView testModelAndView(){String viewName = SUCCESS;ModelAndView modelAndView = new ModelAndView(viewName);modelAndView.addObject("time", new Date());return modelAndView;}
2.2 Map及Model:
Spring MVC在内部使用了一个org.springframework.ui.Model接口存储模型数据。
具体步骤:
SpringMVC在调用方法之前会创建一个隐含的模型对象作为模型数据的存储容器;
如果方法中的入参为Map或者Model类型,SpringMVC会将隐含模型的引用传递给这些入。
在方法体内,开发者可以通过这个入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据。
@RequestMapping("/testMap")public String testMap(Map<String, Object> map){System.out.println(map.getClass().getName()); map.put("names", Arrays.asList("Tom", "Jerry", "Mike"));return SUCCESS;}
2.3 @SessionAttributes:
若希望在多个请求之间共用某个模型属性数据,则可以在控制器上标注一个@SessionAttributes,SpringMVC将在模型中对应的属性暂存到HttpSession中。
@SessionAttributes除了可以通过属性名指定需要放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中。
@SessionAttributes(types=User.class)会将隐含模型中所有类型为User.class的属性添加到会话中。
@SessionAttributes(value={“user1”, “user2”})
@SessionAttributes(types={User.class, Dept.class})
@SessionAttributes(value={“user1”, “user2”}, types={Dept.class})
@SessionAttributes(value={"user"}, types={String.class})
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {@RequestMapping("/testSessionAttributes")public String testSessionAttributes(Map<String, Object> map){User user = new User("Tom", "123456", "tom@atguigu.com", 15);map.put("user", user);map.put("school", "atguigu");return SUCCESS;}
}
2.4 @ModelAttribute:
在只需要修改数据库部分字段的原始操作:
改进后:
这就是SpringMVC的@ModelAttribute注解的作用。
在方法定义上使用@ModelAttribute注解:SpringMVC在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute的方法。
在方法的入参前使用@ModelAttribute注解:
-可以从隐含对象中获取隐含的模型数据中获取对象,再将请求参数绑定到对象中,再传入入参。
-将方法入参对象添加到模型中。
<!-- 模拟修改操作1. 原始数据为: 1, Tom, 123456,tom@atguigu.com,122. 密码不能被修改.3. 表单回显, 模拟操作直接在表单填写对应的属性值--><form action="springmvc/testModelAttribute" method="Post"><input type="hidden" name="id" value="1"/>username: <input type="text" name="username" value="Tom"/><br>email: <input type="text" name="email" value="tom@atguigu.com"/><br>age: <input type="text" name="age" value="12"/><br><input type="submit" value="Submit"/></form>
//上面图一的情况
//可以通过@ModelAttribute("user")获取user也可以不使用
//若@ModelAttribute("user")不能获取,则会从@SessionAttributes获取
//若@SessionAttributes也没有,则会抛出异常,前提是有@SessionAttributes注解
@RequestMapping("/testModelAttribute")public String testModelAttribute(@ModelAttribute("user")User user){System.out.println("修改: " + user);return SUCCESS;}//加上下面的方法之后就是图二的情况
//但是这个方法会在所有方法调用之前都调用一下
//在执行这个方法时,会把表单的数据赋给这个对象的对应数据
@ModelAttributepublic void getUser(@RequestParam(value="id",required=false) Integer id, Map<String, Object> map){System.out.println("modelAttribute method");if(id != null){//模拟从数据库中获取对象User user = new User(1, "Tom", "123456", "tom@atguigu.com", 12);System.out.println("从数据库中获取的对象: " + user);map.put("user", user);}}