1

会社のjson Webサービスからjson応答を取得しようとしています。コードは次のとおりです。

public final static String GOINOUT_HOST_NAME = "http://ec2-54-254-123-244.ap-southeast-1.compute.amazonaws.com";
public final static String GOINOUT_API_VERSION = "/api/v1";

public final static String GOINOUT_FACEBOOK_AUTHENTICATE = GOINOUT_HOST_NAME + GOINOUT_API_VERSION + "/facebook_authenticate";

public static JSONObject loginGoinoutWithFacebook(String accessToken) {
    JSONObject goinoutUserJsonObject = null;
    try {
        Hashtable params = new Hashtable();
        params.put("access_token", accessToken);
        String paramsString = StringUtil.toURLParameters(params);

        Hashtable properties = new Hashtable();
        String response = HttpUtils.sendGoinoutJsonRequest(GOINOUT_FACEBOOK_AUTHENTICATE + "?" + paramsString, paramsString, HttpUtils.TIMEOUT, properties, HttpConnection.POST);
        Dialog.alert("res: " + response);
        JSONObject goinoutJsonObject = new JSONObject(response);
        goinoutUserJsonObject = new JSONObject(goinoutJsonObject.getString("user"));
    } catch (IOException e) {
        Dialog.alert("e1: " + e.getMessage());
        e.printStackTrace();
    } catch (JSONException e1) {
        Dialog.alert("e2: " + e1.getMessage());
        e1.printStackTrace();
    }
    return goinoutUserJsonObject;
}

次のコードのチャンクは goinout json リクエストです。

public static String sendGoinoutJsonRequest(String url,String data,long timeout, Hashtable properties, String method) throws IOException {

    HttpConnectionFactory factory = new HttpConnectionFactory(Util.getTransportPriority());
    while(true) {

        HttpConnectionIOSession httpConnectionIOSession = null;
        try {

            HttpConnection httpConnection = factory.getHttpConnection(url);
            if(httpConnection == null) throw new IOException();
            try {

                httpConnection.setRequestMethod(method);
                httpConnection.setRequestProperty("If-Modified-Since","29 Oct 1999 19:43:31 GMT");
                httpConnection.setRequestProperty("User-Agent","Profile/MIDP-2.0 Configuration/CLDC-1.0");
                httpConnection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
                httpConnection.setRequestProperty("Accept","application/json");                    
                httpConnection.setRequestProperty("Content-Length",data.getBytes().length + "");
                httpConnection.setRequestProperty("Content-Language","en-US");
                httpConnection.setRequestProperty("x-rim-transcode-content","none");
                Enumeration keys = properties.keys();
                while(keys.hasMoreElements()) {
                    String key = (String) keys.nextElement();
                    String value = (String) properties.get(key);
                    httpConnection.setRequestProperty(key, value);
                }
                OutputStream outputStream = httpConnection.openOutputStream();
                InputStream inputStream = null;
                if(timeout != -1) {

                    httpConnectionIOSession = new HttpConnectionIOSession(httpConnection,inputStream,outputStream,timeout);

                }
                outputStream.write(data.getBytes());
                outputStream.close();
                int responseCode = httpConnection.getResponseCode();
                if(responseCode != HttpConnection.HTTP_OK) {

                    if(responseCode == HttpConnection.HTTP_BAD_REQUEST) {

                        continue;

                    }
                    if(timeout != -1 && HttpUtils.TIMEOUT + 2000 <= TIMEOUT_MIN) {

                        HttpUtils.TIMEOUT += 2000;

                    }
                    throw new IOException("HTTP " + responseCode + " error code.");

                }
                inputStream = httpConnection.openInputStream();
                final ByteBuffer byteBuffer = new ByteBuffer(inputStream);
                final String response = byteBuffer.getString();
                close(httpConnection,inputStream,outputStream);

                if(timeout != -1 && HttpUtils.TIMEOUT - 1000 >= TIMEOUT_MIN) {

                    HttpUtils.TIMEOUT -= 1000;

                }
                if(httpConnectionIOSession != null) httpConnectionIOSession.interrupt();
                return response;

            } catch(IOException ioException) {

                if(timeout != -1 && HttpUtils.TIMEOUT + 2000 <= TIMEOUT_MIN) {

                    HttpUtils.TIMEOUT += 2000;

                }
                throw ioException;


            }

        } catch(IOException ioException) {

            if(timeout != -1 && HttpUtils.TIMEOUT + 2000 <= TIMEOUT_MIN) {

                HttpUtils.TIMEOUT += 2000;

            }
            throw ioException;

        } finally {
            if(httpConnectionIOSession != null) httpConnectionIOSession.interrupt();
        }

    }

}

