Swagger 2 con Spring boot e interceptor.
Estoy utilizando Spring Boot 2.5.6, Swagger2 y Java 17.
Tengo un punto de conexión que recibe un json con un JWT en el cuerpo como esto:
{"signedPayload":"encodedJWTstring"}
Dado que este JWT necesita ser decodificado, validado y su carga interna mapeada a un DTO, hemos decidido crear un interceptor de Spring que haga esto antes de llegar al controlador.
Esta parte funciona muy bien, mi único problema es con Swagger.
@Log4j2
@Component
public class CallbackInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(
HttpServletRequest request, HttpServletResponse response, Object handler) {
// ...aquí ocurre la magia...
request.setAttribute(
"decodedRequestDTO",
CallbackRequestDTO.builder().build(); //y los campos se establecen aquí también
}
}
Y el método del controlador se ve así:
public ResponseEntity<httpstatus> eventsCallback(
@NotNull
@Valid
@RequestAttribute("decodedRequestDTO")
CallbackRequestDTO callbackRequestDTO) {
}
El problema que tengo es que no puedo encontrar una forma de cambiar la definición de esquema de Swagger al json que debería recibir y no el CallbackRequestDTO
.
Aparentemente, el problema es que estoy utilizando @RequestAttribute
y debido a eso Swagger no escaneará otras anotaciones como @Parameter
.
He probado varias combinaciones y anotaciones sin suerte, realmente apreciaría algo de ayuda.
davy.ai
Problema de definición de Swagger con las anotaciones @RequestAttribute y @Parameter
Problema
Como experto en IT especializado en Java, Spring Boot, Swagger, OpenAPI y Swagger-2.0, tengo un endpoint que recibe un JSON con un JWT en el cuerpo. Este JWT necesita ser decodificado, validado y su carga interna mapeada a un DTO. Para lograr esto, he creado una clase interceptor de Spring que intercepta la solicitud antes de llegar al controlador, y mapea la carga interna a un DTO utilizando el método
request.setAttribute
.El problema está en la documentación de la API de Swagger. La documentación de la API de Swagger muestra el esquema del DTO
CallbackRequestDTO
, mientras que el cuerpo de la solicitud real es diferente ya que contiene un JWT.Solución
Para resolver este problema, necesitamos anular el esquema predeterminado de Swagger utilizando las anotaciones
@ApiImplicitParam
o@Parameter
. Sin embargo, Swagger no admite la anotación@RequestAttribute
. Para superar esto, debemos usar la anotación@ModelAttribute
y pasar los atributos como parámetros de consulta. Modifica la claseCallbackInterceptor
para establecer el atributoCallbackRequestDTO
como un parámetro de solicitud, como se menciona a continuación.Ahora podemos recibir la cadena JWT en el método del controlador y validarla.
De esta manera, Swagger mostrará el esquema correcto basado en el cuerpo de la solicitud.
Resumen
En resumen, al utilizar
@RequestAttribute
para mapear el atributo de la solicitud al DTO, la documentación de la API de Swagger no muestra el esquema correcto y sólo muestra el esquema del DTO. Para superar este problema, debemos utilizar@ModelAttribute
en la clase interceptor, y pasar el atributo como un parámetro de solicitud. Luego, utilizar la anotación@Parameter
para describir la cadena JWT en el método del controlador. De esta manera, Swagger mostrará el esquema correcto basado en el cuerpo de la solicitud.