본문 바로가기

개발/BACK

[SpringFramework] WebSocket 통신을 이용한 간단한 쪽지(메세지) 기능 구현[2]

728x90

지난 포스팅에서는 웹 소켓을 통해 쪽지를 발송했으면,

해당 쪽지의 건수를 상단 메인 화면에 뿌려주는 작업까지 진행했다

 

지난 포스팅 링크

 

https://hdhdeveloper.tistory.com/38

 

[SpringFramework] WebSocket통신을 이용한 간단한 쪽지(메세지) 기능 구현 예제[1]

이번에는 저번에 Socket을 구현하여 1대1 및 다중 채팅 기능을 구현했다면, 이번에는 웹소켓을 이용해 다른 이에게 쪽지를 보내고, 확인할 수 있는 기능을 구현할 예정이다. 웹소캣은 http 프로토콜

hdhdeveloper.tistory.com

 

 

이번 포스팅에서는 해당 아이디로 발송된 메세지를 확인하는

페이지 생성 및 메세지를 발송하는 기능까지 포스팅 하겠다.

 


 

지난번에 작업했던 화면이다.

 상단에 [1통의 쪽지가 있습니다.]

라는 메세지를 클릭하면 왼쪽 바가 화면으로 출력되도록 만들고,

해당 div에다 아래와 같은 식으로 받은 메세지의 내용을 출력할 것이다.

 

 

 

 

먼저 JSP 페이지, 스크립트 및 CSS 부분이다. 

 

1
<span id="recMs" onclick="openNav()" name="recMs" style="float:right;cursor:pointer;margin-right:10px;color:pink;"><img src="../resources/images/msgicon.png" id="messageImage" style="opacity :0.3;width:15px;"></span>
cs

 

 

1
2
3
4
<div id="mysidenav" class="sidenav">
        <a href="#" class="closebtn" onclick='closeNav()'>x</a>
        <div id="mssage_send_btn" name="mssage_send_btn" class="btn btn-warning"><p>쪽지 보내기</p></div>
    </div>
cs

 

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
    function openNav() {
        document.getElementById('mysidenav').style.width = '350px';
        $.ajax({
            type:"post",
            dataType:"json",
            url:"/message/list.do",
            data :{
                receiver_name : $("#user_name").val(),
            },
            success:function(data){
                var i =1;
                var dataset = data.result;
                dataset.forEach(function(row){
                    if($("#"+i).length >0){
                    }else{
                        $("#mysidenav").append("<div id='"+row.view_check+"'class='letter'><div class='header'><p style='color:white;font-size:23px;margin-left: 20px;'>"+row.ms_title+"</p></div><table><tbody><tr><th>발송일자:  "+row.creat_dt+"</th><th>발송자: "+row.sender_name+"</th></tr>"+   
                                   "<tr><th>"+row.ms_content+"</th></tr></tbody></table><div class='footer'></div></div>");
                
                        if(row.read_yn ==0){
                                $("#"+i+" .footer").append("<input type='button' style='float:right;' id='letter_read' class='btn btn-danger' value='read'/>");
                        }
                        i++;    
                    }
                });
            }
        })
        if($("#mysidenav").css("width"=="350px")
            document.getElementById('mysidenav').style.width = '0';
            
    }
    function closeNav() {
        document.getElementById('mysidenav').style.width = '0';
    }
cs

 

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/* 사이드바 스타일 */
.sidenav {
    height:100%;
    width: 0;
    position: fixed;
    z-index:1;
    top: 0;
    left: 0;
    background-color: #e60e45;
    overflow-x: hidden;
    transition:0.5s ease-in-out;
    padding-top: 60px;
}
.sidenav a {
    padding: 8px 8px 8px 32px;
    text-decoration: none;
    font-size: 25px;
    color: #fff;
    display: block;
    transition: 0.2s ease-in-out;
}
.sidenav a:hover, .offcanvas a:focus {
    color: #000;
}
.closebtn {
    position: absolute;
    top: 0;
    right: 25px;
    font-size: 36px !important;
    margin-left: 50px;
}
.openmenu:hover {
    color:rgb(0,154,200);
    transition:0.5s ease-in-out;
}
.openmenu {
    font-size: 25px;
    cursor:pointer;
    transition:0.5s ease-in-out;
}
.openmenu > i {
    font-size: 30px;
}
/* 미디어쿼리 적용 */
@media screen and (max-height:450px) {
    .sidenav {
        padding-top:15px;
    }
    .sidenav a {
        font-size: 18px;
    }
}
 
.letter {
    margin-left : 20px;
    border : 1px solid white;
    background-color : white;
    margin-bottom : 10px;
    display :inline-block;
    width : 300px;
    height : 150px;
}
.letter .header {
    background-color : #e60e45;
    font-color : white;
}
 
#mssage_send_btn {
    float : left;
    margin-top : -50px;
    margin-left : 10px;
    height :35px;
}
 
