1. 程式人生 > >HTTP狀態碼(重定向/error 301/302)

HTTP狀態碼(重定向/error 301/302)

1. HTTP狀態碼

當瀏覽器訪問一個網頁時,瀏覽者的瀏覽器會向網頁所在伺服器發出請求。當瀏覽器接受並顯示網頁前,此網頁所在的伺服器會返回一個包含HTTP狀態碼的英文為HTTP status Code。

  1. 200 - 請求成功
  2. 301 - 資源(網頁等)被永久轉移到其它URL
  3. 404 - 請求的資源(網頁等)不存在
  4. 500 - 內部伺服器錯誤

2. HTTP狀態碼分類

HTTP狀態碼由三個十進位制數字組成,第一個十進位制數字定義了狀態碼的型別,後兩個數字沒有分類的作用。HTTP狀態碼共分為5種類型:
這裡寫圖片描述
HTTP狀態碼列表:
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述

3.Java 中Redirect和Forward

java中連線跳轉的方式有兩種:Redirect和Forward

  • (重定向)Redirect
    重定向是把request 直接轉到其他元件處理,response.sendRedirect()後,response已經提交,不能再對response操作。
response.sendRedirect("redirect");

用fiddler檢視網頁獲取資訊:

http://localhost:7080/test/testd

GET /test/testd HTTP/1.1
Host: localhost:7080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive Upgrade-Insecure-Requests: 1 HTTP/1.1 302 Location: redirect Content-Length: 0 Date: Mon, 26 Jun 2017 09:15:23 GMT

瀏覽器手動302後,對 redirect發起請求,一個重定向,瀏覽器發了2次請求。
預設的response.sendRedirect返回的是302,即使我在上面設定status code最後也返回302。(Tomcat 8.5中測試)
如果想返回301,只能手動設定了:

response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
        String newLocn = request.getServletContext().getContextPath()+"/redirect";
        response.setHeader("Location",newLocn);

4.301/302區別

  1、什麼是301轉向?什麼是301重定向?

  301轉向(或叫301重定向,301跳轉)是當用戶或搜尋引擎向網站伺服器發出瀏覽請求時,伺服器返回的HTTP資料流中頭資訊(header)中的狀態碼的一種,表示本網頁永久性轉移到另一個地址。

  2、什麼是302重定向?

  302重定向又稱之為302代表暫時性轉移(Temporarily Moved ),英文名稱:302 redirect。 也被認為是暫時重定向(temporary redirect),一條對網站瀏覽器的指令來顯示瀏覽器被要求顯示的不同的URL,當一個網頁經歷過短期的URL的變化時使用。一個暫時重定向是一種服 務器端的重定向,能夠被搜尋引擎蜘蛛正確地處理。

  3、301重定向與302重定向的區別

  302重定向是暫時的重定向,搜尋引擎會抓取新的內容而保留舊的網址。因為伺服器返回302程式碼,搜尋引擎認為新的網址只是暫時的。

  301重定向是永久的重定向,搜尋引擎在抓取新內容的同時也將舊的網址替換為重定向之後的網址。

  4、為什麼302 重定向和網址劫持有關聯

  從網址A 做一個302 重定向到網址B 時,主機伺服器的隱含意思是網址A 隨時有可能改主意,重新顯示本身的內容或轉向其他的地方。大部分的搜尋引擎在大部分情況下,當收到302 重定向時,一般只要去抓取目標網址就可以了,也就是說網址B。如果搜尋引擎在遇到302 轉向時,百分之百的都抓取目標網址B 的話,就不用擔心網址URL 劫持了。問題就在於,有的時候搜尋引擎,尤其是Google,並不能總是抓取目標網址。

  比如說,有的時候A 網址很短,但是它做了一個302 重定向到B 網址,而B 網址是一個很長的亂七八糟的URL 網址,甚至還有可能包含一些問號之類的引數。很自然的,A 網址更加使用者友好,而B 網址既難看,又不使用者友好。這時Google 很有可能會仍然顯示網址A。由於搜尋引擎排名演算法只是程式而不是人,在遇到302 重定向的時候,並不能像人一樣的去準確判定哪一個網址更適當,這就造成了網址URL 劫持的可能性。也就是說,一個不道德的人在他自己的網址A 做一個302 重定向到你的網址B,出於某種原因, Google 搜尋結果所顯示的仍然是網址A,但是所用的網頁內容卻是你的網址B 上的內容,這種情況就叫做網址URL 劫持。你辛辛苦苦所寫的內容就這樣被別人偷走了。

5.異常處理

1.異常處理介紹
  Spring在web專案中,如果在請求處理時出現異常,那輸出會是Servlet響應。這時異常需要以某種方式轉換為響應。
  Spring將異常轉換為響應的方式:
    a.特定的Spring異常將自動對映為指定的HTTP狀態碼;
    b.異常上新增@ResponseStatus註解,從而將其對映為某一個HTTP狀態碼;
    c.方法上新增@ExceptionHandler註解,使其處理異常。
2.異常處理程式碼

1     @RequestMapping("getPathVariable/{id}")
2     public String getPathVariable(
3             @PathVariable("id") String id){
4         if("error".equals(id)){
5             throw new SpittleException();
6         }
7         return "index";
8     }
 1 package com.taozhiye.controller;
 2 
 3 import org.springframework.http.HttpStatus;
 4 import org.springframework.web.bind.annotation.ResponseStatus;
 5 
 6 @ResponseStatus(
 7         // 404
 8             value = HttpStatus.NOT_FOUND,
 9             reason = "Spittle not found"
10         )
11 public class SpittleException extends RuntimeException {
12 
13 }

  正常情況下,當id為error時,會報錯,這時是500錯誤,我們可以通過@ResponseStatus註解,對映到404狀態碼上,進行簡單的異常處理。
  
  第二種方法是報相應的異常,直接跳轉到錯誤頁面。

 1 package com.taozhiye.controller;
 2 
 3 import org.springframework.web.bind.annotation.ControllerAdvice;
 4 import org.springframework.web.bind.annotation.ExceptionHandler;
 5 
 6 
 7 
 8 @ControllerAdvice
 9 public class AppExcepitonHandler {
10     
11     @ExceptionHandler(Exception.class)
12     public String deal(){
13         System.out.println("出現異常");
14         return "index";
15     }
16 }

3.重定向傳值

1     @RequestMapping("getPathVariable/{id}")
 2     public String getPathVariable(
 3             @PathVariable("id") String id,
 4             Model model,
 5             RedirectAttributes model2){
 6         if("error".equals(id)){
 7             throw new SpittleException();
 8         }else if("findAll".equals(id)){
 9             /**
10              * 重定向傳引數:
11              *         相當於把引數寫到session中,
12              *             如果重定向到controller的時候,用@ModelAttribute接收
13              *             如果重定向到頁面,可以直接接收
14              */
15             model2.addFlashAttribute("flash", "flash");
16             /**
17              * 通過url模板進行重定向
18              */
19             return "redirect:/{id}";
20         }else if("index".equals(id)){
21 //            model.addAttribute("id", id);
22             /**
23              * 轉發不可以使用模板
24              */
25 //            return "/{id}";
26             model2.addFlashAttribute("flash", "flash");
27             /**
28              * 通過url模板進行重定向
29              */
30             return "index";
31         }else{
32             return "ajax1";
33         }
34     }
@RequestMapping("/findAll")
    @ResponseBody
    public List<User> findAll(@ModelAttribute("flash") String flash){
        System.out.println("flash:"+flash);
        return userService.findUserAll();
    }

@RequestMapping("/index")
    @ResponseBody
    public List<User> index(Map<String, Object> map,@ModelAttribute("flash")String flash){
        System.out.println("flash:"+flash);
        return userService.findUserAll();
    }

重定向傳引數:
    相當於把引數寫到session中,
       如果重定向到controller的時候,用@ModelAttribute接收
       如果重定向到頁面,可以直接接收