私が設定したプロパティを見てください。この次のプロパティを使用する場合:

httpConnection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
httpConnection.setRequestProperty("Accept","application/json");

何が起こるかというと、BB シミュレーターから、また WiFi 接続を使用して実際のデバイスから JSON データを取得できたということです。しかし、モバイル サービス プロバイダーを使用して REAL DEVICE を使用すると、常に IOException: stream closed が発生します。

この次のコードを使用する場合:

httpConnection.setRequestProperty("Content-Type","application/json");
httpConnection.setRequestProperty("Accept","application/json");   

シミュレーターでは常に HTTP エラー コード 500 が表示されます。そして、モバイル サービス プロバイダーを使用して実際のデバイスでこのプロパティを使用すると、そこに while(true) があるため、コードは実行され続けます。皆さん、私を助けていただけないでしょうか。

実際のところ、このコードのチャンクは、Facebook API および Tumblr API から json データを取得する際に機能することが証明されています。私はいつもこのコードを使用していますが、問題はありません。サーバー側に何か問題があるのだろうか、それとも別のプロパティを追加する必要があるのでしょうか??? どうもありがとう。

HttpConnectionFactory の Nate リクエスト:

package com.hammyliem.abateify.ui.network;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Vector;

import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;

import net.rim.device.api.io.http.HttpHeaders;
import net.rim.device.api.io.http.HttpProtocolConstants;
import net.rim.device.api.servicebook.ServiceBook;
import net.rim.device.api.servicebook.ServiceRecord;
import net.rim.device.api.system.Branding;
import net.rim.device.api.system.CoverageInfo;
import net.rim.device.api.system.DeviceInfo;
import net.rim.device.api.system.WLANInfo;

public class HttpConnectionFactory {

  public static final int TRANSPORT_WIFI = 1;
  public static final int TRANSPORT_BES = 2;
  public static final int TRANSPORT_BIS = 4;
  public static final int TRANSPORT_DIRECT_TCP = 8;
  public static final int TRANSPORT_WAP2 = 16;
  public static final int TRANSPORT_SIM = 32;

  public static final int TRANSPORTS_ANY = TRANSPORT_WIFI | TRANSPORT_BES | TRANSPORT_BIS | TRANSPORT_DIRECT_TCP | TRANSPORT_WAP2 | TRANSPORT_SIM;
  public static final int TRANSPORTS_AVOID_CARRIER = TRANSPORT_WIFI | TRANSPORT_BES | TRANSPORT_BIS | TRANSPORT_SIM;
  public static final int TRANSPORTS_CARRIER_ONLY = TRANSPORT_DIRECT_TCP | TRANSPORT_WAP2 | TRANSPORT_SIM;

  public static final int DEFAULT_TRANSPORT_ORDER[] = { TRANSPORT_WIFI, TRANSPORT_SIM, TRANSPORT_BIS, TRANSPORT_BES, TRANSPORT_WAP2, TRANSPORT_DIRECT_TCP };

  private static final int TRANSPORT_COUNT = DEFAULT_TRANSPORT_ORDER.length;

  // private static ServiceRecord srMDS[], srBIS[], srWAP2[], srWiFi[];
  private static ServiceRecord srWAP2[];
  private static boolean serviceRecordsLoaded = false;

  private int transports[];
  private int lastTransport = -1;

  public HttpConnectionFactory() {
    this(0);
  }

  public HttpConnectionFactory(int allowedTransports) {
    this(transportMaskToArray(allowedTransports));
  }

  public HttpConnectionFactory(int transportPriority[]) {
    if (!serviceRecordsLoaded) {
      loadServiceBooks(false);
    }
    transports = transportPriority;
  }

  public static String getUserAgent() {
    StringBuffer sb = new StringBuffer();
    sb.append("BlackBerry");
    sb.append(DeviceInfo.getDeviceName());
    sb.append("/");
    sb.append(DeviceInfo.getSoftwareVersion());
    sb.append(" Profile/");
    sb.append(System.getProperty("microedition.profiles"));
    sb.append(" Configuration/");
    sb.append(System.getProperty("microedition.configuration"));
    sb.append(" VendorID/");
    sb.append(Branding.getVendorId());

    return sb.toString();
  }

  public static String getProfile() {
    StringBuffer sb = new StringBuffer();
    sb.append("http://www.blackberry.net/go/mobile/profiles/uaprof/");
    sb.append(DeviceInfo.getDeviceName());
    sb.append("/");
    sb.append(DeviceInfo.getSoftwareVersion().substring(0, 3)); //RDF file format is 4.5.0.rdf (does not include build version)
    sb.append(".rdf");

    return sb.toString();
  }

  public HttpConnection getHttpConnection(String pURL) {
    return getHttpConnection(pURL, null, null);
  }

  public HttpConnection getHttpConnection(String pURL, HttpHeaders headers) {
    return getHttpConnection(pURL, headers, null);
  }

  public HttpConnection getHttpConnection(String pURL, byte[] data) {
    return getHttpConnection(pURL, null, data);
  }

  public HttpConnection getHttpConnection(String pURL, HttpHeaders headers, byte[] data) {

    int curIndex = 0;
    HttpConnection con = null;

    while ((con = tryHttpConnection(pURL, curIndex, headers, data)) == null) {
      try {
        curIndex = nextTransport(curIndex);
      } catch (HttpConnectionFactoryException e) {
        e.printStackTrace();
        break;
      } finally {
      }
    }

    if (con != null) {
      setLastTransport(transports[curIndex]);
    }

    return con;
  }

  private int nextTransport(int curIndex) throws HttpConnectionFactoryException {
    if ((curIndex >= 0) && (curIndex < transports.length - 1)) {
      return curIndex + 1;
    } else {
      throw new HttpConnectionFactoryException("No more transport available.");
    }
  }

  private HttpConnection tryHttpConnection(String pURL, int tIndex, HttpHeaders headers, byte[] data) {

    HttpConnection con = null;
    OutputStream os = null;

    switch (transports[tIndex]) {
    case TRANSPORT_SIM:
      try {
        con = getSimConnection(pURL, false);
      } catch (IOException e) {
      } finally {
        break;
      }
    case TRANSPORT_WIFI:
      try {
        con = getWifiConnection(pURL);
      } catch (IOException e) {
      } finally {
        break;
      }
    case TRANSPORT_BES:
      try {
        con = getBesConnection(pURL);
      } catch (IOException e) {
      } finally {
        break;
      }
    case TRANSPORT_BIS:
      try {
        con = getBisConnection(pURL);
      } catch (IOException e) {
      } finally {
        break;
      }
    case TRANSPORT_DIRECT_TCP:
      try {
        con = getTcpConnection(pURL);
      } catch (IOException e) {
      } finally {
        break;
      }
    case TRANSPORT_WAP2:
      try {
        con = getWap2Connection(pURL);
      } catch (IOException e) {
      } finally {
        break;
      }
    }

    if (con != null) {
      try {
        //add headers to connection
        if (headers != null) {
          int size = headers.size();

          for (int i = 0; i < size;) {
            String header = headers.getPropertyKey(i);
            String value = headers.getPropertyValue(i++);

            if (value != null) {
              con.setRequestProperty(header, value);

            }
          }
        }
        // post data
        if (data != null) {
          con.setRequestMethod(HttpConnection.POST);
          con.setRequestProperty(HttpProtocolConstants.HEADER_CONTENT_TYPE, HttpProtocolConstants.CONTENT_TYPE_APPLICATION_X_WWW_FORM_URLENCODED);
          con.setRequestProperty(HttpProtocolConstants.HEADER_CONTENT_LENGTH, String.valueOf(data.length));

          os = con.openOutputStream();
          os.write(data);
        } else {
          con.setRequestMethod(HttpConnection.GET);
        }

      } catch (IOException e) {
        e.printStackTrace();
      }
    }

    return con;
  }

  public int getLastTransport() {
    return lastTransport;
  }

  public String getLastTransportName() {
    return getTransportName(getLastTransport());
  }

  private void setLastTransport(int pLastTransport) {
    lastTransport = pLastTransport;
  }

  private HttpConnection getSimConnection(String pURL, boolean mdsSimulatorRunning) throws IOException {
    if (DeviceInfo.isSimulator()) {
      if (mdsSimulatorRunning) {
        return getConnection(pURL, ";deviceside=false", null);
      } else {
        return getConnection(pURL, ";deviceside=true", null);
      }
    }
    return null;
  }

  private HttpConnection getBisConnection(String pURL) throws IOException {
    if (CoverageInfo.isCoverageSufficient(4 /* CoverageInfo.COVERAGE_BIS_B */)) {
      return getConnection(pURL, ";deviceside=false;ConnectionType=mds-public", null);
    }
    return null;
  }

  private HttpConnection getBesConnection(String pURL) throws IOException {
    if (CoverageInfo.isCoverageSufficient(2 /* CoverageInfo.COVERAGE_MDS */)) {
      return getConnection(pURL, ";deviceside=false", null);
    }
    return null;
  }

