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
but the Informations get lost after that
In AbstractOpenApiResources produces and consumes are null
And even if you change the value there, it will be overriden again in MethodAttribute