3

サービス モジュールを使用して、Android デバイスから drupal Web サイトに画像ファイルをアップロードしようとしています。

私は正常にログインできます:

HttpParams connectionParameters =  new BasicHttpParams(); 
int timeoutConnection = 3000;
HttpConnectionParams.setConnectionTimeout(connectionParameters, timeoutConnection);                 
int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(connectionParameters, timeoutSocket);

httpClient   =   new DefaultHttpClient(connectionParameters);
HttpPost httpPost       =   new HttpPost(serverUrl+"user/login");
JSONObject json = new JSONObject();    

try{
     json.put("password", editText_Password.getText().toString());
     json.put("username", editText_UserName.getText().toString());                          
     StringEntity se = new StringEntity(json.toString());
     se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));

     httpPost.setEntity(se);                       

     //Execute HTTP post request
     HttpResponse response    =   httpClient.execute(httpPost);   
     int status_code = response.getStatusLine().getStatusCode();                            

     ... 
     ...

}
catch(Exception ex)
{

}

応答オブジェクトを介して、セッション名 session id 、ユーザー ID およびその他の多くの情報を取得できます。

ログイン後、HttpGet オブジェクトを介して自分でセッション情報を設定しませんが、同じ DefaultHttpClient を使用すると、次のコードを使用して魔法のようにノードを取得できます。

HttpGet httpPost2 = new HttpGet(serverUrl+"node/537.json"); HttpResponse response2 = httpClient.execute(httpPost2);

これは、httpClientオブジェクトがセッション情報を自動的に保存したと思いました。最初にログインしないか、新しい HttpClient オブジェクトを使用してノードを取得しようとすると、401 エラーが発生するためです。

ただし、ログイン後に次のように画像ファイルをアップロードしようとすると:

   httpPost = new HttpPost(serverUrl+"file/");
   json = new JSONObject();
   JSONObject fileObject = new JSONObject();    

   fileObject.put("file", photodata); //photodata is a byte[] that is set before this point
   fileObject.put("filename", "myfirstfile");
   fileObject.put("filepath", "sites/default/files/myfirstimage.jpg");
   json.put("file", fileObject);            

   se = new StringEntity(json.toString());
   se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
   httpPost.setEntity(se);      

   //Execute HTTP post request
   response    =   httpClient.execute(httpPost);   
   status_code = response.getStatusLine().getStatusCode();  

ログインして同じ HttpClient オブジェクトを使用しているにもかかわらず、401 エラーが発生します。

私も追加しようとしました:

httpPost.setHeader("Cookie", SessionName+"="+sessionID);

これでも 401 エラーが発生します。

file.create メソッドを使用しようとしているため、正しい URL を使用しているかどうかもわかりませんが、URL を「myip:myport/rest/file/create」と記述すると、間違ったアドレスが返されます。私の目的は、イメージをユーザー ノードにアップロードすることなので、ファイルを正常に追加した後、node.create を使用しますよね?

誰かが私がこれを乗り越えるのを手伝ってくれることを願っています.

4

1 に答える 1

4

私が最初にこれをやり始めたとき、私のエラーのほとんどは正しく認証されていないことが原因であることがわかりました..あなたの方法が正しいかどうかはわかりません..これが機能することはわかっています。

Drupal Services 3 を使用してログインし、セッション Cookie を共有設定に保存します。dataOut は、必要なユーザー ログインとパスワード情報を保持する JSON オブジェクトです。

