協議是交易雙方共同遵照的一種約定,好比: 租房協議 , 購買協議....css
HTTP協議是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫 HTTP 是基於 TCP/IP 協議的應用層協議。它不涉及數據包(packet)傳輸,主要規定了客戶端和服務器之間的通訊格式,默認使用80端口 。html
最先版本是1991年發佈的0.9版 , 只有一個GET 命令 。 如 GET /index.html 表示返回的是html網頁,別的數據結果不接受。0.9只是一個雛形,並不能表示很豐富的結果。java
1996年5月,HTTP/1.0 版本發佈 , 任何格式的內容均可以傳輸, 這使得互聯網不只能夠傳輸文字,還能傳輸圖像、視頻、二進制文件。這爲互聯網的大發展奠基了基礎 。 其次除了GET 命令,還引入了 POST 和 HEAD 命令。 數據也變得豐富了起來, 除了原本應該要傳輸的數據以外,還包含了頭信息(HTTP header),用來描述一些元數據web
1.0 有一個缺點 ,每一個TCP鏈接只能發送一個請求。發送數據完畢,鏈接就關閉,若是還要請求其餘資源,就必須再新建一個鏈接。spring
1997年1月,HTTP/1.1 版本發佈,只比 1.0 版本晚了半年 。 直到現在的20年後,1.1版本仍然是最流行的版本。 1.1 版的最大變化,就是引入了長鏈接, 服務器端響應完畢後,再也不關閉鏈接json
2009年,谷歌公開了自行研發的 SPDY 協議 , 主要解決 HTTP/1.1 效率不高的問題 , 後面的http2正是繼承了SPDY 。緩存
2015年,HTTP/2 發佈。它不叫 HTTP/2.0,是由於標準委員會不打算再發布子版本了,下一個新版本將是 HTTP/3。服務器
爲了加深你們對http協議認知,咱們接下來可使用一些工具來監視 請求 & 響應的過程。這些工具經常使用的有:
PostMan
,HttpWatch
...app
compile("org.springframework.boot:spring-boot-starter-web:1.5.10.RELEASE")
<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h2>如下表單採用GET方式提交</h2><br> <form action="user_login" method="get"> 用戶名:<input type="text" name="username"/><br> 密 碼:<input type="text" name="password"/><br> <input type="submit" value="登陸"/> </form> </body> </html>
@RestController public class UserController { private static final String TAG = "UserController"; @RequestMapping("user_login") public String login(String username , String password){ System.out.println("執行登陸了~"); String content ="process login with "+username + " : "+password; return content; } }
請求行 : GET /user_login?username=admin&password=123 HTTP/1.1 表示使用Get請求 , 表示請求什麼路徑地址 ,表示使用什麼版本的協議 請求頭 : Host: localhost:8080 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Referer: http://localhost:8080/login.html Connection: keep-alive --------------------------------------------------------------------- Host : 表示主機地址 User-Agent : 表示客戶端的信息 Accept : 聲明客戶端能夠接收什麼類型的數據 Accept-Language : 表示客戶端支持的語言 Accept-Encoding : 表示客戶端支持的壓縮格式 Referer : 表示請求從哪裏過來的 Connection : 表示鏈接狀態。 請求體 get請求沒有請求體。
響應行 HTTP/1.1 200 表示服務器也支持1.1的版本協議 , 對此次請求處理的狀態碼是200 響應頭 Content-Type: text/html;charset=UTF-8 : 表示返回的結果是一份網頁,使用的是UTF-8編碼 Content-Length: 75 : 返回的數據長度 Date: Sun, 21 May 2017 07:09:28 GMT : 響應時間 響應體 process login with admin : 123
請求行: POST /user_login HTTP/1.1 意思和get請求的意思同樣,只不過這裏的地址不再跟數據了。 而且這裏使用post請求 請求頭: 這裏只講沒有見過的就能夠了 Content-Type : 其實就是說明提交上去的數據是什麼類型數據 。 是一個通過url編碼的form表單數據 Content-Length : 提交的數據長度 Cache-Control : 表示再次請求的時候,是否讀緩存。 請求體: username=zhangsan&password=123 是以流的形式寫給服務器的。
響應信息和GET請求的響應請求同樣,此處就不解釋了。jsp
前面演示過了Controller ,也解釋了http協議,接下來爲了讓你們更直觀的感覺
請求
和響應
對象,經過一個簡單例子, 引出request
&response
對象
request 對象實際上是HttpServletRequest 類型, 經過它能夠獲取請求相關的一切信息, 包含請求信息 、 以及請求參數 ,
甚至能夠當成往裏面存儲數據【暫定】
@RequestMapping("/aa") @ResponseBody public String aa(HttpServletRequest request , HttpServletResponse response){ //1. 獲取請求行 String method = request.getMethod(); //請求方式 String uri = request.getRequestURI(); //請求地址 String protocol = request.getProtocol(); //獲取協議 System.out.println(method + " :" + uri + " : "+ protocol); //2. 獲取請求頭信息 Enumeration<String> headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()){ String headerName = headerNames.nextElement(); String headerValue = request.getHeader(headerName); System.out.println(headerName + " = " + headerValue); } //3. 獲取請求參數 String username = request.getParameter("username"); return "請求成功"; }
response的類型爲HttpServletResponse類型 , 在客戶端發出每一個請求時,服務器都會建立一個response對象,目的是爲了對客戶端的請求作出響應。
@RequestMapping("testResponse") public void testResponse(HttpServletResponse response)throws IOException{ //1. 設置響應行 response.setStatus(200); //2. 設置響應頭 response.setHeader("myHeader" , "myHeaderValue"); //3. 設置響應體 response.setContentType("text/html;charset=UTF-8"); response.getWriter().write("你好~!??"); System.out.println("執行了testResponse"); }
跳轉頁面的分類有兩種,一種是請求轉發 、 另外一種是重定向, 兩種跳轉操做各有千秋、下面先給你們演示一個基本的跳轉。
在咱們的工程目錄結構中,有一個叫作
resource
的目錄,該目錄主要是用來存放項目的資源,通常是html
、css
、js
、圖片
... . 默認狀況下,resource下的資源是不能隨便亂放的。由於Spring Boot 在處理資源匹配上,有本身默認的配置。 其中/**
匹配的是/static
,/public
,/resources
,/META-INF/resources
目錄 。 什麼意思呢 ? 後面的幾個目錄都是從resource目錄開始的。 好比咱們有一個html頁面,那麼這個html頁面,默承認以放在以上4個目錄中,注意: 這4個目錄要咱們本身建立。詳情請參看 SpringBoot 文檔 27.1.5
假設在以上4個目錄有一個 login.html , 那麼訪問該網頁的路徑應該是 localhost:8080/login.html 。 上面的/** 表示無論多少重的路徑,都是在這默認的4個路徑下查詢資源。例如: 咱們訪問路徑爲:
localhost:8080/image/aa.jpg
或者localhost:8080/image/jpg/01/aa.jpg
。 從8080 後面就表示要在我們的項目裏面找東西了,那麼如何找呢。 在那默認的4個目錄中找子目錄image
, 而後在子目錄iamge
中查找aa.jpg
,後面的例子是在4個目錄中查找image/jpg/01
這個子目錄,而後在這個子目錄中查找aa.jpg
通常來講,官方給定的默認目錄已經足夠咱們開發用了。咱們若是想要聲明 html文件, 能夠在static下新建目錄html , 若是要表示 圖片,能夠再static下新建image目錄。若是自定義目錄,須要在resource下新建application.properties 文件,在文件中指定路徑。
#表示靜態資源位置 直到public 都是默認的位置。 後面的是咱們本身添加的。 spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,classpath:/html,classpath:/image
<form action="/user_register" method="get"> 用戶名: <input type="text" name="username"/><br> 密 碼: <input type="password" name="password"/><br> 暱 稱: <input type="text" name="nickname"/><br> <input type="submit" value="註冊"/><br> </form>
public class User { private static final String TAG = "User"; private String username; private String password; private String nickname; // getXXX & setXXX ... @Override public String toString() { return username + "#" + password + "#" + nickname; } }
@RestController public class UserController { private static final String TAG = "UserController"; @RequestMapping("/user_register") public String register(User user){ //此處使用對象來封裝數據 try { FileWriter fileWriter = new FileWriter("stu.txt", true); fileWriter.write(user.toString() + "\r\n"); fileWriter.close(); System.out.println("註冊成功"); } catch (IOException e) { e.printStackTrace(); } return "註冊成功"; } }
要想跳轉頁面,類上使用的註解應該換成
@Controller
,@RestController
是用於返回json字符串的,而@Controlle
使用於跳轉頁面
@Controller public class UserController { private static final String TAG = "UserController"; @RequestMapping("/user_register") public String register(User user){ //此處使用對象來封裝數據 try { FileWriter fileWriter = new FileWriter("stu.txt", true); fileWriter.write(user.toString() + "\r\n"); fileWriter.close(); System.out.println("註冊成功"); } catch (IOException e) { e.printStackTrace(); } return "index.html"; } }
請求轉發的寫法有如下幾種。
request.getRequestDispatcher("index.html").forward(request,response);
return "index.html"; 或者 return "forward:index.html";
返回值使用
redirect:
做爲前綴,表示使用重定向來跳轉頁面 。
response.sendRedirect("index.html");
@RequestMapping("/save09") public String save09() throws ServletException, IOException { System.out.println("來到save9方法了~!~!"); return "redirect:index.jsp"; }
有時候咱們須要在頁面上顯示一些動態的數據,好比,登陸失敗的時候,咱們須要顯示爲何失敗。 登陸成功進入首頁,咱們須要在右上角顯示 登陸人的暱稱。 又或者咱們想查詢全部學生的信息,這些數據想要在頁面上顯示,咱們應該如何顯示呢?
在之前的時候,有諸如使用jsp , 配合做用域顯示 , 也有使用freemarker模板技術,現在咱們給你們講講SpringBoot 主推的模板技術Thymeleaf. 使用這個Thymeleaf,咱們很簡單便可在頁面上顯示一些動態數據。
Thymeleaf 是一款用於渲染XML/XHTML/HTML5內容的模板引擎,相似JSP、Velocity、FreeMarker 等模板引擎。 Thymeleaf的主要目的是提供一個優雅和格式良好的方式建立模板。爲了實現這一目標,它把預約義的邏輯放在XML的標記和屬性上,而不是顯式放在XML標記的內容上
compile("org.thymeleaf:thymeleaf-spring4:2.1.4.RELEASE")
@requestMapping("test") public String test(){ ModelAndView modelAndView = new ModelAndView(); //設置模型數據 modelAndView.addObject("name" , "奧巴馬"); //設置跳轉的目標是哪裏。 list.html modelAndView.setViewName("list"); return "index"; }
務必要在resources下面新建一個templates文件夾,用於存放模板頁面。早前咱們說的static 頁面是用於存放靜態頁面,靜態頁面的內容都是固定好的,不會再改變。而要顯示動態數據的頁面,須要放置在
resources/templates
文件夾中。咱們通常把這些頁面稱之爲模板頁面。
<!-- 引入命名空間 --> <html xmlns:th="http://www.thymeleaf.org" > <body> <!-- thymeleaf的模板取值顯示都是寫在標籤裏面。使用th命名空間來取值 1. 取值的寫法是: ${屬性的名稱} , 這種寫法不能獨立存在, 必須放在th:xxx="${屬性名稱}" 2. 若是數據要放置到標籤的中間造成文本,那麼使用th:text, 若是數據要填充到標籤的value屬性中,那麼使用th:value --> <p th:text="${name}"></p> <br/> <input type="text" th:value="${name}"/> </body>
@RequestMapping("test") public String test(Model model){ model.addAttribute("address","深圳"); return "testpage"; }
@RequestMapping("test2") public ModelAndView test2(){ ModelAndView modelAndView = new ModelAndView(); //1. 存數據 modelAndView.addObject("address","北京"); //2. 指定視圖 modelAndView.setViewName("testPage"); return modelAndView; }
這裏的基本用法,咱們給你們講兩個基本的表達式便可 表達式要求務必寫在 th:xxx這樣的屬性中。而th:xxx這樣的屬性又必須寫在html標籤中,不能單獨使用。
用於取值
${變量名}
,
用於指定超連接
@{路徑}
若是是須要從model中取值的話,寫法爲
th:href="@{${model中的name值}}"。
有的時候咱們不止須要從model中進行取值,還需寫字符串與model中的值進行拼接,寫法爲
th:href="@{'字符串'+${model中的name值}}"。
註冊功能 :
登陸功能: