1. 스프링에서 파일 업로드 설정
pom.xml
<!-- 파일 업로드 드라이브
servlet-context.xml 에서 CommonsMultipartResolver 파일 설정 필수
-->
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
servlet-context.xml
<resources location="/WEB-INF/upload/andorid/" mapping="/andorid/**" />
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="maxUploadSize" value="10485760" />
</beans:bean>
class UploadPath
package com.macaronics.www.util.fileupload;
import java.io.File;
import javax.servlet.http.HttpServletRequest;
public class UploadPath {
public static String attach_path ="WEB-INF/uploads/";
public static String path(HttpServletRequest request){
String uploadPath ="";
try{
String root_path =request.getServletContext().getRealPath("/");
uploadPath =root_path+attach_path.replace('/', File.separatorChar);
}catch(Exception e){
e.printStackTrace();
}
return uploadPath;
}
}
class AndoridUploadController
package com.macaronics.www.sample.Controller;
import java.io.File;
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import com.macaronics.www.util.fileupload.UploadPath;
@Controller
public class AndoridUploadController {
private final String UPLOAD_PATH="WEB-INF/uploads/andorid/";
@RequestMapping(value="/andoridUpload", method=RequestMethod.POST)
public ResponseEntity<String> upload(HttpServletRequest request, MultipartFile file1){
ResponseEntity<String> entity=null;
try{
UploadPath.attach_path=UPLOAD_PATH;
String path =UploadPath.path(request);
String fileName="";
if(!file1.isEmpty()){ //첨부파일이 존재하면
//첨부파일의 이름
fileName=file1.getOriginalFilename();
try{
//디렉토리 생성
new File(path).mkdir();
//지정된 업로드 경로로 저장됨
file1.transferTo(new File(path+fileName));
entity=new ResponseEntity<String>("success", HttpStatus.OK);
}catch (Exception e) {
e.printStackTrace();
}
}
}catch(Exception e){
e.printStackTrace();
entity=new ResponseEntity<String>("fail", HttpStatus.BAD_REQUEST);
}
return entity;
}
}
2. 안드로이드에서 업로드 구현
파일 전송 Request 요청시
POST /andoridUpload HTTP/1.1 Connection: Keep-Alive Content-Type: multipart/form-data;boundary=files User-Agent: Dalvik/2.1.0 (Linux; U; Android 6.0; Android SDK built for x86_64 Build/MASTER) Host: localhost:2424 Accept-Encoding: gzip Content-Length: 164 |
request 요청시 파일을 보낸다 이때에 데이터 넘길 형식
--files 파일 업로드 테스트 |
Response
성공시
HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Content-Type: text/plain;charset=ISO-8859-1 Content-Length: 7 Date: Thu, 23 Feb 2017 02:51:10 GMT |
success |
class UploadActivity
package com.example.choi.ex05_network;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class UploadActivity extends AppCompatActivity implements Runnable{
//1.변수 선언
Button btnUpload, springUpload;
TextView txtResult;
final String url_address="http://192.168.0.2:1111/andoridUpload";
//안드로이드 내 저장 파일 이름
String files="/data/data/com.example.choi.ex05_network/files/test.txt";
String str; //결과를 저장할 변수
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.upload);
//2.위젯 설정
btnUpload=(Button)findViewById(R.id.btnUpload);
springUpload=(Button)findViewById(R.id.springUpload);
txtResult=(TextView)findViewById(R.id.txtResult);
//3.버튼 클릭 이벤트
btnUpload.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
save();
}
});
springUpload.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
upload();
}
});
}
//Alt+Insert , Implement Methods
@Override
public void run() {
try{
FileInputStream fis =new FileInputStream(files);
URL url=new URL(url_address);
HttpURLConnection conn=(HttpURLConnection)url.openConnection();
//웹서버를 통해 입출력 가능하도록 설정
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);//캐쉬 사용하지 않음
conn.setRequestMethod("POST");
//정해진 시간 내에 재접속할 경우 소켓을 새로 생성하지 않고 기존연결 사용
//대소문자 주의
conn.setRequestProperty("Connection", "Keep-Alive");
//첨부파일에 대한 정보
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=files");
//데이터 아웃풋 스트림
DataOutputStream dos =new DataOutputStream(conn.getOutputStream());
//form-data;name=파일변수명;filename="첨부파일이름"
//작은따옴표를 사용할 수 없음
dos.writeBytes("--files\r\n"); // --은 파일 시작 알림 표시
dos.writeBytes("Content-Disposition: form-data; name=\"file1\"; filename=\""
+files+"\""+"\r\n");
dos.writeBytes("\r\n");//줄바꿈 문자
int bytes=fis.available();
int maxBufferSize=1024;
//Math.min(A, B)둘중 작은값;
int bufferSize =Math.min(bytes, maxBufferSize);
byte[] buffer=new byte[bufferSize];
int read=fis.read(buffer, 0, bufferSize);
while(read >0){
//서버에 업로드
dos.write(buffer,0, bufferSize);
bytes=fis.available();
bufferSize=Math.min(bytes, maxBufferSize);
//읽은 바이트 수
read=fis.read(buffer, 0, bufferSize);
}
dos.writeBytes("\r\n");//줄바꿈 문자
/*boundary=경계문자 => 경계문자의 이름
--경계문자 => 첨부파일 전송 시작부분
--경계문자-- => 첨부파일 전송 끝부분*/
dos.writeBytes("--files--\r\n");
fis.close();//스트림 닫기
dos.flush();//버퍼 클리어
dos.close();//출력 스트림 닫기
//서버의 응답을 처리
int ch;
InputStream is=conn.getInputStream(); //입력스트림
StringBuffer sb=new StringBuffer();
while( (ch=is.read()) != -1){ // 내용이 없을 때까지 반복
sb.append((char)ch); // 문자를 읽어서 저장
}
// 스트링.trim() 스트링의 좌우 공백 제거
str = sb.toString().trim();
if(str.equals("success")){
str = "파일이 업로드되었습니다.";
}else if(str.equals("fail")){
str = "파일 업로드 실패...";
}
//안드로이드에서는 백그라운드 스레드에서 메인UI를 터치할 수 없음
// runOnUiThread()를 사용하면 백그라운드 스레드에서
// 메인UI를 직접 수정할 수 있음
runOnUiThread(new Runnable() {
@Override
public void run() {
txtResult.setText(str);
Toast.makeText(UploadActivity.this,
"업로드되었습니다.", Toast.LENGTH_SHORT).show();
}
});
is.close();
conn.disconnect();
}catch (Exception e){
e.printStackTrace();
}
}
//내부 메모리 영역에 텍스트 파일을 생성
void save(){
// data/data/패키지이름/files/ 내부메모리 경로
File file=new File(files);
try{
FileOutputStream fos =new FileOutputStream(file);
String str="파일 업로드 테스트";
// 스트링.getBytes() : 스트링을 바이트 배열로 변환
fos.write(str.getBytes()); //파일이 저장됨
fos.close(); //스트림 닫기
Toast.makeText(this, "저장 되었습니다.", Toast.LENGTH_SHORT).show();
}catch (Exception e){
e.printStackTrace();
}
}
//텍스트 파일을 웹서버로 업로드(백그라운드 스레드로 처리)
void upload(){
//백그라운드 스레드 생성, 호출
Thread th =new Thread(this);
th.start(); //run() 가 실행됨.
}
}
upload.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/upload"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.choi.ex05_network.UploadActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/btnUpload"
android:layout_marginTop="20dp"
android:id="@+id/txtResult"
android:layout_alignParentEnd="true"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true" />
<Button
android:text="업로드"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:id="@+id/btnUpload"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true" />
<Button
android:text="스프링으로 업로드"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/txtResult"
android:layout_toEndOf="@+id/btnUpload"
android:layout_marginStart="20dp"
android:id="@+id/springUpload" />
</RelativeLayout>
댓글 ( 4)
댓글 남기기