文档章节

《Spring实战》读书笔记--SpringMVC之forward与redirect

javaer
 javaer
发布于 2018/01/12 16:33
字数 1342
阅读 115
收藏 0

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

1.forward与redirect介绍

1.1 redirect
重定向,服务器收到请求后发送一个状态码给客户端,让客户端再重新请求,并且第一次请求中Request里的数据消失。所以redirect相当于客户端向服务器发出两次请求,第一次请求的数据不会转发给第二次请求,URL地址会变化两次。

1.2 forward
转发(前往),服务器内部的重定向,在Servlet中通过RequestDispatcher转发给另一个程序处理请求,请求的数据依然在。所以forward相当于客户端向服务器发送一次请求,服务器处理两次,请求数据不会消失且URL地址只变化一次。

2.Servlet与SpringMVC中的forward与redirect

2.1 Servlet中的forward与redirect
Servlet中的HttpServletResponse类中有sendRedirect(String location)方法直接重定向到URL为location的地址。
应用:

public class DeleteOneServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private ContentService contentService = new ContentService();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        // 从页面中获取数据
        String id = req.getParameter("id");
        // 调用Servive执行业务逻辑
        contentService.deleteOne(id);
        // 重定向
        resp.sendRedirect("/list.action");
    }

}

Servlet可以通过HttpServletRequest类的getRequestDispatcher(String path)获得RequestDispatcher对象,该通过该对象的forward(ServletRequest request, ServletResponse response)方法转发请求与相应给任何资源(如Servlet、HTML file、JSP file)。
RequestDispatcher类的API

package javax.servlet;

public interface RequestDispatcher{

    public void forward(ServletRequest request, ServletResponse response) 
        throws ServletException, IOException;
    public void include(ServletRequest request, ServletResponse response) 
        throws ServletException, IOException;
}
API上的介绍:
Defines an object that receives requests from the client and sends them to any resource (such as a servlet, HTML file, or JSP file) on the server. 
The servlet container creates the RequestDispatcher object, which is used as a wrapper around a server resource located at a particular path or given by a particular name.

This interface is intended to wrap servlets, but a servlet container can create RequestDispatcher objects to wrap any type of resource.

应用:

@WebServlet(name = "query", urlPatterns = "/query.action")
public class QueryServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;
    private ContentService contentService = new ContentService();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
        throws ServletException, IOException {
        // 从页面获取参数
        String command = req.getParameter("command");
        String description = req.getParameter("description");
        // 调用Service处理业务逻辑
        List<Message> messages = contentService.query(command, description);
        // 向页面传递值
        req.setAttribute("messages", messages);
        req.setAttribute("command", command);
        req.setAttribute("description", description);
        // 转发到视图中
        req.getRequestDispatcher("/WEB-INF/jsp/back/list.jsp").forward(req, resp);
    }
}

2.2 SpringMVC中的Servlet
SpringMVC是基于Servlet的Web MVC框架,所以forwardredirect的处理结果一样,方式更为简单。SpringMVC中的InternalResourceViewResolver视图解析器会识别redirectforward关键字,然后处理。
应用:

@Controller
@RequestMapping(value="/springMVC")
public class UserController {

    @RequestMapping(value="/login")
    public String login() {
        return "login";
    }
    
    @RequestMapping(value="/upload", method=RequestMethod.POST)
    public String fileUpload(@RequestPart(value="file") MultipartFile multipartFile) throws Exception{
        String path = "E:/java/fileupload/" + multipartFile.getOriginalFilename();
        multipartFile.transferTo(new File(path));
        // 重定向
        return "redirect:/springMVC/index";
        // 转发
        return "foward:/springMVC/index";
    }    
}

3. SpringMVC重定向传递数据

从上面我们可以看出redirect不能传递数据,但我们可以使用其它方案传递数据。主要有:

  • 通过URL模板以路径变量或查询参数形式传递数据
  • 通过flash属性传递数据

3.1 通过URL模板进行重定向
方式如下:

@Controller
@RequestMapping(value="/springMVC")
public class UserController {
    @RequestMapping(value="/index/{name}",method=RequestMethod.GET)
    public String index(@PathVariable(value="name") String name,
            @RequestParam(value="id") int id) {
        System.out.println(name + id);
        return "login";
    }
    
    @RequestMapping(value="/data/{id}",method=RequestMethod.GET)
    public String data(@PathVariable(value="id") int id, Model model) {
        model.addAttribute("id", id);
        model.addAttribute("name", "Tom");
        return "redirect:/springMVC/index/{name}";
    }
}

使用模板方式时,若使用了占位符则变为路径参数,否则变为请求变量。所以以上重定向URL路径变为"/springMVC/index/Tom?id=5"。
该方法简单有效,但传递数据值简单,若数据复杂则可使用下面的方式传递数据

3.2 使用flash属性
Spring提供了RedirectAttributes设置flash属性的方法重定向传递参数。
原理:在重定向执行之前,所有的flash属性会复制到session中。在重定向后,放在Session中的flash属性会被取出,放到Model中。注:RedirectAttributes类继承自Model类。
方式如下:

@Controller
@RequestMapping(value="/springMVC")
public class UserController {
    @RequestMapping("/doLogin")
    public String doLogin(RedirectAttributes attr) {
        Users u1=new Users();
        u1.setName("zhangsan");
        u1.setPassWord("123");
        attr.addFlashAttribute("u1", u1);
        return "redirect:toMain4";
    }
    
