<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          SpringBoot RESTful實戰(zhàn)

          共 13768字,需瀏覽 28分鐘

           ·

          2020-01-04 23:21


          本文公眾號來源:美碼師作者:美碼師本文已收錄至我的GitHub

          一、目標

          1. 了解 Restful 是什么,基本概念及風格;

          2. 能使用SpringBoot 實現(xiàn)一套基礎(chǔ)的 Restful 風格接口;

          3. 利用Swagger 生成清晰的接口文檔。

          二、Restful 入門

          什么是REST?

          摘自百科的定義:REST即表述性狀態(tài)轉(zhuǎn)移(英文:Representational State Transfer,簡稱REST) 是Roy Fielding博士(HTTP規(guī)范主要貢獻者)在2000年的論文中提出來的一種軟件架構(gòu)風格。 是一種針對網(wǎng)絡(luò)應(yīng)用的設(shè)計和開發(fā)方式,可以降低開發(fā)的復(fù)雜性,提高系統(tǒng)的可伸縮性。

          通俗點說,REST就是一組架構(gòu)約束準則;在這些準則中,有不少是利用了現(xiàn)有的WEB標準能力。 而最終的目的則是簡化當前業(yè)務(wù)層的設(shè)計及開發(fā)工作。

          Restful API 則是指符合REST架構(gòu)約束的API,關(guān)于這個詞在早年前其實已經(jīng)非常流行,但大多數(shù)開發(fā)者對其仍然 處于觀望狀態(tài),并不一定會立即采用。這個相信與當時技術(shù)社區(qū)的成熟度及氛圍是密切相關(guān)。 無論如何,在微服務(wù)架構(gòu)如此流行的今天,Restful API已經(jīng)成為了一種必備的的標準設(shè)計風格。


          關(guān)鍵要點

          理解 Restful 風格需要理解以下幾點:

          • 資源

          資源指的就是一個抽象的信息實體,可以是一個用戶、一首歌曲、一篇文章,只要是可作為引用的對象就是資源。 每個資源通常會被映射到一個URI,通過訪問這個URI可以獲取到信息。

          • 資源的表述

          資源表述(Representation)指的則是資源的外在表現(xiàn)形式 比如一個帖子,可以通過HTML格式展現(xiàn),也可以通過XML、JSON等格式輸出到客戶端。

          在前面的文章(SpringBoot-Scope詳解)中提到,HTTP協(xié)議通過MIME來統(tǒng)一定義數(shù)據(jù)信息的格式標準。 通常,Accept、Content-Type可以用來指定客戶端及服務(wù)端可接受的信息格式,而這個就是資源的表述

          • 狀態(tài)轉(zhuǎn)移

          在HTTP訪問過程中,資源的狀態(tài)發(fā)生變化。這里會涉及到以下的幾個動詞:

          名稱語義
          GET獲取資源
          POST新建資源
          PUT更新資源
          DELETE刪除資源

          對于不同的訪問方法,服務(wù)器會產(chǎn)生對應(yīng)的行為并促使資源狀態(tài)產(chǎn)生轉(zhuǎn)換。

          關(guān)于無狀態(tài)

          Restful 是無狀態(tài)的設(shè)計,這點意味著交互過程中的請求應(yīng)該能包含所有需要的信息,而不需要依賴于已有的上下文。 然而 JavaEE中存在一些違背的做法,比如Cookie中設(shè)置JSESSIONID, 在多次請求間傳遞該值作為會話唯一標識,這標識著服務(wù)端必須保存著這些會話狀態(tài)數(shù)據(jù)。

          PlayFramework框架實現(xiàn)了無狀態(tài)的Session,其將會話數(shù)據(jù)經(jīng)過加密編碼并置入Cookie中, 這樣客戶端的請求將直接攜帶上全部的信息,是無狀態(tài)的請求**,這點非常有利于服務(wù)端的可擴展性。


          三、SpringBoot 實現(xiàn) Restful

          接下來,我們利用 SpringBoot 來實現(xiàn)一個Restful 風格的樣例。

          說明基于 PetStore(寵物店) 的案例,實現(xiàn)對某顧客(Customer)名下的寵物(Pet)的增刪改查。

          1. 實體定義

          Customer

          1. publicclassCustomer{

          2. ? ?privateString name;

          3. ? ?publicCustomer(){

          4. ? ? ? ?super();

          5. ? ?}

          6. ? ?publicCustomer(String name){

          7. ? ? ? ?super();

          8. ? ? ? ?this.name = name;

          9. ? ?}

          10. ? ?publicString getName(){

          11. ? ? ? ?return name;

          12. ? ?}

          13. ? ?publicvoid setName(String name){

          14. ? ? ? ?this.name = name;

          15. ? ?}

          16. }

          Customer 只包含一個name屬性,我們假定這是唯一的標志。

          Pet

          1. publicclassPet{

          2. ? ?privateString petId;

          3. ? ?privateString name;

          4. ? ?privateString type;

          5. ? ?privateString description;

          6. ? ?publicString getPetId(){

          7. ? ? ? ?return petId;

          8. ? ?}

          9. ? ?publicvoid setPetId(String petId){

          10. ? ? ? ?this.petId = petId;

          11. ? ?}

          12. ? ?publicString getName(){

          13. ? ? ? ?return name;

          14. ? ?}

          15. ? ?publicvoid setName(String name){

          16. ? ? ? ?this.name = name;

          17. ? ?}

          18. ? ?publicString getType(){

          19. ? ? ? ?return type;

          20. ? ?}

          21. ? ?publicvoid setType(String type){

          22. ? ? ? ?this.type = type;

          23. ? ?}

          24. ? ?publicString getDescription(){

          25. ? ? ? ?return description;

          26. ? ?}

          27. ? ?publicvoid setDescription(String description){

          28. ? ? ? ?this.description = description;

          29. ? ?}

          30. }

          Pet 包含了以下幾個屬性

          屬性名描述
          petId寵物ID編號
          name寵物名稱
          type寵物類型
          description寵物的描述

          2. URL資源

          基于Restful 的原則,我們定義了以下的一組URL:

          接口方法URL
          添加寵物POST/rest/pets/{customer}
          獲取寵物列表GET/rest/pets/{customer}
          獲取寵物信息GET/rest/pets/{customer}/{petId}
          更新寵物信息PUT/rest/pets/{customer}/{petId}
          刪除寵物DELETE/rest/pets/{customer}/{petId}

          3. 數(shù)據(jù)管理

          接下來實現(xiàn)一個PetManager 類,用于模擬在內(nèi)存中對Pet數(shù)據(jù)進行增刪改查 代碼如下:

          1. @Component

          2. publicclassPetManager{

          3. ? ?privatestaticMap<String,Customer> customers =newConcurrentHashMap<String,Customer>();

          4. ? ?privatestaticMap<String,Map<String,Pet>> pets =newConcurrentHashMap<String,Map<String,Pet>>();

          5. ? ?@PostConstruct

          6. ? ?publicvoid init(){

          7. ? ? ? ?String[] customerNames =newString[]{"Lilei","Hanmeimei","Jim Green"};

          8. ? ? ? ?for(String customerName : customerNames){

          9. ? ? ? ? ? ?customers.put(customerName,newCustomer(customerName));

          10. ? ? ? ?}

          11. ? ?}

          12. ? ?/**

          13. ? ? * 獲取customer

          14. ? ? *

          15. ? ? * @param customer

          16. ? ? * @return

          17. ? ? */

          18. ? ?publicCustomer getCustomer(String customer){

          19. ? ? ? ?if(StringUtils.isEmpty(customer)){

          20. ? ? ? ? ? ?returnnull;

          21. ? ? ? ?}

          22. ? ? ? ?return customers.get(customer);

          23. ? ?}

          24. ? ?/**

          25. ? ? * 獲取customer名下的 pet 列表

          26. ? ? *

          27. ? ? * @param customer

          28. ? ? * @return

          29. ? ? */

          30. ? ?publicList<Pet> getPets(String customer){

          31. ? ? ? ?if(StringUtils.isEmpty(customer)){

          32. ? ? ? ? ? ?returnCollections.emptyList();

          33. ? ? ? ?}

          34. ? ? ? ?if(!pets.containsKey(customer)){

          35. ? ? ? ? ? ?returnCollections.emptyList();

          36. ? ? ? ?}

          37. ? ? ? ?return pets.get(customer).values().stream().collect(Collectors.toList());

          38. ? ?}

          39. ? ?/**

          40. ? ? * 獲取某個pet

          41. ? ? *

          42. ? ? * @param customer

          43. ? ? * @param petId

          44. ? ? * @return

          45. ? ? */

          46. ? ?publicPet getPet(String customer,String petId){

          47. ? ? ? ?if(StringUtils.isEmpty(customer)||StringUtils.isEmpty(petId)){

          48. ? ? ? ? ? ?returnnull;

          49. ? ? ? ?}

          50. ? ? ? ?if(!pets.containsKey(customer)){

          51. ? ? ? ? ? ?returnnull;

          52. ? ? ? ?}

          53. ? ? ? ?return pets.get(customer).get(petId);

          54. ? ?}

          55. ? ?/**

          56. ? ? * 刪除pet

          57. ? ? *

          58. ? ? * @param customer

          59. ? ? * @param petId

          60. ? ? * @return

          61. ? ? */

          62. ? ?publicboolean removePet(String customer,String petId){

          63. ? ? ? ?if(StringUtils.isEmpty(customer)||StringUtils.isEmpty(petId)){

          64. ? ? ? ? ? ?returnfalse;

          65. ? ? ? ?}

          66. ? ? ? ?if(!pets.containsKey(customer)){

          67. ? ? ? ? ? ?returnfalse;

          68. ? ? ? ?}

          69. ? ? ? ?return pets.get(customer).remove(petId)!=null;

          70. ? ?}

          71. ? ?/**

          72. ? ? * 添加pet

          73. ? ? *

          74. ? ? * @param customer

          75. ? ? * @param pet

          76. ? ? * @return

          77. ? ? */

          78. ? ?publicPet addPet(String customer,Pet pet){

          79. ? ? ? ?if(StringUtils.isEmpty(customer)|| pet ==null){

          80. ? ? ? ? ? ?returnnull;

          81. ? ? ? ?}

          82. ? ? ? ?Map<String,Pet> customerPets =null;

          83. ? ? ? ?if(!pets.containsKey(customer)){

          84. ? ? ? ? ? ?customerPets =newLinkedHashMap<String,Pet>();

          85. ? ? ? ? ? ?Map<String,Pet> previous = pets.putIfAbsent(customer, customerPets);

          86. ? ? ? ? ? ?// 已經(jīng)存在

          87. ? ? ? ? ? ?if(previous !=null){

          88. ? ? ? ? ? ? ? ?customerPets = previous;

          89. ? ? ? ? ? ?}

          90. ? ? ? ?}else{

          91. ? ? ? ? ? ?customerPets = pets.get(customer);

          92. ? ? ? ?}

          93. ? ? ? ?if(pet.getPetId()==null){

          94. ? ? ? ? ? ?pet.setPetId(UUID.randomUUID().toString());

          95. ? ? ? ?}

          96. ? ? ? ?customerPets.put(pet.getPetId(), pet);

          97. ? ? ? ?return pet;

          98. ? ?}

          99. ? ?/**

          100. ? ? * 更新某個pet

          101. ? ? *

          102. ? ? * @param customer

          103. ? ? * @param petPojo

          104. ? ? * @return

          105. ? ? */

          106. ? ?publicPet updatePet(String customer,Pet petPojo){

          107. ? ? ? ?if(StringUtils.isEmpty(customer)|| petPojo ==null){

          108. ? ? ? ? ? ?returnnull;

          109. ? ? ? ?}

          110. ? ? ? ?if(petPojo.getPetId()==null){

          111. ? ? ? ? ? ?returnnull;

          112. ? ? ? ?}

          113. ? ? ? ?Pet pet = getPet(customer, petPojo.getPetId());

          114. ? ? ? ?pet.setType(petPojo.getType());

          115. ? ? ? ?pet.setName(petPojo.getName());

          116. ? ? ? ?pet.setDescription(petPojo.getDescription());

          117. ? ? ? ?return pet;

          118. ? ?}

          119. }


          4. 控制層實現(xiàn)

          SpringBoot 提供了 @RestController,用于快速定義一個Restful 風格的Controller類@RestController=@ResponseBody + @Controller

          1. @RestController

          2. @RequestMapping("/rest/pets/{customer}")

          3. publicclassRestApiController{

          4. ? ?@Autowired

          5. ? ?privatePetManager dataManager;

          6. ? ?/**

          7. ? ? * 添加寵物

          8. ? ? *

          9. ? ? * @param customer

          10. ? ? * @param pet

          11. ? ? * @return

          12. ? ? */

          13. ? ?@PostMapping

          14. ? ?publicResponseEntity<Object> addPet(@PathVariableString customer,@RequestBodyPet pet){

          15. ? ? ? ?validateCustomer(customer);

          16. ? ? ? ?Pet newPet = dataManager.addPet(customer, pet);

          17. ? ? ? ?// 返回 201.created

          18. ? ? ? ?if(newPet !=null){

          19. ? ? ? ? ? ?URI location =ServletUriComponentsBuilder.fromCurrentRequest().path("/{petId}")

          20. ? ? ? ? ? ? ? ? ? ?.buildAndExpand(newPet.getPetId()).toUri();

          21. ? ? ? ? ? ?returnResponseEntity.created(location).build();

          22. ? ? ? ?}

          23. ? ? ? ?// 返回 204.noContent

          24. ? ? ? ?returnResponseEntity.noContent().build();

          25. ? ?}

          26. ? ?/**

          27. ? ? * 獲取寵物列表

          28. ? ? *

          29. ? ? * @param customer

          30. ? ? * @return

          31. ? ? */

          32. ? ?@GetMapping

          33. ? ?@ResponseBody

          34. ? ?publicList<Pet> listPets(@PathVariableString customer){

          35. ? ? ? ?validateCustomer(customer);

          36. ? ? ? ?List<Pet> pets = dataManager.getPets(customer);

          37. ? ? ? ?return pets;

          38. ? ?}

          39. ? ?/**

          40. ? ? * 獲取某個寵物

          41. ? ? *

          42. ? ? * @param customer

          43. ? ? * @param petId

          44. ? ? */

          45. ? ?@GetMapping("/{petId}")

          46. ? ?@ResponseBody

          47. ? ?publicPet getPet(@PathVariableString customer,@PathVariableString petId){

          48. ? ? ? ?validateCustomer(customer);

          49. ? ? ? ?validatePet(customer, petId);

          50. ? ? ? ?Pet pet = dataManager.getPet(customer, petId);

          51. ? ? ? ?return pet;

          52. ? ?}

          53. ? ?/**

          54. ? ? * 更新寵物信息

          55. ? ? *

          56. ? ? * @param customer

          57. ? ? * @param petId

          58. ? ? * @param pet

          59. ? ? */

          60. ? ?@PutMapping("/{petId}")

          61. ? ?publicResponseEntity<Object> updatePet(@PathVariableString customer,@PathVariableString petId,@RequestBodyPet pet){

          62. ? ? ? ?validateCustomer(customer);

          63. ? ? ? ?validatePet(customer, petId);

          64. ? ? ? ?pet.setPetId(petId);

          65. ? ? ? ?Pet petObject = dataManager.updatePet(customer, pet);

          66. ? ? ? ?if(petObject !=null){

          67. ? ? ? ? ? ?returnResponseEntity.ok(petObject);

          68. ? ? ? ?}

          69. ? ? ? ?returnResponseEntity.noContent().build();

          70. ? ?}

          71. ? ?/**

          72. ? ? * 刪除某個寵物

          73. ? ? *

          74. ? ? * @param customer

          75. ? ? * @param petId

          76. ? ? * @return

          77. ? ? */

          78. ? ?@DeleteMapping("/{petId}")

          79. ? ?publicResponseEntity<Object> removePet(@PathVariableString customer,@PathVariableString petId){

          80. ? ? ? ?validateCustomer(customer);

          81. ? ? ? ?validatePet(customer, petId);

          82. ? ? ? ?dataManager.removePet(customer, petId);

          83. ? ? ? ?returnResponseEntity.ok().build();

          84. ? ?}

          上述代碼中已經(jīng)實現(xiàn)了完整的增刪改查語義。 在Restful 風格的API 接口定義中,往往會引用 HTTP 狀態(tài)碼用于表示不同的結(jié)果,比如一些錯誤的狀態(tài)類型。

          這里我們對Customer、Pet 進行存在性校驗,若資源不存在返回404_NotFound。

          1. ? ?/**

          2. ? ? * 校驗customer是否存在

          3. ? ? *

          4. ? ? * @param customer

          5. ? ? */

          6. ? ?privatevoid validateCustomer(String customer){

          7. ? ? ? ?if(dataManager.getCustomer(customer)==null){

          8. ? ? ? ? ? ?thrownewObjectNotFoundException(String.format("the customer['%s'] is not found", customer));

          9. ? ? ? ?}

          10. ? ?}

          11. ? ?/**

          12. ? ? * 校驗pet是否存在

          13. ? ? *

          14. ? ? * @param customer

          15. ? ? */

          16. ? ?privatevoid validatePet(String customer,String petId){

          17. ? ? ? ?if(dataManager.getPet(customer, petId)==null){

          18. ? ? ? ? ? ?thrownewObjectNotFoundException(String.format("the pet['%s/%s'] is not found", customer, petId));

          19. ? ? ? ?}

          20. ? ?}

          自定義異常攔截

          1. ? ?/**

          2. ? ? * 自定義異常,及攔截邏輯

          3. ? ? *

          4. ? ? * @author atp

          5. ? ? *

          6. ? ? */

          7. ? ?@SuppressWarnings("serial")

          8. ? ?publicstaticclassObjectNotFoundExceptionextendsRuntimeException{

          9. ? ? ? ?publicObjectNotFoundException(String msg){

          10. ? ? ? ? ? ?super(msg);

          11. ? ? ? ?}

          12. ? ?}

          13. ? ?@ResponseBody

          14. ? ?@ExceptionHandler(ObjectNotFoundException.class)

          15. ? ?@ResponseStatus(HttpStatus.NOT_FOUND)

          16. ? ?publicString objectNotFoundExceptionHandler(ObjectNotFoundException ex){

          17. ? ? ? ?return ex.getMessage();

          18. ? ?}


          5. 接口驗證

          1. 添加寵物

          URLPOST http://{{server}}/rest/pets/LiLei請求內(nèi)容

          1. {

          2. "name":"Smart Baby",

          3. "description":"very small and smart also.",

          4. "type":"Dog"

          5. }

          返回示例

          1. 201 created

          2. Content-Length0

          3. DateMon,09Jul201805:15:01 GMT

          4. Locationhttp://localhost:8090/rest/pets/LiLei/b5400334-e7b3-42f1-b192-f5e7c3193543

          2. 獲取寵物列表

          URLGET http://{{server}}/rest/pets/LiLei請求內(nèi)容

          返回示例

          1. 200 OK

          2. Content-Typeapplication/json;charset=UTF-8

          3. DateMon,09Jul201805:23:27 GMT

          4. Transfer-Encodingchunked

          5. [

          6. ? ?{

          7. ? ? ? ?"petId":"b5400334-e7b3-42f1-b192-f5e7c3193543",

          8. ? ? ? ?"name":"Smart Baby",

          9. ? ? ? ?"type":"Dog",

          10. ? ? ? ?"description":"very small and smart also."

          11. ? ?},

          12. ? ?{

          13. ? ? ? ?"petId":"610780af-94f1-4011-a175-7a0f3895163d",

          14. ? ? ? ?"name":"Big Cat",

          15. ? ? ? ?"type":"Cat",

          16. ? ? ? ?"description":"very old but I like it."

          17. ? ?}

          18. ]

          3. 查詢寵物信息

          URLGET http://{{server}}/rest/pets/LiLei/b5400334-e7b3-42f1-b192-f5e7c3193543請求內(nèi)容

          返回示例

          1. 200 OK

          2. Content-Typeapplication/json;charset=UTF-8

          3. DateMon,09Jul201805:25:24 GMT

          4. Transfer-Encodingchunked

          5. {

          6. ? ?"petId":"b5400334-e7b3-42f1-b192-f5e7c3193543",

          7. ? ?"name":"Smart Baby",

          8. ? ?"type":"Dog",

          9. ? ?"description":"very small and smart also."

          10. }

          4. 更新寵物信息

          URLPUT http://{{server}}/rest/pets/LiLei/b5400334-e7b3-42f1-b192-f5e7c3193543請求內(nèi)容

          1. {

          2. "name":"Big Cat V2",

          3. "description":"I don't like it any more",

          4. "type":"Cat"

          5. }

          返回示例

          1. 200 OK

          2. Content-Typeapplication/json;charset=UTF-8

          3. DateMon,09Jul201805:31:28 GMT

          4. Transfer-Encodingchunked

          5. {

          6. ? ?"petId":"a98e4478-e754-4969-851b-bcaccd67263e",

          7. ? ?"name":"Big Cat V2",

          8. ? ?"type":"Cat",

          9. ? ?"description":"I don't like it any more"

          10. }

          5. 刪除寵物

          URLDELETE http://{{server}}/rest/pets/LiLei/b5400334-e7b3-42f1-b192-f5e7c3193543請求內(nèi)容

          返回示例

          1. 200 OK

          2. Content-Length0

          3. DateMon,09Jul201805:32:51 GMT

          相關(guān)出錯

          • 客戶不存在:404 the customer['test'] is not found

          • 寵物不存在:404 the pet['LiLei/b5400334-e7b3-42f1-b192-f5e7c31935431'] is not found

          四、Swagger 的使用

          關(guān)于Swagger

          Swagger是目前非常流行的一個API設(shè)計開發(fā)框架(基于OpenApi), 可用于API的設(shè)計、管理、代碼生成以及Mock測試等。

          目前Swagger的應(yīng)用非常廣,其涵蓋的開源模塊也比較多,這里將使用swagger-ui實現(xiàn)API在線DOC的生成。

          引入依賴

          1. ? ? ? ?

          2. ? ? ? ? ? ?io.springfox

          3. ? ? ? ? ? ?springfox-swagger2

          4. ? ? ? ? ? ?2.7.0

          5. ? ? ? ?

          6. ? ? ? ?

          7. ? ? ? ? ? ?io.springfox

          8. ? ? ? ? ? ?springfox-swagger-ui

          9. ? ? ? ? ? ?2.7.0

          10. ? ? ? ?

          定義API配置

          1. @EnableSwagger2

          2. @Configuration

          3. publicclassSwaggerConfig{

          4. ? ?publicstaticfinalString VERSION ="1.0.0";

          5. ? ?@Value("${swagger.enable}")

          6. ? ?privateboolean enabled;

          7. ? ?ApiInfo apiInfo(){

          8. ? ? ? ?returnnewApiInfoBuilder().

          9. ? ? ? ? ? ? ? ?title("Pet Api Definition")

          10. ? ? ? ? ? ? ? ?.description("The Petstore CRUD Example")

          11. ? ? ? ? ? ? ? ?.license("Apache 2.0")

          12. ? ? ? ? ? ? ? ?.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")

          13. ? ? ? ? ? ? ? ?.termsOfServiceUrl("")

          14. ? ? ? ? ? ? ? ?.version(VERSION)

          15. ? ? ? ? ? ? ? ?.contact(newContact("","","[email protected]"))

          16. ? ? ? ? ? ? ? ?.build();

          17. ? ?}

          18. ? ?@Bean

          19. ? ?publicDocket customImplementation(){

          20. ? ? ? ?returnnewDocket(DocumentationType.SWAGGER_2).select()

          21. ? ? ? ? ? ? ? ?.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))

          22. ? ? ? ? ? ? ? ?.build()

          23. ? ? ? ? ? ? ? ?.enable(enabled)

          24. ? ? ? ? ? ? ? ?.apiInfo(apiInfo());

          25. ? ?}

          26. }

          @EnableSwagger2聲明了Swagger的啟用,Docket的Bean定義是API配置的入口, 可以設(shè)置API名稱、版本號,掃描范圍等。

          聲明API描述

          在原有的Controller 方法上添加關(guān)于API的聲明,如下:

          1. @Api(value ="Pet Restful api")

          2. @RestController

          3. @RequestMapping("/rest/pets/{customer}")

          4. publicclassRestApiController{

          5. ? ?@ApiOperation("添加寵物")

          6. ? ?@ApiImplicitParams({

          7. ? ? ? ? ? ?@ApiImplicitParam(paramType ="path", name ="customer", dataType ="String", required =true, value ="客戶名", defaultValue =""),

          8. ? ? ? ? ? ?@ApiImplicitParam(paramType ="body", name ="pet", dataType ="Pet", required =true, value ="pet 請求", defaultValue ="")})

          9. ? ?@ApiResponses({

          10. ? ? ? ?@ApiResponse(code =201, message ="添加成功"),

          11. ? ? ? ?@ApiResponse(code =404, message ="資源不存在")

          12. ? ?})

          13. ? ?@PostMapping

          14. ? ?publicResponseEntity<Object> addPet(@PathVariableString customer,@RequestBodyPet pet){

          15. ? ? ? ?...

          為了能描述返回對象的文檔說明,為Pet類做API聲明:

          1. @ApiModel("寵物信息")

          2. publicclassPet{

          3. ? ?@ApiModelProperty(name="petId", value="寵物ID")

          4. ? ?privateString petId;

          5. ? ?@ApiModelProperty(name="name", value="寵物名稱")

          6. ? ?privateString name;

          7. ? ?@ApiModelProperty(name="type", value="寵物類型")

          8. ? ?privateString type;

          9. ? ?@ApiModelProperty(name="description", value="寵物描述")

          10. ? ?privateString description;

          相關(guān)的注解:

          注解描述
          @ApiModelProperty用在出入?yún)?shù)對象的字段上
          @Api用于controller類
          @ApiOperation用于controller方法,描述操作
          @ApiResponses用于controller方法,描述響應(yīng)
          @ApiResponse用于@ApiResponses內(nèi),描述單個響應(yīng)結(jié)果
          @ApiImplicitParams用于controller的方法,描述入?yún)?/td>
          @ApiImplicitParam用于@ApiImplicitParams內(nèi),描述單個入?yún)?/td>
          @ApiModel用于返回對象類

          訪問文檔

          最后,訪問 http://localhost:8000/swagger_ui.html,可看到生成的文檔界面:

          bf991dc04c675e6bc7f2b59a25d408b5.webp


          歡迎加入交流群學習,備注加群說實話在這個群,哪怕您不說話,光看聊天記錄,都能學到東西




          兩年嘔心瀝血的文章「面試題」「基礎(chǔ)」「進階」這里全都有!

          300多篇原創(chuàng)技術(shù)文章加入交流群學習海量視頻資源精美腦圖面試題

          長按掃碼可關(guān)注獲取?

          在看和分享對我非常重要!a2749161df7dffaa68a479835e46a51d.webp

          瀏覽 62
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩骚逼网站 | 天天天天色天天天干 | 欧美操屄网 | 精品无码人妻一区二区免费蜜桃 | 久久久91人妻无码精品蜜桃ID |