Programmer's Progress

도서 정보 제공 웹 서비스 - 메세지 전송 구현하기 본문

Web Service/도서 정보 제공 웹 서비스

도서 정보 제공 웹 서비스 - 메세지 전송 구현하기

Blanc et Noir 2021. 12. 7. 19:49

이번에는 사용자끼리 메시지를 주고받을 수 있도록 메시지 기능을 추가할 것이다.

메시지 기능을 추가하기에 앞서 먼저 메시지에 대한 스키마 다이어그램을 소개하자면

 

 

 

 

좌측은 송신함, 우측은 수신함을 나타낸다.

 

 

 

보는 것과 같이 송신함과 수신함을 위한 테이블을 따로 구성하였는데

이는 메시지를 보낸 사람이 해당 메시지를 자신의 송신함에서 지우더라도, 즉 송신 기록을 제거하더라도

수신자에게는 그대로 해당 메시지가 남아있을 수 있도록 하기 위함이다.

 

 

 

 

 

물론, 송신 메시지인지, 수신 메시지인지 구분하는 값을 더 추가한다면

하나의 테이블로도 처리가 가능하긴 하지만, 하나의 릴레이션이 너무 커지면 데이터 접근 속도도 그렇고

여러 가지 면에서 상당히 불리한 점이 많기 때문에, 일부러 분할하여 처리하였다.

 

 

 

 

 

 

메시지의 기본키는 SYS_GUID( ) 함수를 이용하여 16바이트의 랜덤 한 값을 생성하고

이를 기본키로 사용하는데, 2 ^ (16 * 8) 가지의 조합이 나타날 수 있으므로, 충돌이 발생할 수 있긴 하지만

그 확률이 정말 말도 안 되게 희박하기 때문에 이를 기본키로 사용하였다.

 

 

 

 

메세지 전송을 위한 화면을 구성한 것

 

 

 

 

 

위와 같이 메시지 전송화면을 구성했는데, 클라이언트가 AJAX 방식으로 메시지를 담당하는 컨트롤러에

메시지 전송 요청을 전달하면, 컨트롤러에서 이 요청에 대해 적절하게 DB에 접근할 수 있도록

알맞은 DAO클래스의 객체를 생성하고, 해당 모델을 통해 DB에 간접적으로 컨트롤러가 접근하도록 구성했다.

 

 

 

 

 

$(document).ready(function(){
	$(document).on("click","#MESSAGE_SEND_BUTTON",function(){
		var RECEIVER_ID = $("#CUSTOMER_ID").val();
		var MESSAGE_TITLE = $("#MESSAGE_TITLE").val();
		var MESSAGE_CONTENT = $("#MESSAGE_CONTENT").val();

		MESSAGE_CONTENT = MESSAGE_CONTENT.replaceAll("\n","<br>");
		
		if(RECEIVER_ID.length == 0){
			alert("메세지를 받을 사람의 아이디를 입력해야합니다.");
		}else if(MESSAGE_TITLE.length == 0){
			alert("메세지 제목을 입력해야합니다.");
		}else if(MESSAGE_CONTENT.length == 0){
			alert("메세지 내용을 입력해야합니다.");
		}else{
			$.ajax({
				"url":"/LibraryService/message/sendMessage.do",
				"type":"POST",
				"dataType":"JSON",
				"data":{
					"RECEIVER_ID":RECEIVER_ID,
					"MESSAGE_TITLE":MESSAGE_TITLE,
					"MESSAGE_CONTENT":MESSAGE_CONTENT
				},
				"success":function(result){
					if(result[0].FLAG =="TRUE"){
						alert(result[0].CONTENT);
						$("#CUSTOMER_ID").val("");
						$("#MESSAGE_TITLE").val("");
						$("#MESSAGE_CONTENT").val("");
					}else{
						alert(result[0].CONTENT);
					}
				},
				"error":function(){
					alert("에러");
				}
			})
		}
	});
})

위의 소스코드는 sendMessage.js의 내용이다.

 

 

 

 

우선 클라이언트 사이드에서 JS를 이용해서 메시지의 형식, 가령 메시지의 제목이나 내용이 비어있다면

컨트롤러에 요청을 전달하기 전에 먼저, 클라이언트 사이드 자체에서 해당 요청에 문제가 있음을 감지하고