  private HttpConnection getWifiConnection(String pURL) throws IOException {
    if (WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED) {
      return getConnection(pURL, ";interface=wifi", null);
    }
    return null;
  }

  private HttpConnection getWap2Connection(String pURL) throws IOException {
    if (CoverageInfo.isCoverageSufficient(1 /* CoverageInfo.COVERAGE_DIRECT */) && (srWAP2 != null) && (srWAP2.length != 0)) {
      return getConnection(pURL, ";deviceside=true;ConnectionUID=", srWAP2[0].getUid());
    }
    return null;
  }

  private HttpConnection getTcpConnection(String pURL) throws IOException {
    if (CoverageInfo.isCoverageSufficient(1 /* CoverageInfo.COVERAGE_DIRECT */)) {
      return getConnection(pURL, ";deviceside=true", null);
    }
    return null;
  }

  private HttpConnection getConnection(String pURL, String transportExtras1, String transportExtras2) throws IOException {
    StringBuffer fullUrl = new StringBuffer();
    fullUrl.append(pURL);
    if (transportExtras1 != null) {
      fullUrl.append(transportExtras1);
    }
    if (transportExtras2 != null) {
      fullUrl.append(transportExtras2);
    }
    return (HttpConnection) Connector.open(fullUrl.toString());
  }

  public static void reloadServiceBooks() {
    loadServiceBooks(true);
  }

  private static synchronized void loadServiceBooks(boolean reload) {
    if (serviceRecordsLoaded && !reload) {
      return;
    }
    ServiceBook sb = ServiceBook.getSB();
    ServiceRecord[] records = sb.getRecords();
    Vector mdsVec = new Vector();
    Vector bisVec = new Vector();
    Vector wap2Vec = new Vector();
    Vector wifiVec = new Vector();

    if (!serviceRecordsLoaded) {
      for (int i = 0; i < records.length; i++) {
        ServiceRecord myRecord = records[i];
        String cid, uid;

        if (myRecord.isValid() && !myRecord.isDisabled()) {
          cid = myRecord.getCid().toLowerCase();
          uid = myRecord.getUid().toLowerCase();
          if ((cid.indexOf("wptcp") != -1) && (uid.indexOf("wap2") != -1) && (uid.indexOf("wifi") == -1) && (uid.indexOf("mms") == -1)) {
            wap2Vec.addElement(myRecord);
          }
        }
      }

      srWAP2 = new ServiceRecord[wap2Vec.size()];
      wap2Vec.copyInto(srWAP2);
      wap2Vec.removeAllElements();
      wap2Vec = null;

      serviceRecordsLoaded = true;
    }
  }

  public static int[] transportMaskToArray(int mask) {
    if (mask == 0) {
      mask = TRANSPORTS_ANY;
    }
    int numTransports = 0;
    for (int i = 0; i < TRANSPORT_COUNT; i++) {
      if ((DEFAULT_TRANSPORT_ORDER[i] & mask) != 0) {
        numTransports++;
      }
    }
    int transports[] = new int[numTransports];
    int index = 0;
    for (int i = 0; i < TRANSPORT_COUNT; i++) {
      if ((DEFAULT_TRANSPORT_ORDER[i] & mask) != 0) {
        transports[index++] = DEFAULT_TRANSPORT_ORDER[i];
      }
    }
    return transports;
  }

  private static String getTransportName(int transport) {
    String tName;
    switch (transport) {
    case TRANSPORT_WIFI:
      tName = "WIFI";
      break;
    case TRANSPORT_BES:
      tName = "BES";
      break;
    case TRANSPORT_BIS:
      tName = "BIS";
      break;
    case TRANSPORT_DIRECT_TCP:
      tName = "TCP";
      break;
    case TRANSPORT_WAP2:
      tName = "WAP2";
      break;
    case TRANSPORT_SIM:
      tName = "SIM";
      break;
    default:
      tName = "UNKNOWN";
      break;
    }
    return tName;
  }

}
4

2 に答える 2

0

Nate が指摘したように、イベント スレッドでコードを実行している可能性に加えて、ここには 2 つの異なる問題があると思われます。

イベント スレッドで実行されているかどうかはわかりません。実行されている場合、アプリケーションはアプリケーション応答なしの例外で終了するためです。しかし、ネイトが指摘しているように、イベント スレッドからダイアログを実行しようとすると、例外が発生します。したがって、いずれにしても例外が予想されます....

