오늘보다 더 나은 내일의 나에게_

비전공자의 IoT 국비 교육 수강일지 Day_37 본문

비전공자의 코딩일지

비전공자의 IoT 국비 교육 수강일지 Day_37

chan_96 2022. 2. 10. 20:02
728x90

로그인 성공 시 페이지 이동

로그인 성공 시
loginService 서블릿에서 세션을 생성한다. 로그인 정보가 담긴 vo객체를 세션에 넣어준다.

loginService 코드
더보기
package com.controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.model.MemberVO;

@WebServlet("/loginService")
public class loginService extends HttpServlet {
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		//application/x-www-form-urlencoded
		//String id = request.getParameter("id");
		//String pw = request.getParameter("pw");
		
		Connection conn = null;
		PreparedStatement psmt = null;
		ResultSet rs = null;
		
		StringBuffer sb = new StringBuffer(); //읽어온 데이터 저장
		String line = null; //버퍼안에 데이터 읽을때 사용(임시저장)
		
		BufferedReader reader = request.getReader(); //요청데이터 읽을때 사용
		while((line = reader.readLine()) != null) {//읽을 데이터가 있을때 반복 수행
			sb.append(line); //읽어온데이터를 sb(StringBuffer)에 추가
		}
		
		JsonParser parser = new JsonParser(); //파싱(문자열 -> JSON)
		JsonElement element = parser.parse(sb.toString());
		
		String id = element.getAsJsonObject().get("id").getAsString(); //키값이 id인 데이터
		String pw = element.getAsJsonObject().get("pw").getAsString(); //키값이 pw인 데이터
		
		System.out.println("아이디 : "+ id);
		System.out.println("비밀번호 : "+ pw);
		
		
		
		//로그인 가능할 경우 콘솔창에 : 로그인 성공 출력(페이지이동x)
		//로그인 불가능할 경우 콘솔창에 : 로그인 실패 (페이지이동x)
		
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			String url = "jdbc:oracle:thin:@127.0.0.1:1521:xe";
			String dbid = "hr";
			String dbpw = "hr";
			
			conn = DriverManager.getConnection(url,dbid,dbpw);
			
			String sql = "select * from mem where id = ? and pw = ?";
			
			psmt = conn.prepareStatement(sql);
			psmt.setString(1, id);
			psmt.setString(2, pw);
			
			rs = psmt.executeQuery();
			
			PrintWriter out = response.getWriter();
			
			if(rs.next()){
				String getid = rs.getString(1);
				String getpw = rs.getString(2);
				String nick = rs.getString(3);
				
				//db에서 읽어온 사용자 데이터 -> MemberVO 객체 초기화
				MemberVO vo = new MemberVO(getid, getpw, nick);
				
				System.out.println("로그인 성공");
				
				//세션이 삭제되기 전까지 로그인한 사용자의 정보 기억
				HttpSession session = request.getSession();
				session.setAttribute("member", vo);
				
				//"success" 응답
				out.print("success");
			}else {
				System.out.println("로그인 실패");
				//"fail" 응답
				out.print("fail");
			}
			
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			try {
				rs.close();
				psmt.close();
				conn.close();			
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}// end of finally
	}//end of service
}//end of class


success 출력 시 board_list.jsp 페이지(게시판 페이지)로 이동한다.
fail 출력 시 페이지 이동하지 않고 "아이디/비밀번호를 확인해주세요" 비밀번호 밑에 공간에 출력한다.


board_login.jsp코드

더보기
<%@ page language="java" contentType="text/html; charset=EUC-KR"
	pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
<link
	href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
	rel="stylesheet" id="bootstrap-css">
<script
	src="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script
	src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link rel="stylesheet" href="asset/css/main.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
	href="https://fonts.googleapis.com/css2?family=Do+Hyeon&display=swap"
	rel="stylesheet">
