前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringMVC:基本应用

SpringMVC:基本应用

作者头像
RendaZhang
发布2020-09-16 11:35:38
1.2K0
发布2020-09-16 11:35:38
举报
文章被收录于专栏:Renda

SpringMVC 简介

MVC 模式

MVC 是软件工程中的一种软件架构模式,它是一种分离业务逻辑与显示界面的开发思想。

代码语言:javascript
复制
* M(model)模型:处理业务逻辑,封装实体
* V(view) 视图:展示内容
* C(controller)控制器:负责调度分发(1.接收请求、2.调用模型、3.转发到视图)
SpringMVC 概述

SpringMVC 是一种基于 Java 的实现 MVC 设计模式的轻量级 Web 框架,属于Spring Framework 的后续产品,已经融合在 Spring Web Flow 中。

SpringMVC 已经成为目前最主流的 MVC 框架之一,并且随着 Spring 3.0 的发布,全面超越 Struts 2,成为最优秀的 MVC 框架。它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持 RESTful 编程风格的请求。

SpringMVC 的框架就是封装了原来 Servlet 中的共有行为;例如:参数封装,视图转发等。

SpringMVC 快速入门

需求:客户端发起请求,服务器接收请求,执行逻辑并进行视图跳转。

步骤分析:

  1. 创建web项目,导入 SpringMVC 相关坐标
  2. 配置 SpringMVC 前端控制器 DispatcherServlet
  3. 编写 Controller 类和视图页面
  4. 使用注解配置 Controller 类中业务方法的映射地址
  5. 配置 SpringMVC 核心文件 spring-mvc.xml
创建 web 项目,导入 SpringMVC 相关坐标
代码语言:javascript
复制
<packaging>war</packaging>

<!-- 指定编码及版本 -->
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
    <java.version>1.11</java.version>
    <maven.compiler.source>1.11</maven.compiler.source>
    <maven.compiler.target>1.11</maven.compiler.target>
</properties>

<dependencies>
    <!-- springMVC 坐标 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.1.5.RELEASE</version>
    </dependency>
    <!-- servlet 坐标 -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <!-- jsp 坐标 -->
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.2</version>
        <scope>provided</scope>
    </dependency>

    ...

