First, modify ApiResponses

package com.crownboot.web.global.response;

import java.io.Serializable;
import java.time.LocalDateTime;

import javax.servlet.http.HttpServletResponse;

import org.springframework.http.HttpStatus;
import org.springframework.http.server.ServerHttpResponse;

/** * The interface returns (polymorphic) **@author luopeng
 *
 * @param <T>
 */
public class ApiResponse<T> implements Serializable {

	/** ** sequence */
	private static final long serialVersionUID = -1296644476749112463L;

	/** * does not need to return the result **@param status
	 */
	public static ApiResponse<Void> success(HttpServletResponse response, int code) {
		response.setStatus(code);
		return SuccessResponse.<Void>builder().code(code).build();

	}

	/** * successfully returns **@param object
	 */
	public static <T> ApiResponse<T> success(T object) {
		return success(HttpStatus.OK.value(), object);
	}

	/** * successfully returns **@param object
	 */
	public static <T> ApiResponse<T> success(int code, T object) {
		return SuccessResponse.<T>builder().code(code).data(object).build();
	}

	/** * successfully returns **@param status
	 * @param object
	 */
	public static <T> ApiResponse<T> success(HttpServletResponse response, T object) {
		return SuccessResponse.<T>builder().code(HttpStatus.OK.value()).data(object).build();
	}

	/** * successfully returns **@param status
	 * @param object
	 */
	public static <T> ApiResponse<T> success(HttpServletResponse response, int status, T object) {
		response.setStatus(status);
		return SuccessResponse.<T>builder().code(status).data(object).build();
	}

	/** * successfully returns **@param status
	 * @param object
	 */
	public static <T> ApiResponse<T> success(ServerHttpResponse response, int status, T object) {
		response.setStatusCode(org.springframework.http.HttpStatus.valueOf(status));
		returnSuccessResponse.<T>builder().code(status).data(object).build(); }}Copy the code

Add SuccessResponses

package com.crownboot.web.global.response;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

/** * successfully returns **@author luopeng
 */
@Setter
@Getter
@ToString
@Builder
@EqualsAndHashCode(callSuper = false)
@AllArgsConstructor
@NoArgsConstructor
public class SuccessResponse<T> extends ApiResponse<T> {

    private static final long serialVersionUID = 1L;

    /** * Whether the request was successful */
    @Builder.Default
    private boolean success = true;

    /** * HTTP status code */
    @Builder.Default
    private int code = 200;
    /** * The result set returns */
    private T data;
}
Copy the code

3. Add FailedResponses to handle exceptions

package com.crownboot.web.global.response;

import java.time.LocalDateTime;

import com.fasterxml.jackson.annotation.JsonFormat;

import cn.hutool.core.date.DatePattern;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

/** * successfully returns **@author luopeng
 */
@Setter
@Getter
@ToString
@Builder
@EqualsAndHashCode(callSuper = false)
@AllArgsConstructor
@NoArgsConstructor
public class FailedResponse<T> extends ApiResponse<T> {

    private static final long serialVersionUID = 1L;

    /** * Whether the request was successful */
    @Builder.Default
    private boolean success = false;

    /** * HTTP status code */
    @Builder.Default
    private int code = 500;
    /** ** */
    private String message;
    /** * Exception message */
    private String exception;

    /** * The specific class name of the exception */
    private String exceptionClazz;
    
    /** * The current timestamp */
    @JsonFormat(timezone = "GMT+8", pattern = DatePattern.NORM_DATETIME_PATTERN)
    private LocalDateTime time;
}
Copy the code

4. Modify UserController

package com.gitee.example.controller;

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.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.gitee.example.model.User;
import com.gitee.web.api.ApiResponses;

/** * Interface class */
@RestController
@RequestMapping(value = "/users2")
public class UserController2 {

	// Create thread-safe Map
	private static Map<Long, User> users = Collections.synchronizedMap(new HashMap<Long, User>());

	@GetMapping
	public ApiResponses<List<User>> getUserList() {
		// Handle the GET request for "/users/" to GET the list of users
		// You can also use @requestParam to pass parameters from the page for query criteria or page-turning information
		List<User> r = new ArrayList<>(users.values());
		return ApiResponses.success(r);
	}
 
	@PostMapping
	public ApiResponses<String> postUser(@RequestBody User user) {
		// Handles POST requests for "/users/", used to create users
		In addition to the @requestBody binding parameter, you can also pass parameters from the page via @requestParam
		users.put(user.getId(), user);
		return ApiResponses.success("New success");
	}

	@GetMapping("/{id}")
	public ApiResponses<User> getUser(@PathVariable Long id) {
		// Handle the GET request for "/users/{id}", which is used to GET the User information for the id value in the URL
		// The ID in the URL can be bound to the parameter of the function via @pathvariable
		return  ApiResponses.success(users.get(id));
	}

