博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《Spring实战》读书笔记--SpringMVC之forward与redirect
阅读量:6887 次
发布时间:2019-06-27

本文共 6241 字,大约阅读时间需要 20 分钟。

hot3.png

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
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://my.oschina.net/liuh1988/blog/1606207

你可能感兴趣的文章
redhat7配置阿里云的yum源并安装httpd服务
查看>>
二叉树的存储结构
查看>>
贝叶斯分类算法实例 --根据姓名推测男女
查看>>
Swarm 如何存储数据?- 每天5分钟玩转 Docker 容器技术(103)
查看>>
关于考证—给大学生考证指明方向
查看>>
Spring用到properties的几种情况与相应配置
查看>>
我学安卓——ImageSwitcher
查看>>
范式:命令式与声明式编程
查看>>
esxtop命令磁盘监控工具详解
查看>>
6月份全球域名商(国际域名)解析量排行榜TOP20
查看>>
11月“.中国”域名总量增至25.8万:2015年首次上涨
查看>>
android 自定义view,画出来的直线发虚。
查看>>
高并发实时直播弹幕研发实践
查看>>
管理DAG
查看>>
AliOS Things SMP系统及其在esp32上实现示例
查看>>
删除mysql的root用户恢复方法
查看>>
分布式下Session一致性架构举例
查看>>
PHP全角半角转换函数
查看>>
35. 传输对象模式
查看>>
Flink、Storm与Spark Stream的区别(未)
查看>>