</dependencies>
配置 SpringMVC 前端控制器 `DispatcherServlet`
代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- springMVC 的前端控制器:DispatcherServlet-->
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 加载 springMVC 相关的配置文件 -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <!-- 
            在应用启动时,就完成 servlet 的实例化及初始化操作。
            数字大于等于 0 时,服务器启动时就加载并初始化 servlet;
            数字越接近 0,则优先级越高
        -->
        <load-on-startup>2</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <!--
            / 和 /* 的区别:
            / 会匹配到所有的访问路径,除了带有 *.jsp 这样的后缀名的路径;
            如可以匹配到 /login /add /update,但 /a.jsp 不能匹配。
        -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>
编写 Controller 类和视图页面

UserController.java

代码语言:javascript
复制
public class UserController {
    public String quick() {
        // 业务处理
        System.out.println("SpringMVC Quick Start...");
        // 页面跳转 请求转发
        return "/WEB-INF/pages/success.jsp";
    }
}

/WEB-INF/pages/success.jsp

代码语言:javascript
复制
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>SUCCESS</title>
</head>
<body>

    <h3>success... ${username}</h3>
    <% System.out.println("Success...");%>

</body>
</html>
使用注解配置 Controller 类中业务方法的映射地址
代码语言:javascript
复制
@Controller
public class UserController {
    @RequestMapping("/quick")
    public String quick() {
        System.out.println("SpringMVC Quick Start...");
        return "/WEB-INF/pages/success.jsp";
    }
}
配置 SpringMVC 核心文件 spring-mvc.xml
代码语言:javascript
复制
<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">

    <!-- IOC 注解扫描 -->
    <context:component-scan base-package="com.renda.controller"/>

</beans>
web 工程执行流程

客户端(浏览器)发送请求到 Tomcat 服务器,Tomcat 服务器发送响应到客户端。

服务器的 Tomcat 引擎:

  1. 接受客户端请求,解析请求资源地址
  2. 创建代表请求的 request 对象
  3. 创建代表响应 response 对象
  4. 调用目标资源
  5. 获得 response 中的内容,组装成 HTTP 响应返回客户端

服务器的 Web 应用:

  1. 获得请求资源地址
  2. 解析映射地址,找到对应的处理器(Controller)
  3. 处理器执行对应的方法(进行业务逻辑以及视图跳转操作),获取被访问的真实资源
小结
代码语言:javascript
复制
* SpringMVC 是对 MVC 设计模式的一种实现,属于轻量级的 WEB 框架。
* SpringMVC 的开发步骤:
    1.创建 web 项目,导入 SpringMVC 相关坐标
    2.配置 SpringMVC 前端控制器 DispatcherServlet
    3.编写 Controller 类和视图页面
    4.使用注解配置 Controller 类中业务方法的映射地址
    5.配置 SpringMVC 核心文件 spring-mvc.xml

SpringMVC 组件概述

SpringMVC 的执行流程
代码语言:javascript
复制
1. 用户发送请求至前端控制器 DispatcherServlet。

2. DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器。

3. 处理器映射器找到具体的处理器(可以根据 xml 配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet。

4. DispatcherServlet 调用 HandlerAdapter 处理器适配器。

5. HandlerAdapter 经过适配调用具体的处理器(Controller,也叫后端控制器)。

6. Controller 执行完成返回 ModelAndView。

7. HandlerAdapter 将 controller 执行结果 ModelAndView 返回给 DispatcherServlet。

8. DispatcherServlet 将 ModelAndView 传给 ViewReslover 视图解析器。

9. ViewReslover 解析后返回具体 View。

10. DispatcherServlet 根据 View 进行渲染视图(即将模型数据填充至视图中)。

11. DispatcherServlet 将渲染后的视图响应响应用户。
SpringMVC 组件解析
代码语言:javascript
复制
1. 前端控制器:DispatcherServlet
    用户请求到达前端控制器,它就相当于 MVC 模式中的 C;DispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求;DispatcherServlet 的存在降低了组件之间的耦合性。

2. 处理器映射器:HandlerMapping
     HandlerMapping 负责根据用户请求找到 Handler 即处理器;SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式、实现接口方式、注解方式等。

3. 处理器适配器:HandlerAdapter
    通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。

4. 处理器:Handler【**开发者编写**】
    它是开发中要编写的具体业务控制器;由 DispatcherServlet 把用户请求转发到 Handler;由 Handler 对具体的用户请求进行处理。

5. 视图解析器:ViewResolver
    View Resolver 负责将处理结果生成 View 视图;View Resolver 首先根据逻辑视图名解析成物理视图名,即具体的页面地址,再生成 View 视图对象,最后对  View 进行渲染将处理结果通过页面展示给用户。

6. 视图:View 【**开发者编写**】
    SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView等。最常用的视图就是 jsp。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面。

7. SpringMVC 中的三大组件是什么?
    处理器映射器 HandlerMapping;
    处理器适配器 HandlerAdapter;
    视图解析器 ViewResolver;
    如果是四大组件,则加上前端控制器 DispatcherServlet。

spring-mvc.xml

代码语言:javascript
复制
<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">

    <!-- IOC 注解扫描 -->
    <context:component-scan base-package="com.renda.controller"/>

    <!-- 处理器映射器-处理器适配器。进行了功能的增强:支持 json 的读写 -->
    <mvc:annotation-driven/>

    <!-- 视图解析器:ViewResolver -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- success :解析逻辑视图名,解析成具体的物理文件地址 /WEB-INF/pages/success.jsp -->
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

</beans>

UserController.java

代码语言:javascript
复制
    @RequestMapping("/quick")
    public String quick() {
        System.out.println("SpringMVC Quick Start...");
        // 页面跳转 请求转发 返回逻辑视图名
        return "success";
    }
SpringMVC 注解解析
`@Controller`

SpringMVC 基于 Spring 容器,所以在进行 SpringMVC 操作时,需要将 Controller 存储到 Spring 容器中,如果使用 @Controller 注解标注的话,就需要使用:

代码语言:javascript
复制
<!-- 配置 IOC 注解扫描 -->
<context:component-scan base-package="com.renda.controller"/>

注意配置 SpringMVC 的 base package 只扫描 web 层的包,其它包交给 Spring 容器扫描;这样 SpringMVC 的容器就相当于是 Spring 容器的一个子容器。

`@RequestMapping`
代码语言:javascript
复制
* 作用:用于建立请求 URL 和处理请求方法之间的对应关系

* 位置:
1. 类上:请求 URL 的第一级访问目录。此处不写的话,就相当于应用的根目录;写的话需要以 / 开头。
    它出现的目的是为了使 URL 可以按照模块化管理:
        用户模块
            /user/add
            /user/update
            /user/delete
            ...
        账户模块
            /account/add
            /account/update
            /account/delete
2. 方法上:请求 URL 的第二级访问目录,和一级目录组成一个完整的 URL 路径。

* 属性:
1. value:用于指定请求的 URL;它和 path 属性的作用是一样的
2. method:用来限定请求的方式
3. params:用来限定请求参数的条件
    例如:
        params={"accountName"} 表示请求参数中必须有 accountName
        params={"money!100"} 表示请求参数中 money 不能是100
代码语言:javascript
复制
@Controller
@RequestMapping("/user") //一级访问目录
public class UserController {

    /**
     * http://localhost:8080/springmvc_quickstart/user/quick?accountName=renda
     * 
     * path :作用等同于 value,同样是设置方法的映射地址
     * method:用来限定请求的方式 RequestMethod.POST: 只能以 post 的请求方式访问该访问,其他请求方式会报错
     * params:用来限定请求参数的条件 params={"accountName"} 表示请求参数中必须有 accountName
     */
    @RequestMapping(
            path = "/quick", // 二级访问目录
            method = {RequestMethod.POST, RequestMethod.GET},
            params = {"accountName"})
    public String quick() {
        // 业务处理
        System.out.println("SpringMVC Quick Start...");
        // 页面跳转 请求转发 返回逻辑视图名
        return "success";
    }

}
小结
代码语言:javascript
复制
* SpringMVC的三大组件
    处理器映射器:HandlerMapping
    处理器适配器:HandlerAdapter
    视图解析器:View Resolver

