Miaha
30
2018-10-12 22:39:33 작성 2018-10-12 22:40:28 수정됨
2
97

JSP 게시판 파일 다운로드가 작동하지 않습니다.


JSP 게시판 만들기를 거의 마무리 짓고 있습니다.

글쓰기, 수정, 삭제 등의 기본 기능을 만들고 MultipartRequest 를 이용해서 파일 업로드 기능을 구현하고 파일이 실제로 복사되서 업로드 폴더에 들어가는 것까지 구현이 됬는데요

이 파일을 게시글 보기 화면에서 다운로드 하는 것에서 막혔습니다.

정확히는 글제목, 내용, 작성자 등의 다른 데이터는 전부 불러와 지는데 파일 다운로드를 위한 파일명이 불러와지지 않고 있는것 같습니다.



<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="f_board.*" %>
<%@ page import="java.text.*" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="contentType" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="<%=request.getContextPath()%>/css/bootstrap.css">
<link rel="stylesheet" href="<%=request.getContextPath()%>/css/custom.css">
<jsp:useBean id="dao" class="f_board.F_boardDataBean"/>
<%
	String snum = request.getParameter("f_num");
	if(snum==null || snum.trim().equals("")){
		response.sendRedirect("list.jsp");
		return;
	}
	
	F_boardDBBean dto = dao.getF_board("f_content", Integer.parseInt(snum));
%>
<title><%= dto.getF_subject().replaceAll(" ", "&nbsp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\n", "<br>") %></title>
</head>
<body>
<jsp:include page="/header.jsp" flush="true"/>
	
	<div class="container" align="center">
		<div class="row">
			<table class="table table-light" style="text-align:center; border:1px solid #dddddd; width:600px;">
				<thead>
					<tr>
						<th colspan="6" style="background-color: #eeeeee; text-align: center;">게시판 글 보기</th>
					</tr>
				</thead>
				<tbody>
					<tr style="background-color: #white;">
						<th style="width: 20%;">글 제목</th>
						<td colspan="4"><%= dto.getF_subject().replaceAll(" ", "&nbsp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\n", "<br>") %></td>
					</tr>
					<tr>
						<th>글번호</th>
						<td colspan="2"><%= dto.getF_num() %></td>
						<th>조회수</th>
						<td><%= dto.getF_readcount() %></td>
					</tr>
					<tr>
						<th>작성자</th>
						<td colspan="2"><%= dto.getF_writer() %></td>
						<th>작성일</th>
						<td colspan="2"><%= dto.getF_reg_date().substring(0, 11) +" / "+ dto.getF_reg_date().substring(11, 13) + " : " + dto.getF_reg_date().substring(14, 16) %></td>
					</tr>
					<tr>
						<th>내용</th>
						<td colspan="4" style="min-height: 600px; text-align: left;"><%= dto.getF_content().replaceAll(" ", "&nbsp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\n", "<br>") %></td>
					</tr>

					<tr>
					<th>첨부파일</th>
						<td colspan="4"><a href = "fileDownload.jsp"><%=dto.getF_fileName()%></a></td>
					</tr>
				</tbody>
			</table>
			<input type="button" class="btn btn-primary" value="답글쓰기" 
					onclick="window.location='writeForm.jsp?f_num=<%=dto.getF_num()%>&re_step=<%=dto.getRe_step()%>&re_level=<%=dto.getRe_level()%>'">
			<input type="button" class="btn btn-primary" value="삭제하기" onclick="window.location='deleteForm.jsp?f_num=<%=dto.getF_num()%>'">
			<input type="button" class="btn btn-primary" value="수정하기" onclick="window.location='updateForm.jsp?f_num=<%=dto.getF_num()%>'">
			<input type="button" class="btn btn-primary" value="목록으로" onclick="window.location='list.jsp'">
		</div>
	</div>
<jsp:include page="/footer.jsp" flush="true"/>
	<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
	<script src="js/bootstrap.js"></script>
