groovy中multipart / form-data的编码器函数

时间:2015-03-05 04:43:10

标签: encoding groovy multipartform-data rest-client httpbuilder

我需要用jpeg图像和JSON文件作为内容来形成'multipart / form-data'REST请求。我坚持将'multipart / form-data'编码为zip文件。

有人可以告诉我,我如何通过groovy RESTClient实现这一目标?我找不到任何关于此的文件。

3 个答案:

答案 0 :(得分:2)

可以在docs RESTClient扩展HTTPBuilder中看到。 HTTPBuilder有一个getEncoder方法,可用于添加专用编码器(带类型和方法)。请参阅以下代码:

import org.codehaus.groovy.runtime.MethodClosure
import javax.ws.rs.core.MediaType

//this part adds a special encoder    
def client = new RESTClient('some host')
client.encoder.putAt(MediaType.MULTIPART_FORM_DATA, new MethodClosure(this, 'encodeMultiPart'))

//here is the method for the encoder added above
HttpEntity encodeMultiPart(MultipartBody body) {
    MultipartEntityBuilder.create()
    .addBinaryBody(
        'file', 
        body.file, 
        ContentType.MULTIPART_FORM_DATA, 
        body.filename
    ).build()
}

//here's how MultipartBody class looks:
class MultipartBody {
   InputStream file
   String filename
}

现在创建一个多部分请求您需要将MultipartBody的实例作为正文参数传递给请求。

答案 1 :(得分:0)

意识到这是一个古老的例子,但可能会对其他人有所帮助,尽管该问题是从初学者的角度回答的,但很难完全理解如何正确地重用以上所有内容。

首先,对问题的最后评论指向this link

哪个尝试不正确地重复使用答案。上面的答案与this link

的答案混合在一起
def content1 = new ContentDisposition("filename=aa.json")
    def json1 = new File("resources/aa.json")
    def attachments1 = new Attachment("root", new ByteArrayInputStream(json1.getBytes()), content1)
    InputStream is2 = getClass().getResourceAsStream("resources/aa.json");
    InputStream is1 = getClass().getResourceAsStream("resources/img.png");
    ContentDisposition content2 = new ContentDisposition("attachment;filename=img.png")
    Attachment attachments2 = new Attachment("root1", is1, content2)
    def attachments = [attachments1, attachments2]
    def body1 = new MultipartBody(attachments)
    def client = new RESTClient( "https://somehost.com" )
    ocutag.encoder.putAt(MediaType.MULTIPART_FORM_DATA, new MethodClosure(this, 'encodeMultiPart1'))
    ocutag.encoder.putAt(MediaType.MULTIPART_FORM_DATA, new MethodClosure(this, 'encodeMultiPart2'))

以上内容永远无法正常工作,我的工作方式如下:

def http = new RESTClient('http://localhost:8080')
http.encoder.putAt(MediaType.MULTIPART_FORM_DATA, new MethodClosure(this, 'encodeMultiPart'))
def body1 = new MultipartBody()   //This is that MultipartBody class in the first answer example not the one from your imports......
body1.file=file.getInputStream()
body1.filename=file.name
def response = http.put( path: url, body:body1, query:['query':action, ], requestContentType: 'multipart/form-data' )

您还具有encodeMultiPart2和encodeMultiPart1,我认为这是一种误解,在两种情况下都只重用此方法的1声明..您无需执行示例中的任何附件。

答案 2 :(得分:0)

以前的响应中编码器注册非常混乱,这是我的工作示例:

import org.apache.cxf.jaxrs.ext.multipart.Attachment
import org.apache.cxf.jaxrs.ext.multipart.ContentDisposition
import org.apache.cxf.jaxrs.ext.multipart.MultipartBody
import org.apache.http.entity.ContentType
import org.apache.http.entity.mime.MultipartEntityBuilder
import javax.ws.rs.core.MediaType 

...

def filenameToUpload = "doggo.jpg"
def expectedRequestParamName = "file"

def static uploadFile() {
    // create attachment
    def fileToUpload = new File(filenameToUpload)
    def attachment = new Attachment(expectedRequestParamName, new ByteArrayInputStream(fileToUpload.getBytes()), new ContentDisposition("filename=" + filenameToUpload))
    def body = new MultipartBody(attachment)

    // create REST client
    def httpClient = new RESTClient('http://localhost:8080')

    // register encoder
    httpClient.encoder.putAt(MediaType.MULTIPART_FORM_DATA, customMultipartEncoder)

    // call REST
    httpClient.post(
        path: "upload",
        body: body,
        requestContentType: MediaType.MULTIPART_FORM_DATA)
}

// register multipart encoder
private def static customMultipartEncoder = { body ->
    def builder = MultipartEntityBuilder.create()

    body.allAttachments.collect {
        builder.addBinaryBody(
            it.contentId,
            it.dataHandler.inputStream,
            ContentType.MULTIPART_FORM_DATA,
            it.contentId) }

    return builder.build()
}