* 开发者编写
    处理器:Handler
    视图:View

SpringMVC 的请求

请求参数类型介绍

客户端请求参数的格式是:name=value&name=value ...

服务器要获取请求的参数的时候要进行类型转换,有时还需要进行数据的封装

SpringMVC 可以接收如下类型的参数:

  • 基本类型参数
  • 对象类型参数
  • 数组类型参数
  • 集合类型参数
获取基本类型参数

Controller 中的业务方法的参数名称要与请求参数的 name 一致,参数值会自动映射匹配。并且能自动做类型转换;自动的类型转换是指从 String 向其他类型的转换。

requestParam.jsp

代码语言:javascript
复制
<%-- ${pageContext.request.contextPath} 动态的来获取当前的项目路径 - springmvc_quickstart;a 标签的请求方式:get 请求 --%>
<a href="${pageContext.request.contextPath}/user/simpleParam?id=1&username=杰克">
    基本类型参数
</a>

UserController 中添加方法

代码语言:javascript
复制
@RequestMapping("/simpleParam")
public String simpleParam(Integer id, String username) {
    System.out.println(id);
    System.out.println(username);
    return "success";
}
获取对象类型参数

Controller 中的业务方法参数的 POJO 属性名与请求参数的 name 一致,参数值会自动映射匹配。

requestParam.jsp

代码语言:javascript
复制
<%-- form 表单;该表单提交的请求方式为 post 类型 --%>
<form action="${pageContext.request.contextPath}/user/pojoParam" method="post">
    编号:<input type="text" name="id"><br>
    用户名:<input type="text" name="username">
    <input type="submit" value="对象类型参数">
</form>

创建 User

代码语言:javascript
复制
public class User {
    private Integer id;
    private String username;
    // setter getter...
}

UserController 中添加方法

代码语言:javascript
复制
@RequestMapping("/pojoParam")
public String pojoParam(User user){
    System.out.println(user);
    return "success";
}
中文乱码过滤器

当 post 请求时,数据会出现乱码,可以在 web.xml 设置一个过滤器来进行编码的过滤。

代码语言:javascript
复制
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
获取数组类型参数

Controller 中的业务方法数组名称与请求参数的 name 一致,参数值会自动映射匹配。

requestParam.jsp

代码语言:javascript
复制
<form action="${pageContext.request.contextPath}/user/arrayParam" method="post">
    编号:<br>
    <input type="checkbox" name="id" value="1"><br>
    <input type="checkbox" name="ids" value="2"><br>
    <input type="checkbox" name="ids" value="3"><br>
    <input type="checkbox" name="ids" value="4"><br>
    <input type="submit" value="数组类型参数">
