先ほど公開した、W3C Markup Validation ServiceとW3C CSS Validation Serviceを使った検証を自動化した際に、ハマったのがこれ。
このサービスには、multipart/form-dataでPOSTする必要があります。
例えば、W3C CSS Validation Serviceを使う時は、こんなデータを送信する必要があります。
Content-Type: multipart/form-data; boundary=---------------------------1490267287501179803520268259 Content-Length: 1066 -----------------------------1490267287501179803520268259 Content-Disposition: form-data; name="text" html { margin: 0; padding: 0; height: 100%; } body { background-repeat: no-repeat; background-position: center top background-attachment: fixed; font-siz: 12px; color: midnightblue; } -----------------------------1490267287501179803520268259 Content-Disposition: form-data; name="profile" css3 -----------------------------1490267287501179803520268259 Content-Disposition: form-data; name="usermedium" all -----------------------------1490267287501179803520268259 Content-Disposition: form-data; name="type" none -----------------------------1490267287501179803520268259 Content-Disposition: form-data; name="warning" 1 -----------------------------1490267287501179803520268259 Content-Disposition: form-data; name="vextwarning" -----------------------------1490267287501179803520268259 Content-Disposition: form-data; name="lang" ja -----------------------------1490267287501179803520268259--
「multipart/form-data; boundary=」が入っているのが、特徴ですね。
これをGroovyのHTTPBuilderで送信する方法が最初わからなくて、四苦八苦していました。
最終的に、Apache HttpComponentsのhttpmimeを使えばよいとわかったので、それで実装。
import java.nio.charset.StandardCharsets @Grab('commons-codec:commons-codec:1.9') @Grab('org.codehaus.groovy.modules.http-builder:http-builder:0.6') @GrabExclude('commons-codec:commons-codec') import groovyx.net.http.HTTPBuilder import groovyx.net.http.Method @Grab('org.apache.httpcomponents:httpmime:4.2.1') import org.apache.http.entity.mime.HttpMultipartMode import org.apache.http.entity.mime.MultipartEntity import org.apache.http.entity.mime.content.StringBody import org.apache.http.util.EntityUtils def url = 'アクセスするURL' def http = new HTTPBuilder(url) def resp = http.request(Method.POST) { req -> def entity = new MultipartEntity() entity.addPart('パラメータ名', new StringBody('送信する値', StandardCharsets.UTF_8)) } req.entity = entity }
必要な部分だけ抜き出すと、こんな感じになります。
httpmimeのバージョンは最新版ではないのですが、HTTPBuilderが依存しているHttpComponentsのバージョンから、こちらに合わせておきました。
MultipartEntityにaddPartしている値やCharsetの指定は、適宜読み替えてくださいね。
あと、話はそれますが、地味にハマったのがここ。
@Grab('commons-codec:commons-codec:1.9') @Grab('org.codehaus.groovy.modules.http-builder:http-builder:0.6') @GrabExclude('commons-codec:commons-codec') import groovyx.net.http.HTTPBuilder import groovyx.net.http.Method
最初は会社でスクリプトを書いていたのですが、GrabExcludeして別途依存関係を追加しないと
org.codehaus.groovy.control.MultipleCompilationErrorsException
みたいなエラーを吐いてコケてくれます。同じ事象で、ハマった方もいらっしゃったようで。
GroovyでHTTPBuilderをGrabしようとしたらエラー
http://d.hatena.ne.jp/kaakaa_hoe/20120824
前に自宅でやった時は何も起こらなかったので、事前にCommons Codec 1.6をGrapeで解決したことがあったんでしょうね。
今回はGrabExcludeしてCommons Codecのバージョンを上げて脱出しました。本来1.6を指定すべきなのですが、どうやっても依存関係の解決ができませんでした。
Grapeを使っていて、たま〜にハマるのでこういうのに遭遇すると、ちょっとつらいです。そもそも、簡単なスクリプトで使うつもりなので、ある程度書き上げた後に試して動かない、みたいな…。