处理完传参和业务逻辑处理后,最后就是带着处理完的数据做页面跳转了,在JavaWeb中做页面跳转分两步,第一步是使用作用域传递、存储数据,第二步是做页面跳转,页面跳转一般又分为forward跳转和redirect跳转。

1. 核心区别
    forward:
        1. 一次请求
        2. 地址栏不变
        3. 可以通过request作用域传递数据

    redirect:
        1. 多次请求
        2. 地址栏改变
        3. 不能通过request作用域传递数据
        4. 可以跨域跳转
  
2. 如何选择
	1. 如果本次功能需求,已经完成,则使用redirect跳转
	2. 如果本次功能需求,没有完成,则使用forward 跳转

redirect跳转是用url?拼接的方式传递数据的,例:

package com.jin;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author jinyunlong
 * @date 2022/2/14 11:16
 * @profession ICBC锅炉房保安
 */
public class AServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("AServlet.service");
        resp.sendRedirect("/view/BServlet?name=90900&password=12234");
    }
}
package com.jin;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author jinyunlong
 * @date 2022/2/14 11:16
 * @profession ICBC锅炉房保安
 */
public class BServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("BServlet.service");
        String name = req.getParameter("name");
        String password = req.getParameter("password");
        System.out.println("name = " + name);
        System.out.println("password = " + password);
    }
}

如上在JavaWeb中还需要基于HttpServlet来处理,有耦合,SpringMVC中有接口处理了这个问题。

一、SpringMVC的四种跳转形式
1. 四种跳转指的是:在SpringMVC中控制器与JSP或者控制器与控制器之间的跳转。
	1. Controller -- forward  --> JSP
	2. Controller -- redirect --> JSP
	3. Controller -- forward  --> Controller
	4. Controller -- redirect --> Controller

2. SpringMVC的四种跳转,底层上就是对Servlet跳转的封装。
   
3. 默认情况下SpringMVC中控制器通过视图解析器跳转到JSP页面,通过的是forward形式。

注意第三点,默认SpringMVC通过视图解析器跳转到JSP页面通过的是forward形式。

forward Controller-->JSP 跳转编码:

package com.jin;

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

/**
 * @author jinyunlong
 * @date 2022/2/16 17:06
 * @profession ICBC锅炉房保安
 */
@Controller
@RequestMapping("/view1")
public class ViewController {
    @RequestMapping("/view1")
    public String view1(){
        return "result";
    }
// 结合ViewResolver的前缀(prefix)、后缀(suffix)进行拼接成完整的页面,并进行forward跳转

    @RequestMapping("/view2")
    public String view2(){
        return "forward:/result.jsp";
    }
}
// 使用了forward:关键字,视图解析器的拼接会失效。所以必须写完整路径。

redirect Controller-->JSP 跳转编码:

package com.jin;

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

/**
 * @author jinyunlong
 * @date 2022/2/16 17:06
 * @profession ICBC锅炉房保安
 */
@Controller
@RequestMapping("/view1")
public class ViewController {

    @RequestMapping("/view3")
    public String view3(){
        return "redirect:/result.jsp";
    }
}

forward Controller-->Controller 跳转编码:

由forward1跳到forward2,再由forward2跳到jsp页面:

package com.jin;

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

/**
 * @author jinyunlong
 * @date 2022/2/16 17:21
 * @profession ICBC锅炉房保安
 */
@Controller
@RequestMapping("/forwardController")
public class ForwardController {
    @RequestMapping("/forward1")
    public String forward1(){
        return "forward:/forwardController/forward2";
    }

    @RequestMapping("/forward2")
    public String forward2(){
        return "forward:/forward2.jsp";   //forward2
    }
}

redirect Controller-->Controller 跳转编码:

由redirect1跳到redirect2,再由redirect2跳到jsp页面:

package com.jin;

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

/**
 * @author jinyunlong
 * @date 2022/2/17 14:59
 * @profession ICBC锅炉房保安
 */
@Controller
@RequestMapping("/redirectController")
public class RedirectController {

        @RequestMapping("/redirect1")
        public String redirect() {
            return "redirect:/redirectController/redirect2";
        }

        @RequestMapping("/redirect2")
        public String redirect2() {
            return "redirect:/redirect2.jsp";   //redirect2
//            return "redirect2";
        }

}

JavaWeb中的三种作用域:

1. HttpServletRequest[简称request作用域]
   用于组件间跳转时传递数据
   组件指的是 控制器 视图(JSP)
   使用方式:
		request.setAttribute("name","value");
		request.getAttribute("name");
  
2. HttpSession       [简称session作用域]
   不用于组件间跳转时传递数据
   用于用户会话追踪,只能存储与用户相关的个人数据
   如:登录状态、令牌、购物车等
   使用方式:
		session.setAttribute("name","value");
		session.getAttribute("name");
  
3. ServletContext    [简称application作用域]
   全局唯一,框架底层使用,多用于存储全局唯一的对象
   如:Spring的工厂(容器)、Hibernate(JPA)的SessionFactory、MyBatis的SqlSessionFactory等。
   使用方式:
		application.setAttribute("name","value");
		application.getAttribute("name");
二、SpringMVC中作用域处理

问题:如果还是用HttpServlet,会与ServletAPI耦合,同时也与视图模板技术耦合,在SpringMVC中不建议使用。

1、SpringMVC中request作用域的处理

可以基于Model的方式,或者基于ModelMap的方式:

package com.jin;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;

/**
 * @author jinyunlong
 * @date 2022/2/17 15:40
 * @profession ICBC锅炉房保安
 */
@Controller
@RequestMapping("/view2")
public class View2Controller {
    @RequestMapping("/view1")
    public String view1(HttpServletRequest request){
        System.out.println("View2Controller.view1");
        request.setAttribute("name","fuckyou");
//        return "view1";
        return "redirect:/view1.jsp";
    }

    @RequestMapping("/view2")
    public String view2(Model model){
        model.addAttribute("name","shit");
//        return "view1";
        return "redirect:/view1.jsp";
    }

    @RequestMapping("/view3")
    public String view3(ModelMap modelMap){
        modelMap.addAttribute("name","shit");
        return "view1";
    }
}
<%@ page pageEncoding="utf-8" contentType="text/html; charset=utf-8" %>
<html>
<head></head>
<body>
<h2>fuck you leather man ${requestScope.name}</h2>
</body>
</html>

Model、ModelMap相关细节分析

22.PNG

2、SpringMVC中session作用域的处理

只需使用@SessionAttributes,删除Session作用只需引入SessionStatus对象,执行对应方法即可:

package com.jin;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;

/**
 * @author jinyunlong
 * @date 2022/2/18 16:56
 * @profession ICBC锅炉房保安
 */
@Controller
@RequestMapping("/view3")
@SessionAttributes(value = {"name","address"})
public class View3Controller {
    @RequestMapping("/view1")
    public String view1(Model model){
        model.addAttribute("age",10);
        model.addAttribute("name","shit");
        return "forward:/view3/view2";
    }

    @RequestMapping("/view2")
    public String view2(SessionStatus sessionStatus){
        if (!sessionStatus.isComplete()) {
            sessionStatus.setComplete();
        }
        return "view2";
    }
}
<%@ page pageEncoding="utf-8" contentType="text/html; charset=utf-8" %>
<html>
<head></head>
<body>
<h2>fuck you leather man ${sessionScope.name}</h2>
<h2>fuck you leather man ${requestScope.name}</h2>
<h2>fuck you leather man ${requestScope.age}</h2>
</body>
</html>

23.PNG

可见存到session的key为name的内容已经获取不到了。

注意:
1、在modelMap或者model没把adress放到request作用域,@SessionAttributes注解中声明adresss,没有问题,不会报错
2、request作用域和session作用域共用同一对象。
3、SpringMVC中application作用域的处理

全局唯一,框架底层使用,多用于存储全局唯一的对象,实际业务处理场景使用较少,略。


标题:SpringMVC(4)
作者:jyl
地址:http://114.116.238.43/articles/2022/02/21/1645411941441.html