如何在HTTP请求中发送多部分表单数据(用于Watson NLC培训)?

亚历山大·波扎斯基(Alexander Pozharskii):

我正在编写将使用Watson Natural Language Classifier(“ NLC”)的应用程序。当我使用以下请求消息正文针对v1 / classifiers URI路径发送HTTP POST请求时,服务器将以状态码415(不支持的媒体类型)进行响应

--04fef47728eb08148fe9c7b18dd42b75abd75ebf752fd3412a85aa3af075
Content-Disposition: form-data; name="training_data"; filename="data.csv"
Content-Type: text/csv

How hot is it today?;temperature
Is it hot outside?;temperature
Will it be uncomfortably hot?;temperature
Will it be sweltering?;temperature
How cold is it today?;temperature
Is it cold outside?;temperature
Will it be uncomfortably cold?;temperature
Will it be frigid?;temperature
What is the expected high for today?;temperature
What is the expected temperature?;temperature
Will high temperatures be dangerous?;temperature
Is it dangerously cold?;temperature
When will the heat subside?;temperature
Is it hot?;temperature
Is it cold?;temperature
How cold is it now?;temperature
Will we have a cold day today?;temperature
When will the cold subside?;temperature
What highs are we expecting?;temperature
What lows are we expecting?;temperature
Is it warm?;temperature
Is it chilly?;temperature
What's the current temp in Celsius?;temperature
What is the temperature in Fahrenheit?;temperature
--04fef47728eb08148fe9c7b18dd42b75abd75ebf752fd3412a85aa3af075
Content-Disposition: form-data; name="training_metadata"; filename="metadata.json"
Content-Type: application/json

{"language": "en"}

415状态代码表明内容类型有问题,但似乎所有MIME类型都是正确的。

我的代码(用Go编写):

func (w WatsonClassifier) createFormFile(writer *multipart.Writer, fieldname string, filename string, contentType string) (io.Writer, error)     {
    h := make(textproto.MIMEHeader)
    h.Set("Content-Disposition",
        fmt.Sprintf(`form-data; name="%s"; filename="%s"`,
            fieldname, filename))
    h.Set("Content-Type", contentType)
    return writer.CreatePart(h)
}

func (w WatsonClassifier) request(method string, apiUrl string, body io.Reader) (string, error) {
    url := w.url + "/" + apiUrl
    req, err := http.NewRequest(method, url, body)
    if err != nil {
        return "", err
    }
    req.SetBasicAuth(w.username, w.password)
    client := http.Client{}
    resp, err := client.Do(req)
    if resp.StatusCode != 200 {
        answer, _ := ioutil.ReadAll(resp.Body)
        fmt.Println(string(answer))
        return "", errors.New("Watson returned wrong status code : " + resp.Status)
    }
    answer, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return "", err
    }
    return string(answer), nil
}

func (w WatsonClassifier) Train(data []ClassifierCategory) (Classifier, error) {
    table := w.buildTable(data)
    str := w.buildCsv(data)
    buf := new(bytes.Buffer)
    writer := multipart.NewWriter(buf)
    data_part, err := w.createFormFile(writer, "training_data", "data.csv", "text/csv")
    if err != nil {
        return WatsonClassifier{}, err
    }
    data_part.Write([]byte(str))
    metadata_part, err := w.createFormFile(writer, "training_metadata", "metadata.json", "application/json")
    if err != nil {
        return WatsonClassifier{}, err
    }
    metadata_json := "{\"language\": \"" + w.Language + "\"}"
    metadata_part.Write([]byte(metadata_json))
    fmt.Println(buf.String())
    answer, err := w.request("POST", "v1/classifiers", buf)
    if err != nil {
        return WatsonClassifier{}, err
    }
    fmt.Println(answer)
    return WatsonClassifier{}, nil
}
看到:

请注意,curl正在发送的“ Content-Type”标头multipart/form-data您的Go程序仅发送“ Content-Disposition”标头form-data(请注意,区别在于,它缺少领先的multipart复合顶级媒体类型),但是它并没有为发送正确的“ Content-Type”标头提供帮助包含HTTP请求。

Go的multipart.Writertype的CreateFormFile方法执行相同的操作,但同样,这只是工作的一部分:

h.Set("Content-Disposition",
        fmt.Sprintf(`form-data; name="%s"; filename="%s"`,
                escapeQuotes(fieldname), escapeQuotes(filename)))

要获取正确的“ Content-Type”标头值,您需要使用multipart.Writer.FormDataContentType要使用该值,您需要multipart.Writer进入WatsonClassifier.request方法,以便可以在http.Request实例上设置内容类型

req.Header.Set("Content-Type", writer.FormDataContentType())

或者,WatsonClassifier.request为内容类型添加另一个参数,然后将的结果FormDataContentType作为来自调用站点的参数传递WatsonClassifier.Train

让我们知道这样做是否成功。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在ajax中发送多部分/表单数据请求

用于发送多部分/表单数据请求的工具

在多部分/表单数据POST请求中发送缓冲区 快递| 请求

如何通过Volley在Android中发送“多部分/表单数据” POST

如何使用请求在 Python 中发布多部分/表单数据

骆驼发送多部分/表单数据请求

如何使用antd上传发送多部分/表单数据

如何使用 Ajax 发送多部分/表单数据

卷曲如何发布多部分/表单数据数据以及如何在Flask请求中读取多部分/表单数据

请求:发布多部分/表单数据

如何在多部分/表单数据请求中获取文件的实际文件大小

如何在Java Servlet中处理多部分/表单数据POST请求?

如何在C#MVC 4 Web服务中使用多部分/表单数据请求

用于多部分/表单数据的POSTMAN

如何在多部分改装请求中发送对象数组

HTTP POST多部分表单数据

如何在wicket中解析多部分表单数据

Mule 4:HTTP请求程序:如何将Meta REST服务调用的多部分/表单数据作为POST正文发送?

在角度为7的多部分/表单数据中发送数组

如何在Swift 3中的POST请求中发送表单数据

如何在Ballerina中的POST请求中发送表单数据?

多部分表单数据是如何工作的?

如何读取多部分/表单数据?

如何获取多部分/表单数据?

IBM Watson NLC-如何在Java SDK中重新训练现有分类器

在Axios vue.js中使用多部分/表单数据发布请求发送阵列数据

IE 11:发送多部分表单数据请求时出错:流意外结束

在Hapijs后端处理Swift中Alamofire发送的多部分/表单数据请求

为什么我不能向Microsoft OneNote发送多部分/表单数据请求?