Spring MVC:请求转发与请求重定向

Spring MVC

请求转发

转发( forward ),指服务器接收请求后,从一个资源跳转到另一个资源中。请求转发是一次请求,不会改变浏览器的请求地址。

简单示例:

1.通过 String 类型的返回值实现转发

java 复制代码
package cn.edu.springmvcdemo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class ForwardAndRedirectDemo {
    @RequestMapping("/forwardTest1")
    public String forwardTest1(){
        return "ForwardAndRedirect";
    }
}

创建 ForwardAndRedirect.jsp

html 复制代码
<%--
  Created by IntelliJ IDEA.
  User: dell
  Date: 2023/7/28
  Time: 22:35
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
    <h3>请求转发</h3>
</body>
</html>

结果如图:

2.通过 ModelAndView 实现转发

java 复制代码
package cn.edu.springmvcdemo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class ForwardAndRedirectDemo {
    @RequestMapping("/forwardTest2")
    public ModelAndView forwardTest2(){
        ModelAndView mav = new ModelAndView();
        mav.setViewName("ForwardAndRedirect");
        return mav;
    }
}

结果如图:

3.通过 < mvc:view-controller > 标签实现转发

在 Spring MVC 配置文件 springmvc.xml 中配置

xml 复制代码
<!-- 配置请求转发实现 -->
<!-- 在通过 mvc:view-controller 标签实现转发中,添加该配置可以解决同时也通过 Controller 类方法访问出错的问题 -->
<mvc:annotation-driven />
<!-- path 映射地址;view-name 视图名字 -->
<mvc:view-controller path="/forwardTest3" view-name="ForwardAndRedirect" />

结果如图:

注:
< mvc:annotation-driven > 是 Spring MVC 框架中的一个标签,主要作用是自动注册 Spring MVC 的处理器( Handler )和视图解析器( ViewResolver ),以便在应用程序中处理 HTTP 请求并生成相应的响应。具体来说,< mvc:annotation-driven > 标签可以完成以下任务:

  1. 注册 RequestMappingHandlerMapping 处理器映射,用于将 Spring 控制器方法(带有 @RequestMapping 注释)映射到 HTTP 请求
  2. 注册 ExceptionHandlerExceptionResolver 异常处理器解析器,用于处理在控制器方法执行期间发生的异常
  3. 注册 MessageConverter 消息转换器,用于将请求消息转换为控制器方法参数的类型,并将响应消息转换为视图解析器所需的类型
  4. 注册 RequestResponseBodyAdvice advice,用于在请求和响应之间进行转换和类型转换

通过使用 < mvc:annotation-driven > 标签,开发人员可以更加简洁地配置 MVC 模式中的控制器部分,而无需手动注册这些组件,可以使代码更加清晰和易于维护。

请求重定向

重定向( redirect ),指服务器接收请求后,不能跳转到当前请求地址指向的资源中,但会指定新的资源地址返回给客户端,客户端再次请求访问指定资源。请求重定向是两次请求,会改变浏览器的请求地址。

简单示例:

1.通过 String 类型的返回值实现重定向

java 复制代码
package cn.edu.springmvcdemo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class ForwardAndRedirectDemo {
    //新的资源地址
    @RequestMapping("/redirectIndex")
    public String redirect(){
        return "ForwardAndRedirect";
    }
	
	//请求重定向
    @RequestMapping("/redirectTest1")
    public String redirectTest1(){
    	//指定新的资源地址
        return "redirect:/redirectIndex";
    }
}

ForwardAndRedirect.jsp 内容简单修改

html 复制代码
<%--
  Created by IntelliJ IDEA.
  User: dell
  Date: 2023/7/28
  Time: 22:35
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
    <h3>请求重定向</h3>
</body>
</html>

结果如图:

输入 redirectTest1 后自动跳转到 redirectIndex

2.通过 ModelAndView 实现重定向

java 复制代码
package cn.edu.springmvcdemo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class ForwardAndRedirectDemo {
    @RequestMapping("/redirectIndex")
    public String redirect(){
        return "ForwardAndRedirect";
    }

    @RequestMapping("/redirectTest2")
    public ModelAndView redirectTest2(){
        ModelAndView mav = new ModelAndView();
        mav.setViewName("redirect:/redirectIndex");
        return mav;
    }
}

结果如图:

输入 redirectTest2 后自动跳转到 redirectIndex

3.通过 < mvc:view-controller > 标签实现重定向

同理,只需在 springmvc.xml 中配置

xml 复制代码
<!-- 配置请求转发重定向 -->
<!-- path 映射地址;view-name 指定新的资源地址 -->
<mvc:view-controller path="/redirectTest3" view-name="redirect:/redirectIndex" />

结果如图:

输入 redirectTest3 后自动跳转到 redirectIndex

自定义视图,指定义一个自定义的视图对象,用于渲染模型数据并生成响应。自定义视图可以继承 View 、AbstractExcelView 或 AbstractPdfView 来将内容以某种格式( Excel 、Pdf 等)显示。

简单示例:

下载 Excel 文档的需求实现

首先,在 pom.xml 中添加以下依赖

xml 复制代码
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-ooxml</artifactId>
  <version>4.1.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-ooxml</artifactId>
  <version>4.1.2</version>
