리스트에서는 첨부 파일이 있는지 여부를 적절한 아이콘으로 보여준다.

리스트에서 다운로드 받게끔 하는 경우도 있지만 본 예제에서는 첨부 개수를 보여주어 첨부 파일 존재 여부만 표시 했다.


먼저, SQL에서 다음과 같이 subquery를 이용하여 첨부 파일 개수를 세어준다.

해당 게시물의 글번호(TB.BRDNO)에 맞는 첨부 파일의 게시물 번호(BRDNO)를 맞는 개수를 세는 것이다.

<select id="selectBoard4List" resultType="gu.board4.boardVO" parameterType="gu.common.SearchVO">
        SELECT BRDNO, BRDTITLE, BRDWRITER, DATE_FORMAT(BRDDATE,'%Y-%m-%d') BRDDATE, BRDHIT
                  , (SELECT COUNT(*) FROM TBL_BOARDFILE WHERE BRDNO=TB.BRDNO) FILECNT
          FROM TBL_BOARD TB
         <include refid="includeBoard"/>
         ORDER BY BRDNO DESC
         LIMIT ${rowStart-1}, 10
    </select>

baord4.xml

subquery의 필드명을 filecnt로 지정하고 boardVO에 추가해 준다.

public class boardVO {

    private String brdno, brdtitle, brdwriter, brdmemo, brddate, brdhit, brddeleteflag
                     , filecnt;
    ~~ 생략 ~~
    public String getFilecnt() {
        return filecnt;
    }

    public void setFilecnt(String filecnt) {
        this.filecnt = filecnt;
    }

boardVO.java

마지막으로 jsp 파일에서 첨부 파일 개수(filecnt)를 보여주는 열을 다음과 추가하고 실행하여 결과를 확인하면 된다.

        <thead>
            <tr>
                <th>번호</th>
                <th>제목</th>
                <th>등록자</th>
                <th>등록일</th>
                <th>조회수</th>
                <th>첨부</th>
            </tr>
        </thead>
        <tbody>
            <c:forEach var="listview" items="${listview}" varStatus="status">   
                <c:url var="link" value="board4Read">
                    <c:param name="brdno" value="${listview.brdno}" />
                </c:url>       
                <tr>
                    <td><c:out value="${searchVO.totRow-((searchVO.page-1)*searchVO.displayRowCount + status.index)}"/></td>
                    <td><a href="${link}"><c:out value="${listview.getShortTitle(35)}"/></a></td>
                    <td><c:out value="${listview.brdwriter}"/></td>
                    <td><c:out value="${listview.brddate}"/></td>
                    <td><c:out value="${listview.brdhit}"/></td>
                    <td><c:out value="${listview.filecnt}"/></td>
                </tr>
            </c:forEach>
        </tbody>

boardList.jsp



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

1. 자료실 - 준비 & 시작  (1) 2016.04.02
2. 자료실 - 글쓰기  (0) 2016.03.28
3. 자료실 - 글 수정  (3) 2016.03.28
5. 자료실 - 글 읽기 / 삭제  (0) 2016.03.26

게시판을 운영하다 보면,

사용자가 글 내용을 입력할 때 텍스트박스(TextArea)로 입력하는 게 아니라 웹 에디터를 이용할 때가 많다.

즉, HTML 태그를 사용자가 입력하는 것이다.

하지만 현재의 코드에서는 사용자가 입력한 HTML 코드가 실행되지 않는다. 

글쓰기에서 글 내용에 “<B>테스트</B>”라고 입력한 후 저장해 보자.

글 읽기에서 확인해보면 입력한 내용이 그대로 출력되는 것을 알 수 있다.



사용자가 원하는 것은 굵게 표시된 글자일 것이다.

이렇게 출력되는 것은 Spring에서 HTML 실행을 막아놨기 때문이다.

다음과 같이 출력(out) 테그에 escapeXml="false"를 넣어주면 문제가 해결된다.

<tr>
    <td>내용</td>
    <td><c:out value="${boardInfo.brdmemo}" escapeXml="false"/></td>
</tr>

boardRead.jsp

하지만 이렇게 처리할 경우 악의적인 사용자에 의해 잘못된 스크립트가 삽입되어 실행되는 문제가 발생할 수 있다.

예로, 글쓰기에서 새로운 게시글을 하나 만들어 글 내용에 다음과 같이 입력해 보자.

<script>
    alert(“이게 실행되면 안 되는데”);
</script>

글 읽기로 확인해 보면 자바 스크립트가 실행되어 메시지 창이 나오는 것을 알 수 있다.



HTML은 실행하고 자바 스크립트는 실행하지 못하게 해야 한다.

따라서 <script>를 &lt;script>로 바꾸어 사용자가 입력한 프로그램 코드가 실행되지 않게 만들어 주면 된다.

개발자에 따라 사용자가 입력한 내용을 DB에 저장할 때 처리하기도 하고 보여 줄 때 처리하기도 한다. 

개인적 성향으로 다음과 같이 데이터를 불러와서 보여줄 때 처리하도록 했다.

public class boardVO {
    private String brdno, brdtitle, brdwriter, brdmemo, brddate, brdhit, brddeleteflag;
 ~~ 생략 ~~
    public void setBrdwriter(String brdwriter) {
        this.brdwriter = brdwriter;
    }

