2016-04-02 19 views
2

私はWatson Natural Language Classifier( "NLC")を使用するアプリケーションを作成しています。私は、次の要求メッセージ本体とv1/classifiers URI pathに対してHTTP POSTリクエストを送信すると 、サーバはステータスコード415(サポートされていないメディアタイプ)で応答:HTTPリクエストでマルチパートフォームデータを送信するにはどうすればよいですか(Watson NLCトレーニング用)?

--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タイプのようにと思われます。

(ゴーで書かれた)私のコード:カールmultipart/form-dataの "コンテンツタイプ" ヘッダを送信していることを

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 
} 
+0

また、curl要求(curl -u "{username}": "{password}" -F [email protected] -F training_metadata = "{\" en \ "、 "name \":\ "My Classifier \"} "" https://gateway.watsonplatform.net/natural-language-classifier/api/v1/classifiers ")正常に動作します。 –

答えて

1

注意。あなたのGoプログラムはちょうどform-dataの "Content-Disposition"ヘッダーを送信しています(差異に注意してください、先頭のmultipart複合トップレベルメディアタイプはありません)。しかし正しい "Content-Type"ヘッダーHTTP要求を含んでいます。

ゴーのmultipart.WriterタイプのCreateFormFile method does the sameは、しかし、再び、それは仕事の一部だけだ:

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

適切な "Content-Type" ヘッダ値を取得するには、multipart.Writer.FormDataContentTypeを使用する必要があります。コンテンツのためWatsonClassifier.requestに別のパラメータを追加し、

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

代わりに:使用するために、その値を置くために、あなたはあなたのhttp.Requestインスタンス上のコンテンツタイプを設定することができるように、あなたのWatsonClassifier.request方法にあなたのmultipart.Writerを取得する必要があります引数としてFormDataContentTypeの結果をコールサイトからWatsonClassifier.Trainに渡します。

これがトリックであるかどうかをお知らせください。

関連する問題