RESTful 架構一個核心概念是「資源」(Resource)。從 RESTful 的角度看,網絡裏的任何東西都是資源,它能夠是一段文本、一張圖片、一首歌曲、一種服務等,每一個資源都對應一個特定的 URI(統一資源定位符),並用它進行標示,訪問這個 URI 就能夠得到這個資源。前端
互聯網中,客戶端和服務端之間的互動傳遞的就只是資源的表述,咱們上網的過程,就是調用資源的 URI,獲取它不一樣表現形式的過程。這種互動只能使用無狀態協議 HTTP,也就是說,服務端必須保存全部的狀態,客戶端能夠使用 HTTP 的幾個基本操做,包括 GET(獲取)、POST(建立)、PUT(更新)與 DELETE(刪除),使得服務端上的資源發生「狀態轉化」(State Transfer),也就是所謂的「表述性狀態轉移」。java
Spring Boot 全面支持開發 RESTful 程序,經過不一樣的註解來支持前端的請求,除了常用的註解外,Spring Boot 還提了一些組合註解。這些註解來幫助簡化經常使用的 HTTP 方法的映射,並更好地表達被註解方法的語義。web
測試類:spring
package com.example; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.context.WebApplicationContext; @RunWith(SpringRunner.class) @SpringBootTest public class MessageControllerTest { @Autowired private WebApplicationContext wac; private MockMvc mockMvc; @Before public void setup() { this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); saveMessages();//初始化數據 } //獲取全部初始化數據get請求 @Test public void getAllMessages() throws Exception { String mvcResult= mockMvc.perform(MockMvcRequestBuilders.get("/messages")).andReturn().getResponse().getContentAsString(); System.out.println("Result === "+mvcResult); } //獲取單個消息get請求 @Test public void getMessage() throws Exception { String mvcResult= mockMvc.perform(MockMvcRequestBuilders.get("/message/6")).andReturn().getResponse().getContentAsString(); System.out.println("Result === "+mvcResult); } //更新 ID 爲 6 的消息體。測試修改(put 請求) @Test public void modifyMessage() throws Exception { final MultiValueMap<String, String> params = new LinkedMultiValueMap<>(); params.add("id", "6"); params.add("text", "text"); params.add("summary", "summary"); String mvcResult= mockMvc.perform(MockMvcRequestBuilders.put("/message").params(params)) .andReturn().getResponse().getContentAsString(); System.out.println("Result === "+mvcResult); } //測試局部修改(patch 請求) @Test public void patchMessage() throws Exception { final MultiValueMap<String, String> params = new LinkedMultiValueMap<>(); params.add("id", "6"); params.add("text", "text"); String mvcResult= mockMvc.perform(MockMvcRequestBuilders.patch("/message/text") .params(params)).andReturn().getResponse().getContentAsString(); System.out.println("Result === "+mvcResult); } //刪除 ID 爲 6 的消息體,最後從新查詢全部的消息 @Test public void deleteMessage() throws Exception { mockMvc.perform(MockMvcRequestBuilders.delete("/message/6")).andReturn(); String mvcResult= mockMvc.perform(MockMvcRequestBuilders.get("/messages")) .andReturn().getResponse().getContentAsString(); System.out.println("Result === "+mvcResult); } @Test public void saveMessage() throws Exception { final MultiValueMap<String, String> params = new LinkedMultiValueMap<>(); params.add("text", "text"); params.add("summary", "summary"); String mvcResult= mockMvc.perform(MockMvcRequestBuilders.post("/message").params(params)).andReturn().getResponse().getContentAsString(); System.out.println("Result === "+mvcResult); } private void saveMessages() { for (int i=1;i<10;i++){ final MultiValueMap<String, String> params = new LinkedMultiValueMap<>(); params.add("text", "text"+i); params.add("summary", "summary"+i); try { MvcResult mvcResult= mockMvc.perform(MockMvcRequestBuilders.post("/message").params(params)).andReturn(); } catch (Exception e) { e.printStackTrace(); } } } }
控制層:springboot
package com.example.controller; import com.example.domain.Message; import com.example.service.MessageRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/") public class MessageController { @Autowired private MessageRepository messageRepository; // 獲取全部消息體 @GetMapping(value = "messages") public List<Message> list() { List<Message> messages = this.messageRepository.findAll(); return messages; } // 建立一個消息體 @PostMapping(value = "message") public Message create(Message message) { message = this.messageRepository.save(message); return message; } // 使用 put 請求進行修改 @PutMapping(value = "message") public Message modify(Message message) { Message messageResult=this.messageRepository.update(message); return messageResult; } // 更新消息的 text 字段 @PatchMapping(value="/message/text") public Message patch(Message message) { Message messageResult=this.messageRepository.updateText(message); return messageResult; } @GetMapping(value = "message/{id}") public Message get(@PathVariable Long id) { Message message = this.messageRepository.findMessage(id); return message; } @DeleteMapping(value = "message/{id}") public void delete(@PathVariable("id") Long id) { this.messageRepository.deleteMessage(id); } }
接口層restful
package com.example.service; import com.example.domain.Message; import java.util.List; public interface MessageRepository { public List<Message> findAll(); public Message save(Message message); public Message update(Message message); public Message updateText(Message message); public Message findMessage(Long id); public void deleteMessage(Long id); }
服務層網絡
package com.example.service.impl; import com.example.domain.Message; import com.example.service.MessageRepository; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicLong; @Service("messageRepository") public class InMemoryMessageRepository implements MessageRepository { private static AtomicLong counter = new AtomicLong(); private final ConcurrentMap<Long, Message> messages = new ConcurrentHashMap<>(); @Override public List<Message> findAll() { List<Message> messages = new ArrayList<Message>(this.messages.values()); return messages; } @Override public Message save(Message message) { Long id = message.getId(); if (id == null) { id = counter.incrementAndGet(); message.setId(id); } this.messages.put(id, message); return message; } @Override public Message update(Message message) { this.messages.put(message.getId(), message); return message; } @Override public Message updateText(Message message) { Message msg=this.messages.get(message.getId()); msg.setText(message.getText()); this.messages.put(msg.getId(), msg); return msg; } @Override public Message findMessage(Long id) { return this.messages.get(id); } @Override public void deleteMessage(Long id) { this.messages.remove(id); } }