浅谈前后端不分离的项目中直接返回模板页面、forward请求转发、redirect重定向的区别,以及参数怎么传递

本文详细探讨了Web开发中处理请求的三种方式:直接返回模板页面、使用请求转发和使用重定向。重点讨论了它们在浏览器URL、错误信息展示以及请求方式一致性等方面的区别。重定向能够在保持请求方式一致性的同时传递错误信息,但刷新后信息会消失。请求转发则不会改变URL,但可能导致请求方式不匹配。
摘要由CSDN通过智能技术生成

总结

  1. 直接返回模板页面请求转发这两种方式都不会改变浏览器地址栏中的url,仅仅是改变浏览器页面展示的内容,但是重定向会改变浏览器地址栏中的url
  2. 请求转发和重定向的发起方是不一样的,请求转发是服务器代替浏览器发起请求,这种请求只能发往当前微服务;而重定向是服务器命令浏览器直接向服务器发送请求,所以这是浏览器发送的请求,那么这种请求可以发往任意服务器;根据以上分析可知,在浏览器中输入地址然后回车,请求转发方式只需要浏览器发送一次请求,而重定向方式需要浏览器发送两次请求,我们所说的请求转发和重定向属于仅进行一次的情况;
  3. 请求转发和重定向想要在模板页面中展示数据的方式是不一样的,请求转发的话使用Model将数据放在请求域中,那么我们就可以模板页面中取出请求域中的数据进行展示了;而重定向需要使用RedirectAttributes来将数据放在请求域中,注意使用的不是Model,我们在重定向中不用Model,如果我们注册信息输错了,那页面中是会显示错误信息的,但是当我们刷新页面的时候,那就是直接向http://auth.gulimall.com/reg.html发送请求,这就会导致请求域中的错误信息对象消失,毕竟这个错误信息对象是我们当时发送注册请求http://cart.gulimall.com/register才得到的,而我们直接发送http://auth.gulimall.com/reg.html,那请求域中肯定不会有错误信息对象了,不过你可以通过参数传递来完成错误信息对象的传递,不过本次就不采用了,错误信息只要展示一次就好,即使用户刷新页面之后错误信息不见了,它也不会怀疑什么;另外重定向中可以使用RedirectAttributesaddFlashAttribute()模拟session往请求域中放数据,也可以使用RedirectAttributesaddAttribute()将里面的请求参数放在重定向地址后面,例如以下代码就相当于让浏览器发送http://cart.gulimall.com/success.html?skuId=XXX请求,代码如下:
@GetMapping("/addToCart")
public String addToCart(@RequestParam Long skuId, @RequestParam Integer num, RedirectAttributes attributes) {
    cartService.addToCart(skuId, num);
    attributes.addAttribute("skuId", skuId);
    // 避免用户多次添加商品,所以使用重定向的方法来改变浏览器地址栏的url
    return "redirect:http://cart.gulimall.com/success.html";
}
  1. 代码写法注意:return中的forward:redirect:中的冒号后面没有空格,直接就是url地址,如果多1个空格的话,那么返回的地址就是错误的

以下三种详细解释的情景

本次注册网页是reg.html,然后使用form表单提交注册请求(url:http://auth.gulimall.com/register),然后登录网页是login.html

如果注册成功,将会在浏览器上展示login.html登录页面;

如果注册失败,将回到reg.html注册页面,并且展示错误信息;

1、直接返回模板页面

比如我使用的是thymeleaf模板,代码如下:

@Controller
public class RegisterController {

	@PostMapping("/register")
    public String register(UserRegisterVo userRegisterVo, Model model) {
    	……………………………………
        if(注册成功){
        	// 注册成功,会到登录页
        	return "login";
        } else {
        	// 注册失败,会到注册页
			model.addAttribute("errorData", errorData);
			return "reg";
		}
    }
}      

首先说一下浏览器地址栏url问题,无论注册成功还是失败,浏览器地址栏的url都是http://auth.gulimall.com/register,所以这种方式不会改变浏览器地址栏的url,只不过浏览器网页中展示页面内容是reg.htmlh或者login.html,因此这就直接pass了这种做法,毕竟谁也不想注册成功之后刷新网页就再次发起注册请求了

然后说一下错误信息展示问题,使用这种做法可以正确显示错误信息,Model是可以使用的

2、使用forward请求转发

比如我使用的是thymeleaf模板,代码如下:

// 可以使用Model进行数据传输
@Controller
public class RegisterController {

	@PostMapping("/register")
    public String register(UserRegisterVo userRegisterVo, Model model) {
    	……………………………………
        if(注册成功){
        	// 注册成功,会到登录页
        	return "forward:http://auth.gulimall.com/login.html";
        } else {
        	// 注册失败,会到注册页
			model.addAttribute("errorData", errorData);
			return "forward:http://auth.gulimall.com/reg.html";
		}
    }
}      

对于/reg.html/login.html请求我使用的是视图映射方式来接受请求并返回结果,具体如下:

@Configuration
public class GulimallWebConfig implements WebMvcConfigurer {

    /**
     * 视图映射
     * @param registry
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        /**
         *     @GetMapping("/login.html")
         *     public String loginPage() {
         *         return "login";
         *     }
         *     下面的这种做法,可以代替上面的空方法,这样配置更简单一点,访问的的时候需要使用GET请求方式
         */
        registry.addViewController("/login.html").setViewName("login");
        registry.addViewController("/reg.html").setViewName("reg");
    }
}

首先说一下浏览器地址栏url问题,无论注册成功还是失败,浏览器地址栏的url都是http://auth.gulimall.com/register,所以这种方式不会改变浏览器地址栏的url,只不过浏览器网页中展示页面内容是reg.htmlh或者login.html,因此这就直接pass了这种做法,毕竟谁也不想注册成功之后刷新网页就再次发起注册请求了;

其次我们请求http://auth.gulimall.com/register的时候使用POST请求方式,而请求/reg.html/login.html页面都需要使用GET请求方式,因此使用请求转发的时候还会沿用之前的请求方法,那就会出现请求方式不对应的错误,所以直接pass了这种做法;

最后说一下错误信息展示问题,使用这种做法可以正确显示错误信息,Model是可以使用的

3、使用redirect重定向

比如我使用的是thymeleaf模板,代码如下:

@Controller
public class RegisterController {

	@PostMapping("/register")
    public String register(UserRegisterVo userRegisterVo, RedirectAttributes attributes) {
    	……………………………………
        if(注册成功){
        	// 注册成功,会到登录页
        	return "redirect:http://auth.gulimall.com/login.html";
        } else {
        	// 注册失败,会到注册页,注意使用的是addFlashAttribute()方法
			attributes.addFlashAttribute("errorData", errorData);
			return "redirect:http://auth.gulimall.com/reg.html";
		}
    }
}      

对于/reg.html/login.html请求我使用的是视图映射方式来接受请求并返回结果,具体如下:

@Configuration
public class GulimallWebConfig implements WebMvcConfigurer {

    /**
     * 视图映射
     * @param registry
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        /**
         *     @GetMapping("/login.html")
         *     public String loginPage() {
         *         return "login";
         *     }
         *     下面的这种做法,可以代替上面的空方法,这样配置更简单一点,访问的的时候需要使用GET请求方式
         */
        registry.addViewController("/login.html").setViewName("login");
        registry.addViewController("/reg.html").setViewName("reg");
    }
}

首先说一下请求方式问题,当我们使用return "redirect:http://auth.gulimall.com/XXX.html"进行重定向的时候依然会采用GET请求,毕竟浏览器地址栏发起的请求只能是GET请求,因此请求方式一致,不存在问题

然后说一下错误信息展示问题,假设注册失败,可以通过RedirectAttributes 把错误信息带过去,但是刷新页面之后错误信息就会消失,毕竟我们刷新页面会导致请求域中的错误信息对象消失,虽然只会展示一次错误信息,那也够了,可以选择使用这种方式

上面代码中我们使用的是attributes.addFlashAttribute("errorData", errorData),也就是使用addFlashAttribute()方法,该方法可以模拟session往请求域中放置数据,然后我们在模板页面中可以像从session中取出数据一样使用;另外还可以使用addAttribute()方法,该方法相当于把参数放在了重定向地址后面,我们在总结中的第3条也使用例子进行了说明

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值