<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                前面的章節中,我們使用了`GetMapping`注解來映射到地址`/Teacher`的`get`請求,本節中我們開始使用`PostMapping`注解來映射到地址`/Teacher`的`post`請求。 # 初始化 TeacherController ```java @RestController @RequestMapping("Teacher") public class TeacherController { ... ? @PostMapping ? @CrossOrigin("*") ? public void save() { ? logger.info("觸發了保存方法"); ? } } ``` * ? `...`表示省略其它非核心代碼 * ? 當使用`post`方法請求`/Teacher`地址時,觸發`save`方法。 * ? 支持任何地址對此方法的跨域訪問都是允許的。 * ? 定義方法名及返回類型 * ? 打印測試日志 ## 測試 除了使用已有的前臺來進行測試以外,還有很多專門的測試工具來測試單獨的后臺項目,比如大名遠揚的`postman`。在此,我們展示一種使用`idea`自帶的測試功能的方法。 首先,讓我們啟動后臺,然后按以下操作來到`REST Client`: ![](https://img.kancloud.cn/d5/86/d586390925216649f7fa40940478193b_1029x573.gif) 發起請求后,我們來到控制臺。 ![](https://img.kancloud.cn/b0/7d/b07d028e8b12e514e1e1a2f141b3d118_663x557.png) ``` 2019-10-11 13:36:10.061 DEBUG 25994 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet : POST "/Teacher", parameters={} 2019-10-11 13:36:10.061 DEBUG 25994 --- [nio-8080-exec-8] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public void com.mengyunzhi.springBootStudy.TeacherController.save() 2019-10-11 13:36:10.061 INFO 25994 --- [nio-8080-exec-8] c.m.springBootStudy.TeacherController : 觸發了保存方法 ? 2019-10-11 13:36:10.061 ? DEBUG ? 25994 ?--- [nio-8080-exec-8 ?] m.m.a.RequestResponseBodyMethodProcessor ?: Using 'application/json', given [application/json] and supported [application/json, application/*+json, application/json, application/*+json]? 2019-10-11 13:36:10.061 DEBUG 25994 --- [nio-8080-exec-8] m.m.a.RequestResponseBodyMethodProcessor : Nothing to write: null body 2019-10-11 13:36:10.061 DEBUG 25994 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet : Completed 200 OK ``` 得到以上幾條日志信息。除?以外,其它幾條均是`spring`的提示信息。在開發的過程中,無論是正常還是異常,我們都離不開控制臺的打印信息,在此再次進行解讀如下: * ?時間 * ?日志等級 * ? 進程號 * ? 線程號 * ? 發送該日志的類 * ? 日志內容 # 數據綁定 前臺發送`數據`給后臺,后臺便需要使用變量來進行接收`數據`。這個使用變量進行接收的過程又叫作`Data Binding`,即`數據綁定`。在`spring`中,使用如下方法來綁定前臺傳入的`post`數據。 ```java import org.springframework.web.bind.annotation.*; ... public void save(@RequestBody ? Teacher ? teacher?) { ``` * ?接收前臺`post`過來的數據對象。 * ?使用`Teacher`類實例化一個對象,拼按`Teacher`類中的屬性名進行數據綁定。 * ?數據綁定成功后把這個對象的名字起名為`teacher`,該對象可以在`save`方法中使用。 ## 測試 打斷點 ![](https://img.kancloud.cn/a1/20/a120d54c1f739b082e16b8615c317633_887x219.png) 使用debug模式啟動項目 ![](https://img.kancloud.cn/9f/2d/9f2d5127241debeaa0d236d07776e0d7_715x60.png) 啟動`REST Client`,添加`Content-Type`信息來告訴后臺:我現在將`json`字符串發送給你。 ![](https://img.kancloud.cn/72/97/7297859367d1f84a9daeee1fb91c303b_603x470.png) 依次點擊下列信息: ![](https://img.kancloud.cn/bd/fd/bdfd9762a89da8fadae143e7fc3490eb_1880x535.png) > 截圖中傳入的數據是`json字符串`與平常我們輸寫的`json對象`并不相同,你出錯了嗎? 此時`idea`將自動彈到`debug`界面。 ![](https://img.kancloud.cn/83/a4/83a454b6e00be69912294e8178ba0e95_1016x502.png) 通過觀察`teacher`變量的值,我們發送通過`REST Client`模擬發送過來的數據的確已經按照`Teacher`的字段名成功的綁定到`teacher`對象上了。 # 持久化 有了`teacher`對象以后,我們可以靜心地思索后臺的JAVA代碼進而完成將數據保存到數據庫中的操作了。和查詢數據相同,我們在此仍然使用`JDBC Template`,執行查詢方法時我們使用了`jdbcTemplate.query()`,新增數據時我們使用`jdbcTemplate.execute`。 ```java /** * 新增教師 * 1. 獲取前臺傳入的教師對象 * 2. 拼接插入sql語句 * 3. 執行sql語句。 * * @param teacher 教師 */ @PostMapping @CrossOrigin("*") public void save(@RequestBody Teacher teacher) { String sql = String.format( "insert into `teacher` (`name`, `username`, `email`, `sex`) values ('%s', '%s', '%s', %s)", ? teacher.getName(), teacher.getUsername(), teacher.getEmail(), teacher.getSex().toString() ? ); ? logger.info(sql); jdbcTemplate.execute(sql); } ``` * ?調用String.format方法對字符串進行格式化。 * ?定義插入sql語句,并預留幾個`%s`作為數據插入項(注意,最后一個`%s`不能使用''包裹)。 * ?按順序用實際的值覆蓋字符串中的`%s`。 ## 測試 ***** **注意**后臺的代碼只要發生變更,那么就必須重新啟動項目來使其生效,在教程后面的部分不再重復。 ***** 啟動`REST Client`來進行測試,將得到以下錯誤信息: ``` {"timestamp":"2019-10-11T06:37:24.258+0000","status":500,"error":"Internal Server Error","message":"StatementCallback; SQL [insert into `teacher` (`name`, `username`, `email`, `sex`) values ('張三', 'zhangsan', 'zhangsan@yunzhiclub.com', true)]; Duplicate entry 'zhangsan' for key 'nx1HkMqiUveGnJz5lHE7mEcFI5WVew3iXbv3HCwF'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry 'zhangsan'? for key 'nx1HkMqiUveGnJz5lHE7mEcFI5WVew3iXbv3HCwF'","path":"/Teacher"} ``` * ? 在數據庫中發現已經有了用戶名 ---- `zhangsan`,而用戶名必須是唯一的。 在REST Client中修正測試的用戶名后: ``` { "name": "張三", "username": "zhangsan1?", "email": "zhangsan@yunzhiclub.com" , "sex": true } ``` 再進行測試,操作成功。 ![](https://img.kancloud.cn/98/ab/98abc5ba5a2043a1b21b65e0b64a83e1_442x93.png) # 本節小測 1. 請求方法除了常用的用于查詢數據`get`方法及用于新增數據的`post`方法以外,我們后面還會接觸用于刪除數據的`delete`方法,用于更新全部屬性的`put`方法以及用于更新部分屬性的`patch`方法。這些方法在`spring`中是否有對應的映射注解呢?請猜測并驗證。 2. 在本節的代碼那個字符串為什么不能這樣寫: ```sql "insert into `teacher` (`name`, `username`, `email`, `sex`) values ('%s', '%s', '%s', '%s')" ``` ## 上節答案 可以將字符串定義到某個公共變量中,`AppComponent`及`TeacherAddComponet`在進行后臺請求時,均使用該公共變量。 # 參考文檔 | 名稱 | 鏈接 | 預計學習時長(分) | | --- | --- | --- | | mvc-ann-arguments | [https://docs.spring.io/spring/docs/5.2.0.RELEASE/spring-framework-reference/web.html#mvc-ann-arguments](https://docs.spring.io/spring/docs/5.2.0.RELEASE/spring-framework-reference/web.html#mvc-ann-arguments) | 10 | | mysql 插入數據 | [https://www.runoob.com/mysql/mysql-insert-query.html](https://www.runoob.com/mysql/mysql-insert-query.html) | 10 | | Accessing Relational Data using JDBC with Spring | [https://spring.io/guides/gs/relational-data-access/](https://spring.io/guides/gs/relational-data-access/) | - | | 源碼地址 | [https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step2.3.4](https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step2.3.4) | - |
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看