본문 바로가기
CLASS/SPRINGBOOT

#10-2 / Ajax로 이미지 전송 및 JPA

by hingu 2024. 8. 28.

🤷‍♂️❓

ajax 파일 전송은 주로 Mobile에서 활용함

accept="image/*" capture="camera"    해당 코드 input type="file" 에 넣을시 모바일에서 버튼 클릭시 바로 카메라로 넘어감

CDN전송시 CORS 방지 코드 필수 (back-end)

 

  👀 ajax로 전송해서 backend로 받기  

- ajax_upload.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>

<!-- 모바일 -->
<meta name="viewport" content="width=device-width, initical-scale=1.0">

</head>
<body>
	파일명 : <input type="file" id="mfile" accept="image/*" capture="camera">
	<input type="button" value="ajax_파일전송" onclick="ajax_fileupload()">
</body>

<script>
	function ajax_fileupload(){
		var f= document.getElementById("mfile");
		var ajax = new XMLHttpRequest();
		
		let fmdata = new FormData(); //<form>태그를 사용한것과 동일함
		fmdata.append("mfile",f.files[0]); //첨부파일 형태 원시배열 형태
		
		ajax.onreadyStatechange = function(){
			if(ajax.readyState==4){
				if(ajax.status==200){
					console.log(this.response);
				}
			}else{
				console.log("통신오류 발생")
			}
		}
		
		ajax.open("POST","./ajax_uploadok.do",true);
		//ajax.open("POST","cdn_uploadok.do",false); //동기 전송
		ajax.send(fmdata);
	}
</script>

</html>

 

- Controller

//ajax로 파일 전송을 받는 메소드
@CrossOrigin(origins="*", allowedHeaders = "*") //cors 해제
@PostMapping("/ajax_uploadok.do")
public String ajax_uploadok(MultipartFile mfile) {
    System.out.println(mfile.getOriginalFilename());

    return null;
}

❗ ❗ ❗ 파일 전송은 무족권 POST사용  / 동기,비동기 중  동기화 전송으로 하는게 좋다

 

 

  👀 ajax로 전송해서 CDN 전송  

- jsp

<script>
	function ajax_fileupload(){
		var f= document.getElementById("mfile");
		var ajax = new XMLHttpRequest();
		
		let fmdata = new FormData(); //<form>태그를 사용한것과 동일함
		fmdata.append("mfile",f.files[0]); //첨부파일 형태 원시배열 형태
		fmdata.append("url","172.30.1.16"); //CDN url
		
		ajax.onreadyStatechange = function(){
			console.log(this.response);
			if(ajax.readyState==4){
				if(ajax.status==200){
					var result = this.response;
					console.log(result);
					if(result == "ok"){
						alert("정상적으로 이미지가 반영되었습니다.");
						//this.loaction.reload();
					}else{
						alert("이미지 반영 실패");
					}
				}
			}else{
				console.log("통신오류 발생")
			}
		}
		
		//ajax.open("POST","./ajax_uploadok.do",true);
		ajax.open("POST","./cdn_uploadok.do",false); //동기 전송
		ajax.send(fmdata);
	}
</script>

 

 

- Controller

@Autowired
cdn_repo cdn_repo;

