Gửi file ảnh từ android studio tới wep api spring boot

Hi mọi người, mình đang gặp lỗi không upload được file ảnh từ android studio (máy thật) xuống wep api spring boot , nó cứ báo lỗi failed to connect to localhost/127.0.0.1:8080, mình đã test gửi file ảnh từ web client xuống thì vẫn ok nhưng bên android thì failed. Dưới đây là code của mình.

class ApiUploadController của Spring Boot

package com.myclass.api.controller;

import java.io.File;
import java.io.IOException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.myclass.repository.PhotoRepository;
import com.myclass.repository.UserRepository;

@RestController
@RequestMapping("/api/file")
public class ApiUploadController {

	@Autowired
	UserRepository userRepository;
	
	@Autowired
	PhotoRepository photoRepository;
	
	@PostMapping("/upload")
	//@CrossOrigin(origins = "*")
	public Object post(@RequestPart(name = "file") MultipartFile file) {

		try {
//			System.out.println("Email: " + email);
//			System.out.println("Password: " + password);
			// Lấy đường dẫn tuyệt đối của thư mục chứa file upload
			// String folderPath = request.getServletContext().getRealPath("/upload/");
			//String folderPath = System.getProperty("user.dir");
			String folderPath = "C:\\Users\\HaiApple.com\\Desktop\\workspace WebCameraAPI SpringBoot\\WebCameraAPI\\src\\main\\resources\\static";
			folderPath += "\\upload\\";
			// Sử dụng đối tượng File của java.io để kiểm tra thư mục
			File dir = new File(folderPath);
			System.out.println("Folder save image: " + folderPath);
			// Nếu chưa tồn tại thư mục upload thì tạo mới
			if (!dir.exists()) {
				dir.mkdir();
			}

			// Lấy ra tên file vừa gửi từ client lên
			String fileName = file.getOriginalFilename();

			// Sử dụng đối tượng File của java.io để lưu file
			File filePath = new File(folderPath + fileName);

			System.out.println("filepath: " + filePath);

//			User user = null;
//			user = userRepository.findByEmail(email);
//
//			if (user == null) {
//				System.out.println("Lỗi null");
//				return new ResponseEntity<String>(HttpStatus.BAD_REQUEST);
//			}
//			if (user != null) {
//				System.out.println("User in database: " + user.toString());
//				if (!user.getPassword().equals(password)) {
//					return new ResponseEntity<String>(HttpStatus.BAD_REQUEST);
//				}
//			}

			// Sử dụng phương thức transferTo của MultipartFile để lưu file xuống thư mục
			file.transferTo(filePath);
			//int id=photoRepository.findAll().size();
			//System.out.println("Length photo: " + id);
//			int userIdUpload= user.getId();
//			Photo photo = new Photo(fileName,filePath.toString(),userIdUpload);
//			photoRepository.save(photo);
			
			System.out.println("Đã save file");
			return new ResponseEntity<String>("/upload/" + fileName, HttpStatus.OK);

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

		return new ResponseEntity<String>(HttpStatus.BAD_REQUEST);
	}
}


Ở Android Studio mình search trên mạng thấy bảo xài retrofit 2 nên mình khai báo

implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.google.code.gson:gson:2.6.1'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'

trong file build.gradle(Module: app)

file AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.camerascan">
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.CAMERA" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:networkSecurityConfig="@xml/network_security_config"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name="com.theartofdev.edmodo.cropper.CropImageActivity"
            android:theme="@style/Base.Theme.AppCompat"/> <!-- optional (needed if default theme has no action bar) -->


    </application>



</manifest>

interface UploadAPI ở Android Studio

package com.example.camerascan;

import okhttp3.MultipartBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;

public interface UploadAPIs {
//    @Multipart
//    @POST("/upload")
//    Call<ResponseBody> uploadImage(@Part MultipartBody.Part file, @Part("email") RequestBody email, @Part("password") RequestBody password);
//

//    @POST("/posts")
//    @FormUrlEncoded
//    Call<POST> savePost(@Field("id") int id,
//                        @Field("email") String email,
//                        @Field("password") String password);
    @Multipart
    @POST("upload")
    Call<ResponseBody> upload(@Part MultipartBody.Part file);
}

class NetworkClient trong Android Studio

package com.example.camerascan;

import android.content.Context;

import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class NetworkClient {
    //private static final String BASE_URL = "http://localhost:8080/api/file/";
    private static final String BASE_URL = "http://127.0.0.1:8080/api/file/";
    private static Retrofit retrofit;

    public static Retrofit getRetrofitClient(Context context) {
        if (retrofit == null) {
            OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .build();
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .client(okHttpClient)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;

    }
}

Trong Main Activity thì mình tạo Button Upload đến Server

btnUpload.setOnClickListener(new View.OnClickListener() {


            @Override
            public void onClick(View view) {

                Retrofit retrofit = NetworkClient.getRetrofitClient(MainActivity.this);
                UploadAPIs uploadAPIs = retrofit.create(UploadAPIs.class);
                //Create a file object using file path
                File file = new File(imgPath);
                if (!file.exists()) {
                    System.out.println("CHUA TON TAI");
                    file.mkdir();
                }

                Toast.makeText(getApplication(), "onclick btnUpload: " + imgPath, Toast.LENGTH_SHORT).show();
                System.out.println("onclick btnUpload: " + imgPath);
                System.out.println("directory file upload: " + file.getAbsolutePath());
                // Create a request body with file and image media type

                //RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
                RequestBody requestFile = RequestBody.create(MediaType.parse("*/*"), file);
                // Create MultipartBody.Part using file request-body,file name and part name
                System.out.println("Name file image: " + file.getName());
                MultipartBody.Part part = MultipartBody.Part.createFormData("file", file.getName(), requestFile);
                //Create request body with text description and text media type
                //RequestBody description = RequestBody.create(MediaType.parse("text/plain"), "image-type");
                //
                Call call = uploadAPIs.upload(part);

                call.enqueue(new Callback<ResponseBody>() {
                    @Override
                    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                        if (response.isSuccessful()) {
                            Toast.makeText(MainActivity.this, "Image uploaded success", Toast.LENGTH_SHORT).show();
                        }
                    }

                    @Override
                    public void onFailure(Call<ResponseBody> call, Throwable t) {
                        Toast.makeText(MainActivity.this, "ERROR " + t.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                });

            }
        });

Nó báo ở dòng nào thế bạn?

2 Likes

Bạn mở CMD lên và gõ ipconfig,
sau đó tìm đến mục IPv4 Address và copy cái địa chị đó thay cho cái localhost/127.0.0.1:xxxx cũ kia.
Tiếp đó bạn tắt tường lửa đi và thử lại

3 Likes

ủa mình tưởng đó là đường dẫn api của web service để android studio gửi file hình qua cái đường dẫn đó chứ ? không phải à bạn

Nó không báo lỗi bạn , nó chạy vô hàm này luôn

 @Override
                    public void onFailure(Call<ResponseBody> call, Throwable t) {
                        Toast.makeText(MainActivity.this, "ERROR " + t.getMessage(), Toast.LENGTH_SHORT).show();
                    }

Nó nhảy vào callback onFailure mà bạn lại bảo không lỗi là sao?
Mà bạn đã làm như mình bảo chưa?

1 Like

làm rồi mà nó vẫn nhảy vô hàm onFailure :frowning:

Bạn tham khảo thử ở đây xem here

nếu làm rồi thì bạn update lại bài để mn biết cái sự sửa của bạn đã đúng hay chưa

2 Likes

À ok r bạn , mình làm dc rồi, quên phải kết nối wifi cho 2 máy, tks bạn nhé

Ok rồi tks bạn nhé :slight_smile:

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?