상세 컨텐츠

본문 제목

[Spring] 외부 파일 접근하여 다운로드 받기

Development/Spring

by J-Developer 2020. 8. 24. 14:01

본문

반응형

회사에서 일을 하다가 외부 파일(다른 도메인의 파일)에 접근해 파일을 다운로드 해야하는 기능을 만들게 되었다.

 

예를들면 이미지 파일 URL로 접근하여 스트림을 받아 복사하여 다운로드 되게끔하였다.

파일 URL을 넘길때는 URL Encoding을하여 넘겨주면 된다.

직접 만든것이라 어떠한 버그가 있는지는 아직 잘 모르겠다.

 

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping( value = "/file" )
public class FileController {

	@RequestMapping(value = "/down/external", method = { RequestMethod.GET, RequestMethod.POST })
	public void downExternalFile ( @RequestParam( value = "encFileUrl", required = true ) String encFileUrl, HttpServletRequest request, HttpServletResponse response ) {
		
		try {
			
			String fileUrl = URLDecoder.decode(encFileUrl, StandardCharsets.UTF_8.name());
            
			// 한글일 경우 Connection 에러가 뜨는 경우가 있어 punyCode로 변환
			// PunyCode 변환은 각자 만들어야 함.
			String punyCodeUrl = WebUtil.getPunycodeEncoding(fileUrl);
			
			String originFileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
			
			URL url = new URL(punyCodeUrl);
			
			HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
			httpCon.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0");
			httpCon.setRequestProperty("Cache-Control", "no-cache");
			httpCon.setReadTimeout(5000);
			httpCon.setConnectTimeout(5000);
			InputStream in = new BufferedInputStream( httpCon.getInputStream() );
			
			ServletOutputStream out = response.getOutputStream();
			
			response.setHeader( "Content-Transfer-Encoding", "binary" );
			response.setContentType( "application/x-download" );
			
			String userAgent = request.getHeader( "User-Agent" );
			
			if ( userAgent.indexOf( "Chrome" ) > -1 || userAgent.indexOf( "Firefox" ) > -1 ) {
				response.setHeader( "Content-Disposition", "attachment;filename=\"" + new String( originFileName.getBytes( "UTF-8" ), "ISO-8859-1" ) + "\";" );
			}
			else if ( userAgent.indexOf( "MSIE 5.5" ) > -1 ) { // MS IE 5.5 이하
				String decodeName = URLDecoder.decode( originFileName, "UTF-8" );
				String encodeName = URLEncoder.encode( decodeName, "UTF-8" );
				response.setHeader( "Content-Disposition", "filename=" + encodeName.replaceAll( "\\+", "\\ " ) + ";" );
			}
			else if ( userAgent.indexOf( "MSIE" ) > -1 || userAgent.contains( "Trident" ) ) { // MS IE (보통은 6.x 이상 가정)
				String decodeName = URLDecoder.decode( originFileName, "UTF-8" );
				String encodeName = URLEncoder.encode( decodeName, "UTF-8" );
				response.setHeader( "Content-Disposition", "attachment; filename=" + encodeName.replaceAll( "\\+", "\\ " ) + ";" );
			}
			else {
				response.setHeader( "Content-Disposition", "attachment; filename=" + new String( originFileName.getBytes( "euc-kr" ), "latin1" ).replaceAll( "\\+", "\\ " ) + ";" );
			}
			

			IOUtils.copy( in, out );

			out.flush();
			
			out.close();
			in.close();
			
		} catch (Exception e) {
			
			e.printStackTrace();
			
		}
		
	}
	
	
}
반응형

관련글 더보기

댓글 영역