1. Response Data với ResponseEntity
1.1 Tạo ResponseSuccess để phản hồi nếu xử lý thành công
import com.fasterxml.jackson.annotation.JsonInclude; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.util.MultiValueMap; public class ResponseSuccess extends ResponseEntity { public ResponseSuccess(HttpStatus status, String message) { super(new Payload(status.value(), message), HttpStatus.OK); } public ResponseSuccess(HttpStatus status, String message, Object data) { super(new Payload(status.value(), message, data), status); } public ResponseSuccess(Payload body, HttpStatus status) { super(body, status); } public ResponseSuccess(MultiValueMap<String, String> headers, HttpStatus status) { super(headers, status); } public ResponseSuccess(Payload payload, MultiValueMap<String, String> headers, int rawStatus) { super(payload, headers, rawStatus); } public ResponseSuccess(Payload payload, MultiValueMap<String, String> headers, HttpStatus status) { super(payload, headers, status); } public static class Payload { private final int status; private final String message; @JsonInclude(JsonInclude.Include.NON_NULL) private Object data; public Payload(int status, String message) { this.status = status; this.message = message; } public Payload(int status, String message, Object data) { this.status = status; this.message = message; this.data = data; } public int getStatus() { return status; } public String getMessage() { return message; } public Object getData() { return data; } } }
1.2 Tạo ResponseFailure để phản hồi nếu xử lý thất bại
public class ResponseFailure extends ResponseSuccess{ public ResponseFailure(HttpStatus status, String message) { super(status, message); } }
1.3 Áp dụng ResponseSuccess và ResponseFailure tại controller.
import jakarta.validation.Valid; import jakarta.validation.constraints.Min; import org.springframework.http.HttpStatus; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import vn.tayjava.dto.request.UserRequestDTO; import vn.tayjava.dto.response.ResponseFailure; import vn.tayjava.dto.response.ResponseSuccess; import java.util.List; @RestController @RequestMapping("/user") @Validated public class UserController { @PostMapping("/") public ResponseSuccess addUser(@Valid @RequestBody UserRequestDTO user) { System.out.println("Request add user " + user.getFirstName()); try { return new ResponseSuccess(HttpStatus.CREATED, "User added successfully,", 1); } catch (Exception e) { return new ResponseFailure(HttpStatus.BAD_REQUEST, e.getMessage()); } } @PutMapping("/{userId}") public ResponseSuccess updateUser(@PathVariable @Min(1) int userId, @Valid @RequestBody UserRequestDTO user) { System.out.println("Request update userId=" + userId); try { return new ResponseSuccess(HttpStatus.ACCEPTED, "User updated successfully"); } catch (Exception e) { return new ResponseFailure(HttpStatus.BAD_REQUEST, e.getMessage()); } } @PatchMapping("/{userId}") public ResponseSuccess updateStatus(@Min(1) @PathVariable int userId, @RequestParam boolean status) { System.out.println("Request change status, userId=" + userId); try { return new ResponseSuccess(HttpStatus.ACCEPTED, "User's status changed successfully"); } catch (Exception e) { return new ResponseFailure(HttpStatus.BAD_REQUEST, e.getMessage()); } } @DeleteMapping("/{userId}") public ResponseSuccess deleteUser(@PathVariable @Min(value = 1, message = "userId must be greater than 0") int userId) { System.out.println("Request delete userId=" + userId); try { return new ResponseSuccess(HttpStatus.NO_CONTENT, "User deleted successfully"); } catch (Exception e) { return new ResponseFailure(HttpStatus.BAD_REQUEST, e.getMessage()); } } @GetMapping("/{userId}") public ResponseSuccess getUser(@PathVariable @Min(1) int userId) { System.out.println("Request get user detail, userId=" + userId); try { return new ResponseSuccess(HttpStatus.OK, "user", new UserRequestDTO("Tay", "Java", "admin@tayjava.vn", "0123456789")); } catch (Exception e) { return new ResponseFailure(HttpStatus.BAD_REQUEST, e.getMessage()); } } @GetMapping("/list") public ResponseSuccess getAllUser(@RequestParam(defaultValue = "0", required = false) int pageNo, @Min(10) @RequestParam(defaultValue = "20", required = false) int pageSize) { System.out.println("Request get all of users"); return new ResponseSuccess(HttpStatus.OK, "users", List.of(new UserRequestDTO("Tay", "Java", "admin@tayjava.vn", "0123456789"), new UserRequestDTO("Leo", "Messi", "leomessi@email.com", "0123456456"))); } }
2. Response Data với Generic
2.1 Tạo class ResponseData với kiểu generic là kiểu T để nhận mọi kiểu data type khác nhau trả về kết quả nếu như xử lý thành công.
import com.fasterxml.jackson.annotation.JsonInclude; public class ResponseData { private final int status; private final String message; @JsonInclude(JsonInclude.Include.NON_NULL) private T data; /** * Response data for the API to retrieve data successfully. For GET, POST only * @param status * @param message * @param data */ public ResponseData(int status, String message, T data) { this.status = status; this.message = message; this.data = data; } /** * Response data when the API executes successfully or getting error. For PUT, PATCH, DELETE * @param status * @param message */ public ResponseData(int status, String message) { this.status = status; this.message = message; } public int getStatus() { return status; } public String getMessage() { return message; } public T getData() { return data; } }
2.2 Tạo class ResponseError kế thừa từ ResponseData để nhận phản hồi nếu xử lý thất bại
public class ResponseError extends ResponseData { public ResponseError(int status, String message) { super(status, message); } }
2.3 Áp dụng ResponseData và ResponseError tại UserController.
@RestController @RequestMapping("/user") @Validated public class UserController { @PostMapping("/") public ResponseData addUser(@Valid @RequestBody UserRequestDTO user) { System.out.println("Request add user " + user.getFirstName()); return new ResponseData<>(HttpStatus.CREATED.value(), "User added successfully,", 1); } @PutMapping("/{userId}") public ResponseData<?> updateUser(@PathVariable @Min(1) int userId, @Valid @RequestBody UserRequestDTO user) { System.out.println("Request update userId=" + userId); return new ResponseData<>(HttpStatus.ACCEPTED.value(), "User updated successfully"); } @PatchMapping("/{userId}") public ResponseData<?> updateStatus(@Min(1) @PathVariable int userId, @RequestParam boolean status) { System.out.println("Request change status, userId=" + userId); return new ResponseData<>(HttpStatus.ACCEPTED.value(), "User's status changed successfully"); } @DeleteMapping("/{userId}") public ResponseData<?> deleteUser(@PathVariable @Min(value = 1, message = "userId must be greater than 0") int userId) { System.out.println("Request delete userId=" + userId); return new ResponseData<>(HttpStatus.NO_CONTENT.value(), "User deleted successfully"); } @GetMapping("/{userId}") public ResponseData getUser(@PathVariable @Min(1) int userId) { System.out.println("Request get user detail, userId=" + userId); return new ResponseData<>(HttpStatus.OK.value(), "user", new UserRequestDTO("Tay", "Java", "admin@tayjava.vn", "0123456789")); } @GetMapping("/list") public ResponseData<List> getAllUser(@RequestParam(defaultValue = "0", required = false) int pageNo, @Min(10) @RequestParam(defaultValue = "20", required = false) int pageSize) { System.out.println("Request get all of users"); return new ResponseData<>(HttpStatus.OK.value(), "users", List.of(new UserRequestDTO("Tay", "Java", "admin@tayjava.vn", "0123456789"), new UserRequestDTO("Leo", "Messi", "leomessi@email.com", "0123456456"))); } }
Xem video để được nghe hướng dẫn chi tiết từ Tây Java
Xem Source Code: https://github.dev/luongquoctay87/tayjava-sample-code/tree/bai-5-response-data
⇒ Lấy Source Code
$ git clone https://github.com/luongquoctay87/tayjava-sample-code.git
$ git checkout bai-5-response-data