JAVA
BLOB 이미지파일업로드
docc
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 으로 읽어야 함 |