Spring MVC【返回数据与请求转发和重定向】

简介: Spring MVC【返回数据与请求转发和重定向】

我们知道,默认请求下⽆论是 Spring MVC 或者是 Spring Boot 都是由控制器(Controller)返回的是视图(View)(xxx.html),⽽现在都是前后端分离的,后端只需要返给给前端数据即可,这个时候我们就需要使⽤@ResponseBody 注解了


🍎一. 返回数据


🍒1.1 返回静态页面


我们先创建一个前端输出的文字的页面,最后来通过Controller来进行访问

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>hello,spring mvc</title>
    <script src="index.js"></script>
</head>
<body>
    <h1>Hello,Spring MVC.</h1>
</body>
</html>
 //访问静态页面
    @RequestMapping("/sayhi")
    public String sayHi(){
        return  "/hello.html";
    }

edf235c1fb57455a9b1f6ab4e4745fbf.png

🍒1.2 返回一个非静态页面


@ResponseBody是修饰类或方法的注解,作用是返回当前类中或方法中的非静态页面

 //访问非静态页面
    @ResponseBody
    @RequestMapping("/sayhi")
    public String sayHi(){
        return  "/hello.html";
    }

de111fc8697243229c6cd55d12666e1e.png

🍒1.3 返回text/html类型页面

这个和返回静态页面的区别就是,需要用@ResponseBody,并且需要使用


前端标题符

  @RequestMapping("/m7")
    @ResponseBody
    public String method_7() {
        return "<h1>Hello,HTML~</h1>";
    }


c0a867c0bccb45cc846f3daedc529957.png


🍒1.4 返回JSON对象

 @RequestMapping("/m8")
    @ResponseBody
    public HashMap<String, String> method_8() {
        HashMap<String, String> map = new HashMap<>();
        map.put("Java", "Java Value");
        map.put("MySQL", "MySQL Value");
        map.put("Redis", "Redis Value");
        return map;
    }

9cf31da687b54e969d88ee0dead9e2d0.png


🍒1.5 实现计算器功能


可使⽤ postman 传递参数,或使⽤ form 表单的⽅式提交参数


前端⻚⾯:


<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>计算器示例</title>
</head>
<body>
<form action="http://localhost:8080/calc">
    <h1>计算器</h1>
    数字1:<input name="num1" type="text"><br>
    数字2:<input name="num2" type="text"><br>
    <input type="submit" value=" 点击相加 ">
</form>
</body>
</html>

后端页面:

@RestController
public class CalcController {
    @RequestMapping("/calc")
    public String calc(Integer num1,Integer num2){
        if (num1 == null || num2==null) {
            if (num1 == null || num2 == null) return "<h1>参数错误!</h1><a href='javascript:history.go(-1);'>返回</a>";
        }
        return "<h1>结果:" + (num1+num2) +"</h1>";
    }
}

19a23aadd776458ab9545e9d92ff2bc2.pngf75c06a8154a4e5bbb852af19f66b20b.png


🍒1.6 使用ajax方式实现登陆功能


前端代码:


<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="js/jquery-1.9.1.min.js"></script>
    <title>Document</title>
    <script>
       // ajax 提交
        function mysub(){
            // 1.判空
            var username = jQuery("#username");
            var password = jQuery("#password");
            if(jQuery.trim(username.val())==""){
                alert("请先输入用户名!");
                username.focus(); // 光标重制到此元素
                return;
            }
            if(jQuery.trim(password.val())==""){
                alert("请先输入密码!");
                password.focus(); // 光标重制到此元素
                return;
            }
            jQuery.ajax({
                url:"/user/login3",
                type:"POST",
                contentType:"application/json",
                data:JSON.stringify({"username":username.val(),
            "password":password.val()}),
                success:function(result){
                    alert(JSON.stringify(result));
                }
            });
        }
    </script>
</head>
<body>
<div style="text-align: center;">
    <h1>登录</h1>
    用户:<input id="username">
    <br>
    密码:<input id="password" type="password">
    <br>
    <input type="button" value=" 提交 " οnclick="mysub()" style="margin-top: 20px;margin-left: 50px;">
</div>
</body>
</html>


后端代码:

 @RequestMapping("/login3")
    public HashMap<String,Object> login2(String username, String password){
        HashMap<String,Object> result = new HashMap<>();
        int state = 200; //状态码
        int data = -1;   //等于1,登陆成功,否则登陆失败
        String msg = "未知错误";
        //使用Spring提供的方法tringUtils.hasLength方法就可以同时判断username是否是"空"和null了
        if (StringUtils.hasLength(username) && StringUtils.hasLength(password) && username.equals("admin") && password.equals("admin") ){
           if ( username.equals("admin") && password.equals("admin")) {
               data = 1;
               msg = "";
           }else {
               msg = "用户名或密码错误";
           }
        }else {
            // 参数为空
            msg = "非法参数";
        }
        result.put("state",state);
        result.put("data",data);
        result.put("msg",msg);
        return result;
    }

