ส่งภาพโดยใช้โพสต์ Http


129

ฉันต้องการส่งภาพจากไคลเอนต์ Android ไปยังเซิร์ฟเวอร์ Django โดยใช้ Http Post รูปภาพถูกเลือกจากแกลเลอรี ปัจจุบันฉันใช้ชื่อค่ารายการเพื่อส่งข้อมูลที่จำเป็นไปยังเซิร์ฟเวอร์และรับการตอบกลับจาก Django ใน JSON สามารถใช้วิธีการเดียวกันนี้สำหรับรูปภาพ (พร้อม URL สำหรับภาพที่ฝังในการตอบกลับ JSON) ได้หรือไม่

นอกจากนี้วิธีไหนดีกว่า: เข้าถึงรูปภาพจากระยะไกลโดยไม่ต้องดาวน์โหลดจากเซิร์ฟเวอร์หรือดาวน์โหลดและเก็บไว้ในอาร์เรย์บิตแมปและใช้ภายในเครื่อง ภาพมีจำนวนน้อย (<10) และขนาดเล็ก (50 * 50 จิ้ม)

กวดวิชาใด ๆ ที่จะแก้ไขปัญหาเหล่านี้จะได้รับการชื่นชมมาก

แก้ไข: รูปภาพที่เลือกจากแกลเลอรีจะถูกส่งไปยังเซิร์ฟเวอร์หลังจากปรับขนาดตามขนาดที่ต้องการ

คำตอบ:


144

ฉันจะสมมติว่าคุณรู้เส้นทางและชื่อไฟล์ของภาพที่คุณต้องการอัปโหลด เพิ่มสตริงนี้เพื่อNameValuePairใช้imageเป็นชื่อคีย์

ภาพที่ส่งสามารถทำได้โดยใช้HttpComponents ห้องสมุด ดาวน์โหลดล่าสุด HttpClient (ปัจจุบัน4.0.1 ) ไบนารีกับแพคเกจการอ้างอิงและคัดลอกapache-mime4j-0.6.jarและhttpmime-4.0.1.jarโครงการของคุณและเพิ่มให้สร้างเส้นทาง Java ของคุณ

คุณจะต้องเพิ่มการนำเข้าต่อไปนี้ในชั้นเรียนของคุณ

import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;

ตอนนี้คุณสามารถสร้างMultipartEntityเพื่อแนบภาพกับคำขอ POST ของคุณ รหัสต่อไปนี้แสดงตัวอย่างของวิธีการนี้:

public void post(String url, List<NameValuePair> nameValuePairs) {
    HttpClient httpClient = new DefaultHttpClient();
    HttpContext localContext = new BasicHttpContext();
    HttpPost httpPost = new HttpPost(url);

    try {
        MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

        for(int index=0; index < nameValuePairs.size(); index++) {
            if(nameValuePairs.get(index).getName().equalsIgnoreCase("image")) {
                // If the key equals to "image", we use FileBody to transfer the data
                entity.addPart(nameValuePairs.get(index).getName(), new FileBody(new File (nameValuePairs.get(index).getValue())));
            } else {
                // Normal string data
                entity.addPart(nameValuePairs.get(index).getName(), new StringBody(nameValuePairs.get(index).getValue()));
            }
        }

        httpPost.setEntity(entity);

        HttpResponse response = httpClient.execute(httpPost, localContext);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

ฉันหวังว่าสิ่งนี้จะช่วยคุณในทิศทางที่ถูกต้อง


6
ฉันจะแนะนำสิ่งนี้อย่างแน่นอนที่สุด วิธีนี้คุณสามารถใช้คุณสมบัติ Django เพื่อรับภาพและจัดเก็บได้อย่างง่ายดาย อีกวิธีหนึ่งก็คือการเข้ารหัสไบต์สตรีมจากภาพไปยังสตริงที่เข้ารหัส base64 และถอดรหัสมันฝั่งเซิร์ฟเวอร์ แต่นี่จะเป็นความยุ่งยากในความคิดของฉันมากเกินไปและไม่ใช่วิธีที่จะไป
Piro

6
เฮ้พวกมีวิธีการทำเช่นนี้โดยไม่ต้อง MultipartEntity? จริงๆแล้วฉันไม่ต้องการนำเข้า Apache HC ทั้งหมดเพียงสำหรับ 4 คลาสเหล่านั้น :-(
Neil Traft

6
เพียงเพิ่มพารามิเตอร์ตัวที่ 2 ลงในFileBodyประเภท Mime ที่คุณต้องการ เช่น:new FileBody(new File (nameValuePairs.get(index).getValue()), "image/jpeg")
Piro

4
ดูเหมือนว่าหลายฝ่ายเลิกใช้แล้วใช่ไหม
Nanne

1
@Piro ฉันกำลังคิดถึงการแก้ไขคำตอบของคุณด้วย เอนทิตีแบบหลายส่วนจะถูกคิดค่าเสื่อมราคาพร้อมกับรุ่นเนื้อหาของสตริงที่คุณกำลังใช้ เหตุผลที่ฉันไม่แก้ไขคือเพราะฉันไม่สามารถผูกข้อมูลทั้งหมดใน namevaluepairs ตามที่คุณทำ
อาร์กิวเมนต์ที่ผิดกฎหมาย

15

รหัสอัปเดตเวอร์ชัน 4.3.5

  • httpclient-4.3.5.jar
  • httpcore-4.3.2.jar
  • httpmime-4.3.5.jar

นับตั้งแต่MultipartEntityได้รับการเลิกใช้ โปรดดูรหัสด้านล่าง

String responseBody = "failure";
HttpClient client = new DefaultHttpClient();
client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);

String url = WWPApi.URL_USERS;
Map<String, String> map = new HashMap<String, String>();
map.put("user_id", String.valueOf(userId));
map.put("action", "update");
url = addQueryParams(map, url);

HttpPost post = new HttpPost(url);
post.addHeader("Accept", "application/json");

MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setCharset(MIME.UTF8_CHARSET);

if (career != null)
    builder.addTextBody("career", career, ContentType.create("text/plain", MIME.UTF8_CHARSET));
if (gender != null)
    builder.addTextBody("gender", gender, ContentType.create("text/plain", MIME.UTF8_CHARSET));
if (username != null)
    builder.addTextBody("username", username, ContentType.create("text/plain", MIME.UTF8_CHARSET));
if (email != null)
    builder.addTextBody("email", email, ContentType.create("text/plain", MIME.UTF8_CHARSET));
if (password != null)
    builder.addTextBody("password", password, ContentType.create("text/plain", MIME.UTF8_CHARSET));
if (country != null)
    builder.addTextBody("country", country, ContentType.create("text/plain", MIME.UTF8_CHARSET));
if (file != null)
    builder.addBinaryBody("Filedata", file, ContentType.MULTIPART_FORM_DATA, file.getName());

post.setEntity(builder.build());

try {
    responseBody = EntityUtils.toString(client.execute(post).getEntity(), "UTF-8");
//  System.out.println("Response from Server ==> " + responseBody);

    JSONObject object = new JSONObject(responseBody);
    Boolean success = object.optBoolean("success");
    String message = object.optString("error");

    if (!success) {
        responseBody = message;
    } else {
        responseBody = "success";
    }

} catch (Exception e) {
    e.printStackTrace();
} finally {
    client.getConnectionManager().shutdown();
}

แพ็คเกจ jar ใดที่จำเป็น?

3
httpclient-4.3.5.jar httpcore-4.3.2.jar httpmime-4.3.5.jar
AZ_

addQueryParams ส่งคืนอะไร?
San

11

loopjห้องสมุดสามารถใช้ตรงไปข้างหน้าเพื่อการนี้:

SyncHttpClient client = new SyncHttpClient();
RequestParams params = new RequestParams();
params.put("text", "some string");
params.put("image", new File(imagePath));

client.post("http://example.com", params, new TextHttpResponseHandler() {
  @Override
  public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
    // error handling
  }

  @Override
  public void onSuccess(int statusCode, Header[] headers, String responseString) {
    // success
  }
});

http://loopj.com/


5

ฉันพยายามอย่างมากในการติดตั้งการโพสต์ภาพจากไคลเอนต์ Android ไปยัง servlet โดยใช้ httpclient-4.3.5.jar, httpcore-4.3.2.jar, httpmime-4.3.5.jar ฉันมีข้อผิดพลาดรันไทม์เสมอ ฉันพบว่าโดยทั่วไปคุณไม่สามารถใช้ไหเหล่านี้กับ Android เนื่องจาก Google ใช้ HttpClient รุ่นเก่าใน Android คำอธิบายอยู่ที่นี่http://hc.apache.org/httpcomponents-client-4.3.x/android-port.html คุณต้องได้รับการ httpclientandroidlib-1.2.1 ขวดจากหุ่นยนต์ http ลูกค้าห้องสมุด จากนั้นเปลี่ยนการนำเข้าของคุณจาก or.apache.http.client เป็น ch.boye.httpclientandroidlib หวังว่านี่จะช่วยได้


-13

ฉันมักจะทำเช่นนี้ในการจัดการด้ายตอบสนอง json:

try {
  Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(imageUrl).getContent());
} catch (MalformedURLException e) {
  e.printStackTrace();
} catch (IOException e) {
  e.printStackTrace();
}

หากคุณต้องการทำการแปลงภาพคุณจะต้องสร้าง Drawable แทนบิตแมป


3
คำถามคือทำอย่างไรจึงจะโพสต์ภาพได้
dwbrito
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.