ABOUT ME

  • BLOB 이미지파일업로드
    JAVA 2021. 7. 27. 11:01

    출력과 다운

    1. 프로필사진 출력하기

    (DB에 blob로 저장된 이미지 꺼내는 버전//이름저장하여 로컬경로로 가져오는 케이스가 아님)

    >> Profile.java(Controller)

    @Controller
    public class Profile{
    
    	@Autowired
    	IMemberDAO memberDAO;
    	
    	@RequestMapping("profile/{no}")
    	public void process(HttpServletRequest request, HttpServletResponse response, @PathVariable int no) {
    		
    		Member member = memberDAO.findByNo(no);
    		byte[] profile = (byte[])member.getProfile();
    		response.setContentType("image/jpeg");
    
    		ServletOutputStream os;
    		try {
    			//' http규격응답' 이 클라이언트에게 보낼 상자("image/jpeg")를 
    			// outputstream 에게 주면서 거기에 바이트단위의 profile의 내용물을 단위마다 write()하며 집어넣게 한다.
    			// flush() : write() 시 단위까지 집어넣으면 client 에게 보내는데 못미쳐 남은 마지막껏 까지 집어넣게 하는 메서드다.
    			// 안써도 작업끝나고 어느 순간에는 보내기 때문에 바로보내고 싶다 할 때 아니면 생략가능하다.
    			os = response.getOutputStream();
    			os.write(profile);
    			os.flush();
    		}catch(Exception e) {
    			e.printStackTrace();
    		}
    		
    	}
    }

    2. 첨부파일(Attach) 다운받게 업로드 하기

    (DB에 이미지를 blob가 아닌 이름과 사이즈만 저장한 경우)

    >> 게시물상세창.jsp - 업로드받을 파일 a태그

    	<c:if test="${not empty board.attachs}">
    	첨부 : <br />
    		<ul>
    		<c:forEach var="attach" items="${board.attachs}" varStatus="status">
    			<li> <a href="/board/attach/${attach.no}">${attach.name} ${attach.size}</a></li>
    		</c:forEach>
    		</ul>
    	</c:if>

    >> AttachDAO

    	@Override
    	public Attach findByNo(int 첨부번호) {
    		Connection connection = null;
    		Statement 명령전달자 = null;
    		Attach attach = null;
    		
    		try {
    			connection = ConnectionUtil.getConnection();
    			명령전달자 = connection.createStatement();
    
    			
    			String 수집SQL = String.format("select * from attach where no = %d",첨부번호);
    			ResultSet 수집된표관리자 = 명령전달자.executeQuery(수집SQL);
    
    			
    			if(수집된표관리자.next()) {
    				int no = 수집된표관리자.getInt("no");
    				String name = 수집된표관리자.getString("name");
    				long size = 수집된표관리자.getLong("size");
    				int board_no = 수집된표관리자.getInt("board_no");
    				Board board = new Board();
    				board.setNo(board_no);
    				
    				attach = new Attach();
    				attach.setNo(no);
    				attach.setName(name);
    				attach.setSize(size);
    				attach.setBoard(board);
    			}
    
    			수집된표관리자.close();
    			명령전달자.close();
    			connection.close();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		
    		
    		return attach;
    	}

    >> Attach컨트롤.java(new)

    @Controller
    public class Attach컨트롤 {
    
    	@Autowired
    	IAttachDAO attachDAO;
    
    	@RequestMapping("board/attach/{a_no}")
    	public void process(HttpServletRequest request, HttpServletResponse response, @PathVariable("a_no") int 첨부번호) {
    		
    		try {
    			 Attach attach=attachDAO.findByNo(첨부번호);
    		     String filename = attach.getName();
    		     String encodedFilename="";
    		     
    		     /*파일명이 제대로 다운로드 되지 않는 이유는
    		     브라우저별로 Content-Disposition의 값에 대한
    		     인코딩 처리 방식에 약간의 차이가 있어서 입니다.
    
    		     브라우저별로 문자열처리를 하셔야
    		     정상적인 파일로 다운로드가 가능합니다.
    		     https://www.egovframe.go.kr/home/qainfo/qainfoRead.do?menuNo=69&qaId=QA_00000000000016942
    		     */
    		     String browser = request.getHeader("User-Agent"); //현재 쓰는 브라우저 알아내기
    		     System.out.println(browser);
    		     
    		     //MSIE = 익스플로러, Chrome = 크롬, Filefox = 파이어폭스, Opera = 오페라
    		     //파일이름에 utf-8 속성을 달아준다.(브라우저마다 법칙이 달라서 if문으로 다르게 넣었다. 이 부분은 깊이 생각말기)
    		     if (browser.contains("MSIE")||browser.contains("Chrome")) {
    		     encodedFilename = URLEncoder.encode(filename, "UTF-8").replaceAll("\\+", "%20");
    		     } else if (browser.contains("Firefox")) {
    		     encodedFilename = "\"" + new String(filename.getBytes("UTF-8"), "8859_1") + "\"";
    		     } else if (browser.contains("Opera")) {
    		     encodedFilename = "\"" + new String(filename.getBytes("UTF-8"), "8859_1") + "\"";
    		     }
    		     String path = request.getSession().getServletContext().getRealPath("/upload/board");
    		     String fullFilePath=path+"\\"+attach.getBoard().getNo()+"\\"+attach.getName();
    			
    			
    			// 1번.
    			response.setContentType("application/octer-stream: charset=utf-8");//바이너리형식
    			response.setHeader("Content-Transfer-Encoding", "binary");
    			response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFilename+"\"");
    			File file = new File(fullFilePath);
    			response.setHeader("Content-Length", "" +file.length());
    			
    			// 2번.
    			OutputStream os = response.getOutputStream();
    			
    			// 3번.
    			FileInputStream fis = new FileInputStream(file);
    			int 읽은크기 = 0;
    			byte[] 버퍼 = new byte[1024];//프로그래머가 대략 정해야함
    			
    			// inputStream 이 반복하여 HDD 파일을 읽어 버퍼에 데이터를 넣고 있다.
    			// 한번에 넣는게 아니라 여러번 쪼개 넣음, 다 읽으면 -1 이 나옴
    			while((읽은크기 = fis.read(버퍼)) != -1) {
    				// outputStream 이 '버퍼' 에서 0부터 inputStream '읽은크기' 만큼 write()하고 있다.
    				os.write(버퍼, 0, 읽은크기);
    			}
    			
    			fis.close();
    			os.close();
    		}catch(Exception e) {
    			e.printStackTrace();
    		}
    		
    	}
    1번. 파일 내용을 읽은 거 위에 헤더를 따로 붙여야 하니 response 로 binary 이며 charset=utf-8로 하며 파일이름이 이렇다 하고 지정

    response.setHeader : 파일의 정보를 미리 설정해 알려준다 (데이터유형, 종류, 길이, 주소, 이름 등)
    POST 방식 : Header 부분을 url 으로 하여 다운받게 할 수도 있다.
    하지만 url 길이에 제한이 있어서 정보를 집어넣기만 하는 방식으로 한다.
    2번. outputStream 이 그 헤더가 담긴 상자를 response 에게서 받아 inputStream 이 read()할 때 write() 한다.
    3번. byte[] 형으로 메모리에 올라간 파일이 아니니 inputStream 으로 읽어야 함

    'JAVA' 카테고리의 다른 글

    댓글

Designed by Tistory.