<style>
body {
	background-image: url('asset/img/bg.jpg');
	font-family: 'Do Hyeon', sans-serif;
	font-size: 30px;
}
#check{
	font-size : 20px;
	color : red;
}
</style>
</head>
<body>
	<div class="wrapper fadeInDown">
		<div id="formContent">

			<!-- Login Form -->
			<form action="#">
				<input type="text" id="id" class="fadeIn second" name="id"placeholder="login" style="margin-top: 30px"> 
				<input type="password" id="password" class="fadeIn third" name="pw" placeholder="password"> 
				<p id="check"></p>
				<input type="button" id="submit" class="fadeIn fourth" value="Log In">
			</form>

		</div>
	</div>
	
	<script>
		let btn_submit = document.getElementById("submit");
		let check_p = document.getElementById("check");
		
		btn_submit.addEventListener("click", function(){
			//1. id칸이나 pw칸 둘중에 하나라도 비어있으면
			//p(id=check) "아이디/비밀번호를 입력해주세요" 문구 출력
			let id = document.getElementById("id").value;
			let pw = document.getElementById("password").value;
			
			// if(!id||!pw){
			if(id == "" || pw == ""){
				check_p.innerText="아이디/비밀번호를 입력해주세요";
			}else{
				//JSON({키 : 실제값}) 형식 데이터 만들기
				let data = {'id': id, 'pw':pw};
				
				let xhr = new XMLHttpRequest();
				
				//요청방식, 요청경로
				xhr.open("post", "loginService");
				//전송데이터의 형식
				xhr.setRequestHeader("Content-Type","application/json;charset=UTF-8");
				//요청 & 전송할 데이터
				xhr.send(JSON.stringify(data));
				
				xhr.onreadystatechange = function() {
					if(xhr.readyState === XMLHttpRequest.DONE){ //요청성공
						if(xhr.status===200){
							console.log("응답성공");
							console.log(xhr.responseText); //응답데이터 확인 //xml로 보내는경우=>(responseXML)
							
							if(xhr.responseText === "success"){
								location.href = "board_list.jsp";
							}else{
								check_p.innerText="아이디/비밀번호를 확인해주세요";
							}
							
						}else{
							console.log("응답실패");
						}
					}else{ // 요청실패
						console.log("요청실패");
					}
				}// end of function
			} // end of else
		});
		
	</script>
</body>
</html>

 

 

게시판 페이지 출력

게시판 페이지로 이동이 되었다면 DB에 있는 데이터를 가져와 페이지에 출력해준다.
- board_list.jsp페이지에서 BoardDAO 객체를 생성하고 게시글 목록을 불러오는 메서드를 호출한다.


=> 게시글 목록을 불러오는 BoardDAO 클래스의 getList( )의 핵심 코드 부분
- sql문 결과값을 컬럼별로 따로 저장해 전달하려면 ArrayList를 사용해 값을 저장하고 반환시켜준다.
BoardDAO의 getList( ) 코드
더보기
public ArrayList<BoardVO> getList() {
    Connection conn = null;
    PreparedStatement psmt = null;
    ResultSet rs = null;
    ArrayList<BoardVO> al = new ArrayList<BoardVO>();

    try {
        Class.forName("oracle.jdbc.driver.OracleDriver");
        String url = "jdbc:oracle:thin:@127.0.0.1:1521:xe";
        String dbid = "hr";
        String dbpw = "hr";

        conn = DriverManager.getConnection(url,dbid,dbpw);

        String sql = "select num, name, writer, views from board";

        psmt = conn.prepareStatement(sql);

        rs = psmt.executeQuery();

        while(rs.next()){

            int getNum = rs.getInt(1);
            String getName = rs.getString(2);
            String getWriter = rs.getString(3);
            int getViews = rs.getInt(4);

            BoardVO vo = new BoardVO(getNum, getName, getWriter, getViews);
            al.add(vo);
        }//end of while

    }catch(Exception e) {
        e.printStackTrace();
    }finally {
        try {
            rs.close();
            psmt.close();
            conn.close();			
        } catch (Exception e2) {
            e2.printStackTrace();
        }
    }
    return al;
}// end of getList


