003.springboot web篇:快速構建較複雜的RESTful API與單元測試
說明
通過實現訂單的增刪改查,初步瞭解web相關的構建和使用
REStful API規劃
請求型別 | URL | 說明 |
---|---|---|
GET | /orders | 查詢所有訂單 |
POST | /orders/add | 建立一個訂單 |
GET | /orders/id | 查詢一個訂單 |
POST | /orders/update/id | 更新訂單 |
DELETE | /orders/delete/id | 刪除訂單 |
常用註解說明
- @Controller:修飾class,用來建立處理http請求的物件
- @RestController:Spring4之後加入的註解,原來在@Controller中返回json需要@ResponseBody來配合,如果直接用@RestController替代@Controller就不需要再配置@ResponseBody,預設返回json格式。
- @RequestMapping:配置url對映
- @PathVariable:通過 @PathVariable 可以將 URL 中佔位符引數繫結到控制器處理方法的入參中:URL 中的 {xxx} 佔位符可以通過@PathVariable(“xxx“) 繫結到操作方法的入參中。
- @ModelAttribute:
①繫結請求引數到命令物件:放在功能處理方法的入參上時,用於將多個請求引數繫結到一個命令物件,從而簡化繫結流程,而且自動暴露為模型資料用於檢視頁面展示時使用;
②暴露表單引用物件為模型資料:放在處理器的一般方法(非功能處理方法)上時,是為表單準備要展示的表單引用物件,如註冊時需要選擇的所在城市等,而且在執行功能處理方法(@RequestMapping註解的方法)之前,自動新增到模型物件中,用於檢視頁面展示時使用;
③暴露@RequestMapping方法返回值為模型資料:放在功能處理方法的返回值上時,是暴露功能處理方法的返回值為模型資料,用於檢視頁面展示時使用。 - @RequestParam:獲取url中的引數,用於將請求引數區資料對映到功能處理方法的引數上。
程式碼參考
實體類order
package com.sunld.domain;
public class Order {
/**
* 訂單id
*/
private Integer id;
/**
* 訂單名稱
*/
private String orderName;
/**
* 訂單型別
*/
private String orderType;
/**
* get、set方法
*/
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
public String getOrderType() {
return orderType;
}
public void setOrderType(String orderType) {
this.orderType = orderType;
}
@Override
public String toString() {
return "Order [id=" + id + ", orderName=" + orderName + ", orderType=" + orderType + "]";
}
}
Controller:OrderController
package com.sunld;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.sunld.domain.Order;
@RestController
//定義統一的入口,通過這裡配置使下面的對映都在/orders下
@RequestMapping("/orders")
public class OrderController {
//定義執行緒安全的map用來儲存訂單資訊
private static final Map<Integer , Order> staticOrderMap =
Collections.synchronizedMap(new HashMap<Integer, Order>());
/**
* 查詢所有訂單
* url地址:http://127.0.0.1:8080/orders/
* 還可以通過@RequestParam從頁面中傳遞引數來進行查詢條件或者翻頁資訊的傳遞
* @return
*/
@RequestMapping(value = "/" , method = RequestMethod.GET)
public List<Order> getOrders(){
List<Order> orderList = new ArrayList<Order>(staticOrderMap.values());
return orderList;
}
/**
* 新增訂單
* url地址:http://127.0.0.1:8080/orders/add
* @ModelAttribute:用來接收form中的訂單資訊
* 除了@ModelAttribute繫結引數之外,還可以通過@RequestParam從頁面中傳遞引數
* @param order
* @return
*/
@RequestMapping(value = "/add", method = RequestMethod.POST)
public String addOrder(@ModelAttribute Order order) {
if(order != null) {
staticOrderMap.put(order.getId(), order);
return "success";
}
return "failure";
}
/**
* 根據訂單id獲取訂單資訊
* url地址:http://127.0.0.1:8080/orders/1234
* url中的id可通過@PathVariable繫結到函式的引數中
* @return
*/
@RequestMapping(value = "/{id}" , method = RequestMethod.GET)
public Order getOrderById(@PathVariable Integer id) {
return staticOrderMap.get(id);
}
/**
* 根據訂單id更新訂單資訊
* url地址:http://127.0.0.1:8080/orders/update/1234
* @param id
* @param order
* @return
*/
@RequestMapping(value = "/update/{id}" , method = RequestMethod.POST)
public String updateOrderById(@PathVariable Integer id, @ModelAttribute Order order) {
Order o = staticOrderMap.get(id);
if(o != null && order != null) {
o.setOrderName(order.getOrderName());
o.setOrderType(order.getOrderType());
staticOrderMap.put(id, o);
return "success";
}else {
return "failure";
}
}
/**
* 根據訂單ID刪除訂單資訊
* url地址:http://127.0.0.1:8080/orders/delete/1234
* @param id
* @return
*/
@RequestMapping(value="/delete/{id}", method=RequestMethod.DELETE)
public String deleteOrderById(@PathVariable Integer id) {
staticOrderMap.remove(id);
return "success";
}
}
測試類:OrderControllerTest
package com.sunld.controller;
import static org.hamcrest.CoreMatchers.equalTo;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import com.sunld.OrderController;
@RunWith(SpringRunner.class)
@SpringBootTest
public class OrderControllerTest {
private MockMvc mvc;
@Before
public void setUp() throws Exception {
mvc = MockMvcBuilders.standaloneSetup(new OrderController()).build();
}
@Test
public void testOrderController() throws Exception {
//1.建立查詢所有訂單,結果返回為空
System.out.println("=====================初次查詢所有訂單資訊start=====================");
getOrders()
.andExpect(MockMvcResultMatchers.content().string(equalTo("[]")))
.andReturn();
System.out.println("=====================初次查詢所有訂單資訊end=======================");
System.out.println("=====================第一次新增訂單start=========================");
// 2、post提交一個訂單
mvc.perform(MockMvcRequestBuilders.post("/orders/add")
.param("id", "1234")
.param("orderName", "購買平板電腦")
.param("orderType", "線上付款")
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.content().string(equalTo("success")))
.andReturn();
//2.1、查詢所有訂單
/**
* 結果應該為"[{\"id\":1234,\"orderName\":\"購買平板電腦\",\"orderType\":\"線上付款\"}]"
*/
getOrders()
.andExpect(MockMvcResultMatchers.content().string(equalTo("[{\"id\":1234,\"orderName\":\"購買平板電腦\",\"orderType\":\"線上付款\"}]")))
.andReturn();
System.out.println("=====================第一次新增訂單end===========================");
System.out.println("=====================再次新增訂單start===========================");
//3、再新增一個訂單
mvc.perform(MockMvcRequestBuilders.post("/orders/add")
.param("id", "3456")
.param("orderName", "購買奶粉")
.param("orderType", "貨到付款")
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.content().string(equalTo("success")))
.andReturn();
//3.1、檢視所有訂單資訊
/**
* 訂單資訊:
* [{"id":3456,"orderName":"購買奶粉","orderType":"貨到付款"},{"id":1234,"orderName":"購買平板電腦","orderType":"線上付款"}]
*/
getOrders();
System.out.println("=====================再次新增訂單end=============================");
System.out.println("=====================修改存在編號的訂單start============================");
//4、修改編號為1234的訂單:該訂單存在
mvc.perform(MockMvcRequestBuilders.post("/orders/update/1234")
.param("orderName", "訂單名稱由【購買平板電腦】修改為【再次購買平板電腦】")
.param("orderType", "線上付款")
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andReturn();
//4.1查詢訂單1234
getOrdersById("1234");
System.out.println("=====================修改存在編號的訂單end==============================");
System.out.println("=====================修改訂單編號不存在的訂單start==============================");
//5、修改編號為1的訂單、該訂單不存在,直接返回failure
mvc.perform(MockMvcRequestBuilders.post("/orders/update/1")
.param("orderName", "訂單名稱由【購買平板電腦】修改為【再次購買平板電腦】")
.param("orderType", "線上付款")
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.content().string(equalTo("failure")))
.andReturn();
System.out.println("=====================修改訂單編號不存在的訂單end==============================");
//6、刪除訂單1234
mvc.perform(MockMvcRequestBuilders.delete("/orders/delete/1234").accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.content().string(equalTo("success")))
.andReturn();
//6、1檢視所有訂單
getOrders();
}
private ResultActions getOrders() throws Exception {
return mvc.perform(MockMvcRequestBuilders.get("/orders/").accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
// .andReturn();
}
private ResultActions getOrdersById(String id) throws Exception {
return mvc.perform(MockMvcRequestBuilders.get("/orders/" + id).accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
// .andReturn();
}
}
總結
參考
程式碼
相關推薦
003.springboot web篇:快速構建較複雜的RESTful API與單元測試
說明 通過實現訂單的增刪改查,初步瞭解web相關的構建和使用 REStful API規劃 請求型別 URL 說明 GET /orders
Spring Boot 入門篇 (二) Spring Boot構建RESTful API與單元測試
http://blog.didispace.com/springbootrestfulapi/ 首先,回顧並詳細說明一下在快速入門中使用的@Controller、@RestController、@RequestMapping註解。如果您對Spring MVC不熟悉並且還沒有嘗試過快速入門案例,建
Spring Boot 2.x基礎教程:構建RESTful API與單元測試
首先,回顧並詳細說明一下在快速入門中使用的@Controller、@RestController、@RequestMapping註
Spring Boot構建RESTful API與單元測試實戰
一 點睛 1 相關注解 @Controller:修飾class,用來建立處理http請求的物件 @RestController:Spring4之後加入的註解,原來在@Controller中返回json需要@ResponseBody來配合,如果直接用@
Spring Boot構建RESTful API與單元測試
@Controller:修飾class,用來建立處理http請求的物件@RestController:Spring4之後加入的註解,原來在@Controller中返回json需要@ResponseBody來配合,如果直接用@RestController替代@Controlle
(轉)第十一篇:springboot集成swagger2,構建優雅的Restful API
html 風格 lan round amt select() hash 指定 model 聲明:本部分內容均轉自於方誌明博友的博客,因為本人很喜歡他的博客,所以一直在學習,轉載僅是記錄和分享,若也有喜歡的人的話,可以去他的博客首頁看:http://blog.csdn.n
004.SpringBoot web篇:靜態資源管理
預設靜態資源管理 在web開發中,靜態資源的訪問是必不可少的,如:圖片、js、css 等資源的訪問。spring Boot 對靜態資源訪問提供了很好的支援,基本使用預設配置就能滿足開發需求。 SpringBoot預設為我們提供了靜態資源處理,使用We
springboot集成swagger2,構建優雅的Restful API
測試 sele ase 我們 conf start orien ket 過程 swagger,中文“拽”的意思。它是一個功能強大的api框架,它的集成非常簡單,不僅提供了在線文檔的查閱,而且還提供了在線文檔的測試。另外swagger很容易構建restful風格的api,簡單
企業級 SpringBoot 教程 (十一)springboot集成swagger2,構建優雅的Restful API
group require pip 掃描 pan itl 信息 elm 框架 swagger,中文“拽”的意思。它是一個功能強大的api框架,它的集成非常簡單,不僅提供了在線文檔的查閱,而且還提供了在線文檔的測試。另外swagger很容易構建restful風格的api,簡單
JAVA springboot微服務b2b2c電子商務系統-springboot集成swagger2,構建優雅的Restful API(十一)
利用 swagger itl ecif b2b 測試 功能 mod rem swagger,中文“拽”的意思。它是一個功能強大的api框架,它的集成非常簡單,不僅提供了在線文檔的查閱,而且還提供了在線文檔的測試。另外swagger很容易構建restful風格的api,簡單優
springboot(基礎篇):快速構建一個springboot專案
前言: springboot作為springcloud的基礎,學會springboot是必不可少的技能,所以這個系列教程一是記錄自己的學習過程,二是作為一份分享教程,幫助新手
SpringBoot第二篇:web(基於Thymeleaf模板)
接著第一篇,繼續配置web專案。 1、在pom檔案中加入: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-sta
一起來學SpringBoot | 第一篇:構建第一個SpringBoot工程
文章目錄 1. 設計的目標 2. 前提 3. 建立專案 3.1. 目錄結果 3.2. pom.xml 依賴 3.3. 主函式入口 3.4. 初窺配置檔案 3.5. 測試 4. 拓展知識 4.1. 自定義Banner 5. 總結 6. 說點什麼
轉載:SpringBoot非官方教程 | 第十一篇:springboot整合swagger2,構建優雅的Restful API
swagger,中文“拽”的意思。它是一個功能強大的api框架,它的整合非常簡單,不僅提供了線上文件的查閱,而且還提供了線上文件的測試。另外swagger很容易構建restful風格的api,簡單優雅帥氣,正如它的名字。 一、引入依賴 <depend
SpringBoot2.X (三):快速構建SpringBoot 專案的兩種方式
上篇通過maven 專案手動構建的方式稍微有點麻煩,我們這裡有兩種快速構建的方式: 一、 通過 http://start.spring.io/ 線上構建 二、 通過IntelliJ IDEA 快速構建 let’s go ----> 選擇group,
SpringBoot第十五篇:swagger構建優雅文件
作者:追夢1819 原文:https://www.cnblogs.com/yanfei1819/p/11007470.html 版權宣告:本文為博主原創文章,轉載請附上博文連結! 引言 前面的十四篇文介紹了 SpringBoot 的一些基本和常用的功能。後面,我們將介紹 SpringBoot 的高階的功
JAVAEE——SpringBoot日誌篇:日誌框架SLF4j、日誌配置、日誌使用、切換日誌框架
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"> <!-- 日誌輸出格式: %d表示日期時間, %thread表示執行緒名
自學Springboot第一篇(快速入門)
SpringBoot的核心入口類和@SpringBootApplication Spring Boot的專案一般都會有*Application的入口類,入口類中會有main方法,這是一個標準的Java應用程式的入口方法。 @SpringBootApplication 註解
Spring Boot基礎教程 ( 一 ) :基礎專案構建,引入web模組,完成一個簡單的RESTful API
簡介 在您第1次接觸和學習Spring框架的時候,是否因為其繁雜的配置而退卻了?在你第n次使用Spring框架的時候,是否覺得一堆反覆黏貼的配置有一些厭煩?那麼您就不妨來試試使用Spring Boot來讓你更易上手,更簡單快捷地構建Spring應用! Spring Boot
一起來學SpringBoot | 第二篇:SpringBoot配置詳解
文章目錄 自定義屬性配置 自定義檔案配置 多環境化配置 外部命令引導 總結 說點什麼 SpringBoot 是為了簡化 Spring 應用的建立、執行、除錯、部署等一系列問題而誕生的產物,自動裝配的特性讓我們可以更好的關注業務本身而不是外部的XML配