자료실에서 글 수정의 핵심은 다음 그림과 같이 기존에 첨부한 파일을 삭제할 수 있게 하는 것이다.



새로 첨부하는 것은 글쓰기와 수정이 하나로 처리되어 있기 때문에 별도의 처리가 필요치 않다.

먼저, 게시물과 같이 첨부 파일 리스트를 가져오도록 구성해 줘야 한다.

@RequestMapping(value = "/board4Form")
public String boardForm(HttpServletRequest request, ModelMap modelMap) throws Exception {
    String brdno = request.getParameter("brdno");
    if (brdno!=null) {
        boardVO boardInfo = boardSvc.selectBoardOne(brdno);
        List<?> listview = boardSvc.selectBoard4FileList(brdno);
   
        modelMap.addAttribute("boardInfo", boardInfo);
        modelMap.addAttribute("listview", listview);
    }
   
    return "board4/boardForm";
}

board4Ctr.java

다음 SELECT문은 첨부 테이블(TBL_BOARDFILE)에서 게시글에 해당하는 데이터를 가져오는 것으로,

서비스에 selectBoard4FileList를 추가해 주고,

컨트롤에서는 이 서비스를 호출하여 넘겨받은 List를 게시물 정보(boardInfo)와 같이 modelMap에 넣어(listview) jsp로 넘겨준다.

<select id="selectBoard4FileList" resultType="gu.common.FileVO" parameterType="String">
        SELECT FILENO, FILENAME, REALNAME, FILESIZE
          FROM TBL_BOARDFILE
         WHERE BRDNO=#{brdno}
         ORDER BY FILENO DESC
    </select>

baord4.xml

글 수정(쓰기) 폼에서는 listview의 개수만큼 반복(foreach)하여 파일 명을 보여주고 사용자가 선택하면 삭제 할 수 있도록 한다.

즉, 파일명을 보여 줄 때 사용자가 삭제하고자 선택 할 수 있는 checkbox를 주고

이름은 fileno로 동일하게 부여 하고 값(value)은 각 첨부 파일의 파일 번호(fileno)를 주도록 한다.

<form name="form1" action="board4Save" method="post" enctype="multipart/form-data">
    <table border="1" style="width:600px">
        ~~ 생략 ~~
            <tr>
                <td>내용</td>
                <td><textarea name="brdmemo" rows="5" cols="60"><c:out value="${boardInfo.brdmemo}"/></textarea></td>
            </tr>
            <tr>
                <td>첨부</td>
                <td>
                    <c:forEach var="listview" items="${listview}" varStatus="status">
                        <input type="checkbox" name="fileno" value="<c:out value="${listview.fileno}"/>">   
                        <a href="fileDownload?filename=<c:out value="${listview.filename}"/>&downname=<c:out value="${listview.realname}"/>">
                        <c:out value="${listview.filename}"/></a> <c:out value="${listview.size2String()}"/><br/>
                    </c:forEach>                   
               
                    <input type="file" name="uploadfile" multiple="" />

boardForm.jsp

예로 파일 이름과 번호(fileno)가 1, 2, 3인 경우 각각의 체크 박스가 동일한 이름으로 선택할 수 있게 생성하는 것이다. 

사용자가 1, 3 번을 선택하면 서버로 이 값이 배열로 fileno에 저장되어 전송된다.


파일명을 선택하면 해당 파일이 다운로드(fileDownload) 되도록 제작하였다.

fileDownload 컨트롤은 해당 파일명을 파라메타로 넘겨주면 지정된 파일을 찾아서 클라이언트로 전송해 준다.

fileDownload도 공통으로 사용하는 것으로 원리는 넘어가니 사용법만 기억해 두자.

파라메터 filename은 사용자가 입력한 파일명(filename)이고, downname은 서버에서 저장한 실제 파일명(realname)을 지정해 준다.

fileDownload에도 파일 경로가 고정되어 있으니 자신에게 맞게끔 수정하면 된다.


사용자가 삭제하기 위해 선택한 파일번호들을

다음과 같이 getParameterValues를 이용하여 배열로 받아와서 처리한다.

@RequestMapping(value = "/board4Save")
public String boardSave(HttpServletRequest request, boardVO boardInfo) throws Exception {
    String[] fileno = request.getParameterValues("fileno");

    FileUtil fs = new FileUtil();
    List<FileVO> filelist = fs.saveAllFiles(boardInfo.getUploadfile());

    boardSvc.insertBoard(boardInfo, filelist, fileno);

    return "redirect:/board4List";
}

board4Ctr.java


컨드롤에서 받은 파일번호들을(fileno) Delete문을 이용하여 삭제하면 개발이 끝나게 된다.

배열 변수 하나을 Mybatis로 넘길 수 없기 때문에,

배열변수를 가지는 클래스를 생성하거나 HashMap 클래스를 이용해야 한다.

본 예제에서는 후자를 이용했다.

public void insertBoard(boardVO param, List<FileVO> filelist, String[] fileno) throws Exception {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus status = txManager.getTransaction(def);
        
        try{
            if (param.getBrdno()==null || "".equals(param.getBrdno()))
                 sqlSession.insert("insertBoard4", param);
            else sqlSession.update("updateBoard4", param);
   
            if (fileno != null) {
                HashMap p = new HashMap();
                p.put("fileno", fileno) ;
                sqlSession.insert("deleteBoard4File", p);
            }

            for (FileVO f : filelist) {
                f.setParentPK(param.getBrdno());
                    sqlSession.insert("insertBoard4File", f);
            }
            txManager.commit(status);
        } catch (Exception ex) {
            txManager.rollback(status);
            throw ex;
        }            
}

board4Svc.java

Mybatis에서 넘겨 받은 삭제할 파일 번호들을 foreach문을 사용하여 삭제 하게 된다.

넘겨 받은 파일번호(fileno)의 배열 값을 콤마(,)로 생성하고

SQL문의 저장되어 있기 때문에 IN을 사용하여 한번에 지정된 모든 파일 정보를 삭제한다.

<delete id="deleteBoard4File" parameterType="hashmap">
    DELETE
      FROM TBL_BOARDFILE
         WHERE FILENO IN (
              <foreach item="item" index="index" collection="fileno" separator=",">
                     ${item}
              </foreach> 
        )    
</delete>

baord4.xml

삭제할 파일이 1번과 3번 파일이면 deleteBoard4File은 다음과 같은 SQL 문을 실행하게 될 것이다.

DELETE FROM TBL_BOARDFILE WHERE FILENO IN (1, 3)

클래스나 HashMap에 넘겨서 처리하는 방법외에

하나의 DELETE 문을 배열의 개수 만큼 반복 실행하는 방법도 있지만

개인적으로 데이터 입출력 횟수가 적은 것을 선호해서 이러한 방법을 사용했다.


앞서서 게시물 삭제를 실제로 삭제하지 않고 플래그(deleteflag) 처리하였는데 첨부 파일도 그렇게 구현할 수 있다. 

더욱이 실제 파일을 삭제하는 코드는 구현하지 않았는데 컨트롤에서 java delete 함수를 이용해 파일 삭제도 해보길 …

'Java > 게시판 4:자료실' 카테고리의 다른 글

1. 자료실 - 준비 & 시작  (1) 2016.04.02
2. 자료실 - 글쓰기  (0) 2016.03.28
4. 자료실 - 리스트  (0) 2016.03.28
5. 자료실 - 글 읽기 / 삭제  (0) 2016.03.26

+ Recent posts