springdoc-openapi icon indicating copy to clipboard operation
springdoc-openapi copied to clipboard

Weird behavior when adding a ControllerAdvice with ResponseBodyAdvice

Open Sang-Dang opened this issue 1 year ago • 1 comments

Describe the bug When I add the ControllerAdvice, the swagger page goes to the default Pet Store instead of the actual swagger.

To Reproduce Steps to reproduce the behavior:

Controller

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@Tag(name = "App", description = "Hello World")
@RestController
public class AppController {
    @GetMapping()
    @ApiResponse(responseCode = "200", description = "Hello World")
    @Operation(summary = "Hello World", description = "Hello World")
    public ResponseEntity<String> hello() {
        return ResponseEntity.ok("Hello World!");
    }
}

Response Body Wrapper

import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.SneakyThrows;
import lombok.ToString;
import org.springframework.core.MethodParameter;
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.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

@Hidden
@Schema(hidden = true)
@RestControllerAdvice
public class ResponseBodyWrapperAdvice implements ResponseBodyAdvice<Object> {
    @Data
    @AllArgsConstructor
    @ToString
    @Schema(description = "API Response Wrapper")
    public static class ApiResponse<T> {
        @Schema(description = "Response data")
        private T data;
        @Schema(description = "Status of the operation")
        private String status;
        @Schema(description = "Additional message (optional)")
        private String message;
    }

    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @SneakyThrows
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        if (body instanceof ApiResponse) {
            return body;
        }

        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.writeValueAsString(new ApiResponse<>(body, "Success", null));
    }
}

Dependencies

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0'
}

Result

image

Sang-Dang avatar Aug 06 '24 19:08 Sang-Dang

This is My Code: public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class selectedConverterType, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { if (selectedConverterType == ByteArrayHttpMessageConverter.class) { return o; } if (selectedConverterType == org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.class) { if (methodParameter.getExecutable().getName().equals("openapiJson")) { return o; } } if (o instanceof ResponseEntity) { return o; } else { ResponseEntity<Object> response = ResponseEntity.ok(o); return response; } }

a1782680475 avatar Aug 08 '24 04:08 a1782680475

@a1782680475,

Not reproducible. Feel free to provide a Minimal, Reproducible Example - with HelloController that reproduces the problem.

This ticket will be closed, but can be reopened if your provide the reproducible sample.

bnasslahsen avatar Sep 22 '24 19:09 bnasslahsen