Spring Boot-構(gòu)建一個(gè)復(fù)雜的RESTful API及單元測試

在前面的快速入門教程中,我們利用5分鐘構(gòu)建了一個(gè)非常簡單的RESTful Webservice,現(xiàn)在我們來利用Spring Boot來構(gòu)建一個(gè)復(fù)雜一點(diǎn)的RestFul API。

關(guān)于RESTful API如何設(shè)計(jì),大家可以自行去阮一峰的博客學(xué)習(xí)一下。話說阮老師真是一個(gè)全才,感覺他都懂,程序猿楷模??!

我們來設(shè)計(jì)一個(gè)Book的RESTful API,如下所示:

請求類型 URL 功能說明
GET /books 查詢書籍列表
POST /books 創(chuàng)建書籍
GET /books/id 根據(jù)ID查詢一本書籍
PUT /books/id 根據(jù)ID更新一本書籍
DELETE /books/id 根據(jù)ID刪除一本書籍

Book的實(shí)體類定義如下:

public class Book {

    private Long bookId;
    private String title;
    private String author;

    //getter/setter方法省略
}

針對Book資源操作的RESTful接口實(shí)現(xiàn)如下:

@RestController
@RequestMapping(value="/books")
public class BookController {

    // 創(chuàng)建線程安全的Map
    static Map<Long, Book> books = Collections.synchronizedMap(new HashMap<Long, Book>());

    @RequestMapping(value="/", method= RequestMethod.GET)
    public List<Book> getUserList() {
        // 處理"/books/"的GET請求,用來獲取圖書列表
        // 還可以通過@RequestParam傳遞參數(shù)來進(jìn)行查詢條件或者翻頁信息的傳遞
        List<Book> r = new ArrayList<Book>(books.values());
        return r;
    }

    @RequestMapping(value="/", method=RequestMethod.POST,produces = "application/json")
    public String createBook(@RequestBody Book book) {
        // 處理"/books/"的POST請求,用來創(chuàng)建User
        // 除了@ModelAttribute綁定參數(shù)之外,還可以通過@RequestParam從頁面中傳遞參數(shù)
        books.put(book.getBookId(), book);
        return "success";
    }

    @RequestMapping(value="/{bookId}", method=RequestMethod.GET)
    public Book getBook(@PathVariable Long bookId) {
        // 處理"/books/{id}"的GET請求,用來獲取url中id值的Book信息
        // url中的id可通過@PathVariable綁定到函數(shù)的參數(shù)中
        return books.get(bookId);
    }

    @RequestMapping(value="/{bookId}", method=RequestMethod.PUT)
    public String putBook(@PathVariable Long bookId, @RequestBody Book book) {
        // 處理"/books/{bookId}"的PUT請求,用來更新Book信息
        Book b = books.get(bookId);
        b.setTitile(book.getTitile());
        b.setAuthor(book.getAuthor());
        books.put(bookId, b);
        return "success";
    }

    @RequestMapping(value="/{bookId}", method=RequestMethod.DELETE)
    public String deleteBook(@PathVariable Long bookId) {
        // 處理"/books/{bookId}"的DELETE請求,用來刪除Book
        books.remove(bookId);
        return "success";
    }
}

單元測試

之前我們在入門教程中使用了Postman來進(jìn)行測試,現(xiàn)在我們使用Spring自家的MockMvc框架來寫單元測試,MockMvc的使用很簡單,更詳細(xì)的用法大家可以自行Google或百度。

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MockServletContext.class)
@WebAppConfiguration
public class TestBookController {

    private MockMvc mvc;

    private RequestBuilder request = null;


    @Before
    public void setUp() throws Exception {
        mvc = MockMvcBuilders.standaloneSetup(new BookController()).build();
        request = null;
    }

    public void testGet() throws Exception{
        request = get("/books/");
        mvc.perform(request)
                .andExpect(status().isOk())
                .andExpect(content().string(equalTo("[]")));
    }

    public void testPost() throws Exception{
        Book book = new Book();
        book.setBookId(Long.parseLong("1"));
        book.setTitile("Spring Boot Tutorial");
        book.setAuthor("bluecoffee");
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonBook = objectMapper.writeValueAsString(book);

        request = post("/books/")
                .contentType(MediaType.APPLICATION_JSON)
                .content(jsonBook.getBytes());

        mvc.perform(request)
                .andExpect(status().isOk())
                .andExpect(content().string(equalTo("success")));

        String respStr = mvc.perform(get("/books/"))
                .andExpect(status().isOk())
                .andExpect(content().string(equalTo("[" + jsonBook + "]")))
                .andReturn().getResponse().getContentAsString();
        System.out.println("testPost.resp:"+respStr);
    }

    public void testPut() throws Exception{
        Book book = new Book();
        book.setBookId(Long.parseLong("1"));
        book.setTitile("Spring Boot學(xué)習(xí)教程");
        book.setAuthor("Alex Qian");
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonBook = objectMapper.writeValueAsString(book);

        request = put("/books/" + book.getBookId())
                .contentType(MediaType.APPLICATION_JSON)
                .content(jsonBook.getBytes());

        mvc.perform(request)
                .andExpect(status().isOk())
                .andExpect(content().string(equalTo("success")));

        String respStr = mvc.perform(get("/books/"+book.getBookId()))
                .andExpect(status().isOk())
                .andExpect(content().string(equalTo(jsonBook)))
                .andReturn().getResponse().getContentAsString();
        System.out.println("testPut.resp:"+respStr);
    }

    public void testDelete() throws Exception{
        request = delete("/books/1");
        mvc.perform(request)
                .andExpect(status().isOk())
                .andExpect(content().string(equalTo("success")));

        String respStr = mvc.perform(get("/books/"))
                .andExpect(status().isOk())
                .andExpect(content().string(equalTo("[]")))
                .andReturn().getResponse().getContentAsString();
        System.out.println("testDelete.resp:"+respStr);

    }

    @Test
    public void testSuite() throws Exception{
        this.testGet();//獲取一本書籍
        this.testPost();//創(chuàng)建一本書籍
        this.testPut();//更新一本書籍
        this.testDelete();//刪除一本書籍
    }
}

小結(jié)

在這次教程里面,我們僅引入Spring Boot的web模塊,并且沒有引入任何配置文件,就構(gòu)建了一個(gè)較完整的RESTful API,文中還簡要介紹了@PathVariable,@RequestBody,@RequestParam等參數(shù)綁定注解的用法,更多的用法大家可以自行去網(wǎng)上查詢資料。

完整代碼戳這里: Chapter 3-1-1 - 構(gòu)建復(fù)雜RESTful API及單元測試

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容