swagger-ui icon indicating copy to clipboard operation
swagger-ui copied to clipboard

multipart/form-data should support custom content-type selection.

Open mathis-m opened this issue 4 years ago • 5 comments

Content & configuration

Swagger/OpenAPI definition:

paths:
 /analysis/api/stores:
   post:
     responses:
       '201':
         $ref: '#/components/responses/CONTINUE'
     requestBody:
       required: true
       content:
         multipart/form-data:
           schema:
             $ref: '#/components/schemas/Child'
           encoding: # The same level as schema
             test: # Property name (see schema)
               contentType: application/json
             test2: # Property name (see schema)
               contentType: application/xml
     tags:
       - Learning
info:
 title: test api
 version: v1
tags:
 - name: Feature Request
   description: respect multipart child content-type
openapi: 3.0.2
components:
 schemas:
   Error:
     type: object
     properties:
       message:
         type: string
         description: Error message
       errors:
         type: object
         description: Errors
       status:
         type: string
         description: Error name
       code:
         type: integer
         format: int32
         description: Error code
   Base:
     type: object
     properties:
       company:
         type: string
   Child:
     type: object
     properties:
       test:
         type: array
         items:
           $ref: '#/components/schemas/Base'
       test2:
         type: array
         items:
           $ref: '#/components/schemas/Base'
 responses:
   CONTINUE:
     description: Continue
     content:
       application/json:
         schema:
           type: object
           properties:
             error:
               type: string

Is your feature request related to a problem?

It is currently not possible to define specific Content-Type for a request part via encoding/{property-name}/contentType.

Describe the solution you'd like

Schema Property Type Content-Type
Primitive or array of primitives text/plain
Complex value or array of complex values application/json
String in the binary or base64 format application/octet-stream

mathis-m avatar Oct 03 '20 20:10 mathis-m

Just ran into this with a file upload API that had an object part for some metadata. The whole proposed solution here would of course be great, but just setting the content types of the request parts based on the schema properties (that is, the last bullet point in the described solution) would be helpful even without any new elements in the UI.

To help anyone else who is searching the web for this problem: it was manifesting in Spring MVC as HttpMediaTypeNotSupportedException: Content type 'application/octet-stream' not supported. A workaround is to write a custom HttpMessageConverter to deserialize application/octet-stream bodies using Jackson.

sgrimm avatar Feb 11 '21 18:02 sgrimm

Related: #5356

hkosova avatar Jul 07 '21 18:07 hkosova

@sgrimm thanks, this workaround seems to work

	@Bean
	public MappingJackson2HttpMessageConverter octetStreamJsonConverter() {
		MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
		converter.setSupportedMediaTypes(Arrays.asList(new MediaType("application", "octet-stream")));
		return converter;
	}

rPraml avatar Sep 28 '21 13:09 rPraml

To expand on @rPraml's code, adding octet-stream to the supported media types in the existing MappingJackson2HttpMessageConverter will prevent bugs when using other media types:

import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import java.util.ArrayList;

@Configuration
public class SwaggerBeanConfig {
    
    public SwaggerBeanConfig(MappingJackson2HttpMessageConverter converter) {
        var supportedMediaTypes = new ArrayList<>(converter.getSupportedMediaTypes());
        supportedMediaTypes.add(new MediaType("application", "octet-stream"));
        converter.setSupportedMediaTypes(supportedMediaTypes);
    }
}

little-pinecone avatar Mar 16 '22 13:03 little-pinecone

+1

JanCizmar avatar Apr 26 '24 12:04 JanCizmar