앞서 만든 멀티 게시판은 게시판 그룹에 대한 관리 기능이 없기 때문에

1. 없는 그룹(게시판)에 대한 오류 처리가 되지 않는다. 즉, 그룹번호(bgno)를 무작위로 넣고 글쓰기를 해도 문제 없이 작동한다.

- 관리자에 의해 생성된 게시판만 사용하도록 해야 한다.

2. 각 게시판은 공지사항, 커뮤니케이션, Q&A 등 다양한 이름으로 제공되어야 하지만 하나의 이름(board)로 고정되어 있다.

3. 배경 이미지 변경, 댓글 기능 가능 여부 등 게시판별 다양한 옵션이 제공되어야 한다.

제대로 멀티 게시판을 사용하기 위해서는 이상의 기능들이 있어야 한다.

권한 관리 기능을 구현하지 않았기 때문에

이러한 기능을 관리자 페이지에서 지정할 순 없지만

별도의 페이지에서 설정하도록 구현하였다.


요약하면

하나의 게시판에 대한 정보를 가지고 있어야 한다는 것이다.

따라서, 게시판 그룹 정보를 저장하는 테이블을 생성하고

게시판 그룹 테이블에 정보(bgno)가 없으면 사용하지 못하도록 한다 ①.

게시판 그룹 테이블에 해당 게시판의 이름(BGNAME)을 저장하게 한다②.

이외에 게시판 사용여부(BGUSED, 삭제(BGDELETEFLAG)는

리스트에서 보이지 않지만 사용여부는 중지/사용을 반복할 수 있음),

댓글 기능 사용여부(BGREPLY),

공지사항을 위해 글쓰기 금지(BGREADONLY) 등의 옵션을 저장할 필드를 추가한다 ③.

따라서 다음과 같은 테이블 구조를 가지게 된다.

CREATE TABLE TBL_BOARDGROUP (
  BGNO INT(11) NOT NULL AUTO_INCREMENT,        -- 게시판 그룹번호
  BGNAME VARCHAR(50),                                    -- 게시판 그룹명
  BGPARENT INT(11),                                          -- 게시판 그룹 부모
  BGDELETEFLAG CHAR(1),                                 -- 삭제 여부
  BGUSED CHAR(1),                                           -- 사용 여부
  BGREPLY CHAR(1),                                          -- 댓글 사용여부
  BGREADONLY CHAR(1),                                    -- 글쓰기 가능 여부
  BGDATE DATETIME,                                          -- 생성일자
  PRIMARY KEY (BGNO)
);

추가적으로 게시판 그룹은 게시판 폴더라고도 부르는데

윈도우 폴더처럼 계층 구조를 가지기 때문이다.

부서별(부서 그룹)로 공지사항, 토론방 등의 게시판을 생성할 수 있고

동아리(그룹) 하위에 기타, 축구 등의 동아리를 하위로 생성하고

기타 동아리 하위에 공지사항, 토론방 등의 게시판을 생성할 수 있다.

따라서 계층 구조를 가지게 된다.

다만, 앞서 계층형 댓글(무한댓글) 에서 다른 것과 개념은 같지만 구현이 다르다.

계층형 댓글은 트리 형태의 웹 구현을 직접 구현했지만

게시판 그룹은 트리 라이브러리(dynatree)를 사용해서 구현할 것이고

부모만 표현하면 라이브러리에서 처리하기 때문에 다른 필드는 사용하지 않았다.


테이블(TBL_BOARDGROUP)을 생성했으면,

다음과 같이 BoardGroupVO를 작성한다.

public class BoardGroupVO {

    private String bgno, bgname, bglevel, bgparent, bgdeleteflag, bgused, bgreply, bgreadonly, bgdate;

    public String getBgno() {
        return bgno;
    }

    public void setBgno(String bgno) {
        this.bgno = bgno;
    }