</form>

UserController 中添加方法

代码语言:javascript
复制
@RequestMapping("/arrayParam")
public String arrayParam(Integer[] ids){
    System.out.println(Arrays.toString(ids));
    return "success";
}
获取集合(复杂)类型参数

获得集合参数时,要将集合参数包装到一个 POJO 中才可以。

requestParam.jsp

代码语言:javascript
复制
<form action="${pageContext.request.contextPath}/user/queryParam" method="post">
    搜索关键字:
    <input type="text" name="keyword"><br>
    user对象:
    <input type="text" name="user.id" placeholder="编号">
    <input type="text" name="user.username" placeholder="姓名"><br>
    list集合:
    元素:
    <input type="text" name="userList[0].id" placeholder="编号">
    <input type="text" name="userList[0].username" placeholder="姓名">
    元素:
    <input type="text" name="userList[1].id" placeholder="编号">
    <input type="text" name="userList[1].username" placeholder="姓名"><br>
    Map集合:
    元素:
    <input type="text" name="userMap['u1'].id" placeholder="编号">
    <input type="text" name="userMap['u1'].username" placeholder="姓名">
    元素:
    <input type="text" name="userMap['u2'].id" placeholder="编号">
    <input type="text" name="userMap['u2'].username" placeholder="姓名"><br>
    <input type="submit" value="复杂类型">
</form>

创建 QueryVo

代码语言:javascript
复制
public class QueryVo {

    private String keyword;
    private User user;
    private List<User> userList;
    private Map<String, User> userMap;
    // setter getter...
}

UserController 中添加方法

代码语言:javascript
复制
@RequestMapping("/queryParam")
public String queryParam(QueryVo queryVo){
    System.out.println(queryVo);
    return "success";
}
自定义类型转换器

SpringMVC 默认已经提供了一些常用的类型转换器。例如:客户端提交的字符串转换成 INT 型进行参数设置,日期格式类型要求为:yyyy/MM/dd 不然的话会报错;对于特有的行为,SpringMVC 提供了自定义类型转换器方便开发者自定义处理。

requestParam.jsp

代码语言:javascript
复制
<form action="${pageContext.request.contextPath}/user/converterParam" method="post">
    生日:<input type="text" name="birthday">
    <input type="submit" value="自定义类型转换器">
</form>

配置自定义日期转换 DateConverter

代码语言:javascript
复制
public class DateConverter implements Converter<String, Date> {

    /**
     * s 就是表单传递过来的请求参数,如 2012-12-12
     */
    @Override
    public Date convert(String s) {
        // 将日期字符串转换成日期对象,进行返回
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = simpleDateFormat.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
}

spring-mvc.xml

代码语言:javascript
复制
<!-- 自定义类型转换器配置 -->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="com.renda.converter.DateConverter"/>
        </set>
    </property>
</bean>
<!-- 处理器映射器-处理器适配器。进行了功能的增强:支持 json 的读写 -->
<mvc:annotation-driven conversion-service="conversionService"/>

UserController 中添加方法

代码语言:javascript
复制
@RequestMapping("/converterParam")
public String converterParam(Date birthday){
    System.out.println(birthday);
    return "success";
}
相关注解
`@RequestParam`

当请求的参数 name 名称与 Controller 的业务方法参数名称不一致时,就需要通过 @RequestParam 注解显示的绑定

requestParam.jsp

代码语言:javascript
复制
<a href="${pageContext.request.contextPath}/user/findByPage?pageNo=2">
    分页查询
</a>

UserController 中添加方法

代码语言:javascript
复制
/**
 * name:匹配页面传递参数的名称
 * defaultValue:设置参数的默认值
 * required:设置是否必须传递该参数,默认值为 true;如果设置了默认值,值自动改为 false
 */
@RequestMapping("findByPage")
public String findByPage(
    @RequestParam(name = "pageNo", defaultValue = "1", required = false) Integer pageNum,
    @RequestParam(defaultValue = "5") Integer pageSize) {
    System.out.println(pageNum);
    System.out.println(pageSize);
    return "success";
}
`@RequestHeader`

获取请求头的数据。

UserController 中添加方法

代码语言:javascript
复制
@RequestMapping("/requestHeader")
public String requestHead(@RequestHeader("cookie") String cookie){
    System.out.println(cookie);
    return "success";
}
`@CookieValue`

获取 cookie 中的数据。

UserController 中添加方法

代码语言:javascript
复制
@RequestMapping("/cookieValue")
public String cookieValue(@CookieValue("JSESSIONID") String jSessionId){
    System.out.println(jSessionId);
    return "success";
}
获取 Servlet 相关 API

SpringMVC 支持使用原始 Servlet API 对象作为控制器方法的参数进行注入,常用的对象如下:

代码语言:javascript
复制
@RequestMapping("/servletAPI")
public String servletApi(HttpServletRequest request, HttpServletResponse response, HttpSession session){
    System.out.println(request);
    System.out.println(response);
    System.out.println(session);
    return "success";
}

SpringMVC 的响应

SpringMVC 响应方式介绍

页面跳转:

