본문 바로가기

미역/자바

BLOB 형태로 파일 업로드 / 다운로드

1. 서버에 있는 파일 다운로드 받기

public void downloadFile( HttpServletRequest req, HttpServletResponse res) throws IOException, Exception {
	BufferedInputStream fin = null;
	BufferedOutputStream outs = null;
	String downloadDir = "C:/downloadFolder/" //다운로드 경로
	
	try {
		//다운로드 받을 파일 이름
		String fileNm = req.getParameter("file") != null ? URLDecoder.decode(req.getParameter("fileNm"),"UTF-8") : "";

		//윈도우에서 그럴 일은 없지만
		//파일명에 "..","../",".\\" 같은 부호들이 붙어있으면 
		//이걸 경로처리해서 파일을 제대로 찾을 수가 없다.
		//그래서 한 번 체크해주는 로직이다.
		boolean downloadFlag = true;
		if( !"".equals(fileNm) ) {
			String blockchar[] = {"..","../",".\\"};
			for(int i=0; i<blockchar.length;i++) {
				if(downloadDir.indexOf(blockchar[i]) != -1 ){
					downloadFlag = false;
				}
			}
		}

		if( downloadFlag ) {
			File file = new File( downloadDir + fileNm );
			if (file.exists()) {
				byte[] b = new byte[2048];
				res.setContentType("application/x-msdownload");
				String header = req.getHeader("User-Agent");

				//브라우저에 맞게 인코딩
				String downName = null;
				if (header.contains("MSIE") || header.contains("Trident")) {
					downName = URLEncoder.encode(fileNm,"UTF-8").replaceAll("\\+", "%20");
					downNm.replaceAll("\r", " ").replaceAll("\n", " "); //HTTP 응답 분할 방지
					res.setHeader("Content-Disposition", "attachment; filename=" + downNm + ";");
				} else {
					downName = new String(fileNm.getBytes("UTF-8"), "ISO-8859-1");
					downNm.replaceAll("\r", " ").replaceAll("\n", " "); //HTTP 응답 분할 방지
					res.setHeader("Content-Disposition", "attachment; filename=\"" +  downNm + "\"");
				}
				
				res.setContentLength((int)file.length());
				res.setHeader("Content-Transfer-Encoding", "binary");
				res.setHeader("Pragma", "no-cache");
				res.setHeader("Expires", "0");

				fin = new BufferedInputStream(new FileInputStream(file));
				outs = new BufferedOutputStream(res.getOutputStream());

				int read = 0;
				while ((read = fin.read(b)) != -1) {
					outs.write(b, 0, read);
				}
			}
			else {
				System.out.println("파일을 찾을수 없습니다.");
			}
		}
	} catch (UnsupportedEncodingException e) {
		System.out.println("문자의 인코딩이 지원 되지 않습니다.");
	} catch (FileNotFoundException e) {
		System.out.println("파일을 찾을수 없습니다.");
	} catch (IOException e) {
		System.out.println("파일 IO처리중 오류가 발생하였습니다.");
	} finally {
		try { 
			if( outs != null ) outs.close();
			if( fin != null ) fin.close();
		} catch( IOException e ) {
			System.out.println("파일 IO처리중 오류가 발생하였습니다.");
		}
	}
}

 

 

 

2-1.  PreparedStatement를 사용하여 파일을 BLOB형태로 저장하기

