-
-
Notifications
You must be signed in to change notification settings - Fork 535
Description
What i am trying to do
I am trying to set a specific consumes / produces Type for multiple Mappings.
I know that i can set them like this:
@PostMapping( "/testPostMapping", consumes = { MediaType.APPLICATION_CBOR_VALUE } )
but then i have to add consumes and produces to every Mapping method.
I have an Controller Class which sets produces for all my RequestMappings
@RequestMapping( produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE } )
public abstract class Controller
{
}
I extend this Controller and have some Mappings inside it.
public class ExampleController extends Controller
{
@GetMapping( value = "/getTest" )
public @ResponseBody ResponseEntity<String> testGetMapping()
{
return new ResponseEntity<String>( "TestString", HttpStatus.OK );
}
@PostMapping( "/testPostMapping" )
public @ResponseBody ResponseEntity<String> testPostMapping( String testString )
{
return new ResponseEntity<String>( "TestString", HttpStatus.OK );
}
}
Now i only want to set the consumes Type to the PostMapping.
What i already tried
I already tried to add The @apiresponse Annotation
@ApiResponses( value = {
@ApiResponse( responseCode = "200", content = @Content( mediaType = MediaType.APPLICATION_XML_VALUE ) ) } )
public @interface DefaultProduces
{
String[] produces() default {
MediaType.APPLICATION_XML_VALUE };
}
but this will override the content Type of my Requests
if i add this to two @PostMappings , and one Returns a String the other one Returns an HTML element
@apiresponse will override the schema type information
Without the ApiResponse Annotation
"content": {
"*/*": {
"schema": {
"type": "string"
}
}
With the ApiResponse Annotation
"content": {
"application/xml": {
}
How i attampted it
I made my own Annotations
@Target( { ElementType.TYPE, ElementType.METHOD } )
@Retention( RetentionPolicy.RUNTIME )
@Inherited
public @interface DefaultProduces
{
String[] produces() default {
MediaType.TEXT_HTML_VALUE };
}
and extended the WebMvcConfig RequestMappingHandler
@Override
protected RequestMappingHandlerMapping createRequestMappingHandlerMapping()
{
return new ExtendedRequestMappingHandlerMapping();
}
So that if i add @DefaultProduces
to a RequestMapping it will have the MediaTypes which i added there
I overrode the RequestMappingInfo with my customized infos.
But OpenAPI does not take the Informations from RequestMappingInfo .
Describe the solution you'd like
Is there a way to let openAPI get his Informations from the RequestMappingInfo.
Or is there an Annotation like Request @ApiResponse
where i can only set the consumes or produces Types without chaning anything else.
** TestProject **
In my TestProject is a Controller with a PostMapping like this
@DefaultConsumes
@PostMapping( value = "/testPostMapping" )
public @ResponseBody ResponseEntity<String> testPostMapping( String testString )
{
return new ResponseEntity<String>( "TestString", HttpStatus.OK );
}
My annotation DefaultConsomes makes the PostMapping only accapt text/plain
The OpenAPI Json still says that the content is /
"content": {
"*/*": {
"schema": {
"type": "string"
}
}
which leads to the following Curl request in Swagger-ui
`curl -X 'POST' \
'http://localhost:8080/testPostMapping' \
-H 'accept: */*' \
-H 'Content-Type: application/json' \
-d '"string"'`
The PostMapping will response with
{
"timestamp": 1647005196793,
"status": 406,
"error": "Not Acceptable",
"path": "/testPostMapping"
}
If text/plain is set it is working.
curl -o - -X 'POST' \
'http://localhost:8080/testPostMapping' \
-H 'accept: text/plain' \
-H 'Content-Type: application/json' \
-d '"string"'
should output "TestString"
Here is a basic Project with my issue
https://github.com/T-Developer1/SpringdocCustomAnnotationSample
Additional Informations
In OpenApiResources the consumes and Produces are correct
Lines 216 to 217 in 378edcf
String[] produces = requestMappingInfo.getProducesCondition().getProducibleMediaTypes().stream().map(MimeType::toString).toArray(String[]::new); | |
String[] consumes = requestMappingInfo.getConsumesCondition().getConsumableMediaTypes().stream().map(MimeType::toString).toArray(String[]::new); |
but the Informations get lost after that
In AbstractOpenApiResources produces and consumes are null
Lines 397 to 398 in 378edcf
String[] methodConsumes = routerOperation.getConsumes(); | |
String[] methodProduces = routerOperation.getProduces(); |
And even if you change the value there, it will be overriden again in MethodAttribute
springdoc-openapi/springdoc-openapi-common/src/main/java/org/springdoc/core/MethodAttributes.java
Lines 228 to 232 in 378edcf
PostMapping reqPostMappingMethod = AnnotatedElementUtils.findMergedAnnotation(method, PostMapping.class); | |
if (reqPostMappingMethod != null) { | |
fillMethods(reqPostMappingMethod.produces(), reqPostMappingMethod.consumes(), reqPostMappingMethod.headers()); | |
return; | |
} |