주말에 지방에 잠시다녀와 해산물을 좀 먹었더니 ㅠㅠ 장염에 걸려 조금 늦게 올렸습니다. ~ 

오늘은 아주 기본적인 게시판(공지사항) 만들기에대해 작성하겠습니다.


우선 게시판 폼을 디자인합니다~

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<title>boardList</title>
</head>
<body>
<div class="page-wrapper">
    <div class="container-fluid">
        <div class="col-lg-8"><!--게시판 넓이 -->
            <div class="col-lg-12">
                <h1 class="page-header">공지사항 관리</h1>
            </div>
            <div class="row">
                  <div class="col-lg-12">
                      <button type="button" class="btn btn-outline btn-primary pull-right">
                          <i class="fa fa-edit fa-fw"></i> 공지사항 작성
                      </button>
                  </div>
              </div>
            <div class="panel panel-default">
                <div class="panel-heading">공지사항 </div>
                <div class="panel-body">
                    <table class="table table-hover">
                        <thead>
                            <tr>
                                <th>No.1</th>
                                <th>제목</th>
                                <th>작성자</th>
                                <th>작성일</th>
                                <th>조회수</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td>1</td>
                                <td>제목</td>
                                <td>작성자</td>
                                <td>작성일</td>
                                <td>조회수</td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
</html>
cs


VO


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//pk
    private Integer nno;
    //  제목
    private String ntitle;
    //  내용
    private String ncontent;
    //  작성자
    private String nwriter;
    //  작성일
    private Date nrdate;
    //  조회수
    private Integer nviewcnt;
    //  삭제여부
    private String nisdelete;
 
getter/setter ...
 
 
cs

저같은 경우에는 nrdate를 Date 타입으로 받았습니다.

이럴경우 

작성일 타입이 저렇게 출력이 됩니다 . 정상적으로 2018-02-13 21:04 이런식으로 출력하기 위해서는 

화변단에서 패턴을 사용해서 처리해야합니다.


1
2
3
4
5
6
7
8
9
10
11
12
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
//jstl 추가
 
 <c:forEach items="${list}" var="boardVO">
    <tr>
      <td>${boardVO.nno}</td>
      <td>${boardVO.ntitle}</td>
      <td>${boardVO.nwriter}</td>
      <td><fmt:formatDate pattern="yyyy-MM-dd HH:mm" value="${boardVO.nrdate}"/></td>
      <td>${boardVO.nviewcnt}</td>
     </tr>
</c:forEach>
cs

JSTL을 추가하고 fmt:formDate pattern을 사용해서 출력해야만 정상적으로 출력이 됩니다. 

또다른 방법은 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
//pk
    private Integer nno;
    //  제목
    private String ntitle;
    //  내용
    private String ncontent;
    //  작성자
    private String nwriter;
    //  작성일
    private String nrdate;
    //  조회수
    private Integer nviewcnt;
    //  삭제여부
    private String nisdelete;
cs

nrdate를 String 타입으로 바꾸고 쿼리에서 처리하는 방법입니다.


1
2
3
4
SELECT
    nno,ntitle,ncontent,nwriter,date_format(nrdate,'%Y-%m-%d') nrdate,nviewcnt,nisdelete
FROM 
    tbl_notice
cs


date_format(nrdate,'%Y-%m-%d') nrdate 이렇게 쿼리에서 처리하는 방법또한 있으니 상황에 맞게 쓰시면 됩니다.


Controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Controller
@RequestMapping("/board/*")
public class BoardCotroller {
    
    @Inject
    private BoardService service;
 
    @RequestMapping(value="/boardList.do", method=RequestMethod.GET)
    public String boardList(BoardVO boardVO, Model model) {
        
        List<BoardVO> list = service.boardList(boardVO);
        model.addAttribute("list", list);
        
        return "board/boardlist";
    }
    
cs

리스트에 넣어서 화면으로 날려주고



Service


1
2
3
4
5
public interface BoardService {
    //게시판 리스트
    public List<BoardVO> boardList(BoardVO boardVO);
 
}
cs

ServiceImpl

1
2
3
4
5
6
7
8
9
10
@Service
public class BoardServiceImpl implements BoardService{
 