=> board_list.jsp에서 게시글 목록 스크립틀릿 출력 코드
- a태그 href속성에 쿼리스트링을 작성해 게시글을 눌렀을 때 그 게시물을 볼 수 있도록 num과 게시물 번호 값을 작성해준다.
board_list.jsp 코드
더보기
<%@page import="com.model.BoardVO"%>
<%@page import="java.util.ArrayList"%>
<%@page import="com.model.BoardDAO"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" integrity="sha512-dTfge/zgoMYpP7QbHy4gWMEGsbsdZeCXz7irItjcC3sPUFtf0kuFbDz/ixG7ArTxmDjLXDmezHubeNikyKGVyQ==" crossorigin="anonymous">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Do+Hyeon&display=swap" rel="stylesheet">
<style>
	body{
		background-image : url('asset/img/bg.jpg');
		font-family: 'Do Hyeon', sans-serif;
		font-size : 30px;
	}
	.container{
		background-color : whitesmoke;
		margin-top : 100px;
		padding-top : 20px;
	}
	th,td{
		text-align:center;
	}

</style>
</head>
<body>
	<%
		BoardDAO dao = new BoardDAO();
		ArrayList<BoardVO> al = dao.getList();
		System.out.print(al.size());
	%>
	<div class="container">
	<table class="table">
		<tr>
		    <th>글 제목</th>
		    <th>작성자</th>
		    <th>조회수</th>
		</tr>
	<%-- 
		<%
			for(int i = 0;i < al.size();i++){
				out.print("<tr><td>"+al.get(i).getName()+"</td>");
				out.print("<td>"+al.get(i).getWriter()+"</td>");
				out.print("<td>"+al.get(i).getViews()+"</td></tr>");
		%>
		
		<%} %>
	--%>
	<%
		for(int i = al.size()-1;i >= 0;i--){
	%>
	<tr>
		<td><a href="board_main.jsp?num=<%=al.get(i).getNum()%>"><%=al.get(i).getName() %></a></td>
		<td><%=al.get(i).getWriter() %></td>
		<td><%=al.get(i).getViews() %></td>
	</tr>
	
	<%
		}
	%>
	
	</table>
	</div>

</body>
</html>

 

게시판 게시글 상세페이지 출력

게시판에서 게시글을 클릭했을 때 각각의 게시물 페이지를 보려면
board_list.jsp => board_main.jsp로 이동하게 되는데 클릭한 게시글의 정보를 전달시켜줘야 한다.
그러기 위해선 board_list.jsp에서 클릭된 게시글의 정보를 쿼리스트링으로 전달시켜준다.

쿼리스트링으로 전달받은 num값을 getOneList()에 매개변수로 넣어 호출한다.
=> getOneList( )는 현재 게시글의 정보(게시글 제목, 작성자, 위치, 게시글 내용)를 담고 있는 BoardVO객체를 반환시켜준다.
int num = Integer.parseInt(request.getParameter("num"));
BoardDAO dao = new BoardDAO();
BoardVO vo = dao.getOneList(num);​

 

BoardDAO의 getOneList( ) 코드
더보기
public BoardVO getOneList(int num) {
    Connection conn = null;
    PreparedStatement psmt = null;
    ResultSet rs = null;
    BoardVO vo = null;

    try {
        Class.forName("oracle.jdbc.driver.OracleDriver");
        String url = "jdbc:oracle:thin:@127.0.0.1:1521:xe";
        String dbid = "hr";
        String dbpw = "hr";

        conn = DriverManager.getConnection(url,dbid,dbpw);

        String sql = "select name, writer, location, content from board where num = ?";

        psmt = conn.prepareStatement(sql);
        psmt.setInt(1, num);

        rs = psmt.executeQuery();

        if(rs.next()){

            String getName = rs.getString(1);
            String getWriter = rs.getString(2);
            String getLocation = rs.getString(3);
            String getContent = rs.getString(4);

            vo = new BoardVO(getName, getWriter, getLocation, getContent);
        }//end of while

    }catch(Exception e) {
        e.printStackTrace();
    }finally {
        try {
            rs.close();
            psmt.close();
            conn.close();			
        } catch (Exception e2) {
            e2.printStackTrace();
        }
    }
    return vo;
}// end of getOneList

