[Write]
writle.jsp파일부터 우선 bbs에서 복사해 옴
여기서도 스크립팅 요소는 싹 지우고 시작하자
여기서는 저번에 사용한 파일 업/다운로드를 이용할거임
자료실이니까 파일 업로드 하니까!
저번에 받은 model에 FileUtils에 메소드를 추가해서 사용할 것
파일을 업로는 하는 로직을 메소드로 빼서
필요할 때 간편하게 메소드만 호출 할 것임
그리고 만약 입력에 실패했을 때(용량이 크다거나 내용이 알맞지 않다거나)
업로드되는걸 막아야 하기 때문에 파일 삭제 로직도 추가
(이거 없으면 실패해도 그냥 업로드가 되버리더라!!)
인자로 part: 파일정보/ savedire : 물리적 경로 를 받는군....
public static String upload(Collection<Part> parts,String saveDirectory) {
String filenames=" ";
//업로드된 파일명들 저장용
try {
for(Part part:parts) {
if(part.getContentType() !=null) { //타입이 파일 일때만 contentType 이 있다.
String systemFileName=FileUtils.getNewFileName(saveDirectory,part.getSubmittedFileName());
filenames+=systemFileName+",";
//파일 업로드(진짜 업로드 됨 ,File.separator는 운영체제따라 경로 사용할 따 \혹은/ 를 다르게 적용시켜줌 )
part.write(saveDirectory+File.separator+systemFileName);
}
}
}
catch(Exception e) {
return null ;
}
return filenames.substring(0,filenames.length()-1);
}/////////////////
//삭제로직
public static void deletes(String filenames,String saveDirectory) {
String[] files = filenames.split(",");
for(String filename: files) {
File f =new File(saveDirectory+File.separator+filename);
if(f.exists()) f.delete();
}
}/////////////////
입력하는거니까 insert메소드 구현해야 겠지? 이번엔 컨트롤러 작성 전에
DAO에 insert메소드 작성을 먼저 해 보자
@Override
public int insert(DataRoomDTO dto) {
int affected = 0;
String sql ="INSERT INTO DATAROOM VALUES(SEQ_DATAROOM.NEXTVAL,?,?,?,?,?,DEFAULT,SYSDATE)";
try {
psmt = conn.prepareStatement(sql);
psmt.setString(1, dto.getName());
psmt.setString(2, dto.getPassword());
psmt.setString(3, dto.getTitle());
psmt.setString(4, dto.getContent());
psmt.setString(5, dto.getAttachFile());
affected = psmt.executeUpdate();
}
catch(SQLException e) {e.printStackTrace();}
return affected;
}////////////
wirtecontroller 만들기
하나의 컨트롤러로 두 가지 기능 처리
즉 GET방식 일 때는 입력폼으로 이동
POST방식 일 때는 입력 처리(get으로 받고 일처리는 post로 몰아주기)
@WebServlet("/DataRoom/Write.kosmo")
@MultipartConfig(maxFileSize = 1024*500,maxRequestSize = 1024*500*5)
public class WriteController extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//2]요청분석- 입력폼 요청
//3]모델호출 및 결과값 받기
//4]결과값이 있으면 ,리퀘스트 영역에 저장
//5]뷰 선택
req.getRequestDispatcher("/dataroom14/Write.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//DB입력 성공시에는 1, 실패시 0, 파일용량 초과시는 -1
int insertflag;
try {
//서버의 물리적 경로 얻기
String saveDirectory = req.getServletContext().getRealPath("/upload");
//기타 파라미터 받기
String name = req.getParameter("name");
String title= req.getParameter("title");
String password = req.getParameter("password");
String content = req.getParameter("content");
//업로드된 파일 정보를 얻기 위한 part객체 생성
Collection<Part> parts=req.getParts();//요 메소드 호출 시 용량 초과하면 에러
//파일 업로드 로직 호출
String filenames=FileUtils.upload(parts, saveDirectory);
//나머지 받은 파람들 입력처리로직(데이터베이스 CRUD관련 작업 호출)
DataRoomDAO dao = new DataRoomDAO(getServletContext());
DataRoomDTO dto = new DataRoomDTO();
dto.setAttachFile(filenames);
dto.setContent(content);
dto.setName(name);
dto.setPassword(password);
dto.setTitle(title);
insertflag=dao.insert(dto);
if(insertflag == 0) { // 입력실패시 업로드 된 파일 삭제로직 호출
//파일 삭제 로직 호출
FileUtils.deletes(filenames, saveDirectory);
}
}
catch (Exception e) { //파일용량 초과시
insertflag=-1;
}
//메시지 뿌려주는 jsp페이지(insertFlag값 사용)로 이동 후 목록으로 이동
//리퀘스트 영역에 결과값 혹은 필요한 값 저장
//입력 시 성공여부
req.setAttribute("SUCCFAIL", insertflag);
//컨트롤러 구분용 -입력: ins,수정edt, 삭제del
req.setAttribute("WHERE","INS");
///포워드
req.getRequestDispatcher("/dataroom14/Message.jsp").forward(req, resp);
}////
}
그러면 메시지를 만들러또 가야겠네
Message.jsp 얘는 새로생성
얘도 꼭
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 잊지말자!
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:choose>
<c:when test="${WHERE =='INS'}">
<c:set var="successMsg" value="입력 성공했어요"/>
<c:set var="failMsg" value="입력 실패했어요"/>
<c:set var="successUrl" value="/DataRoom/List.kosmo"/>
</c:when>
<c:when test="${WHERE =='EDT'}">
<c:set var="successMsg" value="수정 성공했어요"/>
<c:set var="failMsg" value="수정 실패했어요"/>
<c:set var="successUrl" value="/DataRoom/View.kosmo?no=${no}"/>
</c:when>
<c:otherwise>
<c:set var="successMsg" value="삭제 성공했어요"/>
<c:set var="failMsg" value="삭제 실패했어요"/>
<c:set var="successUrl" value="/DataRoom/List.kosmo"/>
</c:otherwise>
</c:choose>
<script>
<c:choose>
<c:when test="${SUCCFAIL==1}">
alert("${successMsg }");
location.replace("<c:url value="${successUrl}"/>");
</c:when>
<c:when test="${SUCCFAIL==0}">
alert("${failMsg}");
history.back();
</c:when>
<c:otherwise>
alert("파일 업로드 용량 초과")
history.back();
</c:otherwise>
</c:choose>
</script>
이래서 자바스크립트도 손을 놓을 수가 없구나
최종 write.jsp에서 받은값들 뿌려주고
등록처리하기
처리할게.. 너무 많아서 ...
맨 위에 taglib 꼭 넣고!!
경고 메시지 넣어
<c:if test="${! empty ERROR }">
<div class="alert alert-danger"><strong>${ERROR}!</strong></div>
</c:if>
자료올릴거니 폼 속성에
enctype="multipart/form-data" 넣고
클릭 후 이동은
"<c:url value="/DataRoom/Write.kosmo"/>"
등등 밑에 자바스크립트로 로직 처리하는 것도 추가!
<jsp:include page="/template/Top.jsp"/>
<div class="container" style="margin-top:65px;">
<div class="jumbotron bg-warning">
<h1>자료실 작성<small>자료 파일을 등록 하세요</small></h1>
</div>
<c:if test="${! empty ERROR }">
<div class="alert alert-danger"><strong>${ERROR}!</strong></div>
</c:if>
<form method="post" enctype="multipart/form-data" action="<c:url value="/DataRoom/Write.kosmo"/>">
<div class="form-group">
<label><kbd class="lead">올린이</kbd></label>
<input type="text" class="form-control" placeholder="이름을 입력하세요" name="name" value="${empty param.name? "" :param.name }">
</div>
<div class="form-group">
<label><kbd class="lead">제목</kbd></label>
<input type="text" class="form-control" placeholder="제목을 입력하세요" name="title" value="${empty param.title? "" :param.title }" >
</div>
<div class="form-group">
<label><kbd class="lead">자료 파일</kbd></label>
<input type="file" class="form-control-file" multiple name="attachFile">${empty param.attachFile? "" :param.attachFile }
</div>
<div class="form-group">
<label><kbd class="lead">비밀번호</kbd></label>
<input type="password" class="form-control" name="password" placeholder="비밀번호를 입력하세요">
</div>
<div class="form-group">
<label><kbd class="lead">내용</kbd></label>
<textarea class="form-control" rows="5" name="content">${empty param.content? "" :param.content}</textarea>
</div>
<button type="submit" class="btn btn-primary">등록</button>
</form>
</div>
<jsp:include page="/template/Footer.jsp"/>
<script>
/*
//[0]은 첫번째 파일 의미
//파일 사이즈(바이트):파일객체(자스 DOM).files[0].size
//파일 명:파일객체(자스 DOM).files[0].name
//파일 컨텐츠 타입:파일객체(자스 DOM).files[0].type
*/
var attaches = document.querySelector("input[type=file]");
var form = document.querySelector("form[enctype='multipart/form-data']");
form.onsubmit=function(){
console.log(attaches.files);
for(var i=0 ; i<attaches.files.length ;i++){
console.log('파일명:%s,크기:%s,컨텐츠 타입:%s',attaches.files[i].name,attaches.files[i].size,attaches.files[i].type);
if(attaches.files[i].size > 1024*500 ){
alert("용량 초과")
return false;
}
}
};
</script>

