1 配置视图解析器
返回的ModelAndView对象被InternalResovlerViewResolver这个解析器处理。
还可以用配置路径方式解析视图和模型。
tomcat里面有个解析xml的方法,解析web.xml。
web.xml中配置spring框架里面的DispatcherServlet类,参数是springmvc配置文件。在源码中,包含配置文件DispacherServlet.proerties。new出来的DispacherServlet会解析xml然后new控制器。在springmvc配置文件中会扫描包new控制器。
大概是这个流程。后面继续完善。在newDispatcherServlet的时候,会去创建默认的对象,按照下图的配置。其中默认的视图解析器配置就是DispacherServlet.proerties里面的
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver一旦配置就会被配置的替换掉。
重新配置视图解析器。用这个的好处是视图定位更加方便。私密资源只能通过controller访问,不能通过浏览器url直接访问。
<!--视图解析器
不需要返回路径,文件后缀-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
package com.bjsxt.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/page")
public class PageController {
@RequestMapping("/login")
public String showLogin(){
return "login";
}
}
login.jsp在web目录下。
<%--
Created by IntelliJ IDEA.
User: HP
Date: 2020/11/30
Time: 8:44
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>
login...
</body>
</html>
运行结果:
将login.jsp放到web/WEB-INF/jsp目录下,用浏览器访问/springannodemo/WEB-INF/jsp/login.jsp访问失败。因为这个WEB-INF是被保护的资源,不能通过url直接访问,如果要被访问到,要通过修改springmvc.xml的配置前缀,然后通过controller访问。
如图,将login.jsp放进WEB-INF/jsp下面,用浏览器访问。找不到404。因为这个WEB-INF目录是被保护的,不能直接访问。
修改spring 视图解析器前缀,指明页面路径。请求控制器,由控制器处理,spring mvc框架视图解析器找到jsp,显示。
如图:
显示出jsp了。
2 SpringMVC作用域传值
作用域,数据共享的范围。
application :整个应用有效
session:当前会话有效
request:当前请求中有效
page:当前页面有效
2.1Request作用域传值(就是视图解析器的配置,控制器只要写jsp名称就能找到jsp页面,数据的话要学作用域,把数据传递给页面。毕竟用ModelAndView绑定,有些麻烦!)
2.1.1使用原生的HttpServletRequest
@RequestMapping("/loginR")
public String showLogin1(HttpServletRequest httpServletRequest) {
httpServletRequest.setAttribute("msg","hello!");
return "login";
}
2.1.2使用Map
@RequestMapping("/loginMap")
public String showLogin2(Map<String,String> map) {
map.put("msg","hello!");
return "login";
}
2.1.3使用Model
@RequestMapping("/loginModel")
public String showLogin3(Model model) {
model.addAttribute("msg","hello!");
return "login";
}
同一个jsp
<%--
Created by IntelliJ IDEA.
User: HP
Date: 2020/11/30
Time: 8:44
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>
login...${msg}
</body>
</html>
视图解析器的配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--配置注解扫描-->
<context:component-scan base-package="com.bjsxt.web.controller"></context:component-scan>
<!-- 配置注解驱动-->
<mvc:annotation-driven/>
<!--视图解析器
不需要返回路径,文件后缀-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
jsp位置
运行结果:
总结,Model和Map封装的数据会被BingAwareModelMap对象拿到,然后springmvc会将BingAwareModelMap对象中的数据保存到HttpServletRequest对象中。BingAwareModelMap实现了Model和Map接口。
2.2 Session作用域传值
一个会话中有效
代码
@RequestMapping("/loginS")
public String showLogin4(HttpSession session) {
session.setAttribute("msg","hello");
return "login";
}
@RequestMapping("/loginS2")
public String showLogin5(HttpServletRequest httpServletRequest) {
HttpSession session = httpServletRequest.getSession();
session.setAttribute("name","OldLu");
return "login";
}
运行结果
调用/page/loginS2,向HttpSession中增加session的属性。在当前浏览器中有效。调用其他请求,也会访问到这个数据。
使用另一个浏览器,访问其他接口,因为没有调用/page/loginS2接口,所以session中没有这个属性。所以页面没有显示。
2.3Application作用域传值
ServletContext,通过session获取。在整个应用中有效。
3SpringMVC的响应方式
3.1请求转发
3.1.1使用ServletAPI
代码:
/**
* 请求转发
* 使用servlet api
*/
@RequestMapping("/showLogin2")
public void showLogin2(HttpServletRequest request, HttpServletResponse response) throws Exception{
request.setAttribute("msg","oldLu");
// 不走视图解析器!所以要写全部路径,如果不写会报错404,已测试
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
}
运行结果:
3.1.2forward关键字
返回路径写字符串
/**
* 请求转发
* 使用forward
*
* @throws Exception
*/
@RequestMapping("/showLogin4")
public String showLogin4(Model model) throws Exception{
model.addAttribute("msg","oldLu");
// 不走视图解析器!所以要写全部路径
return "forward:/WEB-INF/jsp/login.jsp";
}
运行结果:
3.1.3视图解析器
就是配置到视图解析器里面返回一个字符串,是jsp的名字。前缀是jsp位置,后缀是文件扩展名。
@RequestMapping("/loginC")
public String showLogin6(HttpSession session) {
ServletContext context = session.getServletContext();
context.setAttribute("msg","hello");
return "login";
}
运行结果:
3.2重定向
就是服务器往响应中增加uri,浏览器解析后再次访问新的uri.特点是地址栏url会改变。在重定向跳转中不经过视图解析器。
/**
* 重定向
* 返回的东西不经过视图解析器。
* @param model
* @return
* @throws Exception
*/
@RequestMapping("/redirectLogin")
public String redirectLogin(Model model) throws Exception{
model.addAttribute("msg","oldLu");
return "redirect:/page/login";
}
运行结果: