SpringMVC - 响应处理

SpringMVC - 响应处理

1. 使用视图解析器

视图解析器(View Resolver)在Spring MVC框架中是一个非常重要的组件,它的主要职责是将控制器(Controller)返回的逻辑视图名称转换成实际的视图对象(View),这个视图对象可以用来渲染最终呈现给用户的HTML页面或其他类型的响应。

内部资源视图解析器 (InternalResourceViewResolver)

  • InternalResourceViewResolver 是Spring MVC中默认提供的视图解析器之一,它主要用于解析JSP页面。当控制器返回一个视图名称时,InternalResourceViewResolver 会根据配置的前缀和后缀来构建完整的视图资源路径。
1.1 xml 版
    <!-- 配置InternalResourceViewResolver Bean -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 设置视图解析器的前缀,用于指定JSP文件的存放目录 -->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!-- 设置视图解析器的后缀,指定JSP文件的扩展名 -->
        <property name="suffix" value=".jsp"/>
    </bean>
  • 该XML代码段配置了一个InternalResourceViewResolver,用于解析视图名称并将其转换为实际的视图资源路径。其功能主要体现在两个属性的设置上:
    1. prefix属性:设置了视图资源的前缀,这里是/WEB-INF/jsp/。这意味着所有的视图名称都会被添加上这个前缀。
    2. suffix属性:设置了视图资源的后缀,这里是.jsp。这意味着所有的视图名称都会被添加上这个后缀。

综上所述,这段XML代码的作用是:配置了一个视图解析器,用于将视图名称解析为实际的JSP文件路径。通过设置前缀和后缀,可以方便地定位和访问JSP视图资源。

1.2 Config 版
@Configuration

@EnableWebMvc
public class SpringWebConfig implements WebMvcConfigurer {
    /**
     * 配置视图解析器
     * <p>
     * 通过覆盖此方法,可以自定义视图解析器的配置,这对于MVC应用程序的视图渲染至关重要
     * 此处特别配置了InternalResourceViewResolver,这是一种常用的视图解析器,用于处理JSP视图
     *
     * @param registry 视图解析器注册表,用于注册视图解析器
     */
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        // 创建并配置InternalResourceViewResolver
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        // 设置JSP文件的前缀路径
        viewResolver.setPrefix("/WEB-INF/jsp/");
        // 设置JSP文件的后缀
        viewResolver.setSuffix(".jsp");

        // 将配置好的视图解析器注册到视图解析器注册表中
        registry.viewResolver(viewResolver);
    }
}

这段代码是Spring MVC中的一个配置方法,用于配置视图解析器(ViewResolver)。其功能如下:

  1. 创建一个InternalResourceViewResolver对象,并进行配置:
    • 设置JSP文件的前缀路径为/WEB-INF/jsp/
    • 设置JSP文件的后缀为.jsp
  2. 将配置好的视图解析器注册到视图解析器注册表(ViewResolverRegistry)中。

通过这个配置,当控制器(Controller)返回一个逻辑视图名时,视图解析器会根据前缀和后缀拼接成实际的视图路径,然后去寻找并返回对应的视图(JSP文件)。例如,如果控制器返回"welcome",则视图解析器会寻找/WEB-INF/jsp/welcome.jsp这个文件。

2. 使用视图控制器

视图控制器(View Controller)是MVC(Model-View-Controller)架构模式中的一个重要组成部分,主要负责处理与用户界面相关的逻辑。在Web应用程序中,视图控制器通常用来处理HTTP请求,并决定应该显示哪个视图(页面)给用户。

视图控制器的作用

  1. 处理请求:
    • 接收用户的HTTP请求。
    • 解析请求中的信息,如查询字符串、表单数据等。
  2. 业务逻辑调用:
    • 调用模型层的方法或服务层的业务逻辑来处理数据或执行某些操作。
  3. 视图选择:
    • 根据业务逻辑的结果选择合适的视图进行渲染。
    • 将必要的数据传递给视图进行展示。
  4. 响应用户:
    • 渲染视图并生成最终的HTML页面或其他格式的内容,返回给客户端。
2.1 xml 版
    <!-- 配置一个视图控制器,用于处理根路径("/")的请求 -->
    <mvc:view-controller path="/" view-name="index"/>
  • 该XML函数是一个MVC视图控制器配置,作用是将特定路径(在这里是根路径"/“)映射到一个视图(在这里是"index”)。当用户访问应用程序的根路径时,将显示名为"index"的视图。这个配置通常用于简化主页或其他常用视图的映射,避免在控制器中编写过多的代码。
2.2 Config 版
@Configuration
@EnableWebMvc
public class SpringWebConfig implements WebMvcConfigurer {
    /**
     * 添加视图控制器,用于映射URL路径到视图名称
     * 该方法通过Spring的视图控制器注册机制,指定了根路径("/")对应的视图为"index"
     *
     * @param registry 视图控制器注册对象,用于注册视图控制器映射
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // 设置根路径的视图控制器,映射到"index"视图
        registry.addViewController("/").setViewName("index");
    }
}

这段Java代码是一个重写的方法,用于在Spring框架中添加视图控制器。具体来说,它将根路径(“/”)映射到名为"index"的视图。以下是详细解释:

  • public void addViewControllers(ViewControllerRegistry registry):这是重写的方法本身,它接受一个ViewControllerRegistry类型的参数。

  • registry.addViewController("/"):这行代码向ViewControllerRegistry对象添加了一个视图控制器,指定路径为根路径(“/”)。

  • .setViewName("index"):这行代码设置了上述视图控制器映射到的视图名称为"index"。

综上所述,这段代码的主要功能是在Spring框架中设置根路径的视图控制器,使其映射到名为"index"的视图。

3. 传输数据到页面

3.1 使用 servlet API
    /**
     * 处理对servletAPI的请求
     *
     * @param request 请求对象,用于设置属性
     * @return 返回逻辑视图名称"main"
     */
    @RequestMapping("/servletAPI")
    public String servletAPI(HttpServletRequest request) {
        request.setAttribute("type", "servletAPI");
        return "main";
    }
  • 该Java函数名为servletAPI,它处理HTTP请求。具体功能如下:
    1. 通过@RequestMapping注解指定处理URL路径为"/servletAPI"的请求。
    2. 函数接收HttpServletRequest类型的参数request,代表客户端发送的HTTP请求。
    3. 将属性"type"设置为"value"(值为"servletAPI")并存入请求对象。
    4. 返回字符串"main",通常表示转发到名为"main"的视图或页面。
3.2 使用 Model
    /**
     * 处理对model的请求
     *
     * @param modelMap 模型对象,用于添加属性
     * @return 返回逻辑视图名称"main"
     */
    @RequestMapping("/model")
    public String model(ModelMap modelMap) {
        System.out.println(modelMap.getClass());
        modelMap.addAttribute("type", "model");
        return "main";
    }

这个Java函数model主要负责处理HTTP请求,其功能如下:

  1. 处理请求路径:该方法通过@RequestMapping注解指定处理路径为"/model"的所有HTTP请求。
  2. 输出ModelMap的类信息:
    • 函数内部首先获取到一个ModelMap对象,通常用于在控制器与视图之间传递数据。
    • 接着调用System.out.println语句打印ModelMap对象的类信息,即输出类似class org.springframework.ui.ModelMap的信息。
  3. 向ModelMap添加属性:
    • 通过modelMap.addAttribute("type", "model")将键值对{"type": "model"}添加到ModelMap中。
    • 这样做是为了将数据传递给后续的视图层,例如HTML页面。
  4. 返回视图名称:
    • 函数最后返回字符串"main",这通常被视图解析器用来定位具体的视图资源(如HTML文件),从而展示给用户
3.3 使用 Map
    /**
     * 处理对map的请求
     *
     * @param Map 模型对象,用于添加属性
     * @return 返回逻辑视图名称"main"
     */
    @RequestMapping("/map")
    public String map(Map Map) {
        System.out.println(Map.getClass());
        Map.put("type", "map");
        return "main";
    }
  • 此Java函数是一个Web控制器方法,其具体功能如下:
    1. 使用@RequestMapping注解将HTTP请求映射到此方法,当用户访问"/map"路径时会触发此方法执行。
    2. 方法接收一个名为Map的参数,该参数类型为Map,意味着它能直接获取到请求中的所有参数,并将它们以键值对的形式存储在这个Map对象中。
    3. 通过System.out.println(Map.getClass());打印出Map对象的类信息,这通常用于调试或确认传入的对象类型。
    4. Map对象中添加一个新的键值对{"type", "map"},其中键为"type",值为"map"。
    5. 最后返回字符串"main",这通常表示控制器将请求转发给视图解析器处理,视图解析器会根据返回的字符串来决定展示哪个页面(例如,可能会显示名为"main"的页面)。
3.4 使用 ModelMap
    /**
     * 处理对modelMap的请求
     *
     * @param modelMap 模型对象,用于添加属性
     * @return 返回逻辑视图名称"main"
     */
    @RequestMapping("/modelMap")
    public String modelMap(ModelMap modelMap) {
        System.out.println(modelMap.getClass());
        modelMap.addAttribute("type", "modelMap");
        return "main";
    }
  • 这个Java函数是一个请求映射函数,用于处理Web应用中的HTTP请求。它的功能是在服务器端接收请求,并向请求发送方返回一个页面。
    1. @RequestMapping("/modelMap")注解表示这个函数处理地址为/modelMap的请求。
    2. 函数参数ModelMap modelMap是一个用来保存模型数据的Map类型对象,它可以将数据绑定到请求作用域中,以便在JSP页面中使用。
    3. System.out.println(modelMap.getClass());语句用于打印modelMap对象的类信息,通常用于调试。
    4. modelMap.addAttribute("type", "modelMap");语句将一个名为"type"的属性添加到modelMap中,值为"modelMap"。这个属性可以在JSP页面中被访问和显示。
    5. return "main";语句指定要返回的视图名称,这里是"main"。根据配置,这个视图名称会被解析为一个物理页面路径,通常是一个JSP文件,该文件将被渲染并返回给请求发送方
3.5. 使用 ModelAndView
    /**
     * 处理对modelAndView的请求
     *
     * @return 返回一个包含逻辑视图名称"main"和对象的ModelAndView对象
     */
    @RequestMapping("/modelAndView")
    public ModelAndView modelAndView() {
        ModelAndView modelAndView = new ModelAndView("main");
        modelAndView.addObject("type", "modelAndView");
        return modelAndView;
    }

这个Java函数的主要功能如下:

  1. 标注了@RequestMapping("/modelAndView"),说明这是一个处理HTTP请求的方法,它会响应路径为/modelAndView的GET请求。
  2. 函数内部首先创建了一个ModelAndView对象,并将视图名称设置为"main"。这意味着当这个方法被调用时,将会渲染一个名为main的视图页面。
  3. 接着向ModelAndView对象中添加了一个名为"type"的对象,其值为"modelAndView"。这表示在渲染main视图时,视图可以访问一个名为type的属性,其值为modelAndView
  4. 最后返回这个填充好的ModelAndView对象。这意味着除了渲染视图外,还会将包含type属性的数据模型一同传递给视图层,供视图层展示或使用这些数据。
3.6. 使用 Session
3.6.1. 通过 servlet API 读写 session
  1. 通过参数绑定的方式去获取 servlet API

    /**
     * 处理与会话相关的请求,演示如何在控制器中使用HttpSession对象设置会话属性
     * 
     * @param session HttpSession对象,用于管理会话状态
     * @return 主页的视图名称,这里假设为"main"
     */
    @RequestMapping("/session01")
    public String session01(HttpSession session) {
        // 设置会话属性"type",用于标识会话的类型
        session.setAttribute("type", "servletApi-session01");
        // 指定返回的视图名称,控制器处理结果将跳转到主页面
        return "main";
    }
    
    

    这个Java函数主要功能如下:

    1. 标注了@RequestMapping("/session01"):表示该方法用于处理URL路径为"/session01"的HTTP请求。

    2. 方法接收一个HttpSession session参数:通过这个参数可以操作用户的会话信息。

    3. 在方法内部:

      • 使用session.setAttribute("type", "servletApi-session01");设置了一个名为"type"的会话属性,并将其值设置为"servletApi-session01"。这可以在后续请求中通过会话ID访问到。
    4. 最后返回字符串"main":这通常意味着将转向名为"main"的视图页面。

  2. 通过自动注入的方式去获取 servlet API(推荐使用)

    // 使用@Autowired注解自动注入HttpSession依赖,便于管理会话信息
    @Autowired
    private HttpSession session;
    
    /**
     * 处理/session02请求,用于演示如何在会话中设置属性
     * 通过在HttpSession中设置属性,可以在整个会话范围内使用这些属性
     * 
     * @return 主页面的逻辑视图名称,用于视图解析器解析实际的视图资源
     */
    @RequestMapping("/session02")
    public String session02() {
        // 将"type"属性设置到当前会话中,值为"autowired-session02"
        // 这种方式使得在同一个会话中的其他地方可以访问这个属性,从而实现会话级的数据共享
        session.setAttribute("type", "autowired-session02");
        // 返回"main",指示控制器完成处理后跳转到主页面
        return "main";
    }
    
    

    这段Java代码的主要功能如下:

    1. @Autowired 注解自动将Spring容器中的HttpSession实例注入到session变量中。这意味着session变量将会持有当前用户的HTTP会话对象。
    2. @RequestMapping("/session02") 注解定义了这个方法将处理所有针对"/session02" URL路径的HTTP GET请求。
    3. session02()方法内部:
      • 调用session.setAttribute("type", "autowired-session02");,将键为"type"、值为"autowired-session02"的数据存储在当前用户的HTTP会话中。这使得数据可以在多个请求之间保持有效,直到会话过期或被显式清除。
    4. 最后,方法返回字符串"main"。在Spring MVC框架中,这通常意味着控制器将请求转发给名为"main"的视图(如JSP页面或其他模板文件),以完成对客户端的响应。
3.6.2. 通过 Spring MVC 注解读写 session
  1. 用在上面

    @Controller
    // 从model中获取指定的属性写入session中
    // 底层会从model中去找一个叫做type的属性
    // 找到了会将type设置一份到session中
    // 这种方式是依赖model的
    // 当前控制器下所有的处理方法 都会将model指定的属性写入session
    @SessionAttributes(value = {"type"})
    public class DTVController {
    }
    

    @SessionAttributes 是Spring MVC中的一个注解,用于配置哪些模型属性应该存储在HTTP会话(session)中。这样可以在多个请求之间保持这些属性的数据。

    • 用途:当需要跨多个请求共享数据时,可以使用@SessionAttributes来指定哪些模型属性应该保存在会话中。
    • 使用方式:
      1. 在控制器类上添加@SessionAttributes注解,并指定要存储在会话中的属性名称。
      2. 当添加这些属性到模型时,它们会被自动保存到会话中。
  2. 用在参数上面

        /**
         * 处理/session03请求,可选地接收并处理会话类型
         * 此方法主要用于演示如何在Spring MVC中使用@SessionAttribute注解来访问会话属性
         * 如果会话中存在"type"属性,则将其值打印到控制台;如果不存在,则不会产生错误,仅打印null
         *
         * @param type  从会话中获取的类型信息,如果会话中没有此属性,值为null
         * @param model 模型对象,用于在控制器和视图之间传递数据,此处未使用
         * @return 页面跳转路径,固定返回"main"页面
         */
        @RequestMapping("/session03")
        public String session03(@SessionAttribute(value = "type", required = false) String type, Model model) {
            System.out.println(type);
            // 将类型信息添加到模型中,以便在页面上显示,但出于演示目的,此行被注释掉
            // model.addAttribute("type", type); 相当于隐式往 model 也写入了 type
            // 返回页面跳转路径,跳转到"main"页面
            return "main";
        }
    

    此Java函数是一个Web控制器方法,用于处理HTTP请求。具体功能如下:

    1. 使用@RequestMapping注解指定处理的URL为/session03,即当客户端访问这个URL时,该方法会被调用。
    2. 函数参数type通过@SessionAttribute注解从当前用户的会话(session)中获取名为"type"的属性值。如果会话中没有这个属性,由于required = false,不会抛出异常,而是type变量将为null
    3. 函数内部通过System.out.println(type)语句将获取到的type值打印到控制台。
    4. 注释掉的model.addAttribute("type", type);这行代码原本的作用是将type值添加到模型(model)中,以便在前端页面上展示。但此处被注释掉了,所以不会执行。
    5. 函数最后返回字符串"main",这通常表示将跳转到名为main的视图页面。

4. 使用 @ModelAttribute 获取请求中的数据

  • @ModelAttribute 是 Spring MVC 中的一个重要注解,用于处理模型属性。它可以用于控制器方法的参数上,也可以用于方法的返回值上。下面是 @ModelAttribute 的详细解释:
4.1. 作用于方法参数

@ModelAttribute 用在控制器方法的参数上时,它的主要作用是:

  • 绑定请求参数到方法参数:从 HTTP 请求中获取数据,并将其绑定到控制器方法的参数上。
  • 自动填充对象:如果参数是一个对象类型,Spring 会尝试从请求中提取数据并自动填充该对象的属性。
  • 模型属性名:可以指定一个名称,该名称将作为模型属性的键,以便在视图层访问这些属性。

示例

  • 假设我们有一个简单的用户对象 User和一个控制器方法,如下所示:
public class User {
    private String name;
    private int age;

    // 构造器、getter 和 setter 省略
}

@Controller
public class UserController {

    /**
     * 处理用户提交的表单数据
     *
     * @param user 通过 @ModelAttribute 绑定的 User 对象,Spring 会自动从请求中提取数据并填充此对象
     * @return 返回视图名称,这里假设是 "userProfile"
     */
    @RequestMapping(value = "/submit", method = RequestMethod.POST)
    public String submit(@ModelAttribute("user") User user) {
        // 这里可以处理 user 对象,例如保存到数据库
        return "userProfile"; // 假设这是视图的名称
    }
}

在这个例子中:

  • @ModelAttribute("user") User user 表示从 HTTP 请求中获取数据,并将其绑定到 User 对象上。这里的 "user" 是模型属性的名称,它将在视图层可用。
  • submit 方法接收这个 User 对象作为参数,并可以进一步处理。
4.2. 作用于方法返回值

@ModelAttribute 用在控制器方法的返回值上时,它的主要作用是:

  • 添加模型属性:将方法的返回值作为模型属性添加到模型中,以便在视图层访问这些属性。

示例

  • 假设我们有一个简单的用户对象 User 和一个控制器方法,如下所示:
public class User {
    private String name;
    private int age;

    // 构造器、getter 和 setter 省略
}

@Controller
public class UserController {

    /**
     * 获取用户信息
     *
     * @return 通过 @ModelAttribute 添加到模型中的 User 对象
     */
    @ModelAttribute("user")
    public User getUser() {
        User user = new User();
        user.setName("John Doe");
        user.setAge(30);
        return user;
    }

    /**
     * 显示用户信息
     *
     * @param user 通过 @ModelAttribute 绑定的 User 对象
     * @return 返回视图名称,这里假设是 "userInfo"
     */
    @RequestMapping(value = "/info", method = RequestMethod.GET)
    public String info(@ModelAttribute("user") User user) {
        // 这里可以处理 user 对象
        return "userInfo"; // 假设这是视图的名称
    }
}

在这个例子中:

  • @ModelAttribute("user") 表示将 getUser() 方法的返回值作为模型属性 "user" 添加到模型中。
  • info 方法接收这个 User 对象作为参数,并可以进一步处理。

5. 获取 servlet API 的线程安全问题

5.1. 通过参数绑定的方式
    /**
     * 处理与会话相关的请求,演示如何在控制器中使用HttpSession对象设置会话属性
     *
     * @param session HttpSession对象,用于管理会话状态
     * @return 主页的视图名称,这里假设为"main"
     */
    @RequestMapping("/session01")
    public String session01(HttpSession session) {
        // 设置会话属性"type",用于标识会话的类型
        session.setAttribute("type", "servletApi-session01");
        // 指定返回的视图名称,控制器处理结果将跳转到主页面
        return "main";
    }

在这个例子中,通过参数绑定的方式传递HttpSession对象到控制器方法中,这种方式是线程安全的。这是因为Spring MVC框架为每个请求创建了一个新的控制器方法调用实例,并且每个请求都拥有自己的HttpSession对象引用。这意味着即使多个请求并发执行,每个请求都会有自己的HttpSession对象实例,不会相互干扰。

5.2. 通过 @AutoWired 自动注入的方式
    // 使用@Autowired注解自动注入HttpSession依赖,便于管理会话信息
    @Autowired
    private HttpSession session;

    /**
     * 处理/session02请求,用于演示如何在会话中设置属性
     * 通过在HttpSession中设置属性,可以在整个会话范围内使用这些属性
     *
     * @return 主页面的逻辑视图名称,用于视图解析器解析实际的视图资源
     */
    @RequestMapping("/session02")
    public String session02() {
        // 将"type"属性设置到当前会话中,值为"autowired-session02"
        // 这种方式使得在同一个会话中的其他地方可以访问这个属性,从而实现会话级的数据共享
        session.setAttribute("type", "autowired-session02");
        // 返回"main",指示控制器完成处理后跳转到主页面
        return "main";
    }

通过@Autowired自动注入的方式获取HttpServletRequestHttpSession等Servlet API对象是线程安全的。这是因为Spring框架采用了特殊的技术来确保这些对象在多线程环境下的正确使用。

如何实现线程安全