private void uploadFile(Map fileInfo) throws SQLException {
	Connection con = null;
	PreparedStatement stmt = null;
    
	String dataconDriver = "com.tmax.tibero.jdbc.TbDriver"
	String dataconUrl = "jdbc:tibero:thin:@111.11.11.111:1111:SAPPER"
	String dataconUser = "SAPPER"
	String dataconPassword = "1234"
	String filePath = "C:/downloadFolder/";

	// 파일을 BLOB형태로 저장
	try {
		con = DriverManager.getConnection(dataconUrl, dataconUser, dataconPassword);
		con.setAutoCommit(false); //auto commit을 꺼놔야지 다수의 sql문을 실행할 수 있다.

		File file = new File(filePath + fileInfo.get("fileNm"));
		FileInputStream fis = new FileInputStream(file);

		stmt = con.prepareStatement("INSERT INTO FILE_TABLE(FILE_NM, FILE_CONTENT) VALUES(?, ?)");

		stmt.setString(1, fileInfo.get("fileNm"));
		stmt.setBinaryStream(2, fis, (int)file.length());

		int result = stmt.executeUpdate(); //sql문 실행
        	if(result != 1){
        		System.out.println("SQL 실패")
            	}
        
		con.commit(); //sql문 실행 후 commit
        
	} catch (Exception e) {
		con.rollback();
	} finally {
		if (con != null) con.close();
		if (stmt != null) stmt.close();
	}
}

 

 

 

2-2.  PreparedStatement를 사용하여 BLOB 형태의 파일 다운로드

public void downloadFile( HttpServletRequest req, HttpServletResponse res) throws IOException, Exception {
	String dataconDriver = "com.tmax.tibero.jdbc.TbDriver";
	String dataconUrl = "jdbc:tibero:thin:@111.11.11.111:1111:SAPPER";
	String dataconUser = "SAPPER";
	String dataconPassword = "1234";
    
	try {
	    Class.forName(dataconDriver);
	} catch (Exception e) {
	    System.out.println(e.getMessage());
	}
	
	Connection con = null;
	PreparedStatement stmt = null;
	ResultSet rs = null;
	InputStream is = null;
	ServletOutputStream os = null;
		    
	// BLOB형의 데이터를 파일로 다운로드
	try {
		con = DriverManager.getConnection(dataconUrl, dataconUser, dataconPassword);

		stmt = con.prepareStatement("SELECT * FROM FILE_TABLE WHERE FILE_NO=?");
		stmt.setString(1, req.getParameter("fileNo"));

		rs = stmt.executeQuery();
		if (rs.next()) {
			String fileNm = rs.getString("FILE_NM");

			res.setContentType("application/x-msdownload");
			String header = req.getHeader("User-Agent");

			String downName = null;
			if (header.contains("MSIE") || header.contains("Trident")) {
				downName = new String(fileNm.getBytes("UTF-8"), "UTF-8");
				downNm.replaceAll("\r", " ").replaceAll("\n", " "); //HTTP 응답 분할 방지
				res.setHeader("Content-Disposition", "attachment; filename=" + downNm + ";");
			} else {
				downName = new String(fileNm.getBytes("UTF-8"), "ISO-8859-1");
				downNm.replaceAll("\r", " ").replaceAll("\n", " "); //HTTP 응답 분할 방지
				res.setHeader("Content-Disposition", "attachment; filename=\"" +  downNm + "\"");
			}

			is = rs.getBinaryStream("FILE_CONTENT");
			os = res.getOutputStream();

			byte[] buf = new byte[2048];
			int len = -1;

			while ((len = is.read(buf)) != -1) {
				os.write(buf, 0, len);
			}
		} else {
			System.out.println("파일이 존재하지 않습니다.");
		}
	} catch (Exception e) {
		System.out.println("파일 IO처리중 오류가 발생하였습니다.");
	} finally {
		if (con != null) con.close();
		if (stmt != null) stmt.close();
		if (is != null) is.close();
		if (os != null) os.close();
	}
}

 

 

 

3-1. BLOB 형태로 파일 업로드하기

public Map uploadFile(Map fileInfo) throws Exception {
	Map result = new HashMap();
	String filePath = "C:/downloadFolder/";

	try {
		File file = new File(filePath + fileInfo.get("fileNm"));
		fileInfo.put("fileContent", FileUtils.readFileToByteArray(file)); //파일을 BYTE형태로 변환
		commonDAO.execute("insertFile", fileInfo);
		file.delete(); //업로드를 위해 임시생성한 파일 삭제
	} catch (FileNotFoundException e) {
		System.out.println("파일을 찾을 수 없습니다.");
	}
}
<insert id="insertFile" parameterType="hashmap">
     INSERT INTO FILE_TABLE
     (
     	FILE_NO, 
     	FILE_NM,  
     	FILE_CONTENT,
        REGIST_DT, 
     	REGISTER_ID
     )
     VALUES
     (
     	#{fileNo}, 
     	#{fileNM}, 
     	#{fileContent, jdbcType=BLOB}, /*BYTE형태 파일을 BLOB타입으로 저장*/
     	TO_CHAR(SYSDATE,'YYYYMMDDHH24MISS'), 
     	#{registerId}
     )
