接收请求与设置响应
1. 接收请求
客户端请求参数的格式是键值对形式:name1=value1&name2=value2…
不同的参数类型
服务器端要获得请求的参数,有时还需要进行数据的封装,SpringMVC 可以接收如下类型的参数:
基本类型参数:令 Controller 中的业务方法的参数名称与请求参数的 name 一致,则参数值会被自动映射匹配。
// http://localhost:8080/itheima_springmvc1/quick9?username=zhangsan&age=12 @RequestMapping("/quick9") @ResponseBody public void quickMethod9(String username, int age) throws IOException { System.out.println(username); System.out.println(age); }
POJO 类型参数:令 Controller 中的业务方法的 POJO 参数的属性名与请求参数的 name 一致,则参数值会自动映射匹配。
// http://localhost:8080/itheima_springmvc1/quick9?username=zhangsan&age=12 public class User{ private String usrname; private int age; getter/setter... } @RequestMapping("/quick10") @ResponseBody public void quickMethod10(User user) throws IOException { System.out.println(user); }
数组类型参数:令 Controller 中的业务方法数组名称与请求参数的 name 一致,则参数值会自动映射匹配。
// http://localhost:8080/itheima_springmvc1/quick11?strs=111&strs=222&strs=333 @RequestMapping("/quick11") @ResponseBody public void quickMethod11(String[] strs) throws IOException { System.out.println(Arrays.asList(strs)); }
集合类型参数:一般地,当获得集合参数时,要将集合参数包装到一个 POJO 中才可以,通常也将这种对象称为 VO(value object, view object) 对象(参见 B 站视频)。
// VO.java package com.itheima.domain; import java.util.List; public class VO { private List<User> userList; public List<User> getUserList() { return userList; } public void setUserList(List<User> userList) { this.userList = userList; } @Override public String toString() { return "VO{" + "userList=" + userList + '}'; } }
// UserController.java @RequestMapping("/quick9") @ResponseBody public void save9(VO vo) { System.out.println(vo); }
<%-- form.jsp --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <form action="${pageContext.request.contextPath}/quick9" method="post"> <%-- 表明第一个 User 对象的 username、age --%> <input type="text" name="userList[0].username" /><br /> <input type="text" name="userList[0].age" /><br /> <input type="text" name="userList[1].username" /><br /> <input type="text" name="userList[1].age" /><br /> <input type="submit" value="提交" /> </form> </body> </html>
30 31 当使用 ajax 提交时,可以指定 contentType 为 json 形式,此时在方法参数位置使用@RequestBody 注解可以直接接收集合数据,而无需使用 POJO 进行包装(参见 B 站视频)。
<script> // 模拟数据 var userList = new Array(); userList.push({username: "zhangsan", age: "20"}); userList.push({username: "lisi", age: "20"}); $.ajax({ type: "POST", url: "/itheima_springmvc1/quick13", data: JSON.stringify(userList), contentType: 'application/json;charset=utf-8' }); </script>
@RequestMapping(value="/quick15") @ResponseBody public void save15(@ResponseBody List<User> userList) throws IOException { System.out.println(userList); }
Restful 风格的请求
Restful 是一种软件架构风格、设计风格,这不是标准,只是提供了一组设计原则和约束条件。主要用于客户端和服务器交互类的软件,基于这个风格设计的软件可以更简洁、更有层次、更易于实现缓存机制等。
Restful 风格的请求使用“url+请求方式”表示一次请求目的,HTTP 协议里面 4 个表示操作方式的动词如下:
操作方式 | 作用 |
---|---|
GET | 用于获取资源 |
POST | 用于新建资源 |
PUT | 用于更新资源 |
DELETE | 用于删除资源 |
示例说明:
URL | 请求方式 | 说明 |
---|---|---|
/user/1 | GET | 得到 id=1 的 user |
/user/1 | DELETE | 删除 id=1 的 user |
/user/1 | PUT | 更新 id=1 的 user |
/user | POST | 新增 user |
上述 url 地址中的/user/1 中的 1 就是要获得的请求参数,在 SpringMVC 中可以使用占位符进行参数绑定。地址/user/1 可以写成/user/{id},占位符{id}对应的就是 1 的值。在业务方法中我们可以使用@PathVariable
注解进行点位符的匹配获取工作。
// http://localhost:8080/itheima_springmvc1/quick19/zhangsan
@RequestMapping("quick19/{name}")
@ResponseBody
public void quickMethod19(@PathVariable(value = "name", required = true) String name) {
System.out.println(name);
}
2. 设置响应
pringMVC 的数据响应方式:
- 页面跳转
- 直接返回字符串;
- 通过 ModelAndView 对象返回。
- 回写数据
- 直接返回字符串;
- 返回对象或集合。
2.1 页面跳转
2.1.1 返回字符串形式
此种方式会将返回的字符串与视图解析器的前后缀拼接后跳转。