@PostMapping("/cdn_uploadok.do")
public String cdn_uploadok(ServletResponse res,
        @RequestParam(defaultValue="",required=false) String url,
        MultipartFile mfile) {
    res.setContentType("text/html;charset=utf-8");

    FTPClient ftp = new FTPClient(); //FTP 접속 클라이언트 객체 생성
    ftp.setControlEncoding("utf-8"); //한글파일 깨짐 방지
    FTPClientConfig fc = new FTPClientConfig(); //FTP 접속 환경설정
    try {
        String filename = mfile.getOriginalFilename(); //업로드 파일명
        String host = url; //FTP 호스트
        String user = "admin"; //FTP 접속 아이디
        String pw = "123123"; //FTP 접속 패스워드
        int port = 20021; //FTP 접속 포트번호

        ftp.configure(fc);
        ftp.connect(host,port);
        if(ftp.login(user, pw)) {
            ftp.setFileType(FTP.BINARY_FILE_TYPE); //이미지 , 동영상, PDF, XLS..

            int result = ftp.getReplyCode(); //CDN서버에서 파일 업로드 지연형태 발생
            System.out.println("지연코드 :" + result);

            this.pw = res.getWriter();
            //FTP의 해당 디렉토리에 파일을 Stream 형태로 업로드 
            boolean ok = ftp.storeFile("/home/admin/cdn_upload_seeun/"+filename, mfile.getInputStream());
            if(ok == true) {
                String fileurl = "http://172.30.1.16/cdn_upload_seeun/";
                this.dto = new cdn_dto();
                this.dto.setImgdate(filename);
                this.dto.setImgurl(fileurl);
                this.dto.setImgdate(cdn_repo.mysql_times());

                try {//예외처리 필수
                    cdn_repo.save(this.dto); //db저장
                    cdn_repo.flush();
                    this.pw.print("ok");
                    System.out.println("정상적으로 cdn 서버로 파일 업로드 완료했습니다.");
                }catch(Exception e) {
                    System.out.println("database 연결 실패 오류!");
                    this.pw.print("fail");
                }
            }else {
                this.pw.print("fail");
                System.out.println("CDN 파일 업로드 실패");
            }
        }else {
            System.out.println("FTP ID 및 패스워드 오류 발생!");
        }
    }catch(Exception e) {
        System.out.println("CDN 서버 접속 오류 발생!!");
    }finally {
        this.pw.close();
        try {
            ftp.disconnect(); //ftp 접속해제 필수
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    return null;
}

 

 

  👀 올라간 이미지를 list로 출력  

✅ Restful Api 서버 => JSON형태로 출력

 

ftp
db

 

 

- cdn_repo.java (interface) 

public interface cdn_repo extends JpaRepository<cdn_dto, Integer>{
	@Query("select now()")
	String mysql_times();
	
	List<cdn_dto> findByImgnameLikeOrderByIdx(String imgname);
}

 

- Controller

@Autowired
cdn_repo cdn_repo;

//CDN API 서버 (파라미터 값을 이용한 API)
@CrossOrigin(origins="*", allowedHeaders = "*") //cors 해제 필수
@GetMapping("/cdn_list/{filenm}")
public @ResponseBody byte[] cdn_list(@PathVariable String filenm,Model m,ServletResponse res) {
    String imgurl = null; //db에 저장된 이미지 전체 경로를 담을 변수
    byte[] img = null;
    try {

        //database에 저장된 파일명을 기점으로 select를 하는 형태
        List<cdn_dto> result = this.cdn_repo.findByImgnameLikeOrderByIdxDesc(filenm + "%");
        //FTP로 업로드된 CDN 서버 전체 경로
        imgurl = result.get(0).getImgurl() + result.get(0).getImgname();

        //InputStream is = new FileInputStream(imgurl); //자기 서버에 있을땐 이렇게 (외부 서버에선 X)

        URL url = new URL(imgurl); //외부 http 경로를 접속하는 형태
        HttpURLConnection httpcon = (HttpURLConnection) url.openConnection();
        //HttpsURLConnection 은 따로 있음
        //해당 경로에 있는 파일 전체 용량을 읽어들임

        InputStream is = httpcon.getInputStream();
        img = IOUtils.toByteArray(is); //org.apache.commons.io.IOUtils
        //byte[]로 변환하여 출력시킴

        is.close(); //IO종료
        httpcon.disconnect(); //프로토콜 종료

    }catch(Exception e) {
        e.printStackTrace();
        System.out.println("database 오류 발생~");
    }

    return img;
}

@ResponseBody byte[] : cdn restAPI일때 사용!

(일반 restAPI 일 경우엔 걍 string 써도됨)

 

 

- cdn_list.jsp  : cdn 서버에 있는 파일 리스트 출력 페이지

<img src="/cdn_list/8"> //파일명만 입력

//^^..

=> /cdn_list.jsp 여기로 접속시 8.jpg 잘뜸