報告された問題を要約すると、次のいずれかが発生するようです。特定のヘッダー。これは、サーバーがあなたのリクエストを返し、それを理解していないことを伝えていることを意味します。だからあなたは何かを間違って送っています。

まず、IOException を調査することをお勧めします。基本的には、取得した例外の詳細を出力します (toString() で実行されます)。これにより、問題の詳細が表示されます。いくつかの選択肢があり、タイムアウトになると思いますが、解決策を提案する前に知っておきたい.

以前のスレッドを参照できますか : blackberry-get-error-code-411 私の返信をもう一度お読みください。

そこには、411 エラーだけでなく、すべての通信にとって重要な 2 つのポイントがありました。

  1. 送信されるデータに使用されるエンコーディング
  2. 使用される接続方法。

ここでは、エンコーディングが 500 リターン コードの鍵となる可能性があります。JSON データを送信していることをサーバーに伝えると、サーバーはおそらくデータが UTF-8 でエンコードされることを期待します。ただし、送信するデータはそうではないようです。標準の Latin-1 文字だけを使用している場合、これは問題になりません。JSON データにその文字セットに含まれていない文字が含まれている場合、データは正しくエンコードされないため、サーバーがそれを理解できない可能性があります。

したがって、安全のために、JSON データを送信するときは、UTF-8 でエンコードすることをお勧めします (生成されるバイト数は、文字列の文字数と必ずしも同じではないことに注意してください)。

さらに、500 エラー コード (実際にはすべてのエラー コード) に関しては、返された応答のヘッダーをダンプすることをお勧めします。彼らはおそらく、実際にリクエストを返したサーバーを特定します。リクエストを拒否できる他のゲートウェイが関係しているため、モバイルネットワーク経由で処理する場合は、サーバーではない可能性があります。

要約すると、この問題 (またはその他のネットワークの問題) を調査するには、次のことをお勧めします。

  1. 取得した例外から詳細を出力します
  2. 失敗したリクエストに使用されている接続方法を確認してください
  3. 適切なリターン コードが得られない場合は、ヘッダーをダンプして、どのサーバーが実際にリターン コードを返したかを調べます。
  4. 送信するデータを正しくエンコード (文字をバイトにエンコード) していることを確認してください (また、これらを文字に戻す場合は、受信した正しいデコード バイトを確認してください)。

最後に 1 つ。サーバーは 500 を返しているので、送信する前に投稿データをログに記録することをお勧めします。失敗した場合は、適切にフォーマットされていることを確認できます。

于 2013-11-03T01:36:09.093 に答える
0

まず、なぜこの質問にタグが付けられているのか、少しわかりませんandroid。おそらく手遅れで、何かが欠けています。とにかく、BlackBerryの質問としてこれに答えています。

まず、requestに対して通常の URL エンコードを使用して一連のパラメーターをエンコードし、 responseでJSON を期待している場合、元のコードは次のようになります。

httpConnection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
httpConnection.setRequestProperty("Accept","application/json");                    

正しい。リクエストのコンテンツが URL エンコードされたパラメーターである場合は、に設定Content-Typeしないでください。application/json

次に、100% 確信はありませんが、UI スレッドでこのネットワーク リクエストを実行していると思います。を呼び出すコードはわかりませんがloginGoinoutWithFacebook()、UI スレッドで実行していると思います。そのメソッドにDialog.alert()は、UI メソッドである への呼び出しが含まれているからです。

UI スレッドでネットワーク呼び出しを行わないでください。

おそらく何が起こっているか (コンテンツ タイプを に設定すると仮定application/x-www-form-urlencoded) は、Wi-Fi 経由でネットワーク リクエストが非常に迅速に完了し、UI が長時間ブロックされていないことです。うまくいくようです。

ただし、モバイル キャリア ネットワークを使用している場合は、すべてが遅くなります。UI スレッドを長時間ブロックすると、問題が発生します。UI スレッドでネットワーク呼び出しを行った場合の症状を正確に思い出すことはできませんが (私はそれをやったことがないため)、これがあなたの問題であると確信しています。

バックグラウンドThread/Runnableを使用して、ネットワーク呼び出しを実行します。

Thread worker = new Thread(new Runnable() {
   // this method is run on a background thread:
   public void run() {
      final JSONObject response = loginGoinoutWithFacebook(token);

      // to update the UI with the response, we must use the UI thread:
      UiApplication.getUiApplication().invokeLater(new Runnable() {
          public void run() {
              // this just shows an alert, but you can insert your
              //  own code to update the UI properly with the response
              //  contents
              Dialog.alert(response.toString());
          }
      });
   }
});

worker.start();
于 2013-11-02T08:20:04.487 に答える