Arraylist
라이브러리를 사용하지 않고 이미지를 서버 에 업로드해야합니다 . 내가 사용하고 Asynctask
하나의 이미지를 업로드 할 수 있으며, HttpURLConnection의 다중 / 폼 데이터의 도움으로 완벽하게 작동합니다. 이제 코드를 변경하여 모든 유형의 여러 파일을 사용하여 업로드해야 Arraylist<String>
하지만 문제는 기존 코드가 FileinputStream
arraylist를 지원하지 않으며 Fileinputstream
arraylist를 서버에 업로드 하는 대신 무엇을 사용 해야할지 모르겠습니다. 이 라이브러리를 사용하고 싶습니다.
public class multipart_test extends AsyncTask<Void,Void,String> {
Context context;
String Images;
public static final String TAG = "###Image Uploading###";
public multipart_test(Context context,String Upload_Images) {
this.context = context;
this.Images = Upload_Images;
}
@Override
protected String doInBackground(Void... params) {
BufferedReader reader;
String WebPath = null;
try {
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1024 * 1024;
//todo change URL as per client ( MOST IMPORTANT )
URL url = new URL("10.0.0.1/uploadMultipart.php");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Allow Inputs & Outputs.
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
// Set HTTP method to POST.
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
FileInputStream fileInputStream;
DataOutputStream outputStream;
outputStream = new DataOutputStream(connection.getOutputStream());
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream.writeBytes("Content-Disposition: form-data; name=\"reference\""+ lineEnd);
outputStream.writeBytes(lineEnd);
//outputStream.writeBytes("my_refrence_text");
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream.writeBytes("Content-Disposition: form-data; name=\"uploadFile\";filename=\"" + "profileImage" +"\"" + lineEnd);
outputStream.writeBytes(lineEnd);
//Dummy ArrayList for upload
ArrayList<String> uploadFiles = new ArrayList<>();
uploadFiles.add(Images);
uploadFiles.add(Images);
uploadFiles.add(Images);
uploadFiles.add(Images);
fileInputStream = new FileInputStream(uploadFiles); // NOT SUPPORTING ARRAYLIST HERE
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
fileInputStream.close();
}
// Responses from the server (code and message)
int serverResponseCode = connection.getResponseCode();
String result = null;
if (serverResponseCode == 200) {
StringBuilder s_buffer = new StringBuilder();
InputStream is = new BufferedInputStream(connection.getInputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String inputLine;
while ((inputLine = br.readLine()) != null) {
s_buffer.append(inputLine);
}
result = s_buffer.toString();
}
connection.getInputStream().close();
outputStream.flush();
outputStream.close();
if (result != null) {
Log.d("result_for upload", result);
}
return WebPath;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
또한 FileInputStream
루프 에 넣으려고했지만 여러 요청에 이미지를 업로드하는 것은 내가 원하는 것이 아닙니다. 내 서버는 n 개의 이미지를 단일 요청하도록 앱이 필요합니다. 라이브러리를 사용하지 않아도 도움이 될 것입니다.
답변
이 코드가 HttpURLConnection과 정확하게 작동한다면 시도하지 않았지만 참고해야합니다.
인터넷에서 읽은 내용에서 언급 한 루프를 여전히 사용할 수 있지만 몇 가지 수정 사항이 있습니다.
나는 multipart / form-data here dev.to 튜토리얼을 따라이 글을 더 많이 배우기 위해이 방법이 어떻게 진행되는지 알려 드리겠습니다.
다중 / 폼 데이터가 같이 전송된다
--boundary
Content-Disposition: form-data; name="something1"
data1
--boundary
Content-Disposition: form-data; name="something2"
data2
--boundary--
내가 할 일은 새로운 방법을 만드는 것이지만 기존 방법으로 코드를 작성할 수 있습니다.
public byte[] get_multipart_data(List<String> files, String boundary)
당신 은 처분 다음에 데이터가 따르는 경계 입니다. 모든 파일에 대해 그런 다음 닫는 경계 를 보냅니다 . 이것은 당신이 원하는 multipart / form-data 구조를 생성 할 것 입니다.
의사 코드에서 이것은
loop for all files
write "--boundary"
write "Content-Disposition: ...."
write image_data
end
write "--boundary--"
코드는 다음과 같이 작성할 수 있습니다. 먼저 변수를 정의하십시오.
ByteArrayOutputStream message = null;
DataOutputStream stream = null;
FileInputStream fileInputStream;
int maxBufferSize = 1024 * 1024;
byte[] buffer = new byte[maxBufferSize];
byte[] sendData = new byte[0];
데이터가 생성되는 위치는 다음과 같습니다. 경계 를 연결 한 다음 데이터를 읽는 것으로 시작합니다. 해당 데이터는 스트림에 기록되며 모든 파일 / 이미지에 대한 루프를 계속합니다.
try {
message = new ByteArrayOutputStream();
stream = new DataOutputStream(message);
// Loop though all file names
for(String fileName : files) {
stream.writeBytes("--" + boundary + "\r\n"); // Start boundary
stream.writeBytes("Content-Disposition: form-data; name=\"" + fileName + "\"\r\n\r\n");
// Read the image data
fileInputStream = new FileInputStream(fileName);
int readBytes = 0;
while((readBytes = fileInputStream.read(buffer)) != -1) {
// Write file data to output
stream.write(buffer, 0, readBytes);
}
fileInputStream.close();
stream.writeBytes("\r\n");
}
stream.writeBytes("--" + boundary + "--\r\n"); // Closing boundary
sendData = message.toByteArray();
} catch(IOException e) {
e.printStackTrace();
}
이제 바이트 배열 sendData
에는 HttpURLConnection과 함께 보내야 하는 multipart / form-data 가 포함됩니다 .
나는 오랫동안 여기에서 활동적이지 않았습니다. 더 많은 사양이 필요하거나 내 텍스트를 분명히 밝히면 알려주십시오.
답변
FileinputStream 은 ArrayList를 지원하지 않습니다. 그러나 ObjectOutputStream 을 사용하는 방법이 있습니다 . 또한 ArrayList를 직렬화합니다. 코드 변경 사항을 확인하십시오.
//Changes required in your code
ArrayList<String> uploadFiles = new ArrayList<>();
uploadFiles.add(Images);
uploadFiles.add(Images);
uploadFiles.add(Images);
uploadFiles.add(Images);
fileInputStream = new FileInputStream("listImages");
java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(fileInputStream);
oos.writeObject(uploadFiles);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
...
...
...
oos.close();
행복한 코딩 🙂
답변
단일 비동기 작업을 사용해야하는지 확실하지 않습니다.
말했듯이 코드는 단일 이미지에 완벽하게 작동합니다. 따라서 arraylist에서 여러 파일을 업로드하려면 AsyncTask를 약간 수정하면됩니다. 한 파일을 다른 파일 로 업로드하기 만해도 수정을 많이하고 싶지 않다면 업로드중인 항목의 인덱스를 보유하는 전역 변수를 선언하고 OnPostExecute에서 비동기 작업의 새 인스턴스를 만들고 arraylist의 다음 항목을 전달하십시오. 이것이 분명하기를 바랍니다.