Правильный способ сделать HTTP-запрос в Android - PullRequest
0 голосов
/ 27 сентября 2011

Какой самый лучший способ установить соединение HTTP. Я имею в виду использование прокси и так далее. Сейчас я использую это:

StringBuilder entity = new StringBuilder();
entity.append("request body");

AndroidHttpClient httpClient = AndroidHttpClient.newInstance(null);

String proxyHost = android.net.Proxy.getDefaultHost();
int proxyPort = android.net.Proxy.getDefaultPort();
if (proxyHost != null && proxyPort > 0) {
    HttpHost proxy = new HttpHost(proxyHost, proxyPort);
    ConnRouteParams.setDefaultProxy(httpClient.getParams(), proxy);
}
HttpPost httpPost = new HttpPost("https://w.qiwi.ru/term2/xmlutf.jsp");
httpPost.setEntity(new StringEntity(entity.toString(), "UTF-8"));
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 15000);
HttpConnectionParams.setSoTimeout(params, 30000);
httpPost.setParams(params);
HttpResponse httpResponse = httpClient.execute(httpPost);

int responseCode = httpResponse.getStatusLine().getStatusCode();
if (responseCode == HttpStatus.SC_OK) {
    // parsing response
}

Я не совсем уверен, что это нормально, потому что один из моих клиентов сказал мне, что у него есть IllegalArgumentException сразу после установки прокси в его настройках APN.

1 Ответ

1 голос
/ 27 сентября 2011

Используйте один метод с именем executeRequest, который выполняет фактический вызов хоста API_REST_HOST, таким образом (API_REST_HOST может быть значением, подобным «api.flickr.com» для остальных API-интерфейсов flickr. Добавляются HTTP и порт)

 private void executeRequest(HttpGet get, ResponseHandler handler) throws IOException {
    HttpEntity entity = null;
    HttpHost host = new HttpHost(API_REST_HOST, 80, "http");
    try {
        final HttpResponse response = mClient.execute(host, get);
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            entity = response.getEntity();
            final InputStream in = entity.getContent();
            handler.handleResponse(in);
        }
    } catch (ConnectTimeoutException e) {
        throw new ConnectTimeoutException();
    } catch (ClientProtocolException e) {
        throw new ClientProtocolException();
    } catch (IOException e) {
        e.printStackTrace();
        throw new IOException();
    } 
    finally {
        if (entity != null) {
            try {
                entity.consumeContent();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Вызовите этот API здесь следующим образом:

final HttpGet get = new HttpGet(uri.build().toString());
    executeRequest(get, new ResponseHandler() {
        public void handleResponse(InputStream in) throws IOException {
            parseResponse(in, new ResponseParser() {
                public void parseResponse(XmlPullParser parser)
                        throws XmlPullParserException, IOException {
                    parseToken(parser, token, userId);
                }
            });
        }
    });

Где ваш URI построен так:

final Uri.Builder builder = new Uri.Builder();
builder.path(ANY_PATH_AHEAD_OF_THE_BASE_URL_IF_REQD);
builder.appendQueryParameter(PARAM_KEY, PARAM_VALUE);

Ваш mClient объявлен как переменная уровня класса thisспособ

private HttpClient mClient;

и, наконец, ваш parseResponse может быть выполнен таким образом (скажем, вы хотите проанализировать данные XML)

private void parseResponse(InputStream in, ResponseParser responseParser) throws IOException {
    final XmlPullParser parser = Xml.newPullParser();
    try {
        parser.setInput(new InputStreamReader(in));

        int type;
        while ((type = parser.next()) != XmlPullParser.START_TAG &&
                type != XmlPullParser.END_DOCUMENT) {
            // Empty
        }

        if (type != XmlPullParser.START_TAG) {
            throw new InflateException(parser.getPositionDescription()
                    + ": No start tag found!");
        }

        String name = parser.getName();
        if (RESPONSE_TAG_RSP.equals(name)) {
            final String value = parser.getAttributeValue(null, RESPONSE_ATTR_STAT);
            if (!RESPONSE_STATUS_OK.equals(value)) {
                throw new IOException("Wrong status: " + value);
            }
        }

        responseParser.parseResponse(parser);

    } catch (XmlPullParserException e) {
        final IOException ioe = new IOException("Could not parse the response");
        ioe.initCause(e);
        throw ioe;
    }
}

Этот код заботится обо всех возможных исключениях и показываеткак правильно проанализировать ответ, поступающий из входного потока из HTTP-соединения.

Как вы уже знаете, убедитесь, что вы используете это в отдельном потоке, а не в потоке пользовательского интерфейса.Вот и все:)

...