2.1.2 返回 ModelAndView 对象
Model 为模型,作用为封装数据;View 为视图,作用为展示数据。
package com.itheima.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
@Controller
public class UserController {
@RequestMapping("/quick")
public String save() {
System.out.println("Controller save running...");
return "success.jsp";
}
@RequestMapping("/quick2")
public ModelAndView save2() {
ModelAndView modelAndView = new ModelAndView();
// 设置模型数据:向域中放入数据
modelAndView.addObject("username", "itcast");
// 设置视图名称
modelAndView.setViewName("success.jsp");
return modelAndView;
}
/**
* SpringMVC 在解析方法时,如果发现方法的参数有 ModelAndView,Model,HttpServletRequest 等
* 常用类型的形参时,那么 SpringMVC 就可以自动帮你对相应的参数进行注入
*/
@RequestMapping("/quick3")
public ModelAndView save3(ModelAndView modelAndView) {
// 设置模数数据:向域中放入数据
modelAndView.addObject("username", "itheima");
// 设置视图名称
modelAndView.setViewName("success.jsp");
return modelAndView;
}
@RequestMapping("/quick4")
public String save4(Model model) {
// 向域中放入数据
model.addAttribute("username", "博学谷");
return "success.jsp";
}
// 不常用,应该尽量调用框架提供的对象,放这里只是说明这样也可以
@RequestMapping("/quick5")
public String save5(HttpServletRequest request) {
// 向域中放入数据
request.setAttribute("username", "酷丁鱼");
return "success.jsp";
}
}
2.2 回写数据
2.2.1 直接返回字符串
Web 基础阶段,客户端访问服务器端,如果想直接写回字符串作为响应体返回的话,只需要使用response.getWriter().print("hello world")
即可,那么在 SpringMVC 的 Controller 中如何写回字符串呢?
方案一(不推荐):通过 SpringMVC 框架注入的response
对象,使用response.getWriter().print("hello world")
回写数据,此时不需要视图跳转,业务方法返回值为void
。
@RequestMapping("/quick6")
public void save6(HttpServletResponse response) throws IOException {
// 回写数据
response.getWriter().print("hello itcast");
}

方案二:将需要回写的字符串直接返回,但此时需要通过@ResponseBody
注解告知 SpringMVC 框架,方法返回的字符串不是跳转而是直接在 http 响应体中返回。
@RequestMapping("/quick7")
// 形式上与/quick1 相似,故而为防歧义,加@ResponseBody 注解
// 告诉 SpringMVC 框架,不进行数据跳转,直接进行数据响应
@ResponseBody
public String save7() {
return "hello itheima";
}

2.2.2 返回对象或集合
通过 SpringMVC 帮助我们将对象/集合进行 json 字符串的转换并回写。
注意相应的对象必须同时实现 get 和 set 方法!
前提:对于一个 User 类,希望将其以 json 格式字符串进行回写:
// User.java package com.itheima.domain; public class User { private String username; private int age; public void setUsername(String username) { this.username = username; } public void setAge(int age) { this.age = age; } public String getUsername() { return username; } public int getAge() { return age; } @Override public String toString() { return "User{" + "username='" + username + '\'' + ", age=" + age + '}'; } }
// UserController.java @RequestMapping("/quick8") @ResponseBody // 不可省略 // 期望 SpringMVC 自动将 User 转换成 json 格式的字符串 public User save8() { User user = new User(); user.setUsername("zhangsan"); user.setAge(27); return user; }
需要导入 jackson(json 解析器)相关依赖:
<!-- 导入 json 解析包 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.0</version> </dependency>
解决方案
方案 1(不推荐):在 spring-mvc.xml 中进行这些配置,为处理器适配器配置消息转换参数,指定使用 jackson 进行对象或集合的转换。
<!-- 配置处理器映射器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/> </list> </property> </bean>
方案 2(推荐):在方法上添加@ResponseBody 就可以返回 json 格式的字符串,可以使用 mvc 的“注解驱动”代替上述配置,简单便捷。
<!--配置 mvc 的注解驱动--> <mvc:annotation-driven/>
方案 2 的解释:在 SpringMVC 的各个组件中,处理器映射器、处理器适配器、视图解析器称为 SpringMVC 的三大组件。配置了
<mvc:annotation-driven/>
语句后,就能够自动加载RequestMappingHandlerMapping
(处理器映射器)和RequestMappingHandlerAdapter
(处理器适配器),同时还会在底层默认集成 jackson 进行对象或集合的 json 格式字符串的转换。故而,可在 spring-mvc.xml 配置文件中使用<mvc:annotation-driven/>
替代注解处理器和适配器的配置。