Home About Contact
Android , Java

HttpClient から URLConnection への切り替え ( Android )

すでにこの世は Android 8.0 OREO 時代なのですが、 Android 6.0 Changes の Apache HTTP Client Removal で、Apache HTTP Client が削除されたという件に今さら直面した話。

Eclipse時代のビルドのままになっていた Android プロジェクトを最新のSDKでビルドしようとしたら Apache HTTP Client が使えなくなっていた。 調べてみると 代わりにURLConnection を使え ということのようなので、いろいろ実装を直した結果の一部を備忘録的にシェアします。

テスト用サーバの準備

必要な機能は JSON データの GET と POST の二種類だったので、そのサーバ側機能をまずは用意します。 ここでは Grails 3.3.0 を使います。

$ grails create-app myserver
$ cd myserver
$ grails create-controller Products

これで grails-app/controllers/myserver/ProductsController.groovy が作成されるので、 ここに GET と POST 先を用意します。

package myserver

import groovy.json.*

class ProductsController {
    static allowedMethods = [
        item:'GET',
        newitem:'POST'
    ]

    private static Map<String,Map<String,String>> db
    static {
        db = new HashMap<>()
        db.put('001', [name:'MacBook', price:'1000'])
        db.put('002', [name:'MacBook Pro', price:'1200'])
        db.put('011', [name:'iPad', price:'800'])
    }

    def item(){
        render text: new JsonBuilder( db[params.id] ).toString()
    }

    def newitem() {
        def productJson = new InputStreamReader(request.inputStream,'UTF-8').text
        db[params.id] = new JsonSlurper().parseText( productJson )
        render text: new JsonBuilder( db[params.id] ).toString()
    }
}

Productsコントローラーはこんな感じの実装です。

以下でクライアントからのテストを受け付けるためにサーバを起動しておきます。

$ grails run-app

GET クライアント

サーバが準備できたので、それに対して GET してみます。

get.groovy

URI uri = new URI('http://localhost:8080/products/item/001')
HttpURLConnection connection = (HttpURLConnection) uri.toURL().openConnection()
connection.setRequestMethod("GET")
def resultJson = new InputStreamReader(connection.getInputStream(),'UTF-8').text
connection.disconnect()
println resultJson

実行結果

$ groovy get
{"name":"MacBook","price":"1000"}

商品 001 の json 文字列を得ることができました。

POST クライアント

次に POST してみます。

post.groovy

def productData = '{"name":"iPad Pro","price":"1200"}'
def bytes = productData.getBytes('UTF-8')
URI uri = new URI('http://localhost:8080/products/newitem/004')

HttpURLConnection connection = (HttpURLConnection) uri.toURL().openConnection()
connection.setRequestMethod("POST")
connection.setDoOutput(true)
connection.setFixedLengthStreamingMode(bytes.length)
connection.addRequestProperty("Content-Type", "application/json; charset=UTF-8")

// 送信
new DataOutputStream(connection.getOutputStream()).write(bytes)

// 受信
def resultJson = new InputStreamReader(connection.getInputStream(),'UTF-8').text
connection.disconnect()

println resultJson

実行結果

$ groovy post
{"name":"iPad Pro","price":"1200"}

商品 004 で POST した結果の json 文字列を得ることができました。