String uri = URL + ENDPOINT + "user/login";
HttpPost httppost = new HttpPost(uri);
httppost.setHeader("Content-type", "application/json");
StringEntity se;
try {
     se = new StringEntity(dataOut.toString());
     se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,
                    "application/json"));
     httppost.setEntity(se);
     HttpResponse response = mHttpClient.execute(httppost);
     mResponse = EntityUtils.toString(response.getEntity());
     // save the sessid and session_name
     JSONObject obj = new JSONObject(mResponse);
     SharedPreferences settings = PreferenceManager
    .getDefaultSharedPreferences(mCtx);
     SharedPreferences.Editor editor = settings.edit();
     editor.putString("cookie", obj.getString("session_name") + "="
                    + obj.getString("sessid"));
     editor.putLong("sessionid_timestamp", new Date().getTime() / 100);
     editor.commit();
} catch { //all of my catches here }

セッション ID を保存したら、次のように drupal でタスクを実行します。次のコードはノードをポストします。関数 getCookie() を使用して、セッション Cookie が存在する場合はそれを取得します。存在しない場合はログインし、有効期限が切れている場合はログインします (drupal 設定で Cookie の有効期限を設定する必要があることに注意してください。 php ファイル (私の記憶が正しければそこにあると思います)

String uri = URL + ENDPOINT + "node";
HttpPost httppost = new HttpPost(uri);
httppost.setHeader("Content-type", "application/json");
String cookie = this.getCookie(mCtx);
httppost.setHeader("Cookie", cookie);
StringEntity se;
try {
    se = new StringEntity(dataOut.toString());
httppost.setEntity(se);
HttpResponse response = mHttpClient.execute(httppost);
    // response is here if you need it.
// mResponse = EntityUtils.toString(response.getEntity());
} catch { //catches }

Cookie を最新の状態に保ち、機能させる getCookie() 関数。

/**
 * Takes the current time, the sessid and determines if we are still part of
 * an active session on the drupal server.
 * 
 * @return boolean
 * @throws InternetNotAvailableException
 * @throws ServiceNotAvailableException
 */
protected String getCookie(Context ctx)
        throws InternetNotAvailableException {
    SharedPreferences settings = PreferenceManager
            .getDefaultSharedPreferences(mCtx);
    Long timestamp = settings.getLong("sessionid_timestamp", 0);
    Long currenttime = new Date().getTime() / 100;
    String cookie = settings.getString("cookie", null);
            //mSESSION_LIFETIME is the session lifetime set on my drupal server
    if (cookie == null || (currenttime - timestamp) >= mSESSION_LIFETIME) {

                    // the following are the classes I use to login.
                    // the important code is listed above.
                    // mUserAccount is the JSON object holding login, 
                    // password etc.
        JSONObject mUserAccount = UserAccount.getJSONUserAccount(ctx);
        call(mUserAccount, JSONServerClient.USER_LOGIN);

        return getCookie(ctx);
    } else {
        return cookie;
    }
}

これにより、サービスが提供するすべての機能を利用できるようになります。エンドポイントが正しいことを確認し、権限が設定されていることも確認してください。ユーザーにノードを作成する許可を与えていないことに気付くまで、私は何時間も悪態をつきました。

ログインしたら.. Drupal サービスにファイルをアップロードするには、次のコードを使用して、まず画像を byteArray に変換し、次に Base64 に変換します。

tring filePath = Environment.getExternalStorageDirectory()+ "/test.jpg";
imageView.setImageDrawable(Drawable.createFromPath(filePath));
Bitmap bm = BitmapFactory.decodeFile(filePath);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] byteArrayImage = baos.toByteArray(); 
String encodedImage = Base64.encodeToString(byteArrayImage, Base64.DEFAULT);

エンコードされたイメージを取得したら。キー、ファイル(必須)、ファイル名(オプションですが、推奨)、ファイルサイズ(オプション、私が推測するポスター)を使用してJSONオブジェクトを構築しますJSONは、その単純な必須フォーム{"file" :encodedImage}. 次に、サーバーでファイル リソースが有効になっていることを確認した後、データを my-server/rest-endpoint/file に POST します。応答には、JSON の fid が含まれます。次に、ノード リソースを使用して後で作成するノードのイメージ フィールドに、この fid を割り当てることができます。

于 2012-06-23T21:15:09.090 に答える