Spring manage http status of custom DTO class without ResponseEntity

Viewed 213
public class ApiResponse {
        long timestamp;
        int status;
        String error;
        String message;
        String path;

        public ApiResponse(HttpStatus status, String message) {
         super();
         this.status = status.value();
         this.message = message;
        }

    }

I have this class and what i want to do is set response status based on status value of ApiResponse object

return new ApiResponse(HttpStatus.CREATED, "Success");

I want response status to be 201.

Is something like this possible?

I know there is ResponseEntity class but i want to handle it without using this class.

1 Answers

Use the ResponseBodyAdvice interface to process the response uniformly.

@RestControllerAdvice
public class TransformStatusBodyAdvice implements ResponseBodyAdvice<ApiResponse> {

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        // check return type is ApiResponse
        return returnType.getParameterType().isAssignableFrom(ApiResponse.class);
    }

    @Override
    public ApiResponse beforeBodyWrite(ApiResponse body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        if (body != null) {
            // change something if you want
            // set the response status code
            response.setStatusCode(HttpStatus.valueOf(body.getStatus()));
        }
        return body;
    }
}

Test Controller

@RestController
@RequestMapping("/test")
public class TestController {

    @PostMapping
    public ApiResponse create() {
        return new ApiResponse(HttpStatus.CREATED, "Success");
    }
}

Use curl to test result. Now the http response code is 201. If you change your HttpStatus in the ApiResponse, the http status response code will be change.

$ curl -v -X POST http://localhost:8080/test
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> POST /test HTTP/1.1
> ...
>
< HTTP/1.1 201
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Mon, 05 Jul 2021 03:45:00 GMT
<
{"timestamp":0,"status":201,"error":null,"message":"Success","path":null}* Connection #0 to host localhost left intact
Related