작성된 댓글 출력
DB에 저장된 댓글을 각 게시물에 알맞게 출력해야 한다.
BoardDAO의 getReply( ) 메서드를 호출시켜준다.
<%
    int num = Integer.parseInt(request.getParameter("num"));

    BoardDAO dao = new BoardDAO();
    BoardVO vo = dao.getOneList(num);

    ArrayList<ReplyVO> al = dao.getReply(num);
    System.out.println(al.size());
%>​



String sql = "select content, writer from reply where boardnum = ?";
psmt = conn.prepareStatement(sql);
psmt.setInt(1, num);
=> getReply( ) 메서드의 매개변수로 현재 게시물 번호로 받아와 쿼리 문의? 바인드 변수에 넣어줘 쿼리문을 실행한다. 후 결과값을 ArrayList<ReplyVO> 반환!

BoardDAO의 getReply( ) 코드
더보기
public ArrayList<ReplyVO> getReply(int num) {
    Connection conn = null;
    PreparedStatement psmt = null;
    ResultSet rs = null;
    ArrayList<ReplyVO> al = new ArrayList<ReplyVO>();

    try {
        Class.forName("oracle.jdbc.driver.OracleDriver");
        String url = "jdbc:oracle:thin:@127.0.0.1:1521:xe";
        String dbid = "hr";
        String dbpw = "hr";

        conn = DriverManager.getConnection(url,dbid,dbpw);

        String sql = "select content, writer from reply where boardnum = ?";

        psmt = conn.prepareStatement(sql);
        psmt.setInt(1, num);

        rs = psmt.executeQuery();

        while(rs.next()){
            String getContent = rs.getString(1);
            String getWriter = rs.getString(2);

            ReplyVO vo = new ReplyVO(getContent, getWriter);
            al.add(vo);
        }//end of while

    }catch(Exception e) {
        e.printStackTrace();
    }finally {
        try {
            rs.close();
            psmt.close();
            conn.close();			
        } catch (Exception e2) {
            e2.printStackTrace();
        }
    }
    return al;
}// end of


=> 스크립틀릿 반복문으로 댓글 출력


board_main.jsp 코드

더보기
<%@page import="java.util.ArrayList"%>
<%@page import="com.model.ReplyVO"%>
<%@page import="com.model.BoardVO"%>
<%@page import="com.model.BoardDAO"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" integrity="sha512-dTfge/zgoMYpP7QbHy4gWMEGsbsdZeCXz7irItjcC3sPUFtf0kuFbDz/ixG7ArTxmDjLXDmezHubeNikyKGVyQ==" crossorigin="anonymous">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
	href="https://fonts.googleapis.com/css2?family=Do+Hyeon&display=swap"
	rel="stylesheet">
<style>
body {
	background-image: url('asset/img/bg.jpg');
	padding-left: 200px;
	padding-right: 200px;
	font-family: 'Do Hyeon', sans-serif;
}

.card-body {
	background-color: whitesmoke;
}

