안드로이드, Multipart form-data 를 이용하여 파일과 텍스트를 동시에 웹서버로 전송하는 예
Multipart form-data에 관련된 명세는 여기를 참조하세요
FileUploadActivity
package test.android.hello;
import java.io.*;
import java.net.*;
import android.app.Activity;
import android.os.*;
import android.util.*;
public class FileUploadActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
AndroidUploader uploader = new AndroidUploader("user", "userPwd");
String path = Environment.getExternalStorageDirectory()+"/DCIM/Camera/test.jpg";
uploader.uploadPicture(path);
} catch (Exception e) {
Log.e(e.getClass().getName(), e.getMessage());
}
}
}
AndroidUploader ( 사용법은 소스 하단의 main()을 참조하세요 )
package test.android.hello;
import java.io.*;
import java.net.*;
import android.util.Log;
public class AndroidUploader {
static String serviceDomain = "http://joongchoun.host.com";
static String postUrl = serviceDomain + "/upload/apacheUpload.jsp";
static String CRLF = "\r\n";
static String twoHyphens = "--";
static String boundary = "*****b*o*u*n*d*a*r*y*****";
private String pictureFileName = null;
private String name = null;
private String password = null;
private DataOutputStream dataStream = null;
enum ReturnCode { noPicture, unknown, http201, http400, http401, http403, http404, http500};
private String TAG = "멀티파트 테스트";
public AndroidUploader(String name, String password) {
this.name = name;
this.password = password;
}
public static void setServiceDomain(String domainName) {
serviceDomain = domainName;
}
public static String getServiceDomain() {
return serviceDomain;
}
public ReturnCode uploadPicture(String pictureFileName) {
this.pictureFileName = pictureFileName;
File uploadFile = new File(pictureFileName);
if (uploadFile.exists())
try {
FileInputStream fileInputStream = new FileInputStream(uploadFile);
URL connectURL = new URL(postUrl);
HttpURLConnection conn = (HttpURLConnection)connectURL.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
//conn.setRequestProperty("User-Agent", "myFileUploader");
conn.setRequestProperty("Connection","Keep-Alive");
conn.setRequestProperty("Content-Type","multipart/form-data;boundary="+boundary);
conn.connect();
dataStream = new DataOutputStream(conn.getOutputStream());
writeFormField("login", name);
writeFormField("password", password);
writeFileField("photo1", pictureFileName, "image/jpg", fileInputStream);
// final closing boundary line
dataStream.writeBytes(twoHyphens + boundary + twoHyphens + CRLF);
fileInputStream.close();
dataStream.flush();
dataStream.close();
dataStream = null;
Log.d("업로드 테스트", "***********전송완료***********");
String response = getResponse(conn);
int responseCode = conn.getResponseCode();
if (response.contains("uploaded successfully"))
return ReturnCode.http201;
else
// for now assume bad name/password
return ReturnCode.http401;
}
catch (MalformedURLException mue) {
Log.e(TAG, "error: " + mue.getMessage(), mue);
return ReturnCode.http400;
}
catch (IOException ioe) {
Log.e(TAG, "error: " + ioe.getMessage(), ioe);
return ReturnCode.http500;
}
catch (Exception e) {
Log.e(TAG, "error: " + e.getMessage(), e);
return ReturnCode.unknown;
} else {
return ReturnCode.noPicture;
}
}
private String getResponse(HttpURLConnection conn) {
try {
DataInputStream dis = new DataInputStream(conn.getInputStream());
byte [] data = new byte[1024];
int len = dis.read(data, 0, 1024);
dis.close();
int responseCode = conn.getResponseCode();
if (len > 0)
return new String(data, 0, len);
else
return "";
}
catch(Exception e) {
//System.out.println("AndroidUploader: "+e);
Log.e(TAG, "AndroidUploader: "+e);
return "";
}
}
/**
* this mode of reading response no good either
*/
private String getResponseOrig(HttpURLConnection conn) {
InputStream is = null;
try {
is = conn.getInputStream();
// scoop up the reply from the server
int ch;
StringBuffer sb = new StringBuffer();
while( ( ch = is.read() ) != -1 ) {
sb.append( (char)ch );
}
return sb.toString(); // TODO Auto-generated method stub
}
catch(Exception e) {
//System.out.println("GeoPictureUploader: biffed it getting HTTPResponse");
Log.e(TAG, "AndroidUploader: "+e);
}
finally {
try {
if (is != null)
is.close();
} catch (Exception e) {}
}
return "";
}
/**
* write one form field to dataSream
* @param fieldName
* @param fieldValue
*/
private void writeFormField(String fieldName, String fieldValue) {
try {
dataStream.writeBytes(twoHyphens + boundary + CRLF);
dataStream.writeBytes("Content-Disposition: form-data; name=\"" + fieldName + "\"" + CRLF);
dataStream.writeBytes(CRLF);
dataStream.writeBytes(fieldValue);
dataStream.writeBytes(CRLF);
} catch(Exception e) {
//System.out.println("AndroidUploader.writeFormField: got: " + e.getMessage());
Log.e(TAG, "AndroidUploader.writeFormField: " + e.getMessage());
}
}
/**
* write one file field to dataSream
* @param fieldName - name of file field
* @param fieldValue - file name
* @param type - mime type
* @param fileInputStream - stream of bytes that get sent up
*/
private void writeFileField(
String fieldName,
String fieldValue,
String type,
FileInputStream fis) {
try {
// opening boundary line
dataStream.writeBytes(twoHyphens + boundary + CRLF);
dataStream.writeBytes("Content-Disposition: form-data; name=\""
+ fieldName
+ "\";filename=\""
+ fieldValue
+ "\""
+ CRLF);
dataStream.writeBytes("Content-Type: " + type + CRLF);
dataStream.writeBytes(CRLF);
// create a buffer of maximum size
int bytesAvailable = fis.available();
int maxBufferSize = 1024;
int bufferSize = Math.min(bytesAvailable, maxBufferSize);
byte[] buffer = new byte[bufferSize];
// read file and write it into form...
int bytesRead = fis.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dataStream.write(buffer, 0, bufferSize);
bytesAvailable = fis.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fis.read(buffer, 0, bufferSize);
}
// closing CRLF
dataStream.writeBytes(CRLF);
}
catch(Exception e) {
//System.out.println("GeoPictureUploader.writeFormField: got: " + e.getMessage());
Log.e(TAG, "AndroidUploader.writeFormField: got: " + e.getMessage());
}
}
public static void main(String[] args) {
if (args.length >= 0) {
AndroidUploader gpu = new AndroidUploader("john", "notmyrealpassword");
String picName = args[0];
ReturnCode rc = gpu.uploadPicture(picName);
//System.out.printf("done");
}
}
}
서버측 코드(apacheUpload.jsp), 서버측에는 아파치 업로드 라이브러리가 설치되어 있어야 함 (여기를 참고하세요 )
<%@ page contentType="text/html;charset=KSC5601"%>
<%@ page import="java.util.List" %>
<%@ page import="java.util.Iterator" %>
<%@ page import="java.io.File" %>
<%@ page import="org.apache.commons.fileupload.servlet.ServletFileUpload"%>
<%@ page import="org.apache.commons.fileupload.disk.DiskFileItemFactory"%>
<%@ page import="org.apache.commons.fileupload.*"%>
<%@ page import="org.apache.commons.io.FilenameUtils"%>
<html><head> <title> Apache ServletFileUpload example </title></head>
<body>
<center><table>
<tr><td><h1>파일 업로드 결과 </h1></td></tr>
<tr><td>
<%
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (!isMultipart) {
}else {
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List items = null;
try {
items = upload.parseRequest(request);
} catch (FileUploadException e) {
out.println("에러 1: "+e);
}
Iterator itr = items.iterator();
while (itr.hasNext()) {
FileItem item = (FileItem) itr.next();
if (item.isFormField()) { // 파일이 아닌 폼필드에 입력한 내용을 가져옴.
if(item!=null && item.getFieldName().equals("name")) {
String name = item.getString("KSC5601");//form field 안에 입력한 데이터를 가져옴
out.println("전송자:"+name+"<br>");
}else if(item!=null && item.getFieldName().equals("pwd")) {
String desc = item.getString("KSC5601");
out.println("파일에 대한 설명:"+desc+"<br>");
}
} else { // 폼 필드가 아니고 파일인 경우
try {
String itemName = item.getName();//로컬 시스템 상의 파일경로 및 파일 이름 포함
if(itemName==null || itemName.equals("")) continue;
String fileName = FilenameUtils.getName(itemName);// 경로없이 파일이름만 추출함
// 전송된 파일을 서버에 저장하기 위한 절차
//String rootPath = getServletContext().getRealPath("/");
File savedFile = new File("/web/home/joongchoun/html/upload/storage/"+fileName);
item.write(savedFile);// 지정 경로에 파일을 저장함
out.println("<tr><td><b>파일저장 경로:</b></td></tr><tr><td><b>"+savedFile+"</td></tr>");
out.println("<tr><td><b><a href=\"DownloadServlet?file="+fileName+"\">"+fileName+"</a></td></tr>");
} catch (Exception e) {
out.println("서버에 파일 저장중 에러: "+e);
}
}
}
}
%>
</table>
</center>
</body></html>