    @RequestMapping("toMain1")
    public String toMain(@ModelAttribute("u1") Users u) {
        System.out.println("1---"+u.getName());
        return "success";
    }
    
    @RequestMapping("toMain2")
    public String toMain2(HttpServletRequest request) {
        Users u = (Users) RequestContextUtils.getInputFlashMap(request).get("u1");
        System.out.println("2---"+u.getName());
        return "success";
    }
    
    @RequestMapping("toMain3")
    public String toMain3(Model model) {
        Users u = (Users)model.asMap().get("u1");
        System.out.println("3---"+u.getName());
        return "success";
    }
    
    @RequestMapping("toMain4")
    public String toMain4(ModelMap model) {
        Users u = (Users)model.get("u1");
        System.out.println("4---"+u.getName());
        return "success";
    }
}

总结:

A:Redirect等于客户端向服务器发出两次request,同时也接受到两次response,Forward却只是一次request一次response,相比之下,Forward性能更高。

B:Forward能够存储request Scope的Attribute而Redirect却不行。
C:Forward的同时URL并不会变。
D:Forward需要在Servlet中需要通过一个Dispatcher来实现。
E :Redirect能够防止某些情况下客户端Refresh造成的一些未知后果(例如连续删除)

1、使用  RedirectAttributes 的 addAttribute()方法设置参数,则参数将直接拼接在转发url后面,然后可以在通过request.getParameter("userName")) 和 直接通过spring mvc配置参数映射接收到参数
2、使用 RedirectAttributes  的 addFlashAttribute()方法设置参数,则参数不会出现在转发url中,可以通过@ModelAttribute、RequestContextUtils、Model、modelMap 取出参数

本文转载自:https://www.cnblogs.com/maying3010/p/6682582.html

javaer

javaer

粉丝 30
博文 76
码字总数 7994
作品 0
太原
程序员
私信 提问
Spring实战读书笔记(1)

Spring的根本使命是? 简化Java开发 为了降低Java开发的复杂性,Spring采取了哪4种关键策略? 1、基于POJO的轻量级和最小侵入性编程 2、通过依赖注入和面向接口实现松耦合 3、基于切面和惯例...

祥林会跟你远走高飞
2014/12/30
475
0
我的RabbitMQ的学习成果

背景 在研发分布式事务的最终一致性事务模式时,使用了RabbitMQ。 在这之前也接触过RabbitMQ,但没有特别深入的去了解它的特性与原理。这次决定系统的学习一次,所以业余时间阅读大神们的书籍...

XuePeng77
2019/04/15
337
0
Spring MVC Flash Attribute 的讲解与使用示例

Spring MVC 3.1版本加了一个很有用的特性,Flash属性,它能解决一个长久以来缺少解决的问题,一个POST/Redirect/GET模式问题。 正常的MVC Web应用程序在每次提交都会POST数据到服务器。一个正...

0595
2014/04/09
21.3K
24
Dubbo源码-Dubbo是如何随心所欲自定义XML标签的

叨叨 今天考虑了很久要不要写这篇文章。 距离《Dubbo源码》系列的开篇到现在已经快两个月时间了。当时是想着工作上的RPC框架使用存在一些让人头疼的问题,就来看看Dubbo给出了一套什么样的解...

Jackie_Zheng
2018/05/20
0
0
Spring Boot Admin 2.0开箱体验

概述 在我之前的 《Spring Boot应用监控实战》 一文中,讲述了如何利用 Spring Boot Admin 1.5.X 版本来可视化地监控 Spring Boot 应用。说时迟,那时快,现在 Spring Boot Admin 都更新到 ...

CodeSheep
2018/07/18
642
0

没有更多内容

加载失败,请刷新页面

加载更多

dynamic-connectivity 动态连通性问题之 quick-union 算法

quick-union 的思想是:若对象 p 的 root_id 和对象 q 的 root_id 相等,则认为 p 和 q 连通。 若要将对象 p 和对象 q 连通(已知两对象未连通),则将 p 的 root_id 的值设为 q 的 root_id ...

Phpythoner_Alei
今天
33
0
OSChina 周六乱弹 —— 实在选不出来就唱国歌

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @花间小酌 :#今日歌曲推荐# 分享阿冗的单曲《你的答案》。--祝大家在2020年都找到自己答案。 《你的答案》- 阿冗 手机党少年们想听歌,请使劲...

小小编辑
今天
10
0
Maven打包可执行Jar包的方法

在使用Java开发中,会使用到将工程打包成可执行的jar包的情况,那么在maven中怎么将项目中的依赖包都添加到jar中呢。在pom.xml中添加一下插件: <build><plugins><plugin><ar...

CapJes
今天
10
0
使用vue 开发地图类系统(openlayers.js)的注意。

使用vue 开发地图类系统的注意。 1、使用地图应该创建的对象 少使用 vue 的data 和计算属性(comments)存数据或是vuex。 为什么要要注意这个问题呢? 答:这个就要了解到vue的实现原理 。原理...

DY-Tao
昨天
7
0
web移动端学习:高德地图demo(一)

在高德地图开发中申请开发者资格,然后在控制台中新建应用,获得KEY; 新建模板HTML文件; <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>地图demo</title><scri......

dxiya
昨天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部