重定向 Redirect

  • 即服务器收到一个url后,再返回给浏览器一个指令,告诉浏览器地址已经变了,麻烦使用新的URL再重新发送新请求。
    • 因为是新的请求,所以重定向2个请求自然不共享session
  • 重定向有两种
    • 一种是302响应,称为临时重定向。302
    • 一种是301响应,称为永久重定向。如果是301重定向,则第一次请求后会把重定向关联结果缓存,下次请求直接访问重定向的url

下面规则对于重定向同理

  • 返回重定向的接口必须采用get请求。如果采用post,那即便sendredirect,也是返回html源码而不会主动跳转
    • 前端跳转等方法都是get请求,如href,a标签,而跳转的url最好是完整的,带有协议头(http)
    • 同理,返回重定向的接口也是在做第二次get请求,所以被重定向的接口必须是get,否则请求方式错误
  • 返回重定向链接的控制器如果使用redirect:字符串返回,不能使回json,得返回普通字符串(即不使用rest)或者modelandview或者不返回,但是设置响应体的重定向。同理,其他返回jsp,返回页面路径的都不能使用@Rest
    • 使用href进行get请求,即便请求的是接口但是控制台中还是会显示在文档请求那一类,地址栏也会变化为接口路径,页面跳到一个新页面,内容为方法返回
    • 使用ajax才会显示为xhr请求,地址栏不变化,如果返回重定向就变为返回源码字符串
      • get-ajax参数写url或者写data都可以
  • 重定向不能使用ajax进行请求,得采用普通的链接,跳转方法等,因为ajax是局部刷新,不会主动跳转
    • 可以前端返回url链接字符串,ajax的success中跳转返回链接(我的水平只能写出这样的解决)
  • 另外button点击提交和div,a等标签跳转可能不一样

  • 浏览器在发送第一个请求后会得到30?响应和重定向的url,会再次发送重定向url的请求。

    • 控制台可以看到发送了2次请求
    • 同时地址栏url会更新为重定向的url ```java @WebServlet(urlPatterns = “/hi”) public class RedirectServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 构造302重定向的路径: String name = req.getParameter(“name”); String redirectToUrl = “/hello” + (name == null ? “” : “?name=” + name); // 发送重定向响应: resp.sendRedirect(redirectToUrl);

      //如果要构造301重定向 resp.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); // 301 resp.setHeader(“Location”, “/hello”);

  1. //如果非@RestCONtroller ,还可以这样:return "redirect:...",试图解析器会返回页面,浏览器识别到redirect:前缀就会自动跳转
  2. }

}

<a name="uWFEE"></a>
# 转发 Forward

- 转发得走return或者model,转发后就不归这个控制器管了,而调用其他控制器方法仍旧在这个控制器里
- 转发又叫内部转发,一个servlet可以将自己的请求转给别的servlet处理。**即可以共享一个request**
   - 对于浏览器来说,只请求了一次,浏览器不知道内部转发过,所以2个servlet仍旧共享同一个session
```java
@WebServlet(urlPatterns = "/morning")
//morning的servlet将请求转给hello的servlet
public class ForwardServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getRequestDispatcher("/hello").forward(req, resp);
    }

    也可以这样: return "forword:/ceng/hello";
}

总结

  • 重定向是在服务器生成,返回给前台操作。请求2次,不共享
  • 转发是服务器内部生成,内部操作。请求一次,共享
  • 转发比重定向的效率更高