1 Controller 类的方法返回值
使用 @Controller 注解的处理器的处理器方法,其返回值常用的有四种类型:
➢ 第一种: ModelAndView
➢ 第二种: String
➢ 第三种:无返回值 void
➢ 第四种:返回自定义类型对象
1.1 返回 ModelAndView
若处理器方法处理完后,需要跳转到其它资源,且又要在跳转的资源间传递数据,此时处理器方法返回 ModelAndView 比较好。
mv.setViewName 设置跳转的页面。
mv.addObject map 的形式,传入 key-value。之后在生成页面内容时,根据 key 对应的 value 值填充页面数据。
处理器方法
@RequestMapping(value = "/receiveobject.do")
public ModelAndView receiveParam(Student myStudent){
System.out.println("receiveParam, name="+myStudent.getName()+" age="+myStudent.getAge());
ModelAndView mv = new ModelAndView();
mv.addObject("myname",myStudent.getName());
mv.addObject("myage",myStudent.getAge());
mv.addObject("mystudent",myStudent);
mv.setViewName("show");
return mv;
}前端页面
<h3>/WEB-INF/view/show.jsp从request作用域获取数据</h3>
<br />
<h3>myname数据:${myname}</h3>
<br />
<h3>myage数据:${myage}</h3>
<h3>student数据:${mystudent}</h3>1.2 返回 String
处理器方法返回的字符串可以指定逻辑视图名,通过视图解析器解析。前面很多例子都是返回 String。
注:使用逻辑视图,记得在 Spring MVC 配置文件中配置前后缀。
1.3 返回 Map
Map 作为返回值是数据,能够自动转为 json。
@GetMapping("/map/json")
@ResponseBody public Map getMap(){
Map<String,Object> map = new HashMap<>();
map.put("id",1001);
map.put("address","大兴区");
map.put("city","北京");
return map;
}1.4 void
对于处理器方法返回 void 的应用场景, AJAX 响应。
若处理器对请求处理后,无需跳转到其它任何资源,此时可以让处理器方法返回 void 。通过 HttpServletResponse 输出数据,响应 AJAX 请求。
使用 JackSon 将对象转换为 Json 格式。
@RequestMapping(value = "/returnVoid-ajax.do")
public void doReturnVoidAjax(HttpServletResponse response, String name, Integer age) throws IOException {
Student student = new Student();
String json = "";
if(student != null){
ObjectMapper om = new ObjectMapper();
json = om.writeValueAsString(student);
}
response.setContentType("application/json;charset=utf-8");
PrintWriter pw = response.getWriter();
pw.println(json);
pw.flush();
pw.close();
}<head>
<title>Title</title>
<script type="text/javascript" src="js/jquery-3.4.1.js"></script>
<script type="text/javascript">
$(function () {
$("button").click(function () {
$.ajax({
url: "returnStringData.do",
data: {
name: "zhangsan",
age: 20,
},
type: "post",
dataType: "text", // 收到的数据类型是什么样的
//dataType:"json",
success: function (resp) {
//resp从服务器端返回的是json格式的字符串 {"name":"zhangsan","age":20}
//jquery会把字符串转为json对象, 赋值给resp形参。
// [{"name":"李四同学","age":20},{"name":"张三","age":28}]
/*$.each(resp,function(i,n){
alert(n.name+" "+n.age)
})*/
},
});
});
});
</script>
</head>
<body>
<p>处理器方法返回String表示视图完整路径</p>
<form action="returnString-view2.do" method="post">
姓名:<input type="text" name="name" /> <br />
年龄:<input type="text" name="age" /> <br />
<input type="submit" value="提交参数" />
</form>
<button id="btn">发起ajax请求</button>
</body>1.5 返回自定义类型对象
SpringMVC-3 HttpMessageConverter
处理器方法也可以返回 Object 对象。这个 Object 可以是 Integer,String,自定义对象,Map,List 等。但返回的对象不是作为逻辑视图出现的,而是作为直接在页面显示的数据出现的。返回对象,需要使用 @ResponseBody 注解,将转换后的 JSON 数据放入到响应体中。
具体步骤:
-
加入处理 json 的工具库的依赖, springmvc 默认使用的 jackson。
-
在 sprigmvc 配置文件之间加入 <mvc: annotation-driven/> 注解驱动。
相当于json = om.writeValueAsString(student); -
在处理器方法的上面加入@ResponseBody 注解
相当于response.setContentType("application/json; charset=utf-8"); PrintWriter pw = response.getWriter(); Pw.println(json);
实现原理:
-
<mvc:annotation-driven>
注解驱动实现的功能是完成 java 对象到 json,xml, text,二进制等数据格式的转换。
<mvc: annotation-driven>在加入到 springmvc 配置文件后,会自动创建 HttpMessageConverter 接口的 7 个实现类对象。 -
HttpMessageConverter接口:消息转换器。功能:定义了 java 转为 json,xml 等数据格式的方法。boolean canWrite(Class<?> var1, @Nullable MediaType var2); void write(T var1, @Nullable MediaType var2, HttpOutputMessage var3)canWrite()作用检查处理器方法的返回值,能不能转为 var2 表示的数据格式。例如检查能转为 json,canWrite 返回 true。MediaType:表示数格式的,例如 json, xml 等等。write()把处理器方法的返回值对象,调用 jackson 中的 ObjectMapper 转为 json 字符串。相当于json = om.writeValueAsString(student);
-
@ResponseBody
作用:把处理器方法返回对象转为 json 后,通过 HttpServletResponse 输出给浏览器。
位置:方法的定义上面。和其它注解没有顺序的关系。
1.5.1 返回 POLO 对象
返回对象框架的处理流程:
- 框架会把返回 Student 类型,调用框架的中 ArrayList<HttpMessageConverter>中每个类的 canWrite () 方法。检查那个 HttpMessageConverter 接口的实现类能处理 Student 类型的数据—MappingJackson2HttpMessageConverter
- 框架会调用实现类的 write(), MappingJackson2HttpMessageConverter 的 write () 方法把李四同学的 student 对象转为 json,调用 Jackson 的 ObjectMapper 实现转为
json/json array/ - ContentType: application/json; charset=utf-8
- 框架会调用@ResponseBody 把 2 的结果数据输出到浏览器, ajax 请求处理完成
// 返回 Json
@RequestMapping(value = "/returnStudentJson.do")
@ResponseBody
public Student doStudentJsonObject(String name, Integer age) {
//调用 service,获取请求结果数据, Student 对象表示结果数据
Student student = new Student();
student.setName("李四同学");
student.setAge(20);
return student; // 会被框架转为 json
}1.5.2 返回 List 对象
// 返回 Json Array
@RequestMapping(value = "/returnStudentJsonArray.do")
@ResponseBody
public List<Student> doStudentJsonObjectArray(String name, Integer age) {
List<Student> list = new ArrayList<>();
Student student = new Student();
list.add(student);
list.add(student);
return list;
}1.5.3 返回 String 对象
处理器方法返回的是 String , String 表示数据的,不是视图。
默认使用“text/plain; charset=ISO-8859-1”作为 contentType, 导致中文有乱码,
解决方案:给 RequestMapping 增加一个属性 produces, 使用这个属性指定新的 contentType.
返回对象框架的处理流程:
- 框架会把返回 String 类型,调用框架的中 ArrayList<HttpMessageConverter>中每个类的 canWrite () 方法. 检查那个 HttpMessageConverter 接口的实现类能处理 String 类型的数据—StringHttpMessageConverter
- 框架会调用实现类的 write(), StringHttpMessageConverter 的 write () 方法。把字符按照指定的编码处理 text/plain; charset=ISO-8859-1
- 框架会调用@ResponseBody 把 2 的结果数据输出到浏览器, ajax 请求处理完成
@RequestMapping(value = "/returnStringData.do",produces = "text/plain;charset=utf-8")
@ResponseBody
public String doStringData(String name,Integer age){
return "Hello SpringMVC 返回对象,表示数据";
}1.6 返回 ResponseEntity 对象
ResponseEntity 包含 HttpStatus Code 和应答数据的结合体。因为有 Http Code 能表达标准的语义,200 成功, 404 没有发现等。
@GetMapping("/show/json3")
ResponseEntity<User> getUserInfo(){
User user = new User();
user.setName("李四");
user.setAge(20);
Role role = new Role();
role.setId(5892);
role.setRoleName("操作员");
role.setMemo("基本操作,读取数据,不能修改");
user.setRole(role);
ResponseEntity<User> response = new ResponseEntity<>(user, HttpStatus.OK);
return response;
}其他创建 ResponseEntity 的方式
// 200 状态码
ResponseEntity<User> response = ResponseEntity.ok(user);
//HTTP 204 No Content 成功状态响应码,表示该请求已经成功了
ResponseEntity<User> response = ResponseEntity.noContent().build();ResponseEntity 还用于文件的上传与下载,参考 SpringMVC 文件上传与下载