2014-04-17 14 views
5

मुझे लगता है कि इस तरह (सरलीकृत) लग रहा है एक फाइल अपलोड विधि के साथ एक जर्सी सेवा है:स्वैगर यूआई, जर्सी और फ़ाइल अपलोड को कॉन्फ़िगर कैसे करें?

@POST 
@Path("/{observationId : [a-zA-Z0-9_]+}/files") 
@Produces({ MediaType.APPLICATION_JSON}) 
@Consumes(MediaType.MULTIPART_FORM_DATA) 
@ApiOperation(
    value = "Add a file to an observation", 
    notes = "Adds a file to an observation and returns a JSON representation of the uploaded file.", 
    response = ObservationMediaFile.class 
) 
@ApiResponses({ 
    @ApiResponse(code = 404, message = "Observation not found. Invalid observation ID."), 
    @ApiResponse(code = 406, message= "The media type of the uploaded file is not supported. Currently supported types are 'images/*' where '*' can be 'jpeg', 'gif', 'png' or 'tiff',") 
}) 
public RestResponse<ObservationMediaFile> addFileToObservation(
    @PathParam("observationId") Long observationId, 
    @FormDataParam("file") InputStream is, 
    @FormDataParam("file") FormDataContentDisposition fileDetail, 
    @FormDataParam("fileBodyPart") FormDataBodyPart body 
){ 

    MediaType type = body.getMediaType(); 

    //Validate the media type of the uploaded file... 
    if(/* validate it is an image */ ){ 
     throw new NotAcceptableException("Not an image. Get out."); 
    } 

    //do something with the content of the file 
    try{ 
     byte[] bytes = IOUtils.toByteArray(is); 
    }catch(IOException e){} 

    //return response... 
} 

यह काम करता है और मैं इसे सफलतापूर्वक क्रोम में डाकिया एक्सटेंशन का उपयोग कर परीक्षण कर सकते हैं।

हालांकि, स्वैगर "फ़ाइल" नामक 2 पैरामीटर देखता है। किसी भी तरह यह समझ में आता है कि InputStream पैरामीटर और FormDataContentDisposition पैरामीटर वास्तव में file पैरामीटर के 2 भाग हैं, लेकिन यह FormDataBodyPart पैरामीटर के लिए यह देखने में विफल रहता है।

इस पैरामीटर के लिए स्वैगर JSON है:

swagger ui

:

parameters: [ 
{ 
    name: "observationId", 
    required: true, 
    type: "integer", 
    format: "int64", 
    paramType: "path", 
    allowMultiple: false 
}, 
{ 
    name: "file", 
    required: false, 
    type: "File", 
    paramType: "body", 
    allowMultiple: false 
}, 
{ 
    name: "fileBodyPart", 
    required: false, 
    type: "FormDataBodyPart", 
    paramType: "form", 
    allowMultiple: false 
}] 

नतीजतन, स्वैगर यूआई एक फ़ाइल पिकर का क्षेत्र, और FormDataBodyPart तर्क के लिए एक अतिरिक्त पाठ क्षेत्र उत्पन्न करता है

तो जब मैं एक फ़ाइल चुनता हूं और स्वैगर यूआई में फॉर्म जमा करता हूं, तो मैं अपलोड की गई सामग्री की सामग्री के बजाय इनपुट फ़ील्ड में टेक्स्ट फ़ील्ड की सामग्री को पढ़ता हूं। और अगर मैं टेक्स्टफील्ड को खाली छोड़ देता हूं, तो मुझे फ़ाइल का नाम मिलता है।

मैं फॉर्मडाटा बॉडीपार्ट पैरामीटर को अनदेखा करने के लिए स्वैगर को कैसे निर्देश दे सकता हूं?

वैकल्पिक रूप से, काम के आसपास के रूप में, मैं FormDataBodyPart ऑब्जेक्ट के बिना अपलोड की गई फ़ाइल के मीडिया प्रकार को कैसे प्राप्त कर सकता हूं?

मैं जर्सी 2.7 और swagger-jersey2-jaxrs_2.10 संस्करण 1.3.4 का उपयोग करता हूं।

+1

कोई भी जानता है कि यह फ़ाइल अपलोड जर्सी 1 के साथ संभव है या नहीं? (मैं 1.1 9 का उपयोग कर रहा हूं) किसी भी तरह से मैं फ़ाइल अपलोड करने के लिए फ़ाइल अपलोड नहीं कर सकता, भले ही मेरे पास मल्टीपार्ट/फॉर्म-डेटा है। पैरामीटर में भी इसे "बॉडी" के रूप में नहीं दिखाया जाता है "फ़ाइल" – dominicbri7

उत्तर

4

जर्सी के लिए एक स्वैगर फ़िल्टर बनाएं और फिर पैरामीटर को आंतरिक या किसी अन्य स्ट्रिंग के रूप में चिह्नित करें जिसे आप फ़िल्टर कर रहे हैं। यह भी इस उदाहरण में दिखाया गया है:

https://github.com/wordnik/swagger-core/blob/master/samples/java-jaxrs/src/main/java/com/wordnik/swagger/sample/util/ApiAuthorizationFilterImpl.java

आपकी सेवा विधि इस पैरामीटर एनोटेशन

@ApiParam(access = "internal") @FormDataParam("file") FormDataBodyPart body, 
होगा

आपका फ़िल्टर इस तरह इसके लिए दिखेगा:

public boolean isParamAllowed(Parameter parameter, Operation operation, ApiDescription api, 
     Map<String, List<String>> params, Map<String, String> cookies, Map<String, List<String>> headers) { 
    if ((parameter.paramAccess().isDefined() && parameter.paramAccess().get().equals("internal"))) 
     return false; 
    else 
     return true; 
} 

रजिस्टर अपने जर्सी के लिए swagger फ़िल्टर और फिर वह उस क्षेत्र को वापस नहीं करेगा और swagger-ui इसे नहीं दिखाएगा जो आपकी अपलोड समस्या को ठीक करेगा।

<init-param> 
     <param-name>swagger.filter</param-name> 
     <param-value>your.company.package.ApiAuthorizationFilterImpl</param-value> 
    </init-param> 
+0

धन्यवाद यह काम करता है। मैं वास्तव में अपने कोड में swagger करने के लिए और अधिक निर्भरता जोड़ने के लिए पसंद नहीं है, लेकिन यह समस्या हल हो गया है, इसलिए मैं सामग्री हूँ। –

+0

हाय @ पियरहेनरी मैं भी मैवेन प्लगइन का उपयोग कर स्वैगर जेसन उत्पन्न कर रहा हूं, लेकिन यह java.io.InputStream को एक प्रकार के रूप में java.io.File नहीं दिखा रहा है। क्या आपको कभी यह त्रुटि मिली है? – Samra

+0

क्षमा करें यह बहुत समय पहले था और मुझे याद नहीं है। मुझे लगता है कि एक नया सवाल पूछने से बेहतर होगा। –

1

यह स्पष्ट नहीं है जब इस जर्सी को जोड़ा गया है, लेकिन मल्टीपार्ट अनुभाग के अंत में एक नोट कहते हैं, "@FormDataParam एनोटेशन भी खेतों पर इस्तेमाल किया जा सकता"। सुनिश्चित करें कि पर्याप्त आप यह कर सकते हैं:

@FormDataParam(value="file") FormDataContentDisposition fileDisposition; 
@FormDataParam("fileBodyPart") FormDataBodyPart body; 

@Path("/v1/source") 
@POST 
@Consumes(MediaType.MULTIPART_FORM_DATA) 
@Produces({ MediaType.APPLICATION_JSON}) 
@ApiOperation(
     value = "Create a new Source from an uploaded file.", 
     response = Source.class 
     ) 
public Response makeSource(
     @FormDataParam(value="file") InputStream inputStream 
     ) 
{ 
    logger.info(fileDisposition.toString()); 
    return makeSourceRaw(inputStream, fileDisposition.getFileName()); 
} 

यह FormDataContentDisposition प्रदान करता है, लेकिन यह स्वैगर से "अदृश्य" बनाता है।

अद्यतन: यह काम करता है, लेकिन यदि अन्य संसाधन परिभाषित नहीं हैं (@ पैथ एनोटेशन) जो FormDataContentDisposition नहीं लेते हैं। यदि जर्सी रनटाइम पर विफल रहता है क्योंकि यह फ़ाइल डिस्पोजिशन फ़ील्ड में भर नहीं सकता है।

एक बेहतर समाधान यदि आप स्वैगर के हाल के संस्करण का उपयोग कर रहे हैं तो बस पैरामीटर को छिपाने के लिए चिह्नित करें।

@FormDataParam("fileBodyPart") FormDataBodyPart body; 

@Path("/v1/source") 
@POST 
@Consumes(MediaType.MULTIPART_FORM_DATA) 
@Produces({ MediaType.APPLICATION_JSON}) 
@ApiOperation(
     value = "Create a new Source from an uploaded file.", 
     response = Source.class 
     ) 
public Response makeSource(
     @FormDataParam(value="file") InputStream inputStream, 
     @ApiParam(hidden=true) @FormDataParam(value="file") FormDataContentDisposition fileDisposition; 

     ) 
{ 
    logger.info(fileDisposition.toString()); 
    return makeSourceRaw(inputStream, fileDisposition.getFileName()); 
} 
संबंधित मुद्दे