响应数据和结果视图
通过处理器方法返回值指定返回视图
- SpringMVC中的处理器方法的返回值用来指定页面跳转到哪个视图,处理器的返回值可以为String,void,ModelAndView对象.
处理器返回String对象: 转发到字符串指定的URL
处理器方法返回字符串可以指定逻辑视图名,通过视图解析器解析为物理视图地址.
在本例中,因为我们在Spring容器配置文件bean.xml中配置的视图解析器中注入prefix和suffix属性,所以视图解析器会把处理器返回的"字符串值"解析为"/WEB-INF/pages/字符串值.jsp",再请求对应视图.这是一个请求转发过程,浏览器地址栏不会发生变化.
bean.xml中配置的视图解析器如下:
<!--配置视图解析器对象,请求时,可以帮你跳转到指定的页面-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--文件路经-->
<property name="prefix" value="/WEB-INF/pages/"/>
<!--指明后缀-->
<property name="suffix" value=".jsp"/>
</bean>
请求方法:
@RequestMapping("/testString")
public String testString(Model model) {
// 执行方法体...向隐式对象添加属性attribute_user,可以在jsp中通过 ${attribute_user} 获取到
model.addAttribute("attribute_user", new User("张三", "123"));
// 经过视图解析器的处理,SpringMVC会将请求转发到/WEB-INF/pages/succeess.jsp,但浏览器地址栏显示的一直是 项目域名/user/testString
return "success";
}
处理器返回void: 转发到当前URL
若处理器返回void,表示执行完处理器方法体内代码后,不进行请求转发,而直接转发到当前URL.若没有在web.xml中配置当前对应的url-pattern,则会返回404错误.
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/testVoid")
public void testVoid(Model model) {
// 执行方法体...向隐式对象添加属性attribute_user,可以在jsp中通过 ${attribute_user} 获取到
model.addAttribute("attribute_user", new User("张三", "123"));
// 处理器没有返回值,则会将请求转发到当前 项目域名/user/testVoid 路径
// 若在web.xml中没有配置 项目域名/user/testVoid 对应的url-pattern,则会返回404错误
return;
}
}
- 解决
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/testVoid")
public void testVoid(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 执行方法体...向隐式对象添加属性attribute_user,可以在jsp中通过 ${attribute_user} 获取到
model.addAttribute("attribute_user", new User("张三", "123"));
// 通过下面三个方法之一,可以指定访问的视图
// 指定视图的方式1: 请求转发
request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
// 指定视图的方式2: 重定向
response.sendRedirect(request.getContextPath() + "/index.jsp");
// 指定视图的方式3: 通过Writer对象写入内容
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
response.getWriter().print("你好");
return;
}
}
处理器返回ModelAndView对象: 更灵活地添加属性和指定返回视图
ModelAndView为我们提供了一种更灵活地为页面添加属性和指定返回视图的方法,其主要方法如下:
- public ModelMap getModelMap(): 返回当前页面的ModelMap对象.
- public ModelAndView addObject(Object attributeValue): 向当前页面的ModelMap对象中添加属性
- public void setViewName(@Nullable String viewName): 指定返回视图,viewName会先被视图解析器处理解析成对应视图.
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView() {
// 创建ModelAndView对象
ModelAndView mv = new ModelAndView();
// 向model中存入属性attribute_user
mv.addObject("attribute_user", new User("张三", "123"));
// 指定返回视图,视图解析器将"success"解析为视图URL /WEB-INF/pages/succeess.jsp
mv.setViewName("success");
return mv;
}
}
SpringMVC框架提供的请求转发和重定向
使用SpringMVC框架提供的请求转发
要使用SpringMVC框架提供的请求转发,只需要在处理器方法返回的viewName字符串首加上forward:即可,要注意的是,此时forward:后的地址不能直接被视图解析器解析,因此要写完整的相对路径.示例如下:
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/testForward")
public String testForward() {
// 在forward:要写完整的相对路径
// return "forward:success" // 错误,会将请求转发到 /项目名/user/success
return "forward:/WEB-INF/pages/success.jsp";
}
}
使用SpringMVC框架提供的重定向
要使用SpringMVC框架提供的请求重定向,只需要在处理器方法返回的viewName字符串首加上redirect:即可,要注意的是,此时redirect:后的地址要写相对于ContextPath的地址.示例如下:
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/testRedirct")
public String testRedirct() {
// 在forward:要写完整的相对路径
// return "redirect:" + request.getContextPath() + "/index.jsp"; // 错误,会将请求转发到 /项目名/项目名/index.jsp
return "redirect:/index.jsp";
}
}
SpringMVC响应json数据
前期准备
- sp在页面上引入jQuery以发送json数据,因此需要向服务器发起一个对jQuery的请求.像这种对静态资源的请求,不应当经过具体的某个处理器处理,而应当直接返回对应的静态资源.
因此我们需要在Spring容器配置bean.xml中使用mvc:resources标签声明该资源为静态资源,否则请求该资源会报404错误.该标签的属性如下:
- location属性: 表示该资源在服务器上所在的位置,必须是一个有效的目录
- mapping属性: 指定匹配的URL
我们在bean.xml中配置各静态文件的位置如下:
<!-- 配置静态文件的路径于对应的URL -->
<!-- location属性必须是一个有效的目录,因此必须以 / 结尾 -->
<mvc:resources location="/css/" mapping="/css/**"/>
<mvc:resources location="/images/" mapping="/images/**"/>
<mvc:resources location="/js/" mapping="/js/**"/>
- 要将json字符串与JavaBean对象相互转换,我们需要引用jackson的jar包,在pom.xml中添加依赖坐标如下:
<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-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency
在jsp中编写代码发送json数据
在jsp页面中编写代码发送json请求如下:
<script>
// 页面加载,绑定单击事件
$(function () {
$("#btn").click(function () {
// 发送ajax请求
$.ajax({
// 配置请求参数
url: "user/testAjax",
contentType: "application/json;charset=UTF-8",
dataType: "json",
type: "post",
// 请求的json数据
data: '{"username":"myname","password":"mypassowrd","age":30}',
// 回调函数,处理服务器返回的数据returnData
success: function (returnData) {
// 我们假定服务器返回的是一个user对象,将其输出在控制台上
console.log(returnData); }
});
});
});
</script>
在控制器中编写代码响应json数据
使用@RequestBody注解将请求体绑定到控制器方法参数上,使用@ResponseBody注解表示将该方法的返回值直接写回到HTTP响应中,而不是存入Model或解析为视图名.
我们引入的jackson包自动完成从Java实体类到json数据之间的相互转换.
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/testAjax")
@ResponseBody
public User testAjax(@RequestBody User user) {
System.out.println(user);
// 将user对象返回给前端页面
return user;
}
}
也可以这样:
@RequestMapping("/testJson")
//@ResponseBody 注在返回值类型User前,自动将User类型转换为json格式数据响应给客户端
public @ResponseBody
User testJson(@RequestBody User user) {
//客户端发送ajax请求,传入的是json字符串(请求体内)由SpringMVC框架自动转换封装到JavaBean中
System.out.println(user);
//模拟数据库查询
user.setName("张三");
//响应,返回给前端
return user;
}
返回页面jsp:
<%--
Created by IntelliJ IDEA.
User: seldom
Date: 2019/8/5
Time: 0:39
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>执行success</h3>
<%-- 显示返回来的数据--%>
${user.name}
${user.age}
${user.password}
</body>
</html>
结果: