springMVC响应数据和结果视图【详解】
文章目录
返回值分类
返回值为String类型
基本响应
- response.jsp页面
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2020/8/26
Time: 22:11
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="user/testString">testString</a>
</body>
</html>
- UserController.java
package cn.itcast.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**一点击jsp页面的超链接,方法就可以执行 * Create By LiFang on 2020/8/26. */
@Controller
@RequestMapping("/user") //一级目录
public class UserController {
@RequestMapping("/testString")
public String testString(){
System.out.println("testString方法执行了。。");
//如果返回字符串success,则需要根据视图解析器去请求那个目录下的jsp文件(跳转到某个页面)
return "success";
}
}
- 如果返回字符串success,则需要根据视图解析器去请求那个目录下的jsp文件(跳转到某个页面)
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解扫描-->
<context:component-scan base-package="cn.itcast"/>
<!-- 视图解析器对象: 如果想跳页面,底层就会通过视图解析器跳到指定页面-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 在bean中 配置参数,属性为:文件所在的目录,-->
<property name="prefix" value="/WEB-INF/pages/"></property>
<!-- 后缀名-->
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 开启SpringMVC框架注解的支持-->
<mvc:annotation-driven/>
<!-- 配置类型转换器工厂 -->
<!-- 开启SpringMVC框架注解的支持:让类型转换配置生效-->
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
- (在WEB-INF目录下新建pages文件夹,新建success.jsp文件。)
视图解析器解析后跳转的目标页面:
success.jsp
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2020/8/26
Time: 22:25
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>执行成功</h3>
</body>
</html>
至此,整个环境(方法返回字符串要根据视图解析器最终成功跳转到某个页面)搭建完成。
然后启动Tomcat服务器,
结果:
点击超链接
因此环境搭建没有问题。以上是最基本的响应。
实际开发
那我们在实际开发中应该怎么做呢?
- 编写一个javaBean的类
User.java
package cn.itcast.domain;
import java.io.Serializable;
/**User类是一个javaBean * Create By LiFang on 2020/8/27. */
public class User implements Serializable {
private String username;
private String password;
private Integer age;
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 Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
2. UserController.java
package cn.itcast.controller;
import org.springframework.ui.Model;
import cn.itcast.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**一点击jsp页面的超链接,方法就可以执行 * Create By LiFang on 2020/8/26. */
@Controller
@RequestMapping("/user") //一级目录
public class UserController {
@RequestMapping("/testString")
public String testString(Model model){
System.out.println("testString方法执行了。。");
//模拟从数据库中查询出User对象
User user = new User();
user.setUsername("美美");
user.setPassword("123");
user.setAge(18);
//model对象(存到model对象,它帮我存到request域中)
model.addAttribute("user",user);
//如果返回字符串success,则需要根据视图解析器去请求那个目录下的jsp文件(跳转到某个页面)
return "success";
}
}
- 写完上面的方法,返回“success”,跳转到success.jsp页面
那么我们在这个页面上可以从request域对象中把user(key)值取出来。
success.jsp
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2020/8/26
Time: 22:25
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>执行成功</h3>
${user.username}
${user.password}
</body>
</html>
- 重新部署项目
返回值为void类型
- response.jsp
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2020/8/26
Time: 22:11
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="user/testString">testString</a>
<br/>
<a href="user/testVoid">testVoid</a>
</body>
</html>
- UserController.java
package cn.itcast.controller;
import org.springframework.ui.Model;
import cn.itcast.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**一点击jsp页面的超链接,方法就可以执行 * Create By LiFang on 2020/8/26. */
@Controller
@RequestMapping("/user") //一级目录
public class UserController {
/** * 返回值类型为String * @param model * @return */
@RequestMapping("/testString")
public String testString(Model model){
System.out.println("testString方法执行了。。");
//模拟从数据库中查询出User对象
User user = new User();
user.setUsername("美美");
user.setPassword("123");
user.setAge(18);
//model对象
model.addAttribute("user",user);
//如果返回字符串success,则需要根据视图解析器去请求那个目录下的jsp文件(跳转到某个页面)
return "success";
}
/** * 返回值类型为void * @param model * @return */
@RequestMapping("/testVoid")
public void testVoid(Model model){
System.out.println("testVoid方法执行了。。");
}
}
- 重新启动服务器
结果:
点击下面的一个超链接
后台:方法执行了。
我们可以看出,如果方法没有写返回值,那么它就会默认请求这个请求路径名称.jsp。这就是方法请求的默认值。
解决办法一:
编写请求转发的程序
- UserController.java
/** * 返回值类型为void * 请求转发是一次请求,不用编写项目的名称;而重定向是两次请求,需要写项目名称 * @param * @return */
@RequestMapping("/testVoid")
public void testVoid(HttpServletRequest request, HttpServletResponse response) throws Exception{
System.out.println("testVoid方法执行了。。");
//1.编写请求转发的程序(手动去调用转发的方法,它不会再去使用视图解析器的对象,
// 就不会再跳转到视图解析器里的目录,因需要你自己提供完整的目录)
request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
return;
}
- 重新部署项目后
结果:
解决办法二:
编写重定向的程序
- UserController.java
/** * 返回值类型为void * 请求转发是一次请求,不用编写项目的名称;而重定向是两次请求,需要写项目名称 * @param * @return */
@RequestMapping("/testVoid")
public void testVoid(HttpServletRequest request, HttpServletResponse response) throws Exception{
System.out.println("testVoid方法执行了。。");
//解决重定向get请求时中文乱码问题
request.setCharacterEncoding("utf-8");
//1.编写请求转发的程序(手动去调用转发的方法,它不会再去使用视图解析器的对象,
// 就不会再跳转到视图解析器里的目录,因需要你自己提供完整的目录)。
//转发可以去直接请求WEB—INF里的东西,但重定向不能。
// request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
//2.编写重定向的程序
response.sendRedirect(request.getContextPath()+"/index.jsp");
return;
}
- index.jsp
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" language="java" %>
<html>
<body>
<h2>重定向</h2>
</body>
</html>
- 重新部署项目(在乱码问题解决后)
结果:
注意:
如何解决重定向中文乱码问题?
请参考这篇博客: 传送门
解决方法三(情况三):
直接进行响应
控制器通过输出流,把数据直接响应给浏览器
1. UserController.java
/** * 返回值类型为void * 请求转发是一次请求,不用编写项目的名称;而重定向是两次请求,需要写项目名称 * @param * @return */
@RequestMapping("/testVoid")
public void testVoid(HttpServletRequest request, HttpServletResponse response) throws Exception{
System.out.println("testVoid方法执行了。。");
//解决中文乱码问题
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
//1.编写请求转发的程序(手动去调用转发的方法,它不会再去使用视图解析器的对象,
// 就不会再跳转到视图解析器里的目录,因需要你自己提供完整的目录)。
//转发可以去直接请求WEB—INF里的东西,但重定向不能。
// request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
//2.编写重定向的程序
// response.sendRedirect(request.getContextPath()+"/index.jsp");
//会直接进行响应
response.getWriter().print("你好");
return;
}
- 重新部署项目
在浏览器地址栏后面加上/user/testVoid, 再回车(发送get请求)
返回值为modelandview对象
- ModelAndView对象是SpringMVC框架提供的一个对象,可以用来调整具体的JSP视图。(它可以通过视图解析器跳转到某个页面)
- 具体的代码如下:
response.jsp
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2020/8/26
Time: 22:11
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="user/testModelAndView">testVoid</a>
</body>
</html>
UserController.java
/** * 返回ModelAndView * @param * @return */
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
//创建ModelAndView对象
ModelAndView mv = new ModelAndView();
System.out.println("testModelAndView方法执行了。。");
//模拟从数据库中查询出User对象
User user = new User();
user.setUsername("小明");
user.setPassword("456");
user.setAge(19);
//把user对象存储到mv对象中去,也会把user对象存入到request对象
mv.addObject("user",user);
//跳转到哪个页面
mv.setViewName("success");
return mv;
}
success.jsp
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2020/8/26
Time: 22:25
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>执行成功</h3>
${user.username}
${user.password}
</body>
</html>
- 重新部署项目后,结果:
SpringMVC框架提供的转发和重定向
关键字方式跳转页面
转发
结果:
重定向
ResponseBody响应json数据
首先需要搭建异步环境
在WEB-INF文件夹下新建一个文件夹js,添加jquery.min.js文件
然后在response.jsp中引入jquery.min.js文件。
<script src="WEB-INF/js/jquery.min.js"></script>
响应json数据之过滤静态资源
response.jsp
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2020/8/26
Time: 22:11
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="js/jquery.min.js"></script>
<script type="text/javascript">
//页面加载,绑定单击事件
$(function () {
$("#btn").click(function () {
alert("hello btn");
//发送ajax请求
});
});
</script>
</head>
<body>
<a href="user/testString">testString</a>
<br/>
<a href="user/testVoid">testVoid</a>
<a href="user/testModelAndView">testModelAndView</a>
<br/>
<button id="btn">发送ajax的请求</button>
</body>
</html>
springmvc.xml
<mvc:default-servlet-handler/>
<!-- 开启SpringMVC框架注解的支持:让类型转换配置生效-->
<mvc:annotation-driven/>
<!-- 告诉前端控制器,哪些静态资源不要拦截-->
<mvc:resources location="/js/" mapping="/js/**" />
<mvc:resources location="/images/" mapping="/images/**" />
<mvc:resources location="/css/" mapping="/css/**" />
结果:
注意:
当时,我遇到静态资源加载不出来的问题,我以为是我springMVC设置不拦截静态资源的配置没有设置好,后来才发现是我的静态资源引入的路径错误导致的。希望看过我博客的小伙伴儿们能够引以为戒,千万不要像我这么粗心大意哦。
如何解决springMVC拦截静态资源,导致程序运行失败?
响应json数据之发送ajax请求
- response.jsp
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2020/8/26
Time: 22:11
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="js/jquery.min.js"></script>
<script type="text/javascript"> //页面加载,绑定单击事件 $(function () {
$("#btn").click(function () {
// alert("hello btn"); //发送ajax请求 $.ajax({
//编写json格式数据,设置属性和值 url:"user/testAjax", contentType:"application/json;charset=UTF-8", data:'{"username":"hehe","password":"123","age":30}', dataType:"json", type:"post", success:function (data) {
//data服务器端响应的json数据,进行解析 } }); }); }); </script>
</head>
<body>
<a href="user/testString">testString</a>
<br/>
<a href="user/testVoid">testVoid</a>
<a href="user/testModelAndView">testModelAndView</a>
<br/>
<button id="btn">发送ajax的请求</button>
</body>
</html>
- UserController.java
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2020/8/26
Time: 22:11
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="js/jquery.min.js"></script>
<script type="text/javascript">
//页面加载,绑定单击事件
$(function () {
$("#btn").click(function () {
// alert("hello btn");
//发送ajax请求
$.ajax({
//编写json格式数据,设置属性和值
url:"user/testAjax",
contentType:"application/json;charset=UTF-8",
data:'{"username":"hehe","password":"123","age":30}',
dataType:"json",
type:"post",
success:function (data) {
//data服务器端响应的json数据,进行解析
}
});
});
});
</script>
</head>
<body>
<a href="user/testString">testString</a>
<br/>
<a href="user/testVoid">testVoid</a>
<a href="user/testModelAndView">testModelAndView</a>
<br/>
<button id="btn">发送ajax的请求</button>
</body>
</html>
- 结果:
响应json数据之响应json格式数据
当发过来的json数据中的key值与javaBean中的属性名相同时,springMVC框架可以直接把发过来的json数据封装到一个javaBean对象中去。
但是它需要用到一组jar包。
在pom.xml中引入jar包
<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>
response.jsp
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2020/8/26
Time: 22:11
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="js/jquery.min.js"></script>
<script type="text/javascript">
//页面加载,绑定单击事件
$(function () {
$("#btn").click(function () {
// alert("hello btn");
//发送ajax请求
$.ajax({
//编写json格式数据,设置属性和值
url:"user/testAjax",
contentType:"application/json;charset=UTF-8",
data:'{
"username":"hehe","password":"123","age":30}',
dataType:"json",
type:"post",
success:function (data) {
//data服务器端响应的json数据,进行解析
alert(data);
alert(data.username);
alert(data.password);
alert(data.age);
}
});
});
});
</script>
</head>
<body>
<a href="user/testString">testString</a>
<br/>
<a href="user/testVoid">testVoid</a>
<a href="user/testModelAndView">testModelAndView</a>
<br/>
<button id="btn">发送ajax的请求</button>
</body>
</html>
UserController,java
/** * 模拟异步请求响应 * @param * @return */
@RequestMapping("/testAjax")
public @ResponseBody User testAjax(@RequestBody User user){
//@RequestBody接收(把接收的字符串转换为对象); @ResponseBody响应(把对象转换为字符串)
System.out.println("testAjax方法执行了。。");
//客户端发送ajax的请求,传的是json字符串,后端把json字符串封装到user对象中
System.out.println(user);
//做响应,模拟查询数据库
user.setUsername("haha");
user.setAge(40);
//做响应
return user;
}
结果: