SpringBoot學習筆記(一)

摘要

\quad 前先後後花了好幾個月的時間學習Java基礎,感受都是零零散散的知識點,不只不知道實際當中怎麼用,並且容易忘。因此,開始一個真正的應用頗有必要,不只能夠整合前面所學的知識,更重要的是開始接觸真正的工做內容。下面講解如何從零開始,搭建一個SpringBoot容器。
html

1. 從一個空的文件夾開始

\quad 一個基本的Spring項目包括:前端

  • pom.xml文件
  • src\main\java\hello\Application.java
  • src\main\java\hello\HelloController.java

1.1 添加內容

\quad pom(project-object-model),maven的配置文件,也是Java項目的核心文件。首先,按照官網的提示,在一個空的文件夾中新建pom.xml文件,而後將Build With Maven中的內容粘貼到其中。
\quad Application以及HelloController,一樣按照提示將代碼複製到其中。刷新Maven後,就能夠發現這時候這個項目以及能夠開始運行了。而且在瀏覽器中輸入lcoalhost:8080就能夠看到這個項目已經啓動了:java

2. web應用的本質

2.1 處理HTTP請求

  • 從HTTP請求中提取querystring(查詢字符串)。
  • 從HTTP中接受payload(負載)中的參數。

\quad例如:咱們在谷歌瀏覽器搜索欄中填入springboot這時能夠看到url變成了https://www.google.com/search?q=springboot&oq=springboot&aqs=chrome..69i57l2j69i60j69i61j69i60l2.2979j0j7&sourceid=chrome&ie=UTF-8
那麼後面這一系列的鍵值對就都稱爲查詢字符串。補充說明一下:search在產品維度上稱爲接口。
git

2.2 返回HTTP響應

響應內容包括:
github

  1. status code
  2. HTTP response header
  3. HTTP response body

補充說明:
web

  1. 字節流中HTTP header與HTTP body之間用四個分隔符\r\n\r\n來分隔。
  2. body中又包括:JSON,HTML,CSS等

2.3 如何獲取查詢字符串

\quad 假設咱們是Google,用戶輸入這樣一個網址http://localhost:8080//search?q=dog,那麼咱們要怎麼拿到這個dog關鍵字呢?回到代碼中:
spring

//將接口名指定爲/search
@RequestMapping("/search")
   //請求的參數指定爲q
    public String search(@RequestParam("q") String searchKeyWord) {
        return "you are searching:"+searchKeyWord;
    }
複製代碼

從新點擊運行,輸入網址: chrome

\quad能夠看到這時候咱們就拿到用戶請求的關鍵字了。可是從前面Google的url請求中能夠看出,實際上url中攜帶的請求參數確定不止一個,而且用戶確定是不知道serach接口中存在多少個參數,那麼如何設置多個參數,並設置默認不須要賦值? 代碼以下:

@RequestMapping("/search")
   //將charset參數設置爲非強制的
    public String search(@RequestParam("q") String searchKeyWord,
                         @RequestParam(required = false,value = "charset") String charset) {
        return "you are searching:"+searchKeyWord + " with charset is :"+charset;
    }
複製代碼

\quad GET請求一般用於傳遞非敏感信息,由於在GET請求中的帳戶名密碼都是會顯示在url中的,因此不能將敏感信息經過GET請求發送。數據庫

2.4 RESTful API

\quad RESTful API是一套用於設計WEB數據接口的一套API設計規範,用以規範URL、狀態碼以及服務器的響應。developer.github.com/v3/ (github的API被稱爲業界的標杆,值得學習)。小程序

  • 使用HTTP動詞來表明動做
  1. GET-獲取資源
  2. POST-新建資源
  3. PUT-更新資源
  4. DELETE-刪除資源
  • 使用URL來表明資源
  1. 資源裏面沒有名詞
  2. 使用複數來表明資源列表
方法中的參數獲取
以DELETE舉例,spring中的代碼以下:
@RestController
//把全部的請求映射到一個方法上
@RequestMapping("repos")
public class IssueController {
    @DeleteMapping("/{owner}/{repo}/issues/{issuesNumber}/lock")
    public void unlock(
            @PathVariable("owner") String owner,
            @PathVariable("repo") String repo,
            @PathVariable("issuesNumber") String issueNumber
    ) {
        System.out.println(owner+" "+repo+" "+issueNumber);
    }
}
複製代碼

因爲DELETE操做不能由瀏覽器發起,這裏使用Postman模擬DELETE請求。

在控制檯中能夠看到輸出信息:

\quad 這樣便實現了第二種請求中參數的獲取,既從路徑中獲取參數。

2.5 從HTTP post中獲取body

\quad 當請求的參數很是多時,通常都是將參數至於HTTP post的body中,那麼如何從HTTP的body中拿到參數呢?一樣以GitHub的POST舉例:
\quad請求的路徑爲POST /repos/:owner/:repo/issues
body爲:

{
  "title": "Found a bug",
  "body": "I'm having a problem with this.",
  "assignees": [
    "octocat"
  ],
  "milestone": 1,
  "labels": [
    "bug"
  ]
}
複製代碼

代碼以下:

@PostMapping("/{owner}/{repo}/issues")
    public void createAnIssue(
            @PathVariable("owner") String owner,
            @PathVariable("repo") String repo,
            @RequestBody HashMap requestBody
    ){
        System.out.println(requestBody);
    }
複製代碼

一樣使用PostMan模擬post請求: url:http://localhost:8080/repos/hello/world/issues
body:

注意,這時候須要設置header:
不然spring是識別不出JSON的。
經過調試看到:

\quad 能夠看到,咱們把post的body中的參數拿出來了,可是使用LinkedHashMap來存儲參數,獲取參數不是那麼方便,咱們能夠生成一個內部類來存儲。使用插件 GsonFormat能夠代替咱們作這件事情:
具體操做:
\quad 新建一個類->alt+insert->Gsonformat->將JSON字符粘貼至其中->點擊肯定便可。
\quad 結果以下: PostBody{title='Found a bug', body='I'm having a problem with this.', milestone=1, assignees=[octocat], labels=[bug]}

2.6 從表單中獲取body

代碼以下:

@PostMapping("/getForm")
    public void getForm(
            @RequestParam("name") String name,
            @RequestParam("city") String city
    ){
        System.out.println(name);
        System.out.println(city);
    }
複製代碼

post請求以下:

結果:

zhangsan
beijin
複製代碼

能夠看到,實現了從form表單中獲取參數,這種方式適用於參數比較少的狀況。

3.生成HTTP響應

\quad 經過前面的幾種方式,咱們拿到了HTTP請求中的參數,接下來就是做出合理的處理,而後生成HTTP響應給前端了。
\quad 首先咱們知道,HTTP響應返回的本質上就是一個HTML文本,使用一些標記語言實現對結果的美化。因此最簡單的操做,咱們也能夠在Java代碼中直接添加HTML標籤:

@RequestMapping("/getForm")
    public String getForm(
            @RequestParam("name") String name,
            @RequestParam("city") String city
    ) {
    //爲返回結果添加標籤
        return ("<em>" + name + "</em>" + " " + "<strong>" + city + "</strong>");
    }
複製代碼

結果:

也能夠直接操做HttpServletResponse對象(Servlet的核心接口)。

@RequestMapping("/Servlet")
    public void controlRawServlet(HttpServletRequest request, HttpServletResponse response) throws IOException {
    //返回一個status code=403錯誤
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
    //將信息寫入http reponse中
        response.getWriter().write("hello world 403");
    }
複製代碼

結果以下:

\quad 固然,實際運用中是不會用這樣簡單粗暴的方式的,通常都是格式化的返回一個 JSON字符串。在Spring中實現往http body中寫入數據:

@RequestMapping("/GetBody")
    @ResponseBody
    public Object writeIntoBody(){
        Map<String,Object> map = new HashMap<>();
        map.put("result", Arrays.asList("zhangsan","beijin"));
        return map;
    }
複製代碼

結果:

\quad 注意:返回的文本,默認格式是JSON。可是,若是咱們返回一個XML呢?在PostMan中這樣設置:
能夠看到console顯示: HttpMediaTypeNotAcceptableException意思就是不接受這種返回類型。
\quad 其實這就是Spring最基本的實現了,獲取一個Http請求返回一個Http reponse。咱們須要作的就是在這個基礎上繼續擴展,包括數據庫、Redis緩存、消息隊列、以及RPC(Remote Procedure Call-遠程過程調用)、微服務化等。

4.提問

4.1 HTTP GET不能帶body嘛?

參考自WebTechGarden的我的博客以及stackoverflow的回答:
\quad 首先HTTP協議中並無規定GET中不能帶body,而且做者採用多種方式證實了,HTTP GET是能夠帶body的。可是GET被設計來用URI來識別資源,若是讓它的請求體中攜帶數據,那麼一般的緩存服務便失效了,URI 不能做爲緩存的 Key。
\quad但另外一方面,若是僅僅是爲了讀取資源,而須要使用 Body 發送一大批數據時,改用 POST 請求卻與 RESTFul 的 post 語義不相符。這時候或許能夠 GET + body, 可是不能對該請求以 URI 做爲 Key 進行緩存了。
\quad 因此,在GET中添加body是沒有意義的。

5. 必備知識

5.1 Servlet、Servlet容器

摘自:知乎.來之孤島的鯨魚

  • Servlet

\quad Java Servlet(Java服務器小程序)是一個基於Java技術的Web組件,運行在服務器端,它由Servlet容器所管理,用於生成動態的內容。 Servlet是平臺獨立的Java類,編寫一個Servlet,實際上就是按照Servlet規範編寫一個Java類。Servlet被編譯爲平臺獨立 的字節碼,能夠被動態地加載到支持Java技術的Web服務器中運行。

  • Servlet容器

\quad Servlet容器也叫作Servlet引擎,是Web服務器或應用程序服務器的一部分,用於在發送的請求和響應之上提供網絡服務,解碼基於 MIME的請求,格式化基於MIME的響應。Servlet沒有main方法,不能獨立運行,它必須被部署到Servlet容器中,由容器來實例化和調用 Servlet的方法(如doGet()和doPost()),Servlet容器在Servlet的生命週期內包容和管理Servlet。在JSP技術 推出後,管理和運行Servlet/JSP的容器也稱爲Web容器。

6. 參考資料:

1.我的博客.《誰說 HTTP GET 就不能經過 Body 來發送數據呢?》跳轉至源文章

2. stackoverflow.「HTTP GET with request body」 跳轉至源文章

3. 微信公衆號: WebTechGarden.《99%的人都理解錯了HTTP中GET與POST的區別》 跳轉至源文章

4. 我的博客.《RESTful API 最佳實踐》跳轉至源文章

5. 知乎.《幾個概念:Servlet、Servlet容器、Tomcat》跳轉至源文章

相關文章
相關標籤/搜索