</body>
</html>

f_filename을 불러오지 못하고 있습니다.


이처럼 원래라면 업로드한 파일명이 나와야 하는 부분이 컬럼명을 그대로 출력하고 있습니다

여기까지 실행하면서 콘솔에는 오류 메세지가 나타나지 않았습니다.




테이블 구조와 들어간 데이터 입니다.

맨마지막 f_num 24 를 보면 파일의 파일명이 들어갔고

실제 업로드 폴더에 정상적으로 해당파일이 복사되었으며 이후 확인해보니 동일한 파일명 rename 처리까지 되는것을 확인 했습니다.

마지막으로 해당 기능들을 작동시키는 action 입니다.


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="f_board.*" %>
<%@ page import="java.text.*" %>
<%@ page import="java.io.*"%>
<%@ page import="java.lang.*" %>
<%@ page import="java.util.*" %>
<%@ page import="java.net.*" %>

<jsp:useBean id="dto" class="f_board.F_boardDBBean"/>
<jsp:setProperty property="*" name="dto"/>
<jsp:useBean id="dao" class="f_board.F_boardDataBean"/>
<%
//파일이 저장될 경로.
	String realPath = "P:/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/portfolio/upload";

//파일 이름이 파라미터로 넘어오지 않으면 리다이렉트 시킨다.
	if(dto.getF_fileName() == null || "".equals(dto.getF_fileName())){

	response.sendRedirect("../list.jsp");

	}else{

 // 파라미터로 받은 파일 이름.
		String requestFileNameAndPath = dto.getF_fileName();
  
 // 서버에서 파일찾기 위해 필요한 파일이름(경로를 포함하고 있음)
 // 한글 이름의 파일도 찾을 수 있도록 하기 위해서 문자셋 지정해서 한글로 바꾼다.
		String UTF8FileNameAndPath = new String(requestFileNameAndPath.getBytes("8859_1"), "UTF-8");
  
 // 파일이름에서 path는 잘라내고 파일명만 추출한다.
		String UTF8FileName = UTF8FileNameAndPath.substring(UTF8FileNameAndPath.lastIndexOf("/") + 1).substring(UTF8FileNameAndPath.lastIndexOf(File.separator) + 1);
  
 // 브라우저가 IE인지 확인할 플래그.
		boolean MSIE = request.getHeader("user-agent").indexOf("MSIE") != -1;
  
 // 파일 다운로드 시 받을 때 저장될 파일명
		String fileNameToSave = "";

 // IE,FF 각각 다르게 파일이름을 적용해서 구분해주어야 한다.
		if(MSIE){
// 브라우저가 IE일 경우 저장될 파일 이름
// 공백이 '+'로 인코딩된것을 다시 공백으로 바꿔준다.
		fileNameToSave = URLEncoder.encode(UTF8FileName, "UTF8").replaceAll("\\+", " ");
 		}else{
// 브라우저가 IE가 아닐 경우 저장될 파일 이름
		fileNameToSave = new String(UTF8FileName.getBytes("UTF-8"), "8859_1");
		}

 // 다운로드 알림창이 뜨도록 하기 위해서 컨텐트 타입을 8비트 바이너리로 설정한다.
		response.setContentType("application/octet-stream");
  
 // 저장될 파일 이름을 설정한다.
		response.setHeader("Content-Disposition", "attachment; f_filename=\"" + fileNameToSave + "\";");
  
// 파일패스 및 파일명을 지정한다.
//  String filePathAndName = pageContext.getServletContext().getRealPath("/") + UTF8FileNameAndPath;
		String filePathAndName = realPath + UTF8FileNameAndPath;
		File file = new File(filePathAndName);
  
// 버퍼 크기 설정
		byte bytestream[] = new byte[2048000];

// response out에 파일 내용을 출력한다.
		if (file.isFile() && file.length() > 0){
      
		FileInputStream fis = new FileInputStream(file);
		BufferedInputStream bis = new BufferedInputStream(fis);
		BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
          
		int read = 0;
          
		while ((read = bis.read(bytestream)) != -1){
		bos.write(bytestream , 0, read);
		}
      
		bos.close();
		bis.close();
      
		}
	}