올바르게 입력할 것을 요구한다. 서버에서 이러한 불필요한 요청을 처리하지 않아도 되니 부담을 경감시킬 수 있다.

 

 

 

 

		if(action.equals("/sendMessage.do")) {
			MessageDAO dao = new MessageDAO();
			PrintWriter out = response.getWriter();
			CustomerVO CUSTOMER = (CustomerVO)request.getSession().getAttribute("CUSTOMER");

			if(CUSTOMER!=null) {
				JSONArray array = dao.sendMessage(CUSTOMER.getCUSTOMER_ID(), request.getParameter("RECEIVER_ID"), request.getParameter("MESSAGE_TITLE"), request.getParameter("MESSAGE_CONTENT"));
				out.print(array);
			}else {
				JSONArray array = new JSONArray();
				JSONObject json = new JSONObject();
				json.put("FLAG", "LOGOFF");
				json.put("CONTENT", "로그인 정보가 유효하지 않습니다.");
				array.add(json);
				out.print(array);;
			}
			out.flush();
			out.close();
		}

MessageController.java 소스코드 내용의 일부

 

 

 

	public JSONArray sendMessage(String SENDER_ID, String RECEIVER_ID, String MESSAGE_TITLE, String MESSAGE_CONTENT) {
		Connection connection;
		PreparedStatement pstmt;
		ResultSet rs;
		String result=null;
		JSONArray array = new JSONArray();
		JSONObject json = new JSONObject();

		try {
			String query ="";
			query += "SELECT CUSTOMER_ID RECEIVER_ID ";
			query += "FROM CUSTOMER ";
			query += "WHERE CUSTOMER_ID = '"+RECEIVER_ID+"'";
			
			connection = dataSource.getConnection();
			pstmt = connection.prepareStatement(query);
			rs = pstmt.executeQuery();
			if(rs.next()) {
				result = rs.getString("RECEIVER_ID");
			}
			
			rs.close();
			pstmt.close();
			
			if(result == null) {
				connection.close();
				json.put("FLAG","FALSE");
				json.put("CONTENT","해당 사용자의 아이디 정보가 없습니다.");
				array.add(json);
				return array;
			}else {
				query="INSERT INTO MESSAGE_SENT VALUES(SYS_GUID(),?,?,TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS'),?,?)";
				pstmt = connection.prepareStatement(query);
				pstmt.setString(1, SENDER_ID);
				pstmt.setString(2, RECEIVER_ID);
				pstmt.setString(3, MESSAGE_TITLE);
				pstmt.setString(4, MESSAGE_CONTENT);
				pstmt.execute();
				pstmt.close();
				
				query="INSERT INTO MESSAGE_RECEIVED VALUES(SYS_GUID(),?,?,TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS'),?,?)";
				pstmt = connection.prepareStatement(query);
				pstmt.setString(1, SENDER_ID);
				pstmt.setString(2, RECEIVER_ID);
				pstmt.setString(3, MESSAGE_TITLE);
				pstmt.setString(4, MESSAGE_CONTENT);
				pstmt.execute();
				
				rs.close();
				pstmt.close();
				connection.close();
				
				json.put("FLAG","TRUE");
				json.put("CONTENT","메세지를 전송했습니다.");
				array.add(json);
				return array;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

먼저 입력한 상대가 실제로 존재하는지 여부를 질의하고, 존재한다면

송신함과 수신함 모두에 메시지를 삽입하도록 했다.

 

 

 

 

 

어쩌면 처음 질의는 불필요한 질의일 수도 있다.

먼저 송신, 수신함에 메시지를 추가해보고 만약 SENDER_ID 또는 RECEIVER_ID가 유효하지 않다면

외래 키 제약조건을 위반하게 될 것이다. 따라서 예외가 발생할 것이다.

해당 예외를 감지하면 이에 따라 사용자가 유효하지 않다고 응답한다면 굳이 해당 사용자의 유효성에 대한

질의를 할 필요가 없어질 것이다.

 

 

 

 

 

qweqweqwe 아이디로 로그인한 홍길동 사용자가 asdasdasd 사용자에게 메시지를 전송하는 모습

 

 

 

 

정상적으로 qweqweqwe 사용자가 asdasdasd 사용자에게 메세지를 전송했음을 알 수 있다.

 

Comments