	@PutMapping("/{id}")
	public ApiResponses<String> putUser(@PathVariable Long id, @RequestBody User user) {
		// Handle the PUT request for "/users/{id}" to update the User information
		User u = users.get(id);
		u.setName(user.getName());
		u.setAge(user.getAge());
		users.put(id, u);
		return ApiResponses.success("Update successful");
	}

	@DeleteMapping("/{id}")
	public ApiResponses<String> deleteUser(@PathVariable Long id) {
		// Handle the DELETE request for "/users/{id}", which is used to DELETE the User
		users.remove(id);
		return ApiResponses.success("Deleted successfully"); }}Copy the code

Modify the unit tests

package com.gitee.example;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
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.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import java.nio.charset.StandardCharsets;
import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
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.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.RequestBuilder;

import com.gitee.Application;
import com.gitee.example.model.User;
import com.gitee.web.api.SuccessResponses;

import cn.hutool.core.lang.TypeReference;
import cn.hutool.json.JSONUtil;

@AutoConfigureMockMvc
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ApplicationTests2 {
   
	@Autowired
    private MockMvc mvc;

 
	@Test
    public void testUserController2(a) throws Exception {
        UserController / / test
        RequestBuilder request;

        // 1, the user list should be empty
        request = get("/users2/");
        MvcResult result = mvc.perform(request)
                .andExpect(status().isOk())
                .andReturn();
        String content = result.getResponse().getContentAsString(StandardCharsets.UTF_8);
        SuccessResponses<List<User>> response = JSONUtil.toBean(content, new TypeReference<SuccessResponses<List<User>>>() {}, true);
        assertThat(response.getData().size(), is(0));

        // 2, post submits a user
        User puser = new User();
        puser.setId(1L);
        puser.setName("Test Master");
        puser.setAge(20);
        
        request =  post("/users2/")
        .contentType(MediaType.APPLICATION_JSON)
        .content(JSONUtil.toJsonStr(puser));
        
        result = mvc.perform(request)
                .andExpect(status().isOk())
                .andReturn();
        content = result.getResponse().getContentAsString(StandardCharsets.UTF_8);
        SuccessResponses<String> response1 = JSONUtil.toBean(content, new TypeReference<SuccessResponses<String>>() {}, true);
        assertThat(response1.getData(), is("New success"));

        // 3, get get user list, should have just inserted data
        request = get("/users2/");
        result = mvc.perform(request)
                .andExpect(status().isOk())
                .andReturn();
        content = result.getResponse().getContentAsString(StandardCharsets.UTF_8);
        SuccessResponses<List<User>> response2 = JSONUtil.toBean(content, new TypeReference<SuccessResponses<List<User>>>() {}, true);
        assertThat(response2.getData().size(), is(1));

        // 4. Put Changes the user whose ID is 1
        puser.setName("The Ultimate Test master.");
        puser.setAge(30);
        request =  put("/users2/1")
                .contentType(MediaType.APPLICATION_JSON)
                .content(JSONUtil.toJsonStr(puser));
        
        result = mvc.perform(request)
                .andExpect(status().isOk())
                .andReturn();
        content = result.getResponse().getContentAsString(StandardCharsets.UTF_8);
        SuccessResponses<String> response3 = JSONUtil.toBean(content, new TypeReference<SuccessResponses<String>>() {}, true);
        assertThat(response3.getData(), is("Update successful"));

        // get a user whose id is 1
        request = get("/users2/1");
        result = mvc.perform(request)
                .andExpect(status().isOk())
                .andReturn();
        content = result.getResponse().getContentAsString(StandardCharsets.UTF_8);
        SuccessResponses<User> response4 = JSONUtil.toBean(content, new TypeReference<SuccessResponses<User>>() {},true);
        User user = response4.getData();
        assertThat(user.getId(), is(1L));
        assertThat(user.getName(), is("The Ultimate Test master."));

        // 6. Del Delete user 1
        request = delete("/users2/1");
        result = mvc.perform(request)
                .andExpect(status().isOk())
                .andReturn();
        content = result.getResponse().getContentAsString(StandardCharsets.UTF_8);
        SuccessResponses<String> response5 = JSONUtil.toBean(content, new TypeReference<SuccessResponses<String>>() {}, true);
        assertThat(response5.getData(), is("Deleted successfully"));

        // select * from user
        request = get("/users2/");
        result = mvc.perform(request)
                .andExpect(status().isOk())
                .andReturn();
        content = result.getResponse().getContentAsString(StandardCharsets.UTF_8);
        SuccessResponses<List<User>> response6 = JSONUtil.toBean(content, new TypeReference<SuccessResponses<List<User>>>() {}, true);
        assertThat(response6.getData().size(), is(0)); }}Copy the code

Unit test results