</insert>

 

 

 

3-2. BLOB 형태의 파일 다운로드

public void downloadFile(HttpServletRequest req, HttpServletResponse res) throws IOException, Exception {
	String filePath = "C:/downloadFolder/";

	Map param = new HashMap();
	param.put("fileNo", req.getParameter("fileNo"));
	Map fileInfo = (Map)commonDAO.select("selectFile", param);

	File fileDir = new File(filePath);
	if (!fileDir.exists()) {
		fileDir.mkdir();
	}

	File tempFile = null;
	try {
		//다운로드할 파일의 임시 파일 생성
		//.dat는 소프트웨어가 처리할 파일 정보 확장자이다.
		tempFile = File.createTempFile("temp_", ".dat", fileDir); 
		//BLOB형태의 파일 데이터를 임시 파일에 덧씌운다.
		FileUtils.writeByteArrayToFile(tempFile, (byte[]) fileInfo.get("fileContent"));
	} catch (Exception e) {
		System.out.println("서버에 파일이 존재하지 않습니다.");
	}

	FileInputStream fis = null;
	OutputStream os = null;
	try {
		fis = new FileInputStream(tempFile);
		os = res.getOutputStream();
		res.setContentType("application/x-msdownload");
        
		String fileNm = fileInfo.get("localFile").toString();
		String downNm = fileNm.replaceAll("\r", " ").replaceAll("\n", " "); //HTTP 응답 분할 방지
		res.setHeader("Content-Type", "application/octet-stream; charset=utf-8");
		res.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(downNm, "utf-8").replaceAll("[+]", "%20"));
		//한글 파일명을 위해 URLEncoder를 사용하는데, URLEncoder가 공백을 +로 만든다.
		//그래서 +를 %20으로 바꿔주는 작업이 필요한 것이다.
        
		byte[] buf = new byte[2048];
		int len = -1;

		while ((len = fis.read(buf)) != -1) {
			os.write(buf, 0, len);
		}
	} catch (UnsupportedEncodingException e) {
		System.out.println("문자의 인코딩이 지원되지 않습니다.");
	} catch (FileNotFoundException e) {
		System.out.println("파일을 찾을수 없습니다.");
	} catch (IOException e) {
		System.out.println("파일 IO처리중 오류가 발생하였습니다.");
	} finally {
		tempFile.deleteOnExit(); //프로세스 종료 후, 임시파일 삭제 

		try {
			if (os != null)	os.close();
			if (fis != null) fis.close();
		} catch (IOException e) {
			System.out.println("파일 IO처리중 오류가 발생하였습니다.");
		}
	}
}
<resultMap id="fileInfoMap" type="hashmap">
	<result property="fileNm" column="FILE_NM" javaType="java.lang.String" jdbcType="VARCHAR"/>
	<result property="fileContent" column="FILE_CONTENT" javaType="[B" jdbcType="BLOB"/>
</resultMap>
/* array([) + byte(B) = [B 이다. Byte Array로 BLOB 타입 데이터를 받겠다는 것이다. */
<select id="selectFile" resultMap="fileInfoMap">
     SELECT 
	     FILE_NM,
	     FILE_CONTENT
	FROM
		FILE_TABLE
	WHERE 
		FIlE_NO = #{fileNo}
</select>

 

 

'미역 > 자바' 카테고리의 다른 글

그래프에서 DFS로 사이클 찾기  (0) 2021.10.28
TreeSet과 Comparator  (0) 2021.10.25
XOR의 성질  (0) 2021.10.22
최대공약수 & 최소공배수  (0) 2021.10.22
코딩테스트, 예시 파일 읽어오기  (0) 2021.10.08