    @Inject
    private BoardDAO dao;
 
    @Override
    public List<BoardVO> boardList(BoardVO boardVO) {
        return dao.boardList(boardVO);
    }
cs


DAO

1
2
3
4
5
6
 
public interface BoardDAO {
    //게시판 리스트
    public List<BoardVO> boardList(BoardVO boardVO);
 
}
cs


DAOImpl

1
2
3
4
5
6
7
8
9
10
11
@Repository
public class BoardDAOImpl implements BoardDAO{
 
    @Inject
    private SqlSession session;
 
    @Override
    public List<BoardVO> boardList(BoardVO boardVO) {
        return session.selectList("boardList",boardVO);
    }
 
cs


BoardMapper


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
 
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  
<mapper namespace="board">
    
        <select id="boardList" resultType="com.sjh.board.BoardVO">
            SELECT
                 nno,ntitle,ncontent,nwriter,nrdate,nviewcnt,nisdelete
             FROM
                  tbl_notice
        </select>
        
      
</mapper>
cs


JSP 수정

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c"      uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<title>boardList</title>
</head>
<body>
<div class="page-wrapper">
    <div class="container-fluid">
        <div class="col-lg-8"><!--게시판 넓이 -->
            <div class="col-lg-12">
                <h1 class="page-header">공지사항 관리</h1>
            </div>
            <div class="row">
                  <div class="col-lg-12">
                      <button type="button" class="btn btn-outline btn-primary pull-right">
                          <class="fa fa-edit fa-fw"></i> 공지사항 작성
                      </button>
                  </div>
              </div>
            <div class="panel panel-default">
                <div class="panel-heading">공지사항 </div>
                <div class="panel-body">
                    <table class="table table-hover">
                        <thead>
                            <tr>
                                <th>No.1</th>
                                <th>제목</th>
                                <th>작성자</th>
                                <th>작성일</th>
                                <th>조회수</th>
                            </tr>
                        </thead>
                        <tbody>
                        <c:forEach items="${list}" var="boardVO">
                            <tr>
                                <td>${boardVO.nno}</td>
                                <td>${boardVO.ntitle}</td>
                                <td>${boardVO.nwriter}</td>
                                <td><fmt:formatDate pattern="yyyy-MM-dd HH:mm" value="${boardVO.nrdate}"/></td>
                                <td>${boardVO.nviewcnt}</td>
                            </tr>
                        </c:forEach>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
</html>
cs


MVC를 기본적으로 이해하고 계시다면 어렵지 않은 부분입니다.

