SpringBoot RESTful風格入門講解
1、Restful簡介
Restful比較熱門,,Spring的微服務(wù)是基于Restful風格搭建的框架。
Restful有一下幾個特點:
- 使用URL描述資源。
- 使用HTTP方法描述行為,使用HTTP狀態(tài)碼來表示不同的結(jié)果。
- 使用JSON交互數(shù)據(jù)。
- Restful只是一種風格,不是強制標準。
2、查詢用戶以及用戶詳情
最簡單的,最常用的GET請求,用于查詢?nèi)繑?shù)據(jù)或者其中一條數(shù)據(jù)的詳情。
2.1常用注解
| 常用注解 | 作用 |
|---|---|
| @RestController | 表明此tController 提供的是Restful服務(wù) |
| @RequestMapping | 將URL映射到Java |
| @RequestParam | 映射請求參數(shù)到Java上的參數(shù) |
| @PageableDefault | 指定分頁參數(shù)的默認值 |
2.2查詢用戶詳情
@RequestMapping(value="/manage", method= {RequestMethod.GET})
public String list(String userId,Map<String,Object> map) {
if(userId==""||userId==null) {
map.put("userList", userService.getUserList());
}else {
map.put("userList",userService.getUserById(Integer.parseInt(userId)));
}
return "user/list";
}3、處理創(chuàng)建請求
3.1@RequestBody注解
3.1.1用途
用于接收前端傳遞給后端的json字符串中的數(shù)據(jù)。(處理json格式的數(shù)據(jù))
@RequestBody用來接收前端傳遞給后端的json字符串中的數(shù)據(jù),GET方式的請求一般通過URL中攜帶key-value參數(shù),而@RequestBody接收的是請求體中的數(shù)據(jù)(json格式的數(shù)據(jù),只有請求體中能保存json),所以使用@RequestBody接收數(shù)據(jù)的時候必須是POST方式等方式。
@RequestBody與@RequestParam()可以同時使用,但@RequestBody最多只能有一個,而@RequestParam()可以多個。
3.1.2語法規(guī)范
(@RequestBody Map map) (@RequestBody Object object)
(@RequestBody Map map)先對簡單,將json解析成Map形式的key-value對,直接通過map.get(“KeyName”)就能拿到值了
(@RequestBody Object object) 通過json字符串中的key來匹配對應(yīng)實體類的屬性如果匹配一致且json中的該key對應(yīng)的值符合實體類的對應(yīng)屬性的類型要求時,會調(diào)用實體類的setter方法將值注入到該屬性。
例如
public Result deleteBookById(@RequestBody HashMap<String, String> map) {
this.bookService.deleteBookById(Long.parseLong(map.get("id")));
return Result.createWithSuccessMessage();
}
public Result updateBookById(@RequestBody Book book){
Book record = this.bookService.updateBookById(book);
return Result.createWithModel(record);
}注意:
在(@RequestBody Object object)中,前端POST過來的數(shù)據(jù)會通過反序列數(shù)據(jù)到實體類中,并且在反序列的過程中會進行類型的轉(zhuǎn)換。
在json中應(yīng)該用null來代表空值,如果是"“(空字符串)會判斷為空串,如果實體類屬性是String類型的,那么接受到的就是”",如果實現(xiàn)類屬性類型是Integer、Double等類型,那么接收到的就是null。
{
name:"",
age:null
}(@RequestBody Object object)內(nèi)部是通過傳遞過來的數(shù)據(jù)中的Key尋找setter方法,有則調(diào)用,無則不作任何操作(其實可以設(shè)計)。
如果通過Key匹配到setter方法,但是Value無法轉(zhuǎn)換為對應(yīng)的實例類屬性的類型時,拋出異常。
3.2日期類型的處理
前端傳入日期格式: yyyy-MM-dd HH:mm:ss,例如:2018-07-09 12:55:12(不使用時間戳,前后雙方聯(lián)調(diào)時查看起來更加友好)
后端返回日期格式: yyyy-MM-dd HH:mm:ss,例如:2018-07-09 12:55:12(不使用時間戳,前后雙方聯(lián)調(diào)時查看起來更加友好)
后端json序列化、反序列化框架: 定義任何一種高效的json工具都行,例如:Fastjson、Gson、Jackson lib
序列化、反序列化日期格式規(guī)范: pattern=”yyyy-MM-dd HH:mm:ss”,timezone = “GMT+8”,除特出場景可以使用pattern=”yyyy-MM-dd”,timezone = “GMT+8”
不要隨意自定義convert處理日期格式以及其他特殊格式轉(zhuǎn)換,應(yīng)該交由基礎(chǔ)框架組或架構(gòu)組統(tǒng)一在框架層面解決,對業(yè)務(wù)開發(fā)透明,或者在有些小公司由Leader或高開來擔當。
3.3BindingResult
/*
* 添加用戶,使用@RequestBody將請求體映射到Action方法參數(shù)中
* 使用@Valid注解驗證請求參數(shù)的合法性
* 使用BindingResult處理校驗結(jié)果
* @param user
* @param result
* @return
*/
@PostMapping("/user")
public User create(@Valid @RequestBody User user, BindingResult result){
if(result.hasErrors()){
result.getAllErrors().stream().forEach(error -> {
FieldError fieldError = (FieldError)error;
String message = fieldError.getField() + " " + error.getDefaultMessage();
System.out.println(message);
});
return null;
}
System.out.println(user.toString());
user.setId(5l);
return user;
}4、用戶信息修改與刪除
PUT和DELETE并不復雜,大家也熟悉,用于對后臺數(shù)據(jù)的更新和刪除。
4.1用戶信息修改
對資源更新的請求方法通常是是PUT,但有時候也可能是POST。那么問題來了,都是更新資源區(qū)別在哪里?
| PUT | POST |
|---|---|
| 在HTTP中PUT被定義為冪等的請求方法 | 而POST則不是 |
| 操作是作用于一個具體資源之上 | 作用于一個集合資源之上 |
| URL在客戶端確定使用PUT | URL在服務(wù)端確定使用POST |
比較直觀的是資源URL的不同
4.2案例
前端界面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../js/jquery.min.js"></script>
<script>
$(function () {
// 查詢所有
$('#btn1').click(function () {
$.get('/employees', function (data) {
console.log(data);
});
});
// 查詢一個
$('#btn2').click(function () {
$.get('/employees/10', function (data) {
console.log(data);
});
});
// 添加
$('#btn3').click(function () {
$.post('/employees', "id=11", function (data) {
console.log(data);
});
});
// 修改
$('#btn4').click(function () {
$.ajax({
url: "/employees",
type: "PUT",
data: {id: 1, name: "小肥羊", age: 10},
success: function (data) {
console.log(data);
}
});
});
// 刪除
$('#btn5').click(function () {
$.ajax({
url: "/employees/13",
type: "DELETE",
data: {id: 1},
success: function (data) {
console.log(data);
}
});
});
});
</script>
</head>
<body>
<button id="btn1">查詢所有</button>
<button id="btn2">查詢一個</button>
<button id="btn3">添加</button>
<button id="btn4">修改</button>
<button id="btn5">刪除</button>
</body>
</html>后端控制器
package com.yy.web.controller;
import com.yy.domain.Employee;
import com.yy.util.JsonResult;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List;
/**
* @program: restful-demo
* @ClassName: EmployeeController
* @description:
* @author: YanYang
* @create: 2021-06-23 15:04
**/
@RestController
@RequestMapping("employees")
public class EmployeeController {
/**
* 2個接口設(shè)計都是用相同資源,相同請求方法,此時 SpringMVC 無法識別,
* 認為是同一方法,報錯:Ambiguous mapping. [模糊映射]
*
* RESTful 解決方案:使用 參數(shù)路徑 方式
* 具體實現(xiàn):將參數(shù)作為請求映射路徑一部分,[參與映射路徑區(qū)分]
* 比如:查詢指定 id 的員工信息接口設(shè)計
* @RequestMapping(value = "/employees/{id}", method = RequestMethod.GET)
* 其中 "/employees/{id}" 參數(shù)路徑,{id} 就是路徑參數(shù)
*
* 訪問該接口時:http:localhost:8080/employees/1 其中 1 是 id 參數(shù)
* 接口接收路徑參數(shù):使用 @PathVariable,表示將參數(shù)路徑上的參數(shù)解析,并賦值給指定變量
* 如果路徑參數(shù)與變量名不一致,使用 @PathVariable("eid")明確指定
*
*/
// 查詢所有(數(shù)據(jù)是模擬的)
// @RequestMapping(value = "/employees", method = RequestMethod.GET)
@GetMapping
public List<Employee> list() {
return Arrays.asList(new Employee(1L,"小肥羊", 10), new Employee(2L, "熊大", 11));
}
// 查詢單個(數(shù)據(jù)是模擬的)
// @RequestMapping(value = "/employees/{id}", method = RequestMethod.GET)
@GetMapping("/{eid}")
public Employee queryById(@PathVariable("eid") Long id) {
System.out.println("查詢單個 = " + id);
return new Employee(3L, "熊二", 8);
}
// 添加(數(shù)據(jù)是模擬的)
// @RequestMapping(value = "/employees", method = RequestMethod.POST)
@PostMapping
public Employee add(@ModelAttribute("employee") Employee employee) {
System.out.println("添加 = " + employee.getId());
return employee;
}
// 修改(數(shù)據(jù)是模擬的)
// @RequestMapping(value = "/employees", method = RequestMethod.PUT)
@PutMapping
public Employee update(@ModelAttribute("employee") Employee employee) {
System.out.println("修改 = " + employee.getId());
employee.setId(employee.getId());
employee.setName(employee.getName());
employee.setAge(employee.getAge());
return employee;
}
// 刪除(數(shù)據(jù)是模擬的)
// @RequestMapping(value = "/employees/{id}", method = RequestMethod.DELETE)
@DeleteMapping("/{id}")
public String delete(@PathVariable Long id) {
System.out.println("刪除 = " + id);
if (id != null && 1 == id) {
return "刪除成功";
}
return "刪除失敗";
}
}到此這篇關(guān)于SpringBoot RESTful接口入門講解的文章就介紹到這了,更多相關(guān)SpringBoot RESTful內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于springcloud異步線程池、高并發(fā)請求feign的解決方案
這篇文章主要介紹了基于springcloud異步線程池、高并發(fā)請求feign的解決方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02
用intellij Idea加載eclipse的maven項目全流程(圖文)
這篇文章主要介紹了用intellij Idea加載eclipse的maven項目全流程(圖文),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-12-12
Java的動態(tài)分派和靜態(tài)分派的實現(xiàn)
這篇文章主要介紹了Java的動態(tài)分派和靜態(tài)分派的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-03-03
mybatis整合springboot報BindingException:Invalid?bound?stateme
這篇文章主要給大家介紹了關(guān)于mybatis整合springboot報BindingException:Invalid?bound?statement?(not?found)異常的解決辦法,這個錯誤通常是由于Mapper文件中的statement?id與Java代碼中的方法名不一致導致的,需要的朋友可以參考下2024-01-01
Java 高并發(fā)編程之最實用的任務(wù)執(zhí)行架構(gòu)設(shè)計建議收藏
高并發(fā)(High Concurrency)是互聯(lián)網(wǎng)分布式系統(tǒng)架構(gòu)設(shè)計中必須考慮的因素之一,它通常是指,通過設(shè)計保證系統(tǒng)能夠同時并行處理很多請求,高并發(fā)相關(guān)常用的一些指標有響應(yīng)時間(Response Time),吞吐量(Throughput),每秒查詢率QPS(Query Per Second),并發(fā)用戶數(shù)等2021-10-10