list목록에서 파일 글자를 클릭하면 파일을 다운로드하게 만들것
그럼 따로 jsp파일은 없어도 되고 대신 컨트롤러만 필요 하겠다
DownloadController.java
@WebServlet("/DataRoom/Download.kosmo")
public class DownloadController extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String no = req.getParameter("no");
String filename = req.getParameter("filename");
//1.다운로드 관련된 모델 호출
//2.파일다운로드 로직 호출
FileUtils.download(filename,"/upload", req, resp);
//3.테이블의 다운로드 수 컬럼 증가용 데이터베이스 관련 로직
DataRoomDAO dao=new DataRoomDAO(getServletContext());
dao.updateDawnCount(no);
dao.close();
}
}
이렇게 되면 fileuitls에 다운로드 로직이랑
dao 에 커럼수 증가용 로직을 만들어야 겠네...
다운로드 로직
public static void download(String filename,String webPath,HttpServletRequest request,HttpServletResponse response) {
try {
String saveDirectory = request.getServletContext().getRealPath(webPath);
File file = new File(saveDirectory+File.separator+filename);
long length = file.length();
response.setContentType("application/octect-stream");
response.setContentLengthLong(length);
boolean isIe = request.getHeader("user-agent").toUpperCase().indexOf("MSIE") != -1 ||
request.getHeader("user-agent").toUpperCase().indexOf("11.0") != -1 ||
request.getHeader("user-agent").toUpperCase().indexOf("EDGE") != -1 ;
if(isIe) {//인터넷 익스플로러 혹은 엣지
filename = URLEncoder.encode(filename,"UTF-8");
}
else {
filename = new String(filename.getBytes("UTF-8"),"8859_1");
}
response.setHeader("Content-Disposition", "attachment;filename="+filename);
BufferedInputStream bis =
new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream bos=
new BufferedOutputStream(response.getOutputStream());
int data;
while((data=bis.read())!=-1){
bos.write(data);
bos.flush();
}
bis.close();
bos.close();
}
catch(Exception e) {e.printStackTrace();}
}
Dao로 가서 다운로드 수 증가용 메소드 추가
public void updateDawnCount(String no) {
String sql="UPDATE dataroom SET downcount=downcount+1 WHERE no=?";
try {
psmt = conn.prepareStatement(sql);
psmt.setString(1, no);
psmt.executeUpdate();
}
catch(SQLException e) {e.printStackTrace();}
}
list에 다운로드 수 적용 시키기
<tbody class="table-sm down-file-body">
<c:if test="${empty records}" var="isEmpty">
<tr>
<td colspan="5">등록된 글이 없습니다.</td>
</tr>
</c:if>
<c:if test="${not isEmpty }">
<c:forEach var="record" items="${records}" varStatus="loop">
<tr>
<td>${record.no}</td>
<td class="text-left"><a href='<c:url value="/DataRoom/View.kosmo?no=${record.no}"/>'>${record.title}</a></td>
<td>${record.name }</td>
<td>
<ul class="list-unstyled">
<c:forEach var="file" items="${fn:split(record.attachFile,',')}">
<li><a class ="down-file${loop.count}" href="<c:url value="/DataRoom/DownLoad.kosmo?filename=${file}&no=${record.no}"/>">${file}</a></li>
</c:forEach>
</ul>
</td>
<td id="down-count${loop.count}">${record.downCount}</td>
<td>${record.postDate}</td>
</tr>
</c:forEach>
</c:if>
</tbody>
list 밑에 자바스크립트로 다운로드 수 관련 로직 작성
<script>
var tbody = document.querySelector(".down-file-body");
tbody.onclick=function(e){
console.log(e.target.nodeName);
if(e.target.nodeName ==='A'){
console.log('클릭한 A태그의 클래스명:',e.target.className);
//a태그의 클래스명에서 끝에 숫자 추출
var className = e.target.className;
var numbering = className.substring("down-file".length,className.length);
console.log("넘버링 숫자:",numbering);
//아이디로 다운수가 있는 td요소 얻기
var td=tbody.querySelector("#down-count"+numbering);
//다운수 읽어오기(숫자로 변환)
var downCount= parseInt(td.textContent);
//1을 더해서 다시 설정
td.textContent=downCount+1;
}
};
</script>
'학원 > JSP' 카테고리의 다른 글
12/05 57-1 [JSP] 자료실만들기4(다운로드 수/비밀번호 확인/delete) (0) | 2022.12.05 |
---|---|
12/02 56-3 [JSP] 자료실만들기.3(view) (0) | 2022.12.04 |
12/02 56-1 [JSP] 자료실만들기1.(DAO,DTO,index,list) (0) | 2022.12.04 |
12/01 55-3 [JSP] 리스너와필터 (0) | 2022.12.01 |
12/01 55-2 [JSP] 서블릿Basic(get/post/both/multi) (0) | 2022.12.01 |