 model.addAttribute("list", list);분 DB에서 불러온 리스트를 모델에 넣어 jsp로 넘겨주고 JSP단에서는

JSTL을 forEach를 활용해서 리스트로 뿌져줬습니다.

JSTL을 사용하시기 위해서

<%@ taglib prefix="c"      uri="http://java.sun.com/jsp/jstl/core" %>  상단에 써주셔야합니다


아직 공지사항 작성을 하지 않았으니 임시로 데이터를 넣겠습니다

1
2
3
4
5
 INSERT INTO tbl_notice(ntitle,ncontent,nwriter    )
 values('반갑습니다 ','많은 이용 바랍니다.','관리자');
  
INSERT INTO tbl_notice(ntitle,ncontent,nwriter    )
values('공지사항 테스트 입니다 ','잘부탁드립니다.','관리자');
cs



서버를 재시작하여 확인하면 !!! 잘 출력됩니다.  조회수는 아직 처리하지 않았습니다. 다음 포스팅에서는 

조회수 처리와 공지사항 작성에대해 올리겠습니다.~


저도 Ajax는 아직 완벽하게 이해한게 아니라 시간이 좀 걸렸네요 ㅠㅠ 400에러 404에러 415에러 500에러 

안본게 없네요 ㅎㅎ


부족하더라도 정리해보겠습니다. ~


우선 동기와 비동기 방식이 있는데 음.. 

이해하기 쉽게 설명드리자면 .. 음 동기는 이어달리기 ? 비동기는 그냥 달리기 시합 이라고 생각하시면 

쉬울것같아요 

동기방식은 요청이 들어오면 응답을 받기전까지 다음 요청을 처리하지 않습니다. 

이어달리기에서 바톤을 받아야 다음 주자가 뛸 수 있는것과 비슷하죠 ??ㅎㅎㅎ

비동기는 그냥 달리기 시합과 같습니다 ~

그냥 다같이 뛰는거죠 먼져 도착한사람이 먼져 응답을 주는 식? 이렇게 하면 이해가 쉽겟죠 ?

흔한 예제에서는 

은행 업무를 많이 들고 있습니다.  

나의 잔고가 10만원인데 . 친구에게 10만원을 입금해줍니다. 그런데 중간에 자동이체로 후르륵 빠져나가면

큰일 나겠죠 ? 그래서 이럴땐 10만원이 이체완료 후에 자동이체가 진행되는 동기 방식을 쓰는거죠 

비동기는 엄청나게 매력적이에요 node.js를 잠깐 해봤는데 단일 페이지에서 이것저것 하는것은 

사용자로 하여금 엄청나게 매력을 줍니다 ㅠㅠ 하지만 저는 이게 왜이렇게 어려운지 한번만 이해하면 쉽다고하는데

ㅠㅠ 각설하고 코드로 설명드리겠습니다.


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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<script type="text/javascript">
//아이디 체크여부 확인 (아이디 중복일 경우 = 0 , 중복이 아닐경우 = 1 )
var idck = 0;
$(function() {
    //idck 버튼을 클릭했을 때 
    $("#idck").click(function() {
        
        //userid 를 param.
        var userid =  $("#userid").val(); 
        
        $.ajax({
            async: true,
            type : 'POST',
            data : userid,
            url : "idcheck.do",
            dataType : "json",
            contentType: "application/json; charset=UTF-8",
            success : function(data) {
                if (data.cnt > 0) {
                    
                    alert("아이디가 존재합니다. 다른 아이디를 입력해주세요.");
                    //아이디가 존제할 경우 빨깡으로 , 아니면 파랑으로 처리하는 디자인
                    $("#divInputId").addClass("has-error")
                    $("#divInputId").removeClass("has-success")
                    $("#userid").focus();
                    
                
                } else {
                    alert("사용가능한 아이디입니다.");
                    //아이디가 존제할 경우 빨깡으로 , 아니면 파랑으로 처리하는 디자인
                    $("#divInputId").addClass("has-success")
                    $("#divInputId").removeClass("has-error")
                    $("#userpwd").focus();
                    //아이디가 중복하지 않으면  idck = 1 
                    idck = 1;
                    
                }
            },
            error : function(error) {
                
                alert("error : " + error);
            }
        });
    });
});
 
 
</script>
cs


우선 Ajax부터 작성했습니다.

var idck = 0; 우선 아이디 체크를했는지 안했는지 안했다면 회원가입이 불가하게 처리하기 위해

변수를 먼져 선언했습니다. 아이디 체크 여부에 따라 1 or 0 으로 처리할것입니다. 


컨트롤러


1
2
3
4
5
6
7
8
9
10
11
12
13
 @RequestMapping("/idcheck.do")
    @ResponseBody
    public Map<Object, Object> idcheck(@RequestBody String userid) {
        
        int count = 0;
        Map<Object, Object> map = new HashMap<Object, Object>();
 
        count = signupService.idcheck(userid);
        map.put("cnt", count);
 
        return map;
    }
 
cs


Ajax사용을 위해 @ResponseBody 위를 어노테이션을 써줘야하구요 

JSON으로 넘어온 userid를 매개변수로 받습니다.


signupService.idcheck(userid); 쿼리를 먼져 확인해보면 


1
2
3
4
5
<select id="idcheck" parameterType="String" resultType="Integer">
      SELECT COUNT(*) FROM tbl_member
      WHERE
          userid = #{userid}
</select>
cs

 

테이블에 저장되어 있는 userid의 COUNT를 가져옵니다.  


다시 컨트롤러에서 count = 1 이 될것입니다. 

이렇게 맵에 넣어서 다시 jsp로 넘겨줍니다. 다시 AJAX 작성한것을 보면 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if (data.cnt > 0) {    
        alert("이미 아이디가 존재합니다.");               
    //아이디가 존제할 경우 빨깡으로 , 아니면 파랑으로 처리하는 디자인
        $("#divInputId").addClass("has-error")
        $("#divInputId").removeClass("has-success")
        $("#userid").focus();
                    
                
else {
         alert("사용가능한 아이디입니다.");
     //아이디가 존제할 경우 빨깡으로 , 아니면 파랑으로 처리하는 디자인
        $("#divInputId").addClass("has-success")
        $("#divInputId").removeClass("has-error")
        $("#userpwd").focus();
        //아이디가 중복하지 않으면  idck = 1 
        idck = 1;
}
cs


컨트롤러에서 아이디가 중복이라면  cnt = 1 아니면 0이 넘어 왔을 때 

data.cnt > 0 이면 중복!

아니라면 사용 가능합니다!


설명을 어렵게 드린거 같네요 ㅠㅠ 


그리고 회원가입을 해봤더니 이전에 유효성 검사에서 버튼을 submit으로 만들었었습니다. 

아이디가 중복인데 ㅠㅠ 막 에러를 뿜뿜  primary key ㅠㅠ

그래서 유효성 검사에서 


1
2
3
4
5
6
7
8
9
if(confirm("회원가입을 하시겠습니까?")){
        if(idck==0){
            alert('아이디 중복체크를 해주세요');
            return false;
        }else{
        alert("회원가입을 축하합니다");
        $("#frm").submit();
        }
    }
cs


마지막 부분에 이렇게 추가 했습니다.


이전 글을 보신분은 회원가입 버튼에 TYPE을 submit에서 button으로 바꿔주시고 

form 에 name="frm" id="frm"을 추가해주세요  





존재하는 아이디를 넣었을 때 count = 1 은 아이디가 존재 합니다.






아이디가 존재할 경우 빯갛게 표시 ㅎㅎㅎㅎ 





아이디가 존재하는데 회원가입을 진행했을 경우  

if(confirm("회원가입을 하시겠습니까?")){
        if(idck==0){
            alert('아이디 중복체크를 해주세요');
            return false;
        }else{
        alert("회원가입을 축하합니다");
        $("#frm").submit();
        }
    }








다시 정상적인 아이디를 입력했을 경우 



디비를 확인해보니 아주 이쁘게 잘 들어갔네요 ㅎㅎㅎㅎㅎㅎ






설명이 많이 부족합니다 .ㅠㅠ ajax는 추가로 따로 음...공부하고  스크립트 카테고리에 올리겠습니다 ㅠㅠ 

이것으로 회원가입에 필요한 비밀번호 암호화 , 유효성검사, 주소 자동완성, 아디디 중복검사를 했습니다. 

다음엔 게시판(공지사항) 을 만들겠습니다. 

공지사항에는 1. 게시글 등록 2.리스트 3. 수정 4. 삭제(CRUD)  5. 검색 6. 페이징  이렇게 다루겠습니다. 

코드가 필요하신 분은 댓글 달아주시면 git으로 코드를 올리겠습니다~ 

+ Recent posts