%>

action페이지의 출처는 이곳입니다.

http://zero-gravity.tistory.com/170

현재 컬럼명이 그대로 출력되는 다운로드 링크를 누르면 게시글 목록으로 리다이렉트 되는 것으로 보면 확실하게 f_fileName을 가져오지 못하는게 분명한데 제가 어느 부분을 놓치고 있는지 잘 모르겠습니다.

오류 메세지라도 나온다면 보고 찾아 보겠는데 오류 메세지 자체가 나오질 않으니 도무지 갈피를 못잡고 도움을 요청합니다.

긴 질문글 읽어주셔서 감사합니다.

0
0
  • 답변 2

  • 멍규
    113
    2018-10-13 09:45:43

     젤 아래 코드는 fileDownload.jsp인가요? 

    					<th>첨부파일</th>
    						<td colspan="4"><a href = "fileDownload.jsp"><%=dto.getF_fileName()%></a></td>
    					</tr>

    이부분이 문제라면 다운로드가 아니라 dto설정하는 부분은 봐야하지 않을까요? 

    1
  • Miaha
    30
    2018-10-14 20:44:46

    DTO의 게터와 세터 부분의 오탈자는 없는거같습니다 ㅠㅠ
    혹시나 해서 DTO도 코드 남기겠습니다.

    package f_board;
    
    public class F_boardDBBean {//DTO
    
    	private int f_num;
    	private String f_writer;
    	private String f_email;
    	private String f_subject;
    	private String f_password;
    	private String f_reg_date;
    	private int f_readcount;
    	private String f_content;
    	private int re_step;
    	private int re_level;
    	private String f_fileName;
    	private String f_fileRealName;
    	
    	public int getF_num() {
    		return f_num;
    	}
    	public void setF_num(int f_num) {
    		this.f_num = f_num;
    	}
    	public String getF_writer() {
    		return f_writer;
    	}
    	public void setF_writer(String f_writer) {
    		this.f_writer = f_writer;
    	}
    	public String getF_email() {
    		return f_email;
    	}
    	public void setF_email(String f_email) {
    		this.f_email = f_email;
    	}
    	public String getF_subject() {
    		return f_subject;
    	}
    	public void setF_subject(String f_subject) {
    		this.f_subject = f_subject;
    	}
    	public String getF_reg_date() {
    		return f_reg_date;
    	}
    	public void setF_reg_date(String f_reg_date) {
    		this.f_reg_date = f_reg_date;
    	}
    	public int getF_readcount() {
    		return f_readcount;
    	}
    	public void setF_readcount(int f_readcount) {
    		this.f_readcount = f_readcount;
    	}
    	public String getF_content() {
    		return f_content;
    	}
    	public void setF_content(String f_content) {
    		this.f_content = f_content;
    	}
    	public String getF_password() {
    		return f_password;
    	}
    	public void setF_password(String f_password) {
    		this.f_password = f_password;
    	}
    	public int getRe_step() {
    		return re_step;
    	}
    	public void setRe_step(int re_step) {
    		this.re_step = re_step;
    	}
    	public int getRe_level() {
    		return re_level;
    	}
    	public void setRe_level(int re_level) {
    		this.re_level = re_level;
    	}
    	public String getF_fileName() {
    		return f_fileName;
    	}
    	public void setF_fileName(String f_fileName) {
    		this.f_fileName = f_fileName;
    	}
    	public String getF_fileRealName() {
    		return f_fileRealName;
    	}
    	public void setF_fileRealName(String f_fileRealName) {
    		this.f_fileRealName = f_fileRealName;
    	}
    		
    }
    


    0
  • 로그인을 하시면 답변을 등록할 수 있습니다.