.msg_form .modal-body table tbody tr {
    margin-bottom : 20px;
}
 
cs

 

 

먼저 JSP 부분에서는 크게 수정할 부분이 없다.

 

왜냐하면 HTML 요소 자체를 동적으로 생성할 것이기 때문에, 유심히 봐야 할 것은 SCRIPT 페이지이다.

 

openNav함수를 실행했을 때

width 의 크기가 커짐으로써 사이드 바를 생성하고, 열려있을 때는 닫히게끔 

 

 if($("#mysidenav").css("width"=="350px")

            document.getElementById('mysidenav').style.width = '0';

 

조건문 또한 주었다.

 


 

또한, 메세지를 호출해와야 하기 때문에 $.ajax를 통해 receiver_name으로 온 메세지들을 모두 불러온다.

if($("#"+i).length >0){

 

해당 if 조건절의 length 는 div의 ID값이 데이터베이스에서 AUTO INCREMENT 되는 값이기 때문에,

div 아이디를 토대로 중복으로 html 요소가 생성되지 않도록 하는 구문이다.

 

ajax에서 호출한 컨트롤러, 서비스, DAO 이다.

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
--MessageController
 
@RequestMapping(value="/message/list.do",  method = {RequestMethod.POST})
    @ResponseBody
    public Map<String,Object> findMessageList(@ModelAttribute("messageVO") MessageVO messageVO,HttpServletRequest req, HttpServletResponse resp, ModelMap model){
        List<MessageVO> msg_result = messageService.findList(messageVO.getReceiver_name());
        Map<String,Object> result = new HashMap<>();
        result.put("result",msg_result);
        return result;
    }
 
@RequestMapping(value="/message/message_proc.do")
    public void addMessageSend(@RequestParam String flag,@ModelAttribute("messageVO") MessageVO messageVO, HttpServletRequest req) {
        switch(flag) {
            case "insert" :
                messageService.insertMessage(messageVO);
                break;
        }
    }
 
 
--MessageService
public List<MessageVO> findList(String receiver_name);
public void insertMessage(MessageVO messageVO);
 
--MessageServiceImpl
    @Override
    public List<MessageVO> findList(String receiver_name) {
        return messageMapper.findList(receiver_name);
    }
@Override
    public void insertMessage(MessageVO messageVO) {
            messageVO.setGubun("0");
            messageVO.setRead_yn("0");
            
            messageMapper.insertMessage(messageVO);
    }
 
--MessageMapper.java
    public List<MessageVO> findList(String receiver_name);
    public void insertMessage(MessageVO messageVO);
 
--MessageMapper.xml
        <select id="findList" resultType="main.com.message.vo.MessageVO">
            select * from tb_message where receiver_name= #{receiver_name} and gubun = 0
        </select>    
 
    <insert id="insertMessage">
        INSERT INTO tb_message(ms_title,receiver_name,gubun,creat_dt,ms_content,sender_name,user_id,read_yn) VALUES(#{ms_title},#{receiver_name},#{gubun},SYSDATE(),#{ms_content},#{sender_name},#{user_id},#{read_yn});
    </insert>
 
 
cs
 

특별한 것은 없다. 단지 Controller 부분에서 flag 처리를 해 동일한 요청에 대해 분기해준다는 점과 

서비스 부분에서 messageVO의 값을 초기화 해주는 정도

INSERT 부분은 후에 사용할 예정이라, 같이 작업해준다.

 


 

 

해당 사항까지 했다면 화면의 모습은 이렇게 구성이 될 것이다.

먼저 상단에 3통의 쪽지가 왔습니다.

라는 메세지가 확인이 되고, 사이드 바가 열리는지 확인 후, 

사이드 바 상단의 쪽지 보내기 버튼에 기능을 붙여야 한다.

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
<div class="modal fade" id="MsgForm" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
        <div class="modal-dialog" role="document">
            <div class="modal-content ">
                <div class="modal-header fn-font">
                    <button class="close" type="button" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">X</span>
                    </button>
                </div>
                <form class="msg_form">
                    <input type="hidden" id="flag" name="flag" value="insert"/>
                    <input type="hidden" id="user_id" name="user_id" value="${sessionConfigVO.user_id}"/>
                    <div class="modal-body fn-font">
                        <table>
                            <colgroup>
                                <col style="width:150px;"/>
                                <col style="width:px;"/>
                            </colgroup>
                            <tbody>
                                <tr>
                                    <th>작성자</th>
                                    <th><input type="text" id="sender_name" name="sender_name" class="form-control" value="<c:out value='${sessionConfigVO.user_name}'/>" readonly/></th>
                                </tr>
                                <tr>
                                    <th>받는 사람</th>
                                    <th>
                                        <select id="receiver_name" name="receiver_name" class="form-control" value="">
                                            <c:forEach var="row" items="${userList}" varStatus="status">
                                                <option value="${row.user_name}">${row.user_name}</option>
                                            </c:forEach>
                                        </select>
                                    </th>
                                </tr>
                                <tr>
                                    <th>제목</th>
                                    <th><input type="text" id="ms_title" name="ms_title" class="form-control" value=""/></th>
                                    
                                </tr>
                                <tr>
                                    <th>내용</th>
                                    <th><textArea id="ms_content" name="ms_content" class="form-control"></textArea></th>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </form>
                <div class="modal-footer fn-font">
                    <button class="btn" type="button" id="msg_submit">SEND</button>
                    <button class="btn" type="button" data-dismiss="modal">NO</button>
                </div>
            </div>
        </div>
    </div>
cs

해당 dialog는 부트스트랩에서 제공하는 dialog를 사용했다. 

 

이전 포스팅 회원가입 기능을 작업할 때, 사용한 modal 창이다.

 

그리고 받는 사람을 조회할 때 select 박스를 넣었는데, 해당 select 박스는 jstl c태그를 사용하여 불러온 객체를 모두 가져온다.

해당 소스가 있는 페이지에서 modelMap을 이용해 가져왔다.

1
2
3
4
5
6
7
8
9
10
11
12
13
    /*최초 접속*/
    @RequestMapping(value = "/", method = {RequestMethod.GET, RequestMethod.POST})
    public String home(ModelMap model,HttpSession session) throws IOException {
        
        /* 네이버아이디로 인증 URL을 생성하기 위하여 naverLoginBO클래스의 getAuthorizationUrl메소드 호출 */
        String naverAuthUrl = naverLoginVO.getAuthorizationUrl(session);
        model.addAttribute("url", naverAuthUrl);
        
        List<UserVO> userList =mainService.findUserList();
        model.addAttribute("userList", userList);
        
        return "home";
    }
cs

이런 식으로 modelMap을 통해 userList를 던져주면 JSP 페이지에서 사용 가능하다.

 

 

소스를 붙여놓고 스크립트 코드를 보자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$("#mssage_send_btn").click(function(){
        $('#MsgForm').modal("show");
    });
    $("#msg_submit").click(function(){
        var msg= "쪽지를 보낼래?";
        
        if(!confirm(msg))
            return false;
        
        $.ajax({
            url : "/message/message_proc.do",
            dataType : "json",
            type : "post",
            data : $(".msg_form").serialize(),
            success:function(data){
                alert("쪽지를 보냈습니다.");                
            }
        })
    });
cs

이제 쪽지 기능을 발송하고, 조회하는 것까지 가능하다.

 

 

결과물 :

홍길동에게 쪽지를 발송 후, 홍길동 계정에서 바로 확인할 수 있는 모습이다.

728x90