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

encoder function for multipart/form-data in groovy

我需要用 jpeg 图像和 JSON 文件形成 'multipart/form-data' REST 请求,因为 content.I 无法将 'multipart/form-data' 编码为 zip 文件。

谁能告诉我,如何使用 groovy RESTClient 实现这一点?我找不到与此相关的任何文档。

正如在 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 的实例作为正文参数传递给请求。

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

首先问题的最后评论指向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 个声明即可。您不需要对您的附件等执行 none例子..

编码器注册在之前的回复中非常混乱,这是我的工作示例:

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()
}

我正在编写测试,使用 Groovy 休息客户端上传 .zip 文件。

在使用 Groovy Rest Client 进行测试时,上述答案的

None 直接对我有用。我不得不对上述答案进行一些调整。我post来这里是为了让某人post使用Groovy休息客户可以获得好处。

import groovyx.net.http.RESTClient
import org.apache.http.HttpEntity
import org.apache.http.entity.mime.MultipartEntityBuilder
import org.codehaus.groovy.runtime.MethodClosure
import static groovyx.net.http.ContentType.JSON

def uploadFile() {
    def httpClient = new RESTClient(this.host)
    File fileToUpload = new File("src/test/resources/fileName.zip")
    httpClient.encoder.putAt(javax.ws.rs.core.MediaType.MULTIPART_FORM_DATA, new MethodClosure(this, 'encodeMultiPart'))
    def multipartBody = new MultipartBody()
    multipartBody.file = new FileInputStream(fileToUpload)
    multipartBody.filename = fileToUpload.name
    def response = httpClient.post(
            path: '/app/uploadfile/path',
            headers: [Accept  : JSON,

                      User    : "user",
                      Password: "password"
              ],
            body: multipartBody,
            requestContentType: 'multipart/form-data')
}

// register multipart encoder
HttpEntity encodeMultiPart(MultipartBody body) {
    MultipartEntityBuilder.create()
            .addBinaryBody(
                    'file',
                    body.file,
                    org.apache.http.entity.ContentType.MULTIPART_FORM_DATA,
                    body.filename
            ).build()
}

class MultipartBody {
    InputStream file
    String filename
}