안드로이드

 

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
Content-Disposition: form-data; name="file1"; filename="/data/data/com.example.choi.ex05_network/files/test.txt"

파일 업로드 테스트
--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>

 

 

 

 

 

about author

PHRASE

Level 60  머나먼나라

이길 수 없는 사람은 머무르는 법이다. 이길 수 있는 사람은 공격하는 법이다. 머무르면 곧 부족하고 공격하면 곧 넉넉하다. 영웅이 되고자 뜻을 세우는 것은 영웅이 되는 계단이다. 성공의 비결은 단호한 결의에 있다. - B. 디즈레일리

댓글 ( 4)

댓글 남기기

작성