    public String getBrdmemo() {
        return brdmemo.replaceAll("(?i)<script", "&lt;script");
    }

boardVO.java






사용자가 게시글을 작성할 때 작성자명, 제목, 내용을 항상 입력해야 한다.

필수 입력이 되어야 하는 것이다.

모든 게시판들이 그런 것은 아니지만 본 예제는 모두 필수 입력이다.

즉, 사용자가 입력한 내용을 확인해서 내용이 있으면 서버로 보내서 저장하고,

그렇지 않으면 안내 메시지를 출력하고 입력하도록 해야 한다.



다음 코드와 같이 fn_formSubmit() 함수를 추가해 준다. 

3개의 필드를 필수로 했기 때문에 3개의 IF문이 사용되었다. 

form1은 폼테그의 이름(name)이고 폼 테그 내의 각 이름을 이용하여 값(value) 있는지 없는지 확인하고 있다.

focus메소드는 커서가 해당 입력상자에서 대기하도록 한다.

~~ 생략 ~~
<head>
<title>board3</title>
<script>
function fn_formSubmit(){
    var form1 = document.form1;
   
    if (form1.brdwriter.value=="") {
        alert("작성자를 입력해주세요.");
        form1.brdwriter.focus();
        return;
    }
    if (form1.brdtitle.value=="") {
        alert("글 제목을 입력해주세요.");
        form1.brdtitle.focus();
        return;
    }
    if (form1.brdmemo.value=="") {
        alert("글 내용을 입력해주세요.");
        form1.brdmemo.focus();
        return;
    }
    form1.submit();   
}
</script>
</head>
<body>
    ~~ 생략 ~~
        <a href="#" onclick="fn_formSubmit()">저장</a>
    </form>   
</body>
</html>

boardForm.jsp

저장 버튼도 기존에 바로 전송하도록(form1.submit()) 되어 있던 것을

코드와 같이 해당 함수에서 확인 후 처리 하도록 바꾸어 준다.


실제 사용에서는 사용자가 공백만 넣을 수도 있다.

따라서 길이를 비교하기 전에 공백을 제거하는 Trim 함수를 사용하면 좋다.

다만, 자바 스크립트의 기본 함수에는 없기 때문에 만들어 써야 한다. 

인터넷을 뒤져서 찾아보거나 패턴으로 만들어 보길 바라고,

차후 다룰 예정인 Jquery는 기본 함수로 제공되기 때문에 여기서는 넘어간다.


다음으로 글쓰기와 관련해서 수정해볼 내용은 board2에서 진행한 글쓰기와 수정을 하나의 컨트롤,

두 개의 서비스로 구현한 것을 다시 하나의 서비스로 구현해 보는 것이다. 

유사한 기능을 하는 서비스를 굳이 두 개로 사용하기 보다는

하나로 사용하는 것이 효율적이고 서비스 개념에도 맞는다고 생각한다.

다음과 같은 기존 코드에서 IF문을 서비스로 옮기면 된다.

@RequestMapping(value = "/board3Save")
public String boardSave(boardVO boardInfo) throws Exception {
    if (param.getBrdno()==null || "".equals(param.getBrdno()))
           boardSvc.insertBoard(boardInfo);
    else boardSvc.updateBoard(boardInfo);

    return "redirect:/board3List";
}

board3Ctr.java

public void insertBoard(boardVO param) throws Exception {
    if (param.getBrdno()==null || "".equals(param.getBrdno()))
           sqlSession.insert("insertBoard3", param);
    else sqlSession.update("updateBoard3", param);
}

board3Svc.java

마지막으로 위와 같이 수정했다면 updateBoard 서비스는 삭제해 준다.





+ Recent posts