响应数据和结果视图
一、返回值分类
1). 字符串
Controller方法返回字符串可以指定逻辑视图名,通过视图解析器解析为物理视图地址。
- index.jsp
<a href="${pageContext.request.contextPath}/user/testReturnString">访问测试</a>
- 控制器
/** 指定逻辑视图名,经过视图解析器解析为jsp物理路径:/WEB_INF/pages/success.jsp */
@RequestMapping("/testReturnString")
public String testReturnString(Model model) {
/** model接口的实现类是将数据存放到request域中!
* 只需要在方法参数上加上该接口声明即可,后面的事就交给底层了 */
System.out.println("返回值为字符串");
model.addAttribute("result", "返回值为字符串!");
return "success";
}
- 返回视图success.jsp
<h1>操作成功!</h1>
<hr>
回馈信息:${result}
2). void
默认情况下会访问视图解析路径下对应访问路径的uri加上".jsp" 的文件,如果不存在将会报404错误!
Servlet原始API可以作为控制器中方法的参数。可以使用原始API做一些操作。可以在
controller
方法形参上可以定义request
和response
,使用request
或者response
指定响应结果
1. jsp
<%-- 返回值为void --%>
<a href="/springmvc/testReturnVoid">void测试</a>
2. 控制器代码
/** 返回值为void,依靠原生Servlet API完成这些操作 */
@RequestMapping("testReturnVoid")
public void testReturnVoid(HttpServletRequest request,
HttpServletResponse response) throws Exception {
/** == 下面的代码可以写在此处 == */
}
- 使用request转向页面,如下:
使用转发不会经过视图解析器
/* 使用request转向页面 */
request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request, response);
- 通过response页面重定向
二次请求
response.sendRedirect("otherPages");
- 通过response指定响应结果,例如响应json数据
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("[{name:'lc',age:'23'},{name:'xq',age:'22'}]");
3). ModelAndView
ModelAndView是SpringMVC为我们提供的一个对象,该对象可以作为控制器方法返回值。该对象中有两个方法。
1. ModelAndView源码分析
- 添加对象数据的方法,底层还是调用的
ModelMap
这个域对象,在页面上可以使用el表达式${ "attributeName" }
获取域中的数据
public ModelAndView addObject(String attributeName, Object attributeValue) {
this.getModelMap().addAttribute(attributeName, attributeValue);
return this;
}
- 用于设置【逻辑视图】的名称,视图解析器会根据名称前往指定的视图
public void setViewName(@Nullable String viewName) {
this.view = viewName;
}
2. 案例演示
底层肯定是放到一个域对象中的,各个域对象都可以取?太神奇了
- index.jsp
<%-- 返回值为ReturnModelAndView --%>
<a href="/springmvc/testReturnModelAndView">ReturnModelAndView</a>
- 控制器代码
@Controller
@RequestMapping("/springmvc")
public class AnnotationTestController {
/** 返回 ModeAndVies */
@RequestMapping("/testReturnModelAndView")
public ModelAndView testReturnModelAndView() {
ModelAndView mv = new ModelAndView();
// 添加数据到域对象中
mv.addObject("username", "弼马温");
// 设置跳转的逻辑视图
mv.setViewName("success");
return mv;
}
}
- success.jsp
<h3>操作成功!</h3>
username: ${ username }
requestScope.username: ${ requestScope.username } // 使用此种方式,浏览器跳转只能是请求转发。
sessionScope.username: ${ sessionScope.username }
二、使用关键字转发和重定向【了解】
1). forward转发
controller方法在提供了String类型的返回值之后,默认就是请求转发。 也可以写成下面这种形式,了解即可,不推荐使用
- jsp代码
<%-- 转发 --%>
<a href="springmvc/testForward">testForward</a>
- 控制器代码
注意,如果使用了
forward:
路径必须写成实际视图的url,不能写逻辑视图。使用请求转发,可以转发到jsp,也可以转发到其他的控制器方法。
@Controller
@RequestMapping("/springmvc")
public class AnnotationTestController {
/** 转发消息 */
@RequestMapping("/testForward")
public String testForward() {
System.out.println("testForward");
return "forward:/WEB-INF/pages/success.jsp";
/* 等效于
request.getRequestDispatcher("/WEB-INF/pages/success.jsp")
.forward(request, response);
*/
}
}
2). Redirect重定向
controller方法提供了个String类型返回值之后,需要在返回值里面使用
redirect:
它相当于response.sendRedirect(url)
,需要注意的是,如果重定向到jsp页面,则jso页面不能写在WEB-INF目录下,否则无法找到。
- jsp代码
<%-- 重定向 --%>
<a href="/springmvc/testRedirect">重定向测试</a>
- 控制器代码
框架底层会自动加上项目虚拟路径,开发者可以不用写
@Controller
@RequestMapping("/springmvc")
public class AnnotationTestController {
/** 重定向 */
@RequestMapping("/testRedirect")
public String testRedirect() {
System.out.println("我要开始转发了");
return "redirect:testForward";
}
}
三、ResponseBody响应json数据
1). 功能介绍
该注解用于将Controller大方法返回的对象,通过HttpMessageConverter接口转换为指定格式的数据,如json,xml等,通过Response响应给客户端。
2). 使用案例
SpringMVC模式用MappingJacksonHttpMessageConverter对json数据进行转换,需要导入jackson的坐标
- 需求:使用@ResponseBody注解实现将controller方法返回对象转换为json响应给客户端。
- 需要导入的maven坐标
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</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-core</artifactId>
<version>2.9.0</version>
</dependency>
- jsp核心代码
注意,json数据封装时,变量名得加上双引号
""
,而且整个数据都必须以字符串的形式上传!否则会报415或者400错误;只能使用$.ajax
的形式,如果使用$.get
或者$.post
,底层提交的还是表单的形式
<input type="button" value="测试ajax请求json和响应json" id="submit">
</body>
<script src="${pageContext.request.contextPath}/js/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
$(function () {
$("#submit").click(function () {
$.ajax({
type: "post",
url: "${pageContext.request.contextPath}/springmvc/testResponseJson",
contentType: "application/json; charset=utf-8",
data:'{"id":1,"name":"test","money":999.0,"address":{"provinceName": "四川","cityName": "成都" }}',
dataType: "json",
success: function (data) {
console.log(data)
}
})
})
})
</script>
- 控制器代码
前端发送的请求体是json格式的字符串,后台中使用对应的pojo进行封装。
@Controller
@RequestMapping("/springmvc")
public class AnnotationTestController {
/**
json请求 @RequestBody 注解
json响应 @ResponseBody 注解*/
@RequestMapping("/testResponseJson")
public @ResponseBody Account testResponseJson(@RequestBody Account account) {
System.out.println("异步请求:" + account);
return account;
}
}