</dependency>

接着,创建自定义视图类 ExcelViewDemo 继承 AbstractXlsxView ,设置文档的相关信息与数据写入

java 复制代码
package cn.edu.springmvcdemo.web;

import cn.edu.springmvcdemo.model.DomainObject;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.servlet.view.document.AbstractXlsxView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

public class ExcelViewDemo extends AbstractXlsxView {

    @Override
    protected void buildExcelDocument(Map<String, Object> model, Workbook workbook, HttpServletRequest request, HttpServletResponse response) throws Exception {
        //设置文档名字
        String file = "ExcelTest.xlsx";
        //设置字符编码
        response.setCharacterEncoding("UTF-8");
        //设置内容类型,在 apache-tomcat-8.5.75/conf/web.xml 配置文件中查找 xlsx 可获取对应类型写法
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        //设置头部信息(下载,下载文件名字)
        response.setHeader("Content-Disposition","inline;file" + new String(file.getBytes(),"UTF-8"));

        //获取 model 数据( controller 类处理方法中放进的数据)
        List<DomainObject> domainObjects = (List<DomainObject>) model.get("domainObjects");

        //获取数据后转换成 Excel 视图返回
        //1.创建 Excel 表(表中 sheet 的名字)
        Sheet sheet = workbook.createSheet("数据表");
        //2.创建第一行
        Row headRow = sheet.createRow(0);
        //3.创建第一行的1、2、3列
        headRow.createCell(0).setCellValue("编号");
        headRow.createCell(1).setCellValue("姓名");
        headRow.createCell(2).setCellValue("年龄");

        //遍历获取数据写入表中
        int rowNum = 1; //从表的第二行开始
        for(DomainObject domainObject:domainObjects){
            //创建新的一行
            Row row = sheet.createRow(rowNum++);
            //获取对应的数据
            row.createCell(0).setCellValue(domainObject.getId());
            row.createCell(1).setCellValue(domainObject.getName());
            row.createCell(2).setCellValue(domainObject.getAge());
        }

        OutputStream outputStream = response.getOutputStream();
        //将数据写入输出流
        workbook.write(outputStream);
        //清空输出流
        outputStream.flush();
        //关闭输出流
        outputStream.close();
    }
}

然后,创建 controller 类的方法,获取数据

java 复制代码
package cn.edu.springmvcdemo.controller;

import cn.edu.springmvcdemo.model.DomainObject;
import cn.edu.springmvcdemo.web.ExcelViewDemo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
public class ExcelDemo {
    @RequestMapping("/excelDownload")
    public ModelAndView excelViewTest(){
        Map<String,Object> map = new HashMap<>();
        //模拟:数据库中取出一个 domainObjects 的 list 集合
        DomainObject domainObject1 = new DomainObject();
        domainObject1.setId(728);
        domainObject1.setName("曹操");
        domainObject1.setAge(24);

        DomainObject domainObject2 = new DomainObject();
        domainObject2.setId(729);
        domainObject2.setName("刘备");
        domainObject2.setAge(22);

        DomainObject domainObject3 = new DomainObject();
        domainObject3.setId(730);
        domainObject3.setName("孙权");
        domainObject3.setAge(18);

        //先将数据放入 list 集合
        List<DomainObject> list = new ArrayList<>();
        list.add(domainObject1);
        list.add(domainObject2);
        list.add(domainObject3);

        // list 集合再放入 map 集合中
        // 键的名字与 (List<DomainObject>) model.get("domainObjects") 中的名字保持一致
        map.put("domainObjects",list);

        //(自定义视图对象,数据)
        ModelAndView mav = new ModelAndView(new ExcelViewDemo(),map);
        return mav;
    }
}

最后,重启服务器,测试结果

输入地址,弹出下载窗口。结果如图:

Excel 表内容如图:

相关推荐
问道飞鱼13 小时前
【知识科普】HTTP相关内容说明
websocket·http·请求转发·请求重定向
熬夜加班写代码2 个月前
【源码解读】SpringMMVC执行流程
java·后端·程序员·spring mvc
GGBondlctrl2 个月前
【Spring MVC】关于Spring MVC编程中前后端交互实现简单登录跳转和留言板实例
java·spring mvc·lombok·前后端交互·登录跳转·留言板·接口文档定义
GGBondlctrl2 个月前
【Spring MVC】初步了解Spring MVC的基本概念与如何与浏览器建立连接
java·spring boot·spring mvc·requestmapping·restcontroller
xbronze3 个月前
【笔记】记一次因Spring版本和Tomcat版本不对应,造成Spring MVC项目启动后页面访问报404的问题
tomcat·spring mvc
不修×蝙蝠3 个月前
请求转发和重定向
请求转发·request·response·重定向
茜茜西西CeCe3 个月前
Java程序设计:spring boot(2)
java·开发语言·spring boot·maven·idea·web·spring mvc
太自由4 个月前
浅聊前后端分离开发和前后端不分离开发模式
前端·servlet·spring mvc·thymeleaf·模板引擎·前后端分离开发
LearnTech_1234 个月前
【学习笔记】手写一个简单的 Spring MVC
笔记·学习·spring·spring mvc
胡耀超5 个月前
Spring MVC 执行流程详解
java·spring·mvc·spring mvc