RESTful 架构一个核心概念是“资源”(Resource)。从 RESTful 的角度看,网络里的任何东西都是资源,它可以是一段文本、一张图片、一首歌曲、一种服务等,每个资源都对应一个特定的 URI(统一资源定位符),并用它进行标示,访问这个 URI 就可以获得这个资源。
互联网中,客户端和服务端之间的互动传递的就只是资源的表述,我们上网的过程,就是调用资源的 URI,获取它不同表现形式的过程。这种互动只能使用无状态协议 HTTP,也就是说,服务端必须保存所有的状态,客户端可以使用 HTTP 的几个基本操作,包括 GET(获取)、POST(创建)、PUT(更新)与 DELETE(删除),使得服务端上的资源发生“状态转化”(State Transfer),也就是所谓的“表述性状态转移”。
Spring Boot 对 RESTful 的支持
Spring Boot 全面支持开发 RESTful 程序,通过不同的注解来支持前端的请求,除了经常使用的注解外,Spring Boot 还提了一些组合注解。这些注解来帮助简化常用的 HTTP 方法的映射,并更好地表达被注解方法的语义。
- @GetMapping,处理 Get 请求
- @PostMapping,处理 Post 请求
- @PutMapping,用于更新资源
- @DeleteMapping,处理删除请求
- @PatchMapping,用于更新部分资源
测试类:
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(); } } } }
控制层:
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); } }
接口层
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); } }
原文地址:https://www.cnblogs.com/gjq1126-web/p/11781355.html
时间: 2024-11-12 15:59:05