티스토리 뷰

- DB

create table study_bbs.article
(
    `index`       int unsigned   not null auto_increment,
    `user_email`  varchar(50)    not null,
    `board_id`    varchar(10)    not null,
    `title`       varchar(100)   not null,
    `content`     varchar(10000) not null,
    `view`        int unsigned   not null default 0,
    `written_on`  datetime       not null default now(),
    `modified_on` datetime       not null default now(),
    constraint primary key (`index`),
    constraint foreign key (`user_email`) references study_member.users (`email`)
        on delete cascade
        on update cascade,
    constraint foreign key (`board_id`) references study_bbs.boards (`id`)
        on delete cascade
        on update cascade
);

- BbsMapper.xml

<insert id="insertBoard"
        useGeneratedKeys="true"
        keyColumn="index"
        keyProperty="index"
        parameterType="dev.shlee.studymemberbbs.entities.bbs.ArticleEntity">
    INSERT INTO `study_bbs`.`articles` (`user_email`, `board_id`, `title`, `content`)
    VALUES (#{userEmail}, #{boardId}, #{title}, #{content})
</insert>

게시글을 등록하기 위해서 insert가 필요하다. 그러므로 xml에서 insert부분을 만들어 준다. view, written-on, modified_od은 default값이 있기 때문에 선택하지 않고 userEmail, boardId, title, content만 insert해준다.


- IBbsmMapper.interface

int insertBoard(ArticleEntity articleEntity);

Insert를 사용하기 위해 interface를 추가해 준다. 


- BbsService

@Transactional
public Enum<? extends IResult> addArticle(ArticleEntity article, UserEntity user, String bid) {

    if (article == null) {
        return CommonResult.FAILURE;
    }
    article.setUserEmail(user.getEmail());
    article.setBoardId(bid);
    this.bbsMapper.insertBoard(article);
    return CommonResult.SUCCESS;
}

title, content을 가져오기 위해 매개변수로 ArticleEntity article을 넣어준다.

또한, user의 이메일을 가져오고 주소에 있는 bid값을 가져오기 위해 매배변수로 같이 추가해준다.

 

만약 article일 null 값이면 값이 없다는 것이기에 FAILURE을 돌려준다.

 

그 후, userEntity에 있는 user 이메일을 가져와서 업데이트,

bid값을 가져와서 업데이트,

xml에서 만들었던 article 값을 가져와 틀을 만들어 주고,

SUCCESS 값을 리턴한다. 


- BbsController

@RequestMapping(value = "/write",
        method = RequestMethod.POST,
        produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody // 문자열 그대로 나온다.
public String postArticle(@SessionAttribute(value = "user", required = false) UserEntity user,
                          @RequestParam(value = "bid", required = false) String bid,
                          ArticleEntity article) {

    Enum<?> result = this.bbsService.addArticle(article, user, bid);
    JSONObject responseObject = new JSONObject();
    responseObject.put("result", result.name().toLowerCase());
    if (result == CommonResult.SUCCESS) {
        System.out.println(article);
    }
    return responseObject.toString();
}

컨트롤러에서 실제 값들을 가져 오기 위해 @SessionAttribute(value = "user", required = false) UserEntity user를 통해 로그인 되었던 User의 정보를 가져오고, @RequestParam(value = "bid", required = false)를 통해 bid 값을 가져온다.

또한, title과 content를 가져와야 하므로 ArticleEntity article도 매개변수로 추가해준다.

쉽게 생각한다면 BbsService에서 만들었던 틀을 Controller를 통해 값을 다 가져온다고 생각하면 된다. 

 

result에 article, user, bid 값을 넣어주고 만약 result가 성공이라면 article을 출력이 된다. 

 

 


- Write.js

 form.onsubmit = (e) => {
        e.preventDefault();
        Warning.hide();
        const xhr = new XMLHttpRequest();
        const formData = new FormData();
        formData.append('title', form['title'].value);
        formData.append('content', form['content'].value);
        xhr.open('POST', './write?bid=' + form['bid'].value);
        xhr.onreadystatechange = () => {
            if (xhr.readyState === XMLHttpRequest.DONE) {
                Cover.hide();
                if (xhr.status >= 200 && xhr.status < 300) {
                    const responseObject = JSON.parse(xhr.responseText);
                    switch (responseObject['result']) {
                        case'success':
                            window.alert('작성 성공.')
                            break;
                        case'failure':
                            alert('작성 실패.')
                            break;
                        default:
                            Warning.show('잠시만 기다려주세요');
                    }
                }
            }
        };
        xhr.send(formData);
    };
}

title, content를 가져오기 위해 append를 해주고 xhr.open을 통해 POST에서 .write?=bid= + form['bid'].value 해주면 write?bid=notice 이러한 형태로 주소값을 불러올 수 있게 된다. 


Teacher Version

 

- IBbsmMapper.interface

int insertArticle(ArticleEntity article);

- BbsService

@Transactional
public Enum<? extends IResult> write(ArticleEntity article) {
    BoardEntity board = this.bbsMapper.selectBoardById(article.getBoardId());

    if (board == null) {
        return WriteResult.NO_SUCH_BOARD;
    }
    return this.bbsMapper.insertArticle(article) > 0
            ? CommonResult.SUCCESS
            : CommonResult.FAILURE;
}

- BbsController

@RequestMapping(value = "/write",
        method = RequestMethod.POST,
        produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody // 문자열 그대로 나온다.
public String postArticle(@SessionAttribute(value = "user", required = false) UserEntity user,
                          @RequestParam(value = "bid", required = false) String bid,
                          ArticleEntity article) {

    Enum<?> result;
    if (user == null) {
        result = WriteResult.NOT_ALLOWED;
    } else if (bid == null) {
        result = WriteResult.NO_SUCH_BOARD;
    } else {
        article.setUserEmail(user.getEmail());
        article.setBoardId(bid);
        result = this.bbsService.write(article);
    }
    JSONObject responseObject = new JSONObject();
    responseObject.put("result", result.name().toLowerCase());
    if (result == CommonResult.SUCCESS) {
        responseObject.put("index", article.getIndex());
    }
    return responseObject.toString();
}

- write.html

<input name="bid" type="hidden" th:value="${bid}">

- Write.js

 Cover.show('게시글을 작성하고 있습니다.\n잠시만 기다려 주세요.');
    const xhr = new XMLHttpRequest();
    const formData = new FormData();
    formData.append('bid', form['bid'].value);
    formData.append('title', form['title'].value);
    formData.append('content', form['content'].value);
    // formData.append('index', form['index'].value);
    // xhr.open('POST', window.location.href);
    xhr.open('POST', './write');
    xhr.onreadystatechange = () => {
        if (xhr.readyState === XMLHttpRequest.DONE) {
            Cover.hide();
            if (xhr.status >= 200 && xhr.status < 300) {
                const responseObject = JSON.parse(xhr.responseText);
                switch (responseObject['result']) {
                    case'not_allowed':
                        Warning.show('게시글을 작성할 수 있는 권한이 없거나 로그아웃되었습나다. 확인 후 다시 시도해 주세요.');
                        break;
                    case'success':
                        alert('작성되었습니다.');
                        window.location.href = 'http://localhost:8080/bbs/read?aid=' + responseObject['index'];
                        break;
                    default:
                        Warning.show('알 수 없는 이유로 게시글을 작성하지 못하였습니다. 잠시 후 다시 시도해 주새요.');
                }
            } else {
                Warning.show('서버와 통신하지 못하였습니다. 잠시 후 다시 시도해 주세요.');
            }
        }
    };
    xhr.send(formData);
}

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
글 보관함