我正在尝试使用服务模块将图像文件从android设备上传到我的drupal网站
我可以成功登录:
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)
{
}
通过响应对象,我可以获得会话名称,会话ID,用户ID和许多其他信息.
登录后,我自己没有通过HttpGet对象设置任何会话信息,但是使用相同的DefaultHttpClient,我可以使用以下代码神奇地检索节点:
HttpGet httpPost2 =新的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错误.
我也不确定我是否使用正确的URL,因为我正在尝试使用file.create方法,但是将URL编写为“ myip:myport / rest / file / create”会给出错误的地址.
我的目标是将图像上传到用户节点,所以我猜想在成功添加文件之后,我将使用node.create对吗?
我希望有人能帮助我解决这个问题.
解决方法:
我发现当我第一次开始执行此操作时,我的大多数错误是由于未正确进行身份验证造成的.我不确定您的方法是否正确.
使用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 }
getCookie()函数可让您的cookie保持最新状态.
/**
* 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 Services,我使用以下代码首先将图像转换为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);
一旦有了encodedImage.使用键,文件(必需),文件名(可选,但推荐),filesize(可选)和uid(可选,我认为是发布者)构造一个JSON对象,因此JSON在其简化列表中必须为{“ file” :encodedImage}.然后,在确保已启用服务器上的文件资源后,将数据发布到my-server / rest-endpoint / file.响应将包含JSON中的fid.然后,您可以将该节点标识符分配给随后使用节点资源创建的节点的图像字段.
标签:file-upload,drupal,android,service
来源: https://codeday.me/bug/20191101/1981677.html