วิธีสร้างคำขอหลายส่วนใน Android ด้วย Retrofit | วิธีอัปโหลดรูปภาพไปยังเซิร์ฟเวอร์

May 01 2023
ในระบบเครือข่าย คำขอหลายส่วนคือคำขอ HTTP ประเภทหนึ่งที่อนุญาตให้คุณส่งข้อมูลหลายประเภทในคำขอเดียว ซึ่งจะมีประโยชน์เมื่อคุณต้องการอัปโหลดไฟล์ เช่น รูปภาพหรือวิดีโอ พร้อมกับข้อมูลอื่นๆ เช่น ข้อความหรือข้อมูลเมตา
ภาพถ่ายโดย Michael Sala บน Unsplash

ในระบบเครือข่าย คำขอหลายส่วนคือคำขอ HTTP ประเภทหนึ่งที่อนุญาตให้คุณส่งข้อมูลหลายประเภทในคำขอเดียว ซึ่งจะมีประโยชน์เมื่อคุณต้องการอัปโหลดไฟล์ เช่น รูปภาพหรือวิดีโอ พร้อมกับข้อมูลอื่นๆ เช่น ข้อความหรือข้อมูลเมตา

คำขอหลายส่วนมีโครงสร้างเป็นชุดของส่วน โดยแต่ละส่วนประกอบด้วยข้อมูลประเภทต่างๆ แต่ละส่วนคั่นด้วยสตริงขอบเขต ซึ่งกำหนดไว้ในส่วนหัวของคำขอ สตริงขอบเขตต้องไม่ซ้ำกันและไม่เกิดขึ้นในข้อมูลที่ส่ง

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

หากต้องการสร้างคำขอหลายส่วน คุณสามารถใช้ไลบรารี เช่น OkHttp หรือ Volley ไลบรารีทั้งสองนี้มีเมธอดสำหรับการสร้างคำขอหลายส่วนและการอัพโหลดไฟล์

เราจะใช้ Retrofit Here เพื่อทำความเข้าใจว่าหลายส่วนทำงานอย่างไร

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

เราสามารถทำได้โดยใช้หลายส่วน

ขั้นตอนที่ 1:เพิ่ม Retrofit ในโครงการของคุณ

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.okhttp3:okhttp:4.9.1'

ขั้นตอนที่ 2 : สร้างคลาสบริการ API

public interface MyApiService {

    @Multipart
    @POST("uploadUser")
    Call<UserResponse> uploadUser(
            @Part("email") RequestBody email,
            @Part("phone") RequestBody phone,
            @Part("name") RequestBody name,
            @Part("password") RequestBody password,
            @Part MultipartBody.Part imageFile
    );
}

ขั้นตอนที่ 3 : สร้างคลาส API

public class MyApi {

    private static final String BASE_URL = "https://example.com/api/";

    private static MyApiService sApiService;

    public static MyApiService getInstance() {
        if (sApiService == null) {
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .client(new OkHttpClient())
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
            sApiService = retrofit.create(MyApiService.class);
        }
        return sApiService;
    }
}

ขั้นตอนที่ 4:สร้าง RequestBody สำหรับพารามิเตอร์สตริงแต่ละตัว

RequestBody emailBody = RequestBody.create(MediaType.parse("text/plain"), email);
RequestBody phoneBody = RequestBody.create(MediaType.parse("text/plain"), phone);
RequestBody nameBody = RequestBody.create(MediaType.parse("text/plain"), name);
RequestBody passwordBody = RequestBody.create(MediaType.parse("text/plain"), password);

ขั้นตอนที่ 5:สร้าง MultipartBody.Part สำหรับพารามิเตอร์รูปภาพ

File file = new File(imageFilePath);
RequestBody fileBody = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part imagePart = MultipartBody

public class UserRepository {
    
    private MyApi mApi;

    public UserRepository() {
        mApi = MyApi.getInstance();
    }

    public LiveData<UserResponse> uploadUser(String email, String phone, String name, String password, String imageFilePath) {
        MutableLiveData<UserResponse> userResponseLiveData = new MutableLiveData<>();

        RequestBody emailBody = RequestBody.create(MediaType.parse("text/plain"), email);
        RequestBody phoneBody = RequestBody.create(MediaType.parse("text/plain"), phone);
        RequestBody nameBody = RequestBody.create(MediaType.parse("text/plain"), name);
        RequestBody passwordBody = RequestBody.create(MediaType.parse("text/plain"), password);

        File file = new File(imageFilePath);
        RequestBody fileBody = RequestBody.create(MediaType.parse("image/*"), file);
        MultipartBody.Part imagePart = MultipartBody.Part.createFormData("profileImage", file.getName(), fileBody);

        mApi.uploadUser(emailBody, phoneBody, nameBody, passwordBody, imagePart).enqueue(new Callback<UserResponse>() {
            @Override
            public void onResponse(Call<UserResponse> call, Response<UserResponse> response) {
                if (response.isSuccessful()) {
                    userResponseLiveData.setValue(response.body());
                } else {
                    // Handle the error
                }
            }

            @Override
            public void onFailure(Call<UserResponse> call, Throwable t) {
                // Handle the error
            }
        });

        return userResponseLiveData;
    }
}

จากนั้นเราใช้อินสแตนซ์ MyApi เพื่อทำการเรียก API โดยส่งวัตถุเหล่านี้เป็นพารามิเตอร์ เรากำหนดการเรียกกลับที่ตั้งค่าของออบเจกต์ MutableLiveData ให้กับการตอบสนองของเซิร์ฟเวอร์ หากการตอบสนองสำเร็จ และจัดการกับข้อผิดพลาดใดๆ

ขั้นตอนที่ 7 : เราสร้างคลาส UserViewModel ที่ใช้ UserRepository เพื่อทำการเรียก API:

class UserViewModel : ViewModel() {
   val mUserRepo: UserRepository = UserRepository()
    private val _userResponse = MutableLiveData<UserResponse>()

    val userResponse: LiveData<UserResponse>
        get() = _userResponse

fun uploadUser(val email : String,val phone : String,val name : String, val password : String,val imageFilePath :String ) {
  viewModelScope.launch {
            _userResponse.postValue(mUserRepository.uploadUser(email, phone, name, password, imageFilePath);)
        }        
    }

เราสามารถทำสิ่งเดียวกันโดยใช้ @PartMap ได้เช่นกัน

PartMap

ใน Retrofit @PartMap เป็นคำอธิบายประกอบที่ช่วยให้เราสามารถส่งแผนผังไดนามิกของคู่คีย์-ค่าโดยเป็นส่วนหนึ่งของคำขอหลายส่วน ซึ่งจะมีประโยชน์เมื่อไม่ทราบจำนวนพารามิเตอร์ในคำขอหรืออาจแตกต่างกันไปตามรันไทม์

แทนที่จะกำหนดพารามิเตอร์แยกกันสำหรับคู่คีย์-ค่าแต่ละคู่ เราสามารถกำหนดพารามิเตอร์เดียวด้วยคำอธิบายประกอบ @PartMap และส่งผ่านในออบเจกต์ Map<String, RequestBody> คีย์ของแต่ละรายการในแผนที่แสดงถึงคีย์ของฟิลด์ฟอร์มในคำขอแบบหลายส่วน และค่าคือออบเจกต์ RequestBody ที่สอดคล้องกัน

มาทำเช่นเดียวกันuploadUserโดยใช้ @PartMap

@POST("uploadUser")
@Multipart
fun uploadUser(
    @Part image: MultipartBody.Part,
    @PartMap data: Map<String, @JvmSuppressWildcards RequestBody>
): Call<UserResponse>

val requestBody = HashMap<String, RequestBody>()
requestBody["name"] = "Karishma".toRequestBody("text/plain".toMediaTypeOrNull())
requestBody["password"] = "09886".toRequestBody("text/plain".toMediaTypeOrNull())
requestBody["email_id"] = "[email protected]".toRequestBody("text/plain".toMediaTypeOrNull())
requestBody["phone"] = "9876543210".toRequestBody("text/plain".toMediaTypeOrNull())

และส่วนของภาพก็จะเหมือนเดิม

อ้างอิง

บทสรุป

โดยสรุปแล้ว คำขอหลายส่วนเป็นคุณสมบัติที่สำคัญของระบบเครือข่ายสมัยใหม่ ช่วยให้เราสามารถส่งข้อมูลประเภทต่างๆ รวมถึงข้อความและข้อมูลไบนารีในคำขอ HTTP เดียว สิ่งนี้มีประโยชน์อย่างยิ่งเมื่ออัปโหลดไฟล์หรือข้อมูลจำนวนมาก เนื่องจากไม่จำเป็นต้องใช้คำขอหลายรายการและทำให้กระบวนการโดยรวมง่ายขึ้น

ในการพัฒนา Android ไลบรารี OkHttp และ Retrofit ให้การใช้งานคำขอหลายส่วนที่ใช้งานง่ายและมีประสิทธิภาพ ด้วยการใช้ไลบรารีเหล่านี้ เราสามารถส่งคำขอหลายส่วนและจัดการการตอบกลับได้อย่างง่ายดาย ทำให้เราสามารถมุ่งเน้นไปที่การสร้างแอปพลิเคชันที่เหลือของเรา

โดยรวมแล้ว คำขอหลายส่วนเป็นเครื่องมือสำคัญในกล่องเครื่องมือของนักพัฒนาที่ทำงานกับแอปพลิเคชันบนเครือข่าย ด้วยเครื่องมือและความรู้ที่เหมาะสม เราสามารถใช้คุณสมบัตินี้เพื่อทำให้แอปพลิเคชันของเราเร็วขึ้น เชื่อถือได้มากขึ้น และเป็นมิตรกับผู้ใช้มากขึ้น

หวังว่าบทความนี้จะเป็นประโยชน์กับคุณ

หากคุณมีข้อเสนอแนะหรือข้อสงสัยใด ๆ โปรดเขียนกลับมาที่[email protected] การตบมือของคุณมีค่ามากที่ช่วยให้ผู้อื่นค้นพบบทความนี้