一、配置视图解析器
SpringMVC默认情况下会在控制器执行完成后跳转到视图页面,视图解析器能找到相应的视图,之前的404异常就是由于没有配置视图解析器导致找不到视图。在SpringMVC中提供了13个视图解析器,用于支持不同的视图技术。InternalResourceViewResolver是SpringMVC的默认视图解析器,用来解析JSP视图。
添加如下标签就算配置视图解析器了
代码语言:javascript复制<!-- 视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 视图前缀 -->
<property name="prefix" value="/"/>
<!-- 视图后缀 -->
<property name="suffix" value=".jsp"/>
</bean>
二、控制器方法的返回值
我们可以通过控制器方法的返回值设置跳转的视图,控制器方法支持以下返回值类型:
2.1 返回值为void
此时会跳转到名字是 前缀 方法路径名 后缀 的jsp页面
2.1.1 控制器方法
代码语言:javascript复制 /**
* SpringMVC处理响应——控制器方法(根据返回值)
*/
// 路径是helloMVC,方法执行完后会跳转到/helloMVC.jsp
@RequestMapping("helloMVC")
public void helloMVC(){
System.out.println("hello SpringMVC!");
}
2.1.2 jsp页面
代码语言:javascript复制<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>MVC</title>
</head>
<body>
<h1>欢迎来到SpringMVC!</h1>
</body>
</html>
2.1.3 测试结果
访问路径:http://localhost:8080/helloMVC
OK,确实返回了jsp页面
2.2 返回值为String
此时会跳转到名字是 前缀 返回值 后缀 的jsp页面
2.2.1 控制器方法
代码语言:javascript复制// 返回值是String,此时会跳转到名字是 前缀 返回值 后缀 的jsp页面
@RequestMapping("c2/hello1")
public String helloMVC1(){
System.out.println("Hello SpringMVC!");
return "helloMVC";
}
2.2.2 测试结果
访问路径:http://localhost:8080/c2/hello1
OK,这次返回的也不是helloMVC1页面,确实成功实现了。
2.3 返回值为ModelAndView
这是SpringMVC提供的对象,该对象可以向request域设置数据并指定跳转的页面。该对象中包含Model对象和View对象。
- Model:向request域中设置数据。
- View:指定跳转的页面。
2.3.1 控制器方法
代码语言:javascript复制// 返回值为ModelAndView
@RequestMapping("/c2/hello2")
public ModelAndView useMAV(){
System.out.println("返回值类型为ModelAndView");
// 1.创建ModelAndView对象
ModelAndView modelAndView = new ModelAndView();
// 2.获取Model对象,本质是一个Map
Map<String,Object> model = modelAndView.getModel();
// 3.使用Model对象向request域设置数据
model.put("username","黄庆禧");
// 4.使用view对象设置跳转的路径
modelAndView.setViewName("lyl-HQX");
return modelAndView;
}
OK,这里设置了一个username的属性,属性值为黄庆禧
2.3.2 JSP页面
代码语言:javascript复制<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>lyl-HQX</title>
</head>
<body>
<h1>name: 你好!${requestScope.name}</h1>
<h1>username: 你好!${requestScope.username}</h1>
<h1>request-Map 你好!${requestScope.usernameMap}</h1>
<h1>session 地址是:${sessionScope.address}</h1>
<h1>context 年龄是:${applicationScope.age}</h1>
</body>
</html>
OK,这里解释一下,这里用到的参数是后面需要的。
2.3.3 测试结果
OK,确实可以成功打印出黄庆禧的名字了。
三、某些会话对象设置数据
当控制器返回值为ModelAndView时我们可以向request域设置数据,我们还有以下方法可以向request域设置数据:
3.1 request域设置数据
3.1.1 使用参数为原生的HttpServletRequest
控制器方法
代码语言:javascript复制 /**
* SpringMVC处理响应-request域
*/
// 使用原生的HttpServletRequest
@RequestMapping("/c2/hello3")
public String setRequestModel(HttpServletRequest request){
request.setAttribute("username","会洗碗的CV工程师");
return "lyl-HQX";
}
OK,username属性值为会洗碗的CV工程师,看一下能否成功获取
测试结果
OK,可以看到确实成功获取了。 接下来尝试其他一些参数。
3.1.2 使用参数为Model和ModelMap
SpringMVC提供了Model接口和ModelMap类,控制器方法添加这两个类型的参数,使用该参数设置数据,该数据就会存到request域中。
控制器方法
代码语言:javascript复制//使用Model、ModelMap
@RequestMapping("/c2/hello4")
public String setRequestModel2(Model model, ModelMap modelMap){
// 使用Model将数据存入request域
model.addAttribute("username","LYL");
// 使用ModelMap将数据传入request域
modelMap.addAttribute("usernameMap","HQX");
return "lyl-HQX";
}
测试结果
OK,可以看得到两个属性都已经成功获取。
3.1.3 使用参数为Map集合
Model接口底层就是一个Map集合,我们可以给控制器方法设置Map类型的参数,向Map中添加键值对,数据也会存到request域中。
控制器方法
代码语言:javascript复制// 使用Map集合
@RequestMapping("/c2/hello5")
public String setRequestModel3(Map map){
map.put("username","程序员");
map.put("usernameMap","程序员");
return "lyl-HQX";
}
测试结果
OK,可以看得出来和上面也是一样可以使用的。
3.2 session域设置数据
Session作用域表示在当前会话中有效。在SpringMVC中对于Session作用域传值,只能使用HttpSession对象来实现。
3.2.1 控制器方法
代码语言:javascript复制 /**
* SpringMVC处理响应-session域设置数据
*/
@RequestMapping("/c2/hello6")
public String setSessionModel(HttpSession session){
session.setAttribute("address","北京");
return "lyl-HQX";
}
OK,这次是在session域设置了一个地址属性,看一下能否成功获取
3.2.2 测试结果
Ok,可以看到确实成功获取了。
3.3 context域设置数据
context作用域表示在整个应用范围都有效。在SpringMVC中对context作用域传值,只能使用ServletContext对象来实现。但是该对象不能直接注入到方法参数中,需要通过HttpSession对象获取。
3.2.1 控制器方法
代码语言:javascript复制 /**
* SpringMVC处理响应-context域设置数据
*/
@RequestMapping("/c2/hello7")
public String setContextModel(HttpSession session){
ServletContext servletContext = session.getServletContext();
servletContext.setAttribute("age",10);
return "lyl-HQX";
}
这次利用context域设置了一个年龄属性,看一下能否获取对应的值。
3.2.2 测试结果
Ok,可以看到确实成功获取了。
3.3 context域设置数据
context作用域表示在整个应用范围都有效。在SpringMVC中对context作用域传值,只能使用ServletContext对象来实现。但是该对象不能直接注入到方法参数中,需要通过HttpSession对象获取。
3.2.1 控制器方法
代码语言:javascript复制 /**
* SpringMVC处理响应-context域设置数据
*/
@RequestMapping("/c2/hello7")
public String setContextModel(HttpSession session){
ServletContext servletContext = session.getServletContext();
servletContext.setAttribute("age",10);
return "lyl-HQX";
}
这次利用context域设置了一个年龄属性,看一下能否获取对应的值。
3.2.2 测试结果
添加描述
OK,确实成功获取到了。
四、请求转发&重定向
之前的案例,我们发现request域中的值可以传到jsp页面中,也就是通过视图解析器跳转到视图的底层是请求转发。 如果我们跳转时不想使用视图解析器,可以使用原生HttpServletRequest进行请求转发或HttpServletResponse进行重定向:
4.1 原生请求转发重定向写法
4.1.1 重定向控制器方法
代码语言:javascript复制 /**
* SpringMVC处理响应-请求转发&重定向
*/
@RequestMapping("/c2/hello8")
public void myForward1(HttpServletRequest request, HttpServletResponse response) throws Exception{
request.setAttribute("name","程序员");
// 请求转发
//request.getRequestDispatcher("/c2/hello9").forward(request,response);
// 原生重定向
response.sendRedirect("/c2/hello9");
}
代码语言:javascript复制OK,这是重定向到/c2/hello9,接下来写一个/c2/hello9的控制器方法,看一下控制台能否打印出来。
@RequestMapping("/c2/hello9")
public void myForward2(HttpServletRequest request){
System.out.println("hello");
System.out.println(request.getAttribute("name"));
}
4.1.2 重定向测试结果
点击这里查看运行结果
OK,可以看得到确实重定向去了。注意看,这里重定向出来后是无法获取request域的属性值的,待会试一下请求转发可不可以。 重定向地址栏会发生变化,而请求转发地址栏是不会变化的。
4.1.3 请求转发测试结果
点击这里查看运行结果
OK,,可以看得到请求转发就可以获取属性值,并且地址栏没有发生变化。
4.2 springmvc提供的请求转发重定向写法
代码语言:javascript复制// SpringMVC提供一种关于重定向和请求转发更为简单的写法
@RequestMapping("/c2/hello10")
public String myForward3(HttpServletRequest request){
request.setAttribute("name","程序员");
// 请求转发
return "forward:/c2/hello9";
// 重定向
//return "redirect:/c2/hello9";
}
OK,本次就学习到这里
我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!