JSP·script·jquery

JSP DB 이미지 BLOB 이미지 업로드 및 페이지 출력

초이짬 2017. 11. 22. 11:12
728x90


JSP JNDI PreparedStatement 이용 DB 핸들링 을 통한 jsp의 JNDI 룩업이 되어 있는 전제하에서 출발한다


아래 내용중 필요한 라이브러리는 파일 업로드를 위한 cos.jar와

commons-io-1.4.jar 이다.

그리고 해당 연결자체가 connetionpool 이기에 굳이 커넥션 close 절차(finally구문)을 생략햇다

물론 상당한 테스트를 거치고 해당 구문이 완성이 되어야 하지만 여기서는 jsp를 통해 blob이미지

의 핸들링과 핸들링 된 이미지의 표시를 jsp에서 바로 보여줄수 있다는것에 있다

하단의 imageView.jsp를 보면 알겠지만 다른 페이지 호출이나 서블릿콜이 아닌 디비에서

직접읽은 bit를 화면에 바로 표시 해주는

String b64 = javax.xml.bind.DatatypeConverter.printBase64Binary(imageInByteArray);

out.print("<img src='data:x-image/jpg;base64,"+ b64+"' alt='Visruth.jpg not found' />");

부분이 굉장히 중요하다.

프로젝트를 진행하다 보면 업로드는 보안과 밀접한 관계가 있는데 스토리지의 발전으로 디비에

넣지 않고 사용했지만 보안이 신경쓰이면 이미지나 파일등을 디비에서 관리 하는것도 하나의

포인트가 될 수 있을것이다.


기본테이블 생성
CREATE TABLE CLOBTEST
(
CTEST1 VARCHAR2(10),
CTEST2 VARCHAR2(10),
CLOB CLOB,
REG_DT DATE,
BLOB BLOB
);

파일인서트 페이지 생성
--fileInsert.jsp--

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="upload.jsp" method="post" enctype="multipart/form-data">
<center>
이름 : <input type="text" name="name"><br>
파일 : <input type="file" name="file"><br>
<input type="submit" name="업로드"><br>

</center>
</form>
</body>
</html>


---upload.jsp---
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@page import="java.io.File"%>
<%@page import="java.util.Enumeration"%>
<%@page import="org.apache.commons.io.FileUtils"%>
<%@page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@ page import="java.sql.*"%>
<%@ page import="test.DBConnection"%>


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<%
// request.getRealPath("상대경로") 를 통해 파일을 저장할 절대 경로를 구해온다.
// 운영체제 및 프로젝트가 위치할 환경에 따라 경로가 다르기 때문에 아래처럼 구해오는게 좋음
String uploadPath = request.getRealPath("/uploadFile");
out.println("절대경로 : " + uploadPath + "<br/>");

int maxSize = 1024 * 1024 * 10; // 한번에 올릴 수 있는 파일 용량 : 10M로 제한

String name = "";
String subject = "";

String fileName1 = ""; // 중복처리된 이름
String originalName1 = ""; // 중복 처리전 실제 원본 이름
long fileSize = 0; // 파일 사이즈
String fileType = ""; // 파일 타입

MultipartRequest multi = null;
File file = null;

try{
// request,파일저장경로,용량,인코딩타입,중복파일명에 대한 기본 정책
multi = new MultipartRequest(request,uploadPath,maxSize,"utf-8",new DefaultFileRenamePolicy());

// form내의 input name="name" 인 녀석 value를 가져옴
name = multi.getParameter("name");
// name="subject" 인 녀석 value를 가져옴
subject = multi.getParameter("subject");

// 전송한 전체 파일이름들을 가져옴
//Enumeration files = multi.getFileNames();
file = multi.getFile("file");

/* while(files.hasMoreElements()){
// form 태그에서 <input type="file" name="여기에 지정한 이름" />을 가져온다.
String file1 = (String)files.nextElement(); // 파일 input에 지정한 이름을 가져옴
// 그에 해당하는 실재 파일 이름을 가져옴
originalName1 = multi.getOriginalFileName(file1);
// 파일명이 중복될 경우 중복 정책에 의해 뒤에 1,2,3 처럼 붙어 unique하게 파일명을 생성하는데
// 이때 생성된 이름을 filesystemName이라 하여 그 이름 정보를 가져온다.(중복에 대한 처리)
fileName1 = multi.getFilesystemName(file1);
// 파일 타입 정보를 가져옴
fileType = multi.getContentType(file1);
// input file name에 해당하는 실재 파일을 가져옴
File file = multi.getFile(file1);
// 그 파일 객체의 크기를 알아냄
fileSize = file.length();
} */
// 커넥션 연결
Connection conn = DBConnection.getConnection();

PreparedStatement psmt = null;

StringBuffer sql = new StringBuffer(" INSERT INTO CLOBTEST (CTEST1, CTEST2,BLOB,REG_DT ) VALUES (?, ?, ?, SYSDATE) ");
byte[] buf = FileUtils.readFileToByteArray(file);
psmt = conn.prepareStatement(sql.toString());

for(int i = 0; i<=10; i++) {
psmt.setString(1, "AAAAAA");
psmt.setString(2, "test"+i);
psmt.setBytes(3, buf);
psmt.addBatch();
psmt.clearParameters();
if(i % 2 == 0){
System.out.println("batch-excute:"+i);
psmt.executeBatch();
}
}
psmt.executeBatch();
}catch(Exception e){
e.printStackTrace();
}
%>


<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
</body>
</html>



----imageView.jsp---


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@page import="java.io.File"%>
<%@page import="java.io.InputStream"%>
<%@page import="java.awt.image.BufferedImage"%>
<%@page import="javax.imageio.ImageIO"%>
<%@page import="java.util.Enumeration"%>
<%@page import="org.apache.commons.io.FileUtils"%>
<%@page import="org.apache.commons.io.output.ByteArrayOutputStream"%>
<%@page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@ page import="java.sql.*"%>
<%@ page import="test.DBConnection"%>


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<center>
        <table border="3" bordercolor="skyblue">
        <tr bgcolor="skyblue"><td>1</td><td>2</td><td>3</td></tr>
       
        <%
     // 쿼리문
     String query="SELECT  CTEST1, CTEST2,BLOB,REG_DT FROM CLOBTEST";
     
     // 커넥션 연결
     Connection conn = DBConnection.getConnection();
     
     // DB에 쿼리문을 보낸다.
     PreparedStatement pstmt = conn.prepareStatement(query);
     
     // 쿼리문의 결과값을 rs에 담는다.
     ResultSet rs = pstmt.executeQuery();
     try{
      // 결과값을 출력한다.
      while(rs.next()){
       // 바이너리 데이터를 저장하고 있는 컬럼으로부터 데이터를 가져온다
       InputStream in = rs.getBinaryStream("BLOB");
       // BufferedImage를 생성하면 ImageIO를 통해 브라우저에 출력하기가 쉽다.
       BufferedImage bimg = ImageIO.read(in);
       in.close();
 
       
       ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write( bimg, "jpg", baos );
    baos.flush();
    byte[] imageInByteArray = baos.toByteArray();
    baos.close();
    String b64 = javax.xml.bind.DatatypeConverter.printBase64Binary(imageInByteArray);
    
          out.println("<tr>");
          out.println("<td>"+rs.getString("CTEST1")+"</td>");
          out.println("<td>"+rs.getString("CTEST2")+"</td>");
          out.print("<td>");
          out.print("<img src='data:x-image/jpg;base64,"+ b64+"' alt='Visruth.jpg not found' />");
          out.print("</td>");
          out.println("</tr>");
      }

//실제 사용시는 당연히 finally로 io가 발생된 부분은 닫아 줘야됨
     }catch(Exception e){
            e.printStackTrace();
     }
        %>
        </table>
    </center>
</body>
</html>


728x90