  1. 使用动态代理:
    • 当你使用@Autowired来注入HttpServletRequest时,Spring实际上注入的是一个动态代理对象。
    • 这个代理对象会在每次请求处理时被初始化,并指向当前请求的实际HttpServletRequest对象。
    • 由于每个请求都有一个不同的代理对象,因此即使多个请求并发执行,也不会出现线程安全问题。
  2. WebApplicationContextUtils:
    • Spring提供了WebApplicationContextUtils工具类来帮助管理这些动态代理对象。
    • 当Spring创建控制器实例时,它会为每个实例注入一个代理对象,而不是实际的HttpServletRequest对象。
    • 在每个请求处理过程中,代理对象会被适当地初始化,以指向当前请求的上下文。
5.3. 通过 @ModelAtrribute 的方式
    // 定义一个HttpSession类型的变量,用于存储会话信息
    HttpSession session02;

    /**
     * 通过@ModelAttribute注解的方法,用来设置HttpSession对象
     *
     * @param session02 从请求中获取的HttpSession对象,用于会话管理
     */
    @ModelAttribute
    public void setReq(HttpSession session02) {
        this.session02 = session02;
    }

线程安全性分析

  • 线程安全性:

    • 在这个例子中,成员变量session02是一个实例变量,这意味着它在控制器类的每个实例中都是共享的。
    • 如果多个线程同时访问同一个控制器实例,那么它们将共享同一个session02变量。
    • 因此,如果多个线程尝试同时修改session02,则可能会导致线程安全问题。
  • 解决方法:

    • 要解决这个问题,可以考虑使用ThreadLocal来为每个线程提供一个独立的HttpSession变量副本。
    • 另一种方法是避免在控制器中使用实例变量来存储HttpSession对象,而是直接在控制器方法中通过参数传递HttpSession对象。

6. 使用 forward 实现页面转发

  • 由服务器的页面进行跳转,不需要客户端重新发送请求:

  • 特点如下:

    1. 地址栏的请求不会发生变化,显示的还是第一次请求的地址
    2. 请求的次数,有且仅有一次请求
    3. 请求域中的数据不会丢失
    4. 根目录:localhost:8080/项目地址/,包含了项目的访问地址

    在这里插入图片描述

    /**
     * forward:转发  ,它不会经过视图解析器的解析,适用于当访问的视图不在我们指定的前缀下
     *
     * 处理请求转发到指定页面
     * <p>
     * 此方法通过@RequestMapping注解映射到URL路径"/forward",其作用是将当前请求转发到"/index"路径
     * 使用转发而不是重定向,可以保持原有的请求上下文,适用于需要在不同控制器之间进行请求转发的场景
     *
     * @return String 表示转发到的路径,此处为"/index.jsp"
     */
    @RequestMapping("/forward")
    public String forward() {
        return "forward:/index.jsp";
    }

7. 使用 redirect 实现重定向

  • 在浏览器端进行页面的跳转,需要发送两次请求(第一次是人为的,第二次是自动的

  • 特点如下:

    1. 地址栏的地址发生变化,显示最新发送请求的地址
    2. 请求次数:2次
    3. 请求域中的数据会丢失,因为是不同的请求
    4. 根目录:localhost:8080/ 不包含项目的名称

    在这里插入图片描述

/**
 * redirect:它不会经过视图解析器的解析,需要写上完整的逻辑视图名称
 *  重定向不能将地址重定向到WEB-INF中
 *  springmvc转发和重定向的“/” 都定位到项目名这一级
 *
 * 处理请求映射为重定向到主页
 * 
 * 此方法用于实现页面跳转,将用户重定向到应用的主页
 * 使用场景包括但不限于用户登录后的初始页面跳转
 */
@RequestMapping("/redirect")
public String redirect() {
    return "redirect:/index.jsp";
}
区别转发重定向
根目录 / (在Spring MVC中无论转发还是重定向都会包含项目名)包含项目访问地址不包含项目访问地址
地址栏不会发生变化会发生变化
哪里跳转服务端进行的跳转浏览器进行的跳转
request 域中数据不会丢失会丢失
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值