  1. 返回字符串逻辑视图
  2. void 原始 ServletAPI
  3. ModelAndView

返回数据:

  1. 直接返回字符串数据
  2. 将对象或集合转为 json 返回
返回字符串逻辑视图

直接返回字符串:此种方式会将返回的字符串与视图解析器的前后缀拼接后跳转到指定页面

代码语言:javascript
复制
@RequestMapping("/returnString")
public String returnString() {
    return "success";
}
`void` 原始 `ServletAPI`

可以通过 request、response 对象实现响应

index.jsp

代码语言:javascript
复制
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Index</title>
    </head>
    <body>
        Hello ${username}
    </body>
</html>

UserController 中添加方法

代码语言:javascript
复制
@RequestMapping("/returnVoid")
public void returnVoid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /* 直接返回数据 */
    response.setContentType("text/html;charset=utf-8");
    response.getWriter().write("张人大");
    request.setAttribute("username", "Renda");

    // 借助 request 对象完成请求转发,一次请求
    // request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request, response);
    // request.getRequestDispatcher("/index.jsp").forward(request, response);

    // 借助 response 对象完成重定向,两次请求。WEB-INF - 安全目录:不允许外部请求直接访问该目录资源,只可以进行服务器内部转发
    // response.sendRedirect(request.getContextPath() + "/index.jsp");
}
转发和重定向

企业开发一般使用返回字符串逻辑视图实现页面的跳转,这种方式其实就是请求转发;也可以写成:forward 转发。如果用了 forward,则路径必须写成实际视图 URL,不能写逻辑视图。它相当于:

代码语言:javascript
复制
request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response)

使用请求转发,既可以转发到 JSP,也可以转发到其他的控制器方法。

代码语言:javascript
复制
@RequestMapping("/forward")
public String forward(Model model){
    // 在模型中设置一些值
    model.addAttribute("username","RendaZhang");
    // 使用请求转发,既可以转发到 jsp,也可以转发到其他的控制器方法
    // return "forward:/product/findAll";
    return "forward:/WEB-INF/pages/success.jsp";
}

Redirect 重定向:可以不写虚拟目录,SpringMVC 框架会自动拼接,并且将 Model 中的数据拼接到 URL 地址上;重定向的目标 JSP 页面不能写在 WEB-INF 目录中,否则无法找到。

代码语言:javascript
复制
@RequestMapping("/redirect")
public String redirect(Model model) {
    // 底层使用的还是 request.setAttribute("username","RENDA"),
    // 域范围是一次请求,所以重定向后,请求发生了变化,请求域的值无法获取
    model.addAttribute("username", "RENDA");
    return "redirect:/index.jsp";
}
`ModelAndView`
方式一

在 Controller 中方法创建并返回 ModelAndView 对象,并且设置视图名称

代码语言:javascript
复制
/**
 * model:模型:作用封装存放数据
 * View :视图:用来展示数据
 */
@RequestMapping("/returnModelAndView")
public ModelAndView returnModelAndView(){
    ModelAndView modelAndView = new ModelAndView();
    // 设置模型数据
    modelAndView.addObject("username","modelAndView 方式一");
    // 设置视图名称。视图解析器解析 modelAndView 拼接前缀和后后缀
    modelAndView.setViewName("success");
    return modelAndView;
}
方式二

在 Controller 中方法形参上直接声明 ModelAndView,无需在方法中自己创建,在方法中直接使用该对象设置视图,同样可以跳转页面