p {
	padding-top: 5px;
	padding-left: 20px;
	font-size: 30px;
}
</style>
</head>
<body>
	<%
		int num = Integer.parseInt(request.getParameter("num"));
	
		BoardDAO dao = new BoardDAO();
		BoardVO vo = dao.getOneList(num);
		
		ArrayList<ReplyVO> al = dao.getReply(num);
		System.out.println(al.size());
	%>
	<div class="card-body" style="margin-top: 100px; margin-bottom: 10px; height: 50px">
		<p><%=vo.getName() %> / <%=vo.getWriter() %></p>
	</div>

	<!-- 장소, 및 지도 -->
	<div id="map" style="width: 100%; height: 350px;">%지도자리%</div>
	
	<!-- 댓글작성 -->
	<div class="card mb-2">
		<div class="card-body">
			<p>한줄 평 : <%=vo.getContent() %></p>
			<ul class="list-group list-group-flush">
				<li class="list-group-item">
					<textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
					<button type="button" class="btn btn-dark mt-3"onclick="addReply()">post reply</button>
				</li>
			</ul>
			<ul class="list-group list-group-flush" id="reply">
				<%
					for(int i = al.size()-1;i >= 0;i--){
				%>
				<li class="list-group-item"><span><%=al.get(i).getContent() %> / <%=al.get(i).getWriter() %></span></li>
				<%} %>
			</ul>
		</div>
	</div>
	
	<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=dac4065a7a1dada3f8ae562756260926&libraries=services"></script>
	<script>
		function addReply(){
			let ta = document.querySelector("textarea"); //댓글 작성창
			let replyDiv = document.querySelector("#reply"); //댓글 출력창
			
			//JSON({키 : 실제값}) 형식 데이터 만들기
            let data = {'boardnum':<%=num%> , 'reply':ta.value}
            
            let xhr = new XMLHttpRequest()
            
            //요청방식 , 요청경로
            xhr.open('post', 'replyService')
            //전송데이터의 형식
            xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8')
            //요청 & 전송할 데이터
            xhr.send(JSON.stringify(data))
            
            xhr.onreadystatechange = function(){
               if(xhr.readyState===XMLHttpRequest.DONE){  //요청성공
                  if(xhr.status===200){ //응답성공
                     console.log("응답성공")
                     console.log(xhr.responseText) //응답데이터 확인 (responseXML)
                     if(xhr.responseText === "success"){
                        //location.href = "board_list.jsp"
                     }else{
                        //check_p.innerText = '아이디/비밀번호를 확인해주세요'
                     }
                  }else{
                     console.log("응답실패")
                  }
               }else{  //요청실패
                  console.log("요청실패")
               }
            }
		}
	
	
	
	
		// 마커를 클릭하면 장소명을 표출할 인포윈도우 입니다
		var infowindow = new kakao.maps.InfoWindow({zIndex:1});
	
		var mapContainer = document.getElementById('map'), // 지도를 표시할 div 
		    mapOption = {
		        center: new kakao.maps.LatLng(37.566826, 126.9786567), // 지도의 중심좌표
		        level: 3 // 지도의 확대 레벨
		    };  
	
		// 지도를 생성합니다    
		var map = new kakao.maps.Map(mapContainer, mapOption); 
	
		// 장소 검색 객체를 생성합니다
		var ps = new kakao.maps.services.Places(); 
	
		// 키워드로 장소를 검색합니다
		ps.keywordSearch('<%=vo.getLocation()%>', placesSearchCB); 
	
		// 키워드 검색 완료 시 호출되는 콜백함수 입니다
		function placesSearchCB (data, status, pagination) {
		    if (status === kakao.maps.services.Status.OK) {
	
		        // 검색된 장소 위치를 기준으로 지도 범위를 재설정하기위해
		        // LatLngBounds 객체에 좌표를 추가합니다
		        var bounds = new kakao.maps.LatLngBounds();
	
		        for (var i=0; i<data.length; i++) {
		            displayMarker(data[i]);   //마커
		            bounds.extend(new kakao.maps.LatLng(data[i].y, data[i].x));
		        }       
	
		        // 검색된 장소 위치를 기준으로 지도 범위를 재설정합니다
		        map.setBounds(bounds);
		    } 
		}
	
		// 지도에 마커를 표시하는 함수입니다
		function displayMarker(place) {
		    
		    // 마커를 생성하고 지도에 표시합니다
		    var marker = new kakao.maps.Marker({
		        map: map,
		        position: new kakao.maps.LatLng(place.y, place.x) 
		    });
	
		    // 마커에 클릭이벤트를 등록합니다
		    kakao.maps.event.addListener(marker, 'mouseover', function() {
		        // 마커를 클릭하면 장소명이 인포윈도우에 표출됩니다
		        infowindow.setContent('<div style="padding:5px;font-size:12px;"><img src="./asset/img/img.jpg" style="width:150px;height:150px;"></div>');
		        infowindow.open(map, marker);
		    });
		    
		    kakao.maps.event.addListener(marker, 'mouseout', function() {
		    	infowindow.close();
		    });
		    
		}
	</script>
	
</body>
</html>

 

728x90
Comments