หลังจากเรากำหนด @RestController
ที่เหนือ class ของ controller ทำให้ object ที่ return จาก controller นั้นจะถูกแปลงไปเป็น JSON response ให้โดยอัตโนมัติ
อย่างไรก็ตาม ถ้าหากเราต้องการสร้าง template ครอบ object ที่ return จาก controller ทุกๆ controller ก่อนที่จะส่งเป็น JSON response ออกไป เรามีขั้นตอนดังนี้
- สร้าง Class สำหรับ JSON response template
package com.example.model.wrapper; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import org.springframework.http.HttpStatus; @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) public class ResultWrapper<T> { @JsonProperty("code") private Integer code; @JsonProperty("status") private HttpStatus status; @JsonProperty("message") private String message; @JsonProperty("data") private T data = null; public Result(Integer code, HttpStatus status, String message) { this.code = code; this.status = status; this.message = message; } public ResultWrapper(Integer code, HttpStatus status, T data) { this.code = code; this.status = status; this.data = data; } }
- สร้าง class ที่เรียกใช้
ControllerAdvice
และResponseBodyAdvice
ดังนี้package com.example.controller.;
import com.example.model.wrapper.ResultWrapper; import org.springframework.core.MethodParameter; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; import java.util.LinkedHashMap; @ControllerAdvice public class ResponseHandler implements ResponseBodyAdvice<Object> { @Override public boolean supports(MethodParameter methodParameter, Class> aClass) { // Skip methods in ExceptionHandler class Boolean isExceptionHandlerMethod = methodParameter.getDeclaringClass().getSimpleName().equals("ExceptionHandler"); return !isExceptionHandlerMethod; } @Override public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { // Convert error that is LinkedHashMap class too if(body instanceof LinkedHashMap){ LinkedHashMap map = (LinkedHashMap) body; if(map.containsKey("status") && !map.get("status").equals(200)){ HttpStatus status = HttpStatus.resolve((int) map.get("status")); return new ResultWrapper(status.value(), status, (String) map.get("error")); } } HttpStatus status = HttpStatus.OK; return new ResultWrapper(status.value(), status, body); } }
@ControllerAdvice
- อนุญาตให้เรา apply เทคนิคใน class ข้างใต้มันกับทุกๆ controller ของเรา (อ่านเพิ่มเติมที่ ControllerAdvice)-
ResponseBodyAdvice
- อนุญาตให้เราเปลี่ยนแปลง response ที่ได้จาก controller ก่อนที่มันจะถูกแปลงเป็น HttpResponse แล้วส่งออกไป (อ่านเพิ่มเติมที่ ResponseBodyAdvice)
No comments:
Post a Comment