代码语言:javascript
复制
@RequestMapping("/returnModelAndView2")
public ModelAndView returnModelAndView2(ModelAndView modelAndView){
    // 设置模型数据
    modelAndView.addObject("username","modelAndView 方式二");
    // 设置视图名称。视图解析器解析 modelAndView 拼接前缀和后后缀
    modelAndView.setViewName("success");
    return modelAndView;
}
`@SessionAttributes`

如果在多个请求之间共用数据,则可以在控制器类上标注一个 @SessionAttributes,配置需要在 session 中存放的数据范围,SpringMVC 将存放在 model 中对应的数据暂存到 HttpSession 中。

注意:@SessionAttributes 只能定义在类上

代码语言:javascript
复制
@Controller
@RequestMapping("/user") //一级访问目录
@SessionAttributes("username") // 向 request 域中(model)中存入 key 为 username 时,会同步到 session 域中
public class UserController {

    ...

    @RequestMapping("/forward")
    public String forward(Model model) {
        // 在模型中设置一些值
        model.addAttribute("username", "RendaZhang");
        // 使用请求转发,既可以转发到 jsp,也可以转发到其他的控制器方法
        // return "forward:/product/findAll";
        return "forward:/WEB-INF/pages/success.jsp";
    }

    ...

    @RequestMapping("/returnString")
    public String returnString(){
        return "success";
    }
}
小结
代码语言:javascript
复制
* 页面跳转采用返回字符串逻辑视图
    forward 转发
        可以通过Model向request域中设置数据
    redirect 重定向
        直接写资源路径即可,虚拟目录springMVC框架自动完成拼接

* 数据存储到 request 域中
    Model model
    model.addAttribute("username", "子慕");

静态资源访问的开启

requestParam.jsp

代码语言:javascript
复制
...
<%-- 引入 jquery.js --%>
<script src="${pageContext.request.contextPath}/js/jquery-3.5.1.js"></script>
...

当有静态资源需要加载时,比如 jQuery 文件,通过谷歌开发者工具抓包发现,没有加载到 jQuery 文件,原因是 SpringMVC 的前端控制器 DispatcherServleturl-pattern 配置的是 /(默认配置),代表对所有的静态资源都进行处理操作,这样就不会执行 Tomcat 内置的 DefaultServlet 处理,可以通过以下两种方式在 spring-mvc.xml 指定放行静态资源。

方式一:放行指定的静态资源

代码语言:javascript
复制
<!-- mapping:放行的映射路径,location:静态资源所在的目录 -->
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/css/**" location="/css/"/>
<mvc:resources mapping="/img/**" location="/img/"/>

方式二:放行全部的静态资源

代码语言:javascript
复制
<!-- 在 springmvc 配置文件中开启 DefaultServlet 处理静态资源 -->
<mvc:default-servlet-handler/>
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-09-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Renda 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • SpringMVC 简介
    • MVC 模式
      • SpringMVC 概述
        • SpringMVC 快速入门
          • 创建 web 项目,导入 SpringMVC 相关坐标
          • 配置 SpringMVC 前端控制器 `DispatcherServlet`
          • 编写 Controller 类和视图页面
          • 使用注解配置 Controller 类中业务方法的映射地址
          • 配置 SpringMVC 核心文件 spring-mvc.xml
        • web 工程执行流程
          • 小结
          • SpringMVC 组件概述
            • SpringMVC 的执行流程
              • SpringMVC 组件解析
                • SpringMVC 注解解析
                  • `@Controller`
                  • `@RequestMapping`
                • 小结
                • SpringMVC 的请求
                  • 请求参数类型介绍
                    • 获取基本类型参数
                      • 获取对象类型参数
                        • 中文乱码过滤器
                          • 获取数组类型参数
                            • 获取集合(复杂)类型参数
                              • 自定义类型转换器
                                • 相关注解
                                  • `@RequestParam`
                                  • `@RequestHeader`
                                  • `@CookieValue`
                                • 获取 Servlet 相关 API
                                • SpringMVC 的响应
                                  • SpringMVC 响应方式介绍
                                    • 返回字符串逻辑视图
                                      • `void` 原始 `ServletAPI`
                                        • 转发和重定向
                                          • `ModelAndView`
                                            • 方式一
                                            • 方式二
                                          • `@SessionAttributes`
                                            • 小结
                                            • 静态资源访问的开启
                                            相关产品与服务
                                            容器服务
                                            腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                                            领券
                                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档