    public String getBgname() {
    ~~ 생략 ~~

BoardGroupVO.java

모든 데이터 입출력은 게시판 응용이라는 것을 강조하기 위해

전혀 다를 것 같은 게시판 그룹 관리도 유사한 방식(함수명)으로 개발했다.

일단, BoardGroupCtr.java, BoardGroupSvc.java 두 개의 파일이 필요한데

소스 코드를 보면 컨트롤 명은 다르지만 실제 함수 명은 게시판과 동일하게 처리했다.

예로, 컨트롤 명 boardGroupList는 게시판 그룹 리스트를 처리하는 컨트롤이지만

함수는 boardList이다.

즉, 게시판 boardList를 수정해서 사용했다는 것으로

코드가 유사하다는 의미이다.

게시판만 만들 줄 알면 데이터 베이스를 기반으로 하는

대부분의 프로그램은 만들 수 있다는 말을 하기 위해서 이렇게 명명했다.


이외에 board8 컨트롤과 jsp도 복사해서 board9로 바꾸어 사용한다.

SQL은 그대로 사용한다.

게시판의 기능은 멀티 게시판(board8)에서 구현된 것을 그대로 사용하고

앞서 언급한 게시판 그룹의 3가지 핵심 기능을 간단하게 추가할 것이기 때문이다.













'Java > 게시판 9: 멀티 & 관리' 카테고리의 다른 글

2. 게시판 그룹 리스트  (2) 2016.08.14
3. 게시판 그룹 읽기 / 삭제  (0) 2016.08.14
4. 게시판 그룹 쓰기와 수정  (0) 2016.08.14
5. 게시판 적용  (0) 2016.08.14

게시판 그룹 리스트의 핵심은 데이터를 트리 구조로 표현하는 것이다.

즉, 리스트 기능을 표 형태가 아닌 트리 구조의 계층형으로 구현한다.

부서별 게시판들(공지사항, 토론방, QNA 등)로 구성하거나

하위 토론방을 주제별로 구분해서 사용할 수 있기 때문이다.

리스트를 트리로 구현하면서 신규, 읽기, 수정, 삭제를 하나의 페이지로 구현하고

신규, 읽기, 수정, 삭제가 발생할때 마다 트리를 매번 다시 생성하는 것은

비효율적이고 복잡해서

신규, 읽기, 수정, 삭제를 Ajax로 구현한다.


따라서 멀티 게시판 관리자 기능의 핵심은 트리 사용과 Ajax 활용이 된다.


개인적으로 사용해본 트리 라이브러리 중

dynatree가 무료(MIT) 중에서 가장 무난하다고 생각해서 사용한다.

자세한 사용법은 찾아보길 바라고 여기서는 관련된 내용만 다룬다.

http://wwwendt.de/tech/dynatree/doc/sample-select.html
http://jwgye.tistory.com/13

이외에 jstree나 bootstrap-treeview도 좋다고 생각한다.

    https://www.jstree.com/demo/
    https://github.com/jonmiles/bootstrap-treeview


다음 그림과 같이 트리 구조로 게시판 그룹이 있다고 하면

dynatree는 다음과 같이 JSON을 이용하여 트리 구조를 표현해서 넘겨만 주면 된다.

    {“key”: “1”, “title”: “공지사항”},
    {"key": "2", "title": "동아리", "isFolder": true,
        "children": [
            {"key": "3", "title": "기타"},
            {"key": "4", "title": "축구"}
            ]
        },
    {"key": "5", "title": "토론방"} 

Key는 그룹번호(bgno), title는 그룹 명(bgname)을 의미하고

2번 동아리는 자식(children)으로 기타(3)와 축구(4)를 가지는 트리 구조이다.

1과 5는 출력만 하면 된다.

이상과 같이 JSON 데이터를 생성하는 것이 트리 표현의 핵심인데

Java의 ObjectMapper를 이용하면 쉽게 처리할 수 있다.

ObjectMapper는 리스트(List)등의 구조체를 문자열로 변환하는 클래스인데

리스트의 항목이 클래스(VO)로 되어 있기 때문에

변환을 하면 JSON형태가 되게 된다.

클래스의 변수(메소드) 명이 JSON의 키로 생성되는 것이다.

변수의 값은 JSON의 키 값으로 생성된다.


따라서, 다음과 같이 TreeVO를 생성하면 쉽게 해결 된다.

dynatree에서 사용하는 key, title, isFolder, children로 클래스 멤버를 구성하고

데이터베이스에서 데이터를 가지고 올 때에도 이와 같이 가지고 오는 것이다.

public class TreeVO {
    private String key, title, parent;
    private boolean isFolder;
    private List children;
   
    public String getKey() {
        return key;
    }
    public void setKey(String key) {
        this.key = key;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    ~~ 생략 ~~

TreeVO.java

List로 지정된 children이 트리 변환의 핵심인데

ObjectMapper에 의해

List는 하위 JSON 집합으로 변환된다.


데이터 베이스에서 danatree의 JSON 키 생성구조(TreeVO)로 데이터 리스트를 조회하고

이 리스트를 계층 구조로 정리하고(children에 넣어주고)

ObjectMapper를 이용해서 JSON으로 변환하는 것이

게시판 그룹 리스트의 핵심 사항이다.


이 개념을 가지고 하나씩 구현해 본다.

먼저, 메인 페이지이자 게시판 그룹 리스트를 구현한다.

하나의 게시판 그룹이 추가될 때 마다

게시판 그룹 리스트 페이지를 새로 실행하고

게시판 그룹 트리를 다시 생성하는 것은 비효율적이고 직관성이 떨어져

이상의 그림과 같이

왼쪽에 리스트(트리), 오른쪽에는 입력/수정 화면이 하나로 묶어서 구현한다.

왼쪽의 트리에서 게시판을 선택하면

오른쪽에 해당 정보가 나오고 수정/삭제 할 수 있는 방식이다.

게시판에서는 각각의 화면이 다른 페이지로 있었지만

여기서는 모든 페이지가 하나에 구현된다.

따라서 Ajax가 많이 사용된다.


먼저, 게시판 그룹 리스트를 가지고 오는(selectBoardGroupList) 컨트롤을 작성한다.

@RequestMapping(value = "/boardGroupList")
public String boardList(ModelMap modelMap){
    List<?> listview   = boardSvc.selectBoardGroupList();

    TreeMaker tm = new TreeMaker();
    String treeStr = tm.makeTreeByHierarchy(listview);
   
    modelMap.addAttribute("treeStr", treeStr);
   
    return "board9/BoardGroupList";

BoardGroupCtr.java

public List<?> selectBoardGroupList(){
    return sqlSession.selectList("selectBoardGroupList");
}

BoardGroupSvc.java

<select id="selectBoardGroupList" resultType="gu.common.TreeVO" >
    SELECT BGNO 'KEY', BGNAME TITLE, BGPARENT PARENT
      FROM TBL_BOARDGROUP
     WHERE BGDELETEFLAG='N'
     ORDER BY BGNO 
</select> 

board9.xml

selectBoardGroupList를 이용해 가지고 온 데이터는

dynatree에 필요한 데이터 구조(KEY, TITLE)로 맞춘 TreeVO에 담겨 있다.

게시판 그룹의 부모(BGPARENT) 정보를 이용하여 계층 구조를 생성하게 된다.


Listview의 개수만큼(size) 하나씩(item=TreeVO) 반복하며

새로운 리스트(rootlist)에 하나씩 추가한다.

이때, 하나의 데이터(TreeVO)의 부모 정보(bgparent)가 NULL이 아니면

부모가 있다는 의미로

부모 데이터를 찾아서 (for ~~~ mtDO.getParent().equals(ptDO.getKey()))

children(List)에 내가 너의 자식이라고 추가(add)해 주는 방식으로 계층을 형성한다.

부모가 없는 경우는 최상위 노드(Root)를 의미하며

새로운 리스트(rootlist)에 추가하고 다음으로 넘어간다.

public class TreeMaker {
    public String makeTreeByHierarchy(List<?> listview){
        List<TreeVO> rootlist= new ArrayList<TreeVO>();
       
        for (Integer i=0; i<listview.size(); i++) {           
            TreeVO mtDO = (TreeVO)listview.get(i);           
           
            if (mtDO.getParent()==null) {
                rootlist.add(mtDO);
                continue;
            }   
             for (Integer j=0; j<listview.size(); j++) {
                 TreeVO ptDO = (TreeVO) listview.get(j);
                 if (mtDO.getParent().equals(ptDO.getKey())) {
                     if (ptDO.getChildren()==null) ptDO.setChildren(new ArrayList<Object>() );
                     List<TreeVO> a = ptDO.getChildren();
                     a.add(mtDO);
                     ptDO.setIsFolder(true);
                     break;
                 }
             }     
         }

        ObjectMapper mapper = new ObjectMapper();
        String str="";
        try {
            str = mapper.writeValueAsString(rootlist);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }

TreeMaker.java

계층 구조로 데이터가 정리되면

ObjectMapper로 JSON형태의 문자열로 변환하면 된다.

일반 리스트 데이터를 위와 같은 방식으로 변환하는 것은

자주 사용하는 것이라 common폴더에 생성하였다.

설명이 어려워서 이해되지 않는 경우

boardGroupList 컨트롤에서 사용하는 것처럼

makeTreeByHierarchy를 호출하는 것만 기억해도 된다.


이렇게 생성한 정보는 modelMap을 이용하여 JSP로 보낸다.

JSP 파일에서는 넘겨 받은 treeStr의 값을

다음과 같이 dynatree의 문법에 맞춰 넣어주면 트리가 생성된다.

#tree는 트리를 만들 대상 DIV의 ID이다.

$(function(){
    $("#tree").dynatree({
        children: <c:out value="${treeStr}" escapeXml="false"/>,
        onActivate: TreenodeActivate
    });
            fn_groupNew();
});
~~ 생략 ~~
<div id="tree"></div> 

BoardGroupList.jsp

Dynatree를 사용하기 위해서는

다음과 같이 CSS와 JS 파일을 포함해야 한다.

<link rel="stylesheet" href="js/dynatree/ui.dynatree.css" id="skinSheet"/>
<script src="js/jquery-2.2.3.min.js"></script>
<script src="js/jquery-ui.js"></script>
<script src="js/dynatree/jquery.dynatree.js"></script> 

BoardGroupList.jsp

Dynatree는 JQuery와 JQueryUI를 기반으로 제작되었기 때문에

위와 같이 JQuery도 지정해야 한다.


웹 페이지를 실행해 보면 이상의 그림과 같이 트리가 생성된 것을 볼 수 있다.

(데이터가 없어서 못 볼 수도 있다.)

onActivate는 트리의 노드가 선택되면 발생하는 이벤트로 

TreenodeActivate를 아직 구현하지 않아서 노드를 클릭하면 오류가 발생한다.











'Java > 게시판 9: 멀티 & 관리' 카테고리의 다른 글

1. 멀티게시판 관리자(그룹) 준비  (2) 2016.08.14
3. 게시판 그룹 읽기 / 삭제  (0) 2016.08.14
4. 게시판 그룹 쓰기와 수정  (0) 2016.08.14
5. 게시판 적용  (0) 2016.08.14

사용자가 트리의 노드를 선택하면

onActivate 이벤트에 지정된 TreenodeActivate함수가 실행된다.

파라메터로 사용자가 선택한 노드(node)가 넘어오고

전역변수(selectedNode)에 넣어서 다른 함수에서 사용할 수 있게 했다.

selectedNode(node).data.key는 TreeVO 구성시 key를 의미하고

그룹번호(bgno)가 저장되어 있다.

이 값(key== bgno)을 파라메터로

게시판 그룹 정보 읽기 컨트롤(boardGroupRead)을 호출한다.

콜백 함수는 receiveData로 반환에 성공하면

지정된 그룹번호(bgno)에 해당하는 데이터가 JSON 형태로 반환된다(receiveData).

Function TreenodeActivate(node) {
    selectedNode = node;
   
    if (selectedNode==null || selectedNode.data.key==0) return;
    $.ajax({
        url: "boardGroupRead",
        cache: false,
        data: { bgno : selectedNode.data.key }       
    }).done(receiveData);
}

function receiveData(data){
    $("#bgno").val(data.bgno);
    $("#bgname").val(data.bgname);
    $('input:radio[name="bgused"][value="' + data.bgused + '"]').prop('checked', true);
    $('input:radio[name="bgreadonly"][value="' + data.bgreadonly + '"]').prop('checked', true);
    $('input:radio[name="bgreply"][value="' + data.bgreply + '"]').prop('checked', true);
}

BoardGroupList.jsp

수신된 데이터(receiveData)는 JQuery 적당하게 값을 설정하면 된다.

코드가 복잡하게 보이는 것은

Radio를 ID가 아닌 Name으로 접근해서 그렇다.

게시판 사용여부(BGUSED), 댓글 기능 사용여부(BGREPLY), 글쓰기 금지(BGREADONLY) 는 Y/N로 저장되고

Radio의 선택여부에 따라서 Y/N으로 설정하면 된다.


사용된 HTML 코드를 보면

사용여부의 경우 name은 bgused이고 ID는 bgusedY와 bgusedN인 두 개의 radio가 있다.

각각은 Label이 사용/사용중지로 되어 있으며

Label의 for 속성이 bgusedY와 bgusedN를 가리킨다.

이것은 작은 radio를 선택할 수도 있고

글자를 표현한 Label를 선택해도 해당(for) radio를 선택하게 하기 위한 것이다.

따라서 radio의 ID가 달라야 한다.

댓글 기능 사용여부(BGREPLY), 글쓰기 금지(BGREADONLY)도 동일한 방식으로 구현하였다.

 <tr>
    <th>사용여부</th>
    <td>
        <input name="bgused" id="bgusedY" type="radio" checked="checked" value="Y"><label for="bgusedY">사용</label>
        <input name="bgused" id="bgusedN" type="radio" value="N"><label for="bgusedN">사용중지</label>
    </td>
</tr>
<tr>
    <th>등록가능</th>
    <td>
        <input name="bgreadonly" id="bgreadonlyN" type="radio" checked="checked" value="N"><label for="bgreadonlyN">사용</label>
        <input name="bgreadonly" id="bgreadonlyY" type="radio" value="Y"><label for="bgreadonlyY">사용안함</label>
    </td>
</tr>
<tr>
    <th>댓글</th>
    <td>
        <input name="bgreply" id="bgreplyY" type="radio" checked="checked" value="Y"><label for="bgreplyY">사용</label>
        <input name="bgreply" id="bgreplyN" type="radio" value="N"><label for="bgreplyN">사용안함</label>
    </td>
</tr>

BoardGroupList.jsp

JQuery는 ID를 이용하여 쉽게 사용할 수 있는데 ($(“bgused"]))

이상의 내용 때문에 다음과 같이 Name을 사용해야 한다.

$('input:radio[name="bgused"])


receiveData에서 다소 복잡해 보이는 다음의 코드는

이름(name)이 그룹번호(bgused)인 태그 중에서

값(value)이 Y/N인 태그의 체크(checked) 속성(prop)을 true로 설정하여

선택된 모습으로 출력해 주는 것이다.

    $('input:radio[name="bgused"][value="' + data.bgused + '"]').prop('checked', true);
    $('input:radio[name="bgreadonly"][value="' + data.bgreadonly + '"]').prop('checked', true);
    $('input:radio[name="bgreply"][value="' + data.bgreply + '"]').prop('checked', true);

JQuery가 복잡해 보일 뿐

컨트롤과 서비스, SQL문은 게시판과 동일하다.

컨트롤에서 BoardGroupVO로 받아온 그룹 정보(bgInfo)를

ObjectMapper를 이용하여 JSON으로 변환하여 전송하는 것이 다르다.

       @RequestMapping(value = "/boardGroupRead")
       public void boardRead(HttpServletRequest request, HttpServletResponse response){
       
        String bgno = request.getParameter("bgno");
       
        BoardGroupVO bgInfo = boardSvc.selectBoardGroupOne(bgno);
       
        ObjectMapper mapper = new ObjectMapper();
        response.setContentType("application/json;charset=UTF-8");
       
        try {
            response.getWriter().print( mapper.writeValueAsString(bgInfo));
        } catch (IOException ex) {
             System.out.println("오류: 게시판 그룹에 문제가 발생했습니다.");
        }
    } 

BoardGroupCtr.java

public BoardGroupVO selectBoardGroupOne(String param){
        return sqlSession.selectOne("selectBoardGroupOne", param);

BoardGroupSvc.java

<select id="selectBoardGroupOne" parameterType="String" resultType="gu.board9.BoardGroupVO">
        SELECT BGNO, BGNAME, BGUSED, BGREPLY, BGREADONLY
          FROM TBL_BOARDGROUP
         WHERE BGDELETEFLAG='N' AND BGNO=#{bgno}
 </select>

board9.xml

삭제(fn_groupDelete)는 지정된 트리 노드의 값(key, bgno)을

Ajax로 서버로 보내(boardGroupDelete)서 삭제하고

적절한 메시지를 출력해 주면 된다.

그리고, 트리에서 현재 선택된 노드를 제거하고(remove)

선택되면서 출력된 값들을 지워준다.

유사한 코드로 구성되어 상세한 설명을 생략한다.



'Java > 게시판 9: 멀티 & 관리' 카테고리의 다른 글

1. 멀티게시판 관리자(그룹) 준비  (2) 2016.08.14
2. 게시판 그룹 리스트  (2) 2016.08.14
4. 게시판 그룹 쓰기와 수정  (0) 2016.08.14
5. 게시판 적용  (0) 2016.08.14

게시판 그룹 쓰기/수정은 게시판 새 글 쓰기/수정과 동일하다.

사용자가 입력한 값을 받아서

새 번호(그룹 - bgno)를 부여하고 INSERT 문을 실행하거나

그룹 번호가 있으면 UPDATE문으로 수정하면 된다.

다만, 댓글처럼 Ajax로 처리하기 때문에

JavaScript가 많이 사용된다.

더욱이 HTML Radio를 사용하면서

작성해야 하는 코드가 조금 더 많아져 복잡해 보인다.


다음 코드를 보면 일반적인 Ajax 사용과 같다.

function fn_groupSave(){
    if($("#bgname").val() == ""){
        alert("게시판 이름을 입력해주세요.");
        return;
    }
    var bgno =null;
    if (selectedNode!=null) bgno =selectedNode.data.key;

    if (!confirm("저장하시겠습니까?")) return;

    $.ajax({
        url: "boardGroupSave",
        cache: false,
        type: "POST",
        data: { bgno:$("#bgno").val(), bgname:$("#bgname").val(), bgparent: bgno,
                bgused : $("input:radio[name=bgused]:checked").val(),
                bgreadonly : $("input:radio[name=bgreadonly]:checked").val(),
                bgreply : $("input:radio[name=bgreply]:checked").val()}       
    }).done(receiveData4Save);

BoardGroupList.jsp

selectedNode는 트리의 노드가 선택되면 발생하는 이벤트(onActivate)에서

선택된 노드를 가지고 있도록 한 전역변수이다.

따라서, selectedNode에 값이 있으면

게시판 그룹 수정이고(bgno 값 존재), 없으면 신규가 된다.

사용자가 노드를 선택하면

선택한 노드가 selectedNode에 지정되고

입력상자(input)의 ID가 bgno에도 값이 저장된다.

저장할 데이터를 구성하여 boardGroupSave를 호출하면

게시판과 유사한 다음 SQL문으로 저장하게 된다.


<insert id="insertBoardGroup" parameterType="gu.board9.BoardGroupVO" >
    <selectKey resultType="String" keyProperty="bgno" order="BEFORE">
        SELECT IFNULL(MAX(BGNO),0)+1 FROM TBL_BOARDGROUP
    </selectKey>   
    INSERT INTO TBL_BOARDGROUP(BGNO, BGNAME, BGUSED, BGREPLY, BGREADONLY, BGPARENT, BGDELETEFLAG, BGDATE)
    VALUES (#{bgno}, #{bgname}, #{bgused}, #{bgreply}, #{bgreadonly}, #{bgparent}, 'N', NOW() )
</insert>


<update id="updateBoardGroup" parameterType="gu.board9.BoardGroupVO">
    UPDATE TBL_BOARDGROUP
       SET BGNAME=#{bgname}, BGUSED=#{bgused}, BGREPLY=#{bgreply}, BGREADONLY=#{bgreadonly}
     WHERE BGNO=#{bgno}
</update>  

board9.xml

SQL문은 별도의 이름을 부여했지만

서비스(DTO)의 이름은 게시판 글쓰기/수정과 이름이 같다(insertBoard).

insertBoard에서는 게시판과 같이 그룹번호(bgno) 값이

없으면 신규 등록 (INSERT)

있으면 수정(UPDATE)을 실행한다.

    public void insertBoard(BoardGroupVO param){
        if ("".equals(param.getBgparent())) param.setBgparent(null);
           
        if (param.getBgno()==null || "".equals(param.getBgno()))
             sqlSession.insert("insertBoardGroup", param);
        else sqlSession.insert("updateBoardGroup", param);
    } 

BoardGroupSvc.java

이렇게 처리한 뒤 컨드롤(boardGroupSave)에서는

Json 형태(ObjectMapper)로 저장한 그룹 정보를 반환한다(bgInfo).

신규일경우는 MyBatis가 글번호를 반환 받아서 bgInfo에 저장해서 반환한다(selectKey).

     @RequestMapping(value = "/boardGroupSave")
       public void boardSave(HttpServletResponse response, BoardGroupVO bgInfo){
        
        boardSvc.insertBoard(bgInfo);
        
        ObjectMapper mapper = new ObjectMapper();
        response.setContentType("application/json;charset=UTF-8");
        
        try {
            response.getWriter().print( mapper.writeValueAsString(bgInfo));
        } catch (IOException ex) {
             System.out.println("오류: 게시판 그룹에 문제가 발생했습니다.");
        }
    }

BoardGroupCtr.java

컨트롤이 반환한 정보(bgInfo)는

클라이언트에서 Ajax 호출시 지정된 receiveData4Save 함수에 파라메타(data)로 넘겨 진다.

선택된 노드(selectedNode)가 있거나(!==null),

선택된 노드의 수정이면(선택된 노드와 반환된 데이터의 키 값이 같으면)

선택된 노드의 제목이 수정될수 있어서 무조건 수정해준다.

IF문 처리를 해도 되지만 간단한 데이터 변경이라 무조건 하도록 했다.

function receiveData4Save(data){
    if (selectedNode!==null && selectedNode.data.key===data.bgno) {
        selectedNode.data.title=data.bgname;
        selectedNode.render();
    } else {
        addNode(data.bgno, data.bgname);
    }
   
    alert("저장되었습니다.");

BoardGroupList.jsp

수정이 아닌 경우

즉, 최상위 노드에 추가(선택 노드 없음, selectedNode===null)하거나

선택노드의 자식 노드를 추가할 경우

(선택노드와 반환된 데이터 키 값이 다르면, selectedNode.data.key!==data.bgno)

새로운 노드를 생성해서 추가해 준다 (addNode).


addNode함수의 내용은 다음과 같다.

dynatree의 사용법으로 별도의 설명을 하지 않으니 찾아보길 바라고

선탠된 노드($("#tree").dynatree("getActiveNode"))가 있으면

자식으로 추가하고

없으면 최상위($("#tree").dynatree("getRoot"))에 추가한다.

function addNode(nodeNo, nodeTitle){
    var node = $("#tree").dynatree("getActiveNode");
    if (!node) node = $("#tree").dynatree("getRoot");
    var childNode = node.addChild({key: nodeNo, title: nodeTitle});
    node.expand() ;
    node.data.isFolder=true;
    node.tree.redraw();

BoardGroupList.jsp










'Java > 게시판 9: 멀티 & 관리' 카테고리의 다른 글

1. 멀티게시판 관리자(그룹) 준비  (2) 2016.08.14
2. 게시판 그룹 리스트  (2) 2016.08.14
3. 게시판 그룹 읽기 / 삭제  (0) 2016.08.14
5. 게시판 적용  (0) 2016.08.14

웹 페이지(JSP파일)가 존재하는

리스트(board9List), 글쓰기(board9Form), 글읽기(board9Read) 컨트롤(Board9Ctr.java)에

다음 코드를 각각 넣어줘야 한다.

        BoardGroupVO bgInfo = boardGroupSvc.selectBoardGroupOne4Used(boardInfo.getBgno());
        if (bgInfo==null) return "board9/BoardGroupFail";
        
        ~~ 생략 ~~
        modelMap.addAttribute("bgInfo", bgInfo);

Board9Ctr.java

게시판 그룹 번호(getBgno)에 대한 정보를 찾아보고(selectBoardGroupOne4Used)

관리자에서 등록된 정보가 없으면(bgInfo==null)

오류 페이지(BoardGroupFail)를 보여주고 종료한다.

정보가 있는 경우  modelMap에 넣어서 적절한 웹 페이지로 넘겨준다.


그룹 번호에 해당하는 정보를 찾는 SQL문은 다음과 같고

삭제(BGDELETEFLAG)되지 않고, 사용가능(BGREPLY)으로 지정된 데이터를 

조회하게 구성한다.

    <select id="selectBoardGroupOne4Used" parameterType="String" resultType="gu.board9.BoardGroupVO">
        SELECT BGNO, BGNAME, BGUSED, BGREPLY, BGREADONLY
          FROM TBL_BOARDGROUP
         WHERE BGDELETEFLAG='N' AND BGNO=#{bgno} AND BGUSED='Y'
    </select>  

board9.xml

모든 게시판 페이지(JSP)에는 게시판 이름(bgname)을 보여주는 다음 코드를 넣어줘야 한다.

    <h1><c:out value="${bgInfo.bgname}"/></h1>

마지막으로

게시판 그룹 관리자에서 지정된 설정(등록가능, 댓글)에 따라

게시판이 운영되도록 해야 한다.


리스트에는 기존의 글쓰기 버튼에 다음 코드를 추가해 준다.


    <c:if test="${bgInfo.bgreadonly=='N'}">
        <a href="board9Form?bgno=<c:out value="${searchVO.bgno}"/>">글쓰기</a>
    </c:if> 

BoardList.jsp

관리 기능에서 [등록가능 (bgreadonly)]이 설정되면(Y)

글쓰기 링크가 활성화 되는 코드를 넣어준다.

기존 코드에 IF문을 넣어서 구현하였다.

제대로 구현하기 위해서는 board9Save 컨트롤에서도 구현할 것이 있지만

이정도 수준에서 처리하고 넘어간다.


[댓글 (bgreply)] 기능 사용여부도 기존 코드에 IF문을 넣어서 처리한다.

<c:if test="${bgInfo.bgreply=='Y'}">
    <div style="border: 1px solid; width: 600px; padding: 5px">
        <form id="form1" name="form1">
            <input type="hidden" id="brdno1" name="brdno" value="<c:out value="${boardInfo.brdno}"/>">
            작성자: <input type="text" id="rewriter1" name="rewriter" size="20" maxlength="20"> <br/>
            <textarea id="rememo1" name="rememo" rows="3" cols="60" maxlength="500" placeholder="댓글을 달아주세요."></textarea>
            <a href="#" onclick="fn_formSubmit()">저장</a>
        </form>
    </div>
</c:if> 

BoardList.jsp

댓글 모든 기능에 IF문을 넣는게 아니고

게시물에 대한 첫 댓글 작성 부문을 보이지 않게 해서 댓글을 작성할 수 없도록했다.

좀더 제대로 구현하려면 컨트롤 처리도 필요하고

댓글 리스트(replyList)도 보이지 않게 하면 된다.


그림과 같이 웹 브라우저에서 접속해 보면 

http://localhost:8080/board/board9List?bgno=2로 접속하면

공지사항이란 게시판 제목이 출력되고

http://localhost:8080/board/board9List?bgno=3으로 접속하면

일반게시판이라는 제목이 출력된다.

또, 공지사항은 글쓰기 버튼이 보이지 않고

일반 게시판은 글쓰기 버튼이 보인다.


글쓰기, 글읽기에서도 적용된 내용을 확인해 보길 바란다.


+ Recent posts