diff --git a/README.md b/README.md
index d423f9d7..8188e8b4 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,20 @@
### 作业描述
-#### 切换到课程对应的分支查看每节课的作业要求
-* Routing: routing
-* Data Binding: data-binding
-* Validation: validation
-* Customised Response: customize-response
-* Error Handling: error-handling
-
- 注意:最终需要将改动合并到master分支
+根据课堂上的demo,完成下面需求
+1. 提供获取某一条热搜事件的接口
+2. 提供能够根据起始参数,获取对应范围内的热搜事件列表的接口
+3. 提供添加热搜事件的接口(事件包含两个字段:事件名称和关键字)
+4. 提供修改某条热搜事件的接口(demo没有展示,请大家自己完成)
+5. 提供删除某条热搜事件的接口(demo没有展示,请大家自己完成)
+
+#### 需求4、5详细描述
+
+* 需求4: 修改某条事件时(通过参数传递的序号,修改列表中对应的事件数据),如果RequestBody只传了eventName没有传keyword那么仅仅只修改eventName
+ 如果只传了keyword没有传eventName,那么只修改keyword字段
+ 如果两个字段都传了,那么都进行修改
+
+* 需求5: 通过参数传递的序号,删除列表中对应的某条事件数据
+
+
+ 注意:所有的需求都请先写测试再写实现
diff --git a/src/main/java/com/thoughtworks/rslist/api/RsController.java b/src/main/java/com/thoughtworks/rslist/api/RsController.java
index 6899e4de..ea546478 100644
--- a/src/main/java/com/thoughtworks/rslist/api/RsController.java
+++ b/src/main/java/com/thoughtworks/rslist/api/RsController.java
@@ -1,11 +1,53 @@
package com.thoughtworks.rslist.api;
-import org.springframework.web.bind.annotation.RestController;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.thoughtworks.rslist.domain.RsEvent;
+import org.springframework.web.bind.annotation.*;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.function.UnaryOperator;
@RestController
public class RsController {
- private List rsList = Arrays.asList("第一条事件", "第二条事件", "第三条事件");
+ private List rsList = initRsEventList();
+ private List initRsEventList(){
+ List rsEventList = new ArrayList<>();
+ rsEventList.add(new RsEvent("第一条事件","无标签"));
+ rsEventList.add(new RsEvent("第二条事件","无标签"));
+ rsEventList.add(new RsEvent("第三条事件","无标签"));
+ return rsEventList;
+ }
+
+ @GetMapping("/rs/{index}")
+ public RsEvent getOneRsEvent(@PathVariable int index){
+ return rsList.get(index -1);
+ }
+
+ @GetMapping("/rs/list")
+ public List getRsEventBetween(@RequestParam(required = false) Integer start,@RequestParam(required = false) Integer end){
+ if(start == null || end == null){
+ return rsList;
+ }
+ return rsList.subList(start-1,end);
+ }
+
+ @PostMapping("/rs/event")
+ public void addRsEvent(@RequestBody String rsEvent) throws JsonProcessingException {
+ ObjectMapper objectMapper = new ObjectMapper();
+ RsEvent event = objectMapper.readValue(rsEvent,RsEvent.class);
+ rsList.add(event);
+ }
+
+ @DeleteMapping ("/rs/{index}")
+ public void deleteRsEvent(@PathVariable int index) {
+ rsList.remove(index-1);
+ }
+
+ @PatchMapping("/rs/{index}")
+ public void modifyRsEvent(@PathVariable int index,@RequestBody RsEvent rsEvent ) {
+ rsList.set(index - 1,rsEvent);
+ }
}
diff --git a/src/main/java/com/thoughtworks/rslist/api/UserController.java b/src/main/java/com/thoughtworks/rslist/api/UserController.java
new file mode 100644
index 00000000..6d161428
--- /dev/null
+++ b/src/main/java/com/thoughtworks/rslist/api/UserController.java
@@ -0,0 +1,27 @@
+package com.thoughtworks.rslist.api;
+
+import com.thoughtworks.rslist.domain.User;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+public class UserController{
+ List userList = new ArrayList<>();
+
+ @PostMapping("/user")
+ public void addUser(@RequestBody @Valid User user){
+ userList.add(user);
+ }
+
+ @GetMapping("/user")
+ public List getUserList(){
+ return userList;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/thoughtworks/rslist/domain/RsEvent.java b/src/main/java/com/thoughtworks/rslist/domain/RsEvent.java
new file mode 100644
index 00000000..79d18026
--- /dev/null
+++ b/src/main/java/com/thoughtworks/rslist/domain/RsEvent.java
@@ -0,0 +1,31 @@
+package com.thoughtworks.rslist.domain;
+
+public class RsEvent {
+ private String eventName;
+ private String keyWord;
+
+ public RsEvent(String eventName,String keyWord){
+ this.eventName = eventName;
+ this.keyWord = keyWord;
+ }
+
+ public RsEvent(){
+
+ }
+
+ public String getKeyWord() {
+ return keyWord;
+ }
+
+ public void setKeyWord(String keyWord) {
+ this.keyWord = keyWord;
+ }
+
+ public String getEventName() {
+ return eventName;
+ }
+
+ public void setEventName(String eventName) {
+ this.eventName = eventName;
+ }
+}
diff --git a/src/main/java/com/thoughtworks/rslist/domain/User.java b/src/main/java/com/thoughtworks/rslist/domain/User.java
new file mode 100644
index 00000000..ca0e65a8
--- /dev/null
+++ b/src/main/java/com/thoughtworks/rslist/domain/User.java
@@ -0,0 +1,76 @@
+package com.thoughtworks.rslist.domain;
+
+import javax.validation.constraints.*;
+
+public class User {
+ @NotNull
+ @Size(max = 8)
+ private String name;
+ @NotNull
+ private String gender;
+ @NotNull
+ @Min(18)
+ @Max(100)
+ private int age;
+ @Email
+ private String email;
+ @Pattern(regexp = "1\\d{10}")
+ private String phone;
+ private int voteNum = 10;
+
+ public User(String name, String gender, int age, String email, String phone) {
+ this.name = name;
+ this.gender = gender;
+ this.age = age;
+ this.email = email;
+ this.phone = phone;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName() {
+ this.name = name;
+ }
+
+ public String getGender() {
+ return gender;
+ }
+
+ public void setGender(String gender) {
+ this.gender = gender;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public int getVoteNum() {
+ return voteNum;
+ }
+
+ public void setVoteNum(int voteNum) {
+ this.voteNum = voteNum;
+ }
+}
diff --git a/src/test/java/com/thoughtworks/rslist/api/RsControllerTest.java b/src/test/java/com/thoughtworks/rslist/api/RsControllerTest.java
new file mode 100644
index 00000000..a9de3371
--- /dev/null
+++ b/src/test/java/com/thoughtworks/rslist/api/RsControllerTest.java
@@ -0,0 +1,126 @@
+package com.thoughtworks.rslist.api;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.thoughtworks.rslist.domain.RsEvent;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+
+import static org.hamcrest.Matchers.hasSize;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+import static org.hamcrest.Matchers.is;
+
+@SpringBootTest
+@AutoConfigureMockMvc
+public class RsControllerTest {
+ @Autowired
+ MockMvc mockMvc;
+ @Test
+ public void should_get_rs_event_list() throws Exception{
+ mockMvc.perform(get("/rs/list")).andExpect(jsonPath("$",hasSize(3)))
+ .andExpect(jsonPath("$[0].eventName",is("第一条事件")))
+ .andExpect(jsonPath("$[0].keyWord",is("无标签")))
+ .andExpect(jsonPath("$[1].eventName",is("第二条事件")))
+ .andExpect(jsonPath("$[1].keyWord",is("无标签")))
+ .andExpect(jsonPath("$[2].eventName",is("第三条事件")))
+ .andExpect(jsonPath("$[2].keyWord",is("无标签")))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ public void should_get_one_rs_event() throws Exception{
+ mockMvc.perform(get("/rs/1"))
+ .andExpect(jsonPath("$.eventName",is("第一条事件")))
+ .andExpect(jsonPath("$.keyWord",is("无标签")))
+ .andExpect(status().isOk());
+ mockMvc.perform(get("/rs/2"))
+ .andExpect(jsonPath("$.eventName",is("第二条事件")))
+ .andExpect(jsonPath("$.keyWord",is("无标签")))
+ .andExpect(status().isOk());
+ mockMvc.perform(get("/rs/3"))
+ .andExpect(jsonPath("$.eventName",is("第三条事件")))
+ .andExpect(jsonPath("$.keyWord",is("无标签")))
+ .andExpect(status().isOk());
+ }
+ @Test
+ public void should_get_rs_event_between() throws Exception{
+ mockMvc.perform(get("/rs/list?start=1&end=2"))
+ .andExpect(jsonPath("$",hasSize(2)))
+ .andExpect(jsonPath("$[0].eventName",is("第一条事件")))
+ .andExpect(jsonPath("$[0].keyWord",is("无标签")))
+ .andExpect(jsonPath("$[1].eventName",is("第二条事件")))
+ .andExpect(jsonPath("$[1】.keyWord",is("无标签")))
+ .andExpect(status().isOk());
+ mockMvc.perform(get("/rs/list?start=2&end=3"))
+ .andExpect(jsonPath("$",hasSize(2)))
+ .andExpect(jsonPath("$[0].eventName",is("第二条事件")))
+ .andExpect(jsonPath("$[0].keyWord",is("无标签")))
+ .andExpect(jsonPath("$[1].eventName",is("第三条事件")))
+ .andExpect(jsonPath("$[1】.keyWord",is("无标签")))
+ .andExpect(status().isOk());
+ mockMvc.perform(get("/rs/list?start=1&end=3"))
+ .andExpect(jsonPath("$",hasSize(3)))
+ .andExpect(jsonPath("$[0].eventName",is("第一条事件")))
+ .andExpect(jsonPath("$[0].keyWord",is("无标签")))
+ .andExpect(jsonPath("$[1].eventName",is("第二条事件")))
+ .andExpect(jsonPath("$[1】.keyWord",is("无标签")))
+ .andExpect(jsonPath("$[2].eventName",is("第三条事件")))
+ .andExpect(jsonPath("$[2】.keyWord",is("无标签")))
+ .andExpect(status().isOk());
+ }
+ @Test
+ public void should_add_rs_event() throws Exception{
+ RsEvent rsEvent = new RsEvent("猪肉涨价了","经济");
+ ObjectMapper objectMapper = new ObjectMapper();
+ String jsonString = objectMapper.writeValueAsString(rsEvent);
+ mockMvc.perform(post("/rs/event").content(jsonString).contentType(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk());
+
+ mockMvc.perform(get("/rs/list")).andExpect(jsonPath("$",hasSize(4)))
+ .andExpect(jsonPath("$[0].eventName",is("第一条事件")))
+ .andExpect(jsonPath("$[0].keyWord",is("无标签")))
+ .andExpect(jsonPath("$[1].eventName",is("第二条事件")))
+ .andExpect(jsonPath("$[1].keyWord",is("无标签")))
+ .andExpect(jsonPath("$[2].eventName",is("第三条事件")))
+ .andExpect(jsonPath("$[2].keyWord",is("无标签")))
+ .andExpect(jsonPath("$[3].eventName",is("猪肉涨价了")))
+ .andExpect(jsonPath("$[3].keyWord",is("经济")))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ public void should_modify_rs_event_eventName_and_keyWord() throws Exception {
+ RsEvent rsEvent = new RsEvent("猪肉涨价了","经济");
+ ObjectMapper objectMapper = new ObjectMapper();
+ String jsonString = objectMapper.writeValueAsString(rsEvent);
+
+ mockMvc.perform(patch("/rs/1").content(jsonString).contentType(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk());
+
+ mockMvc.perform(get("/rs/list")).andExpect(jsonPath("$",hasSize(3)))
+ .andExpect(jsonPath("$[0].eventName",is("猪肉涨价了")))
+ .andExpect(jsonPath("$[0].keyWord",is("经济")))
+ .andExpect(jsonPath("$[1].eventName",is("第二条事件")))
+ .andExpect(jsonPath("$[1].keyWord",is("无标签")))
+ .andExpect(jsonPath("$[2].eventName",is("第三条事件")))
+ .andExpect(jsonPath("$[2].keyWord",is("无标签")))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ public void should_delete_rs_event() throws Exception {
+ mockMvc.perform(delete("/rs/1")).andExpect(status().isOk());
+
+ mockMvc.perform(get("/rs/list")).andExpect(jsonPath("$",hasSize(2)))
+ .andExpect(jsonPath("$[0].eventName",is("第二条事件")))
+ .andExpect(jsonPath("$[0].keyWord",is("无标签")))
+ .andExpect(jsonPath("$[1].eventName",is("第三条事件")))
+ .andExpect(jsonPath("$[1].keyWord",is("无标签")))
+ .andExpect(status().isOk());
+ }
+
+}
diff --git a/src/test/java/com/thoughtworks/rslist/api/UserControllerTest.java b/src/test/java/com/thoughtworks/rslist/api/UserControllerTest.java
new file mode 100644
index 00000000..c848049e
--- /dev/null
+++ b/src/test/java/com/thoughtworks/rslist/api/UserControllerTest.java
@@ -0,0 +1,89 @@
+package com.thoughtworks.rslist.api;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.thoughtworks.rslist.domain.RsEvent;
+import com.thoughtworks.rslist.domain.User;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+
+import static org.hamcrest.Matchers.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+@SpringBootTest
+@AutoConfigureMockMvc
+public class UserControllerTest {
+ @Autowired
+ MockMvc mockMvc;
+
+ @Test
+ public void should_register_user() throws Exception {
+ User user = new User("lyx","female",18,"1@2.com","12222222222");
+ ObjectMapper objectMapper = new ObjectMapper();
+ String jsonString = objectMapper.writeValueAsString(user);
+ mockMvc.perform(post("/user")
+ .content(jsonString)
+ .contentType(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk());
+
+ mockMvc.perform(get("/user"))
+ .andExpect(jsonPath("$",hasSize(1)))
+ .andExpect(jsonPath("$[0].name",is("lyx")))
+ .andExpect(jsonPath("$[0].gender",is("female")))
+ .andExpect(jsonPath("$[0].age",is(18)))
+ .andExpect(jsonPath("$[0].email",is("1@2.com")))
+ .andExpect(jsonPath("$[0].phone",is("12222222222")))
+ .andExpect(status().isOk());
+ }
+
+
+ @Test
+ public void name_should_less_than_8() throws Exception{
+ User user = new User("lyx111111","female",18,"1@2.com","12222222222");
+ ObjectMapper objectMapper = new ObjectMapper();
+ String jsonString = objectMapper.writeValueAsString(user);
+ mockMvc.perform(post("/user")
+ .content(jsonString)
+ .contentType(MediaType.APPLICATION_JSON))
+ .andExpect(status().isBadRequest());
+ }
+
+ @Test
+ public void age_should_between_18_and_100() throws Exception{
+ User user = new User("lyx","female",118,"1@2.com","12222222222");
+ ObjectMapper objectMapper = new ObjectMapper();
+ String jsonString = objectMapper.writeValueAsString(user);
+ mockMvc.perform(post("/user")
+ .content(jsonString)
+ .contentType(MediaType.APPLICATION_JSON))
+ .andExpect(status().isBadRequest());
+ }
+
+ @Test
+ public void email_should_right() throws Exception{
+ User user = new User("lyx","female",28,".com","12222222222");
+ ObjectMapper objectMapper = new ObjectMapper();
+ String jsonString = objectMapper.writeValueAsString(user);
+ mockMvc.perform(post("/user")
+ .content(jsonString)
+ .contentType(MediaType.APPLICATION_JSON))
+ .andExpect(status().isBadRequest());
+ }
+
+ @Test
+ public void phone_should_right() throws Exception{
+ User user = new User("lyx","female",28,".com","3312222222222");
+ ObjectMapper objectMapper = new ObjectMapper();
+ String jsonString = objectMapper.writeValueAsString(user);
+ mockMvc.perform(post("/user")
+ .content(jsonString)
+ .contentType(MediaType.APPLICATION_JSON))
+ .andExpect(status().isBadRequest());
+ }
+}
\ No newline at end of file