415f8953e4b849368b46dc870c366c78.png





🍎二.请求转发与请求重定向


return 不但可以返回⼀个视图,还可以实现跳转,跳转的⽅式有两种:

forward 是请求转发

redirect:请求重定向


forward(请求转发)和 redirect(请求重定向)的区别,举例来说,例如:

你告诉你妈妈,你想吃辣条,如果你妈妈,说好,我帮你去买,这就是 forward 请求转发;

如果你妈妈让你⾃⼰去买,那么就是请求 redirect 重定向


🍒2.1 请求转发(forward)


代码示例:

// [请求转发]
    // 实现方法(1)
    @RequestMapping("/fw")
    public String myForward(){
        return "forward:/hello.html";
    }
    // 实现方法(2)
    @RequestMapping("/fw2")
    public void myFoward2(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getRequestDispatcher("/hello.html").forward(request,response);
    }

2aa0058ce20c4864907eab943df00fd0.png

我们可以使用fiddler来进行抓包验证,我们可以发现请求转发客户端只是访问了一次,而转发的过程中是由服务器内部进行访问静态页面后返回数据给服务端的


cf8a61539ffe4466a7ba1063bcf88339.png


df709de4474147f78038f7ff0a9889d5.png


🍒2.2 请求重定向(redirect)


代码示例:


  // [请求重定向]
    // 实现方法(1)
    @RequestMapping("/rd")
    public String myRedirect(){
        return "redirect:/hello.html";
    }
    // 实现方法(2)
    @RequestMapping("/rd2")
    public void myRedirect(HttpServletResponse response) throws IOException {
        response.sendRedirect("/hello.html");
    }

b57a8c15393e420ba8ae12d26b69f95c.png



我们可以使用fiddler来进行抓包验证,我们可以发现请求1转发客户端是先访问服务器,而服务器内部会响应客户端的请求1,之后客户端会进行请求2,服务器进行进行访问静态页面后返回数据给客户端的,我们看到页面就了解了,重定向会将页面地址最后跳转到我们需要访问的静态页面地址



ec9810492c7341688daecd6b2be5ea9b.png



238664c16f034e38aa53da491f8de445.png


🍎三.请求转发和请求重定向有什么区别


请求转发和请求重定向主要区别,包含以下 5 点:


● 定义不同

● 跳转方不同

● 数据共享不同

● 最终 URL 地址不同

● 代码实现不同


🍒3.1 定义不同


请求转发(Forward):发生在服务端程序内部,当服务器端收到一个客户端的请求之后,会先将请求,转发给目标地址,再将目标地址返回的结果转发给客户端


请求重定向(Redirect):请求重定向指的是服务器端接收到客户端的请求之后,会给客户端返回了一个临时响应头,这个临时响应头中记录了,客户端需要再次发送请求(重定向)的 URL 地址,客户端再收到了地址之后,会将请求发送到新的地址上,这就是请求重定向


🍒3.2 跳转方不同


请求转发是服务器端的行为,服务器端代替客户端发送请求,并将结果返回给客户端;

而请求重定向是客户端的行为,它们的交互流程

如下图所示:



3b8de9741b074200a07e371eaa035a3f.png

a9d8e4f73a2e437a9080b549151ede4e.png


🍒3.3 数据共享不同


请求转发是服务器端实现的,所以整个执行流程中,客户端(浏览器端)只需要发送一次请求,因此整个交互过程中使用的都是同一个 Request 请求对象和一个 Response 响应对象,所以整个请求过程中,请求和返回的数据是共享的;而请求重定向客户端发送两次完全不同的请求,所以两次请求中的数据是不同的


🍒3.4 最终 URL 地址不同


请求转发是服务器端实现的,所以整个执行流程中,客户端(浏览器端)只需要发送一次请求,因此整个交互过程中使用的都是同一个 Request 请求对象和一个 Response 响应对象,所以整个请求过程中,请求和返回的数据是共享的;而请求重定向客户端发送两次完全不同的请求,所以两次请求中的数据是不同的


请求转发:



6e73a05f6d6b4b07b531bd5b476288e8.png


请求重定向:


d2a88e718023422fa93a6895957d65cd.png



🍒3.5 代码实现不同

// [请求转发]
    // 实现方法(1)
    @RequestMapping("/fw")
    public String myForward(){
        return "forward:/hello.html";
    }
    // 实现方法(2)
    @RequestMapping("/fw2")
    public void myFoward2(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getRequestDispatcher("/hello.html").forward(request,response);
    }
    // [请求重定向]
    // 实现方法(1)
    @RequestMapping("/rd")
    public String myRedirect(){
        return "redirect:/hello.html";
    }
    // 实现方法(2)
    @RequestMapping("/rd2")
    public void myRedirect(HttpServletResponse response) throws IOException {
        response.sendRedirect("/hello.html");
    }

🍒3.6 转发和重定向的选择


1、重定向的速度比转发慢,因为浏览器还得发出一个新的请求,如果在使用转发和重定向都无所谓的时候建议使用转发


2、因为转发只能访问当前web的应用程序,所以不同web应用程序之间的访问,特别是要访问到另外一个web站点上的资源的情况,这个时候就只能使用重定向了


3、另外,重定向还有一个应用场景:避免在用户重新加载页面时两次调用相同的动作

相关文章
|
10天前
|
缓存 安全 Java
Spring Get请求 与post请求
本文详细介绍了Spring框架中GET请求和POST请求的区别及应用场景。GET请求用于从服务器获取资源,参数附在URL末尾,适合查看非敏感信息;POST请求用于向服务器提交数据,参数在请求体中传输,适合处理敏感信息。Spring通过`@GetMapping`和`@PostMapping`注解分别处理这两种请求。此外,文章还提供了示例代码,展示了如何在Spring中实现这两种请求的处理。最后,文章总结了推荐使用POST请求的原因,包括更高的安全性、更大的数据传输量、更好的幂等性及灵活性。
Spring Get请求 与post请求
|
22天前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
9天前
|
XML 缓存 前端开发
springMVC02,restful风格,请求转发和重定向
文章介绍了RESTful风格的基本概念和特点,并展示了如何使用SpringMVC实现RESTful风格的请求处理。同时,文章还讨论了SpringMVC中的请求转发和重定向的实现方式,并通过具体代码示例进行了说明。
springMVC02,restful风格,请求转发和重定向
|
2月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
2月前
|
XML JSON 数据库
SpringMVC入门到实战------七、RESTful的详细介绍和使用 具体代码案例分析(一)
这篇文章详细介绍了RESTful的概念、实现方式,以及如何在SpringMVC中使用HiddenHttpMethodFilter来处理PUT和DELETE请求,并通过具体代码案例分析了RESTful的使用。
SpringMVC入门到实战------七、RESTful的详细介绍和使用 具体代码案例分析(一)
|
2月前
|
安全 Java 应用服务中间件
如何在 Spring Boot 3.3 中实现请求 IP 白名单拦截功能
【8月更文挑战第30天】在构建Web应用时,确保应用的安全性是至关重要的。其中,对访问者的IP地址进行限制是一种常见的安全措施,特别是通过实施IP白名单策略,可以只允许特定的IP地址或IP段访问应用,从而有效防止未授权的访问。在Spring Boot 3.3中,我们可以通过多种方式实现这一功能,下面将详细介绍几种实用的方法。
87 1
|
2月前
|
Java API UED
【实战秘籍】Spring Boot开发者的福音:掌握网络防抖动,告别无效请求,提升用户体验!
【8月更文挑战第29天】网络防抖动技术能有效处理频繁触发的事件或请求,避免资源浪费,提升系统响应速度与用户体验。本文介绍如何在Spring Boot中实现防抖动,并提供代码示例。通过使用ScheduledExecutorService,可轻松实现延迟执行功能,确保仅在用户停止输入后才触发操作,大幅减少服务器负载。此外,还可利用`@Async`注解简化异步处理逻辑。防抖动是优化应用性能的关键策略,有助于打造高效稳定的软件系统。
42 2
|
2月前
|
JSON Java API
哇塞!Spring Boot 中的 @DateTimeFormat 和 @JsonFormat,竟能引发数据时间大变革!
【8月更文挑战第29天】在Spring Boot开发中,正确处理日期时间至关重要。
31 1
|
2月前
|
前端开发 应用服务中间件 数据库
SpringMVC入门到实战------八、RESTful案例。SpringMVC+thymeleaf+BootStrap+RestFul实现员工信息的增删改查
这篇文章通过一个具体的项目案例,详细讲解了如何使用SpringMVC、Thymeleaf、Bootstrap以及RESTful风格接口来实现员工信息的增删改查功能。文章提供了项目结构、配置文件、控制器、数据访问对象、实体类和前端页面的完整源码,并展示了实现效果的截图。项目的目的是锻炼使用RESTful风格的接口开发,虽然数据是假数据并未连接数据库,但提供了一个很好的实践机会。文章最后强调了这一章节主要是为了练习RESTful,其他方面暂不考虑。
SpringMVC入门到实战------八、RESTful案例。SpringMVC+thymeleaf+BootStrap+RestFul实现员工信息的增删改查
|
2月前
|
XML JSON Java
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
本文介绍了如何使用IntelliJ IDEA和Maven搭建一个整合了Struts2、Spring4、Hibernate4的J2EE项目,并配置了项目目录结构、web.xml、welcome.jsp以及多个JSP页面,用于刷新和学习传统的SSH框架。
36 0
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
下一篇
无影云桌面