Dynamic Web Project : projectMVC

1. jar 파일 설정

webapp

       WEB-INF

                 lib

                       *.jar파일들


2. 파일들 복사하기

 


3. Add and Remove 하기


4. 한글처리 하기


5. Run on Server


index.jsp

메인화면 부분 다 지우기 ( <body> </body> 안에 다 지우기 )

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>메인화면</title>
<style type="text/css">
html, body {
	width: 100%;
	height: 100%;
}
html {
	overflow-y: scroll;
}

#wrap{
	width: 1000px; 
	margin: 0 auto;
}

#header {
	height: 10%;
	text-align: center;
}

#container {
	margin: auto;
	width: 1000px;
	/* height: 500px; */
}

#container:after {
	content: '';
	display: block;
	clear: both;
	float: none;
}

#nav {
	margin-left: 10px;
	width: 25%;
	height: 100%;
	float: left;
}

#section {
	width: 70%;
	height: 100%;
	float: left;
}

#footer {
	width: 1000px;
	height: 10%;
}
</style>
</head>
<body>
	<div id="wrap">
		<div id="header">
			<h1>
				<img alt="하트" src="/projectMVC/image/free-icon-love-4096198.png" width="60" height="60">
				MVC를 활용한 미니프로젝트
			</h1>
		</div>
		<div id="container">
			<div id="nav"></div>
			<div id="section"></div>
		</div>
		<div id="footer"></div>
	</div>
</body>
</html>


webapp

     main

          menu.jsp -  header부분

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
ㅋㅋㅋㅋ
</body>
</html>

index.jsp - include

<body>
	<div id="wrap">
		<div id="header">
			<h1>
				<img alt="하트" src="/projectMVC/image/free-icon-love-4096198.png" width="60" height="60">
				MVC를 활용한 미니프로젝트
			</h1>
			<jsp:include page="./main/menu.jsp" />
		</div>
		<div id="container">
			<div id="nav"></div>
			<div id="section"></div>
		</div>
		<div id="footer"></div>
	</div>
</body>
</html>

이렇게 코드를 다 들고오므로 - 다 지우는게 맞다 !


menu.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<style>
.mainnav{
	background-color: #483D8B;
	list-style: none;
	color: #ffffff;
}

.mainnav:after{ /*container-snb,content  바로 붙지 않게 하기 위해서 clear 함 */
	content: '';
	display: block;
	clear: both;
}

.mainnav li{
	display: inline-block;
	justify-content: space-between;
}

.mainnav li a {
	display: block;
	padding: 0 13px; /*  위아래, 좌우 */
	background-color: #483D8B;
	color: #ffffff;
	font: bold 16px/40px 'Nanum Gothic', sans-serif; 
 /*폰트의 굵기 | 글자의 크기 | /line-height 줄간격 |  글꼴  , 앞에 글꼴없으면 다음 글꼴*/
	text-transform: uppercase;
	text-decoration: none;
}

.mainnav li a:hover {
	color: #660000;
	background-color: #ffcc00;
}
</style>
<ul class="mainnav">
	<li><a href="">글쓰기</a></li>
	<li><a href="">목록</a></li>
</ul>


로그인해야 글쓰기가 뜨게 하기

<ul class="mainnav">
	<c:if test="${sessionScope.memId != null }">
		<li><a href="">글쓰기</a></li>
	</c:if>
	<li><a href="">목록</a></li>
</ul>


index.jsp - ${ pageContext.request.contextPath } - 프로젝트명 안 바꿔도 되게 하기 !

<body>
	<div id="wrap">
		<div id="header">
			<h1>
				<img alt="하트" src="${ pageContext.request.contextPath }/image/free-icon-love-4096198.png" width="60" height="60">
				MVC를 활용한 미니프로젝트
			</h1>
			<jsp:include page="./main/menu.jsp" />
		</div>
		<div id="container">
			<div id="nav"></div>
			<div id="section"></div>
		</div>
		<div id="footer"></div>
	</div>
</body>
</html>

index.jsp - nav 부분 - <jsp:include page="./main/nav.jsp" />

<body>
	<div id="wrap">
		<div id="header">
			<h1>
				<img alt="하트" src="${ pageContext.request.contextPath }/image/free-icon-love-4096198.png" width="60" height="60">
				MVC를 활용한 미니프로젝트
			</h1>
			<jsp:include page="./main/menu.jsp" />
		</div>
		<div id="container">
			<div id="nav">
				<jsp:include page="./main/nav.jsp" />
			</div>
			<div id="section"></div>
		</div>
		<div id="footer"></div>
	</div>
</body>
</html>

nav.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<input type="button" value="로그인"/><br/><br/>
<input type="button" value="회원가입"/><br/><br/>
<input type="button" value="로그아웃"/><br/><br/>
<input type="button" value="회원정보수정"/><br/><br/>


로그인 상태여부에 따라 버튼이 보이게 해야한다.

pageScope > requestScope > sessionScpoe 순서로 찾는다.

알아서 찾으므로 아까처럼 sessionScope를 안 써도 된다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<c:if test="${memId == null}">
<input type="button" value="로그인"/><br/><br/>
<input type="button" value="회원가입"/><br/><br/>
</c:if>

<c:if test="${memId != null}">
<input type="button" value="로그아웃"/><br/><br/>
<input type="button" value="회원정보수정"/><br/><br/>
</c:if>

로그인이 안되었으므로 로그아웃과 회원정보 수정이 뜨지않음.


/projectMVC/member/loginForm.do

     ↓

ControlServlet.java <------------>  command.properties에서 자바파일을 들고온다.

     ↓

LoginFormService.java

     ↓

ControlServlet.java 

     ↓

/member/memberLoginForm.jsp

 

 

command.properties - #로그인

/member/loginForm.do=member.service.LoginFormService

 

 

LoginFormService.java

return "/member/memberLoginForm.jsp";


로그인

nav.jsp 

<input type="button" value="로그인" 
       onclick="location.href='/projectMVC/member/loginForm.do'"/><br/><br/>

memberLoginForm.jsp -  ${ pageContext.request.contextPath }로 바꾸기

<img src="../image/free-icon-love-4096198.png" alt="홈" width="60" height="60" 
           onclick="location.href='${ pageContext.request.contextPath }/index.do'" />
         <tr>
             <td colspan="2" align="center">
                 <input type="submit" value="로그인" id="loginBtn"/>
                 <input type="button" value="회원가입" onclick="location.href='${ pageContext.request.contextPath }/member/writeForm.do'" />
             </td>
         </tr>

memberMVC -------> projectMVC로 바꾸기

$('#loginBtn').click(function(event) {
    event.preventDefault(); // 기본 제출 동작 방지
    
    $('#idDiv').empty();
    $('#pwdDiv').empty();
    
    if ($('#id').val() == '') {
        $('#idDiv').html('아이디를 입력하세요.');
    } else if ($('#pwd').val() == '') {
        $('#pwdDiv').html('비밀번호를 입력하세요.');
    } else {
        $.ajax({
            type: 'POST',
            url: '/projectMVC/member/login.do',
            data: {
                'id': $('#id').val(),
                'pwd': $('#pwd').val()
            },
            dataType: 'text', // 서버로부터 순수한 텍스트만 받음
            success: function(data) {
               console.log(data);
                if (data.trim() === 'fail') {
                    alert("아이디 또는 비밀번호가 틀렸습니다.");
                } else {
                    alert(data.trim() + "님이 로그인하였습니다.");                    
                    location.href = '/projectMVC/index.do'
                }
            },
            error: function(e) {
                console.log(e);
            }
        });
    }
});

 


로그아웃

nav.jsp 

<script type="text/javascript" src="http://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
	//로그아웃
	$('#logoutBtn').click(function(){
		$.ajax({
			type: 'post',
			url: '/projectMVC/member/logout.do',
			dataType: 'text',
			success: function(data){
				
			},
			error: function(e){
				console.log(e);
			}
		});
	});
</script>

command.properties

/member/logout.do=member.service.LogoutService

LogoutService.java

package member.service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.control.CommandProcess;

public class LogoutService implements CommandProcess {

	@Override
	public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Throwable {
		HttpSession session = request.getSession();// 세션 생성
		session.removeAttribute("memName");
		session.removeAttribute("memId");
					
		//session.invalidate();
		return "none";
	}

}

 


nav.jsp - ajax로 return된다.

<script type="text/javascript" src="http://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
	//로그아웃
	$('#logoutBtn').click(function(){
		$.ajax({
			type: 'post',
			url: '/projectMVC/member/logout.do',
			success: function(data){
				alert("로그아웃");
				location.href="/projectMVC/index.do";
			},
			error: function(e){
				console.log(e);
			}
		});
	});
</script>

memberLoginForm.jsp -- alert 주석걸기 - 아이디 또느 비밀번호가 틀렸습니다 div로 처리

            success: function(data) {
               console.log(data);
                if (data.trim() === 'fail') {
                    $('#loginResult').html("아이디 또는 비밀번호가 틀렸습니다.");
                } else {
                    //alert(data.trim() + "님이 로그인하였습니다.");                    
                    location.href = '/projectMVC/index.do'
                }

#loginResult {
   color: red;
   font-size: 12pt;
   font-weight: bold;
   margin-bottom: 15px;
   text-align: center;
}


회원가입

nav.jsp 

<c:if test="${memId == null}">
	<input type="button" value="로그인" 
       	   onclick="location.href='${ pageContext.request.contextPath }/member/loginForm.do'"/><br/><br/>
	<input type="button" value="회원가입" 
	       onclick="location.href='${ pageContext.request.contextPath }/member/writeForm.do'"/><br/><br/>
</c:if>

command.properties

/member/writeForm.do=member.service.WriteFormService

WriteFormService.java

package member.service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.control.CommandProcess;

public class WriteFormService implements CommandProcess{
	@Override
	public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Throwable {
		return "/member/memberWriteForm.jsp";
	}
}

memberWriteForm.jsp

<body>
<img src="../image/free-icon-love-4096198.png" alt="홈" width="60" height="60" onclick="location.href='/memberMVC/index.do'" />
<form name="memberWriteForm" method="post" action="${ pageContext.request.contextPath }/member/write.do">
    <table>
        <tr>
            <th>이름</th>
            <td>
                <input type="text" name="name" id="name" placeholder="이름 입력" size="15"/>
                <div id="nameDiv"></div>
            </td>
        </tr>
        
        <tr>
            <th>아이디</th>
            <td>
                <input type="text" name="id" id="id" placeholder="아이디 입력" size="15"/>
                <input type="hidden" id="check" value=""/>
                <div id="idDiv"></div>
            </td>
        </tr>
        
        <tr>
            <th>비밀번호</th>
            <td>
                <input type="password" name="pwd" id="pwd" placeholder="비밀번호 입력" size="25"/>
                <div id="pwdDiv"></div>    
            </td>
        </tr>
        
        <tr>
            <th>재확인</th>
            <td>
                <input type="password" name="repwd" id="repwd" placeholder="비밀번호 입력" size="25"/>
                <div id="repwdDiv"></div>    
            </td>
        </tr>
        
        <tr>
            <th>성별</th>
            <td>
                <input type="radio" name="gender" value="0" checked/> 남자
                <input type="radio" name="gender" value="1"/> 여자
            </td>
        </tr>
        
        <tr>
            <th>이메일</th>
            <td>
                <input type="text" name="email1" size="15"/> @
                <input type="text" name="email2" id="email2" size="15"/>
                <input type="text" name="email3" id="email3" list="email3_list" size="15" oninput="change()"/>
                <datalist id="email3_list">
                    <option value="직접입력">직접입력</option>
                    <option value="naver.com"></option>
                    <option value="gmail.com"></option>
                    <option value="daum.net"></option>
                </datalist>                        
            </td>
        </tr>
        
        <tr>
            <th>휴대전화</th>
            <td>
                <select name="tel1" style="width: 70px;">
                    <option value="010">010</option>
                    <option value="011">011</option>
                    <option value="019">019</option>
                </select>
                -
                <input type="text" name="tel2" size="4" maxlength="4"/>
                -
                <input type="text" name="tel3" size="4" maxlength="4"/>
            </td>
        </tr>
        
        <tr>
            <th>주소</th>
            <td>
                <input type="text" name="zipcode" id="zipcode" placeholder="우편번호" size="6" readonly/>
                <input type="button" value="우편번호 검색" onclick="checkPost()"/><br>
                <input type="text" name="addr1" id="addr1" placeholder="주소" size="50" readonly/><br>
                <input type="text" name="addr2" id="addr2" placeholder="상세주소" size="50"/>
            </td>
        </tr>
        
        <tr>
            <td colspan="2" align="center">
                <input type="submit" value="회원가입" onclick="memberWrite(event)" />
                <input type="reset" value="다시입력" />
            </td>
        </tr>
    </table>
</form>
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-3.7.1.min.js"></script>
<script type="../js/member.js"></script>
<script type="text/javascript">
// 아이디 중복 검사
$(function () {
    $('#id').on('focusout', function(){
        $('#idDiv').empty(); // 메시지 초기화
        let id = $('#id').val(); 

        if (id === '') {
            $('#idDiv').html('아이디를 입력하세요.').css('color', 'red'); 
            return;
        }

        $.ajax({
            type: 'post',
            url: '/memberMVC/member/checkId.do', 
            data: {'id': id},
            dataType: 'text',
            success: function(data){			   
                if (data.trim() === 'exist') {
                    $('#idDiv').html('이미 사용 중인 아이디입니다.').css('color', 'red');
                } else {
                    $('#idDiv').html('사용가능한 아이디입니다.').css('color', 'green'); 
                    $('#check').val($('#id').val()); // 중복 체크가 완료된 아이디 저장
                }
            },
            error: function(e){
                console.log(e);
            }
        });
    });
});
</script>
</body>
</html>

//회원가입
function memberWrite(e){
    let isValid = true; // 유효성 검사를 통과하면 true, 아니면 false

    document.getElementById("nameDiv").innerHTML = "";
    document.getElementById("idDiv").innerHTML = "";
    document.getElementById("pwdDiv").innerHTML = "";
    document.getElementById("repwdDiv").innerHTML = "";
    
    if(document.memberWriteForm.name.value == ""){
        document.getElementById("nameDiv").innerHTML = "이름을 입력해주세요.";
		e.preventDefault();
		isValid = false;
    }
    
    if(document.getElementById("id").value == ""){
        document.getElementById("idDiv").innerHTML = "아이디를 입력해주세요.";
        e.preventDefault();
		isValid = false;
    }

    if(document.getElementById("pwd").value == ""){
        document.getElementById("pwdDiv").innerHTML = "비밀번호를 입력해주세요.";
		e.preventDefault();
		isValid = false;
    }
    
    if(document.getElementById("pwd").value != document.getElementById("repwd").value){
        document.getElementById("repwdDiv").innerHTML = "비밀번호가 맞지 않습니다.";
		e.preventDefault();
		isValid = false;
    }

    // 중복 체크 확인
    if(document.getElementById("check").value != document.getElementById("id").value){
        document.getElementById("idDiv").innerHTML = "중복체크를 해주세요!";
		e.preventDefault();
		isValid = false;
    }

    if(isValid)
		 $.ajax({
			type: 'post',
			url:'/projectMVC/member/write.do',
			data: $('#writeForm').serialize(),
			success: function(){
				alert('회원가입을 축하합니다.');
				location.href = '/projectMVC/index.jsp';
			},
			error: function(e){
				console.log(e);
			}
		 });
}

/member/write.do=member.service.WriteService

 


WriteService.java

package member.service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.control.CommandProcess;

import member.bean.MemberDTO;
import member.dao.MemberDAO;

public class WriteService implements CommandProcess {

	@Override
	public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Throwable {
		
		//데이터
		String name = request.getParameter("name");
		String id = request.getParameter("id");
		String pwd = request.getParameter("pwd");
		String gender = request.getParameter("gender");
		String email1 = request.getParameter("email1");
		String email2 = request.getParameter("email2");
		String tel1 = request.getParameter("tel1");
		String tel2 = request.getParameter("tel2");
		String tel3 = request.getParameter("tel3");
		String zipcode = request.getParameter("zipcode");
		String addr1 = request.getParameter("addr1");
		String addr2 = request.getParameter("addr2");
		
		MemberDTO memberDTO = new MemberDTO();
		memberDTO.setName(name);
		memberDTO.setId(id);
		memberDTO.setPwd(pwd);
		memberDTO.setGender(gender);
		memberDTO.setEmail1(email1);
		memberDTO.setEmail2(email2);
		memberDTO.setTel1(tel1);
		memberDTO.setTel2(tel2);
		memberDTO.setTel3(tel3);
		memberDTO.setZipcode(zipcode);
		memberDTO.setAddr1(addr1);
		memberDTO.setAddr2(addr2);
		
		//DB
		MemberDAO memberDAO = MemberDAO.getInstance();
		memberDAO.memberWrite(memberDTO);
				
		return "none";
	}

}

 


회원정보 수정

nav.jsp

<c:if test="${memId != null}">
	<h3>${memId }님이 로그인</h3>
	<input type="button" value="로그아웃" id="logoutBtn"/><br/><br/>
	<input type="button" value="회원정보수정"
	       onclick="location.href='${ pageContext.request.contextPath }/member/updateForm.do'" /><br/><br/>
</c:if>

/member/updateForm.do=member.service.UpdateFormService

UpdateFormService.java

package member.service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.control.CommandProcess;

import member.bean.MemberDTO;
import member.dao.MemberDAO;

public class UpdateFormService implements CommandProcess {

	@Override
	public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Throwable {
        // 세션에서 사용자 ID를 가져옴
        HttpSession session = request.getSession();
        String id = (String) session.getAttribute("memId");

        // DB에서 회원 정보 가져오기
        MemberDAO memberDAO = MemberDAO.getInstance();
        MemberDTO memberDTO = memberDAO.getMember(id);

        // 회원 정보를 request에 저장 (JSP에서 사용)
        request.setAttribute("memberDTO", memberDTO);
        
		return "/member/memberUpdateForm.jsp";
	}

}

memberUpdateForm.jsp

<form name="memberUpdateForm" id="memberUpdateForm">


member.js

if(isValid){
        $.ajax({
            type: 'post',
            url: '/projectMVC/member/update.do',
            data: $('form').serialize(),
            dataType: 'text',
            success: function(){
                alert('회원정보가 수정되었습니다.');
                window.location.href = "/projectMVC/index.do";
            },
            error: function(e){
                console.log(e);
            }
        });
    }

UpdateService.java

package member.service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.control.CommandProcess;

import member.bean.MemberDTO;
import member.dao.MemberDAO;

public class UpdateService implements CommandProcess {

    @Override
    public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Throwable {

        String id = request.getParameter("id");
        String name = request.getParameter("name");
        String pwd = request.getParameter("pwd");
        String gender = request.getParameter("gender");
        String email1 = request.getParameter("email1");
        String email2 = request.getParameter("email2");
        String tel1 = request.getParameter("tel1");
        String tel2 = request.getParameter("tel2");
        String tel3 = request.getParameter("tel3");
        String zipcode = request.getParameter("zipcode");
        String addr1 = request.getParameter("addr1");
        String addr2 = request.getParameter("addr2");

        MemberDTO memberDTO = new MemberDTO();
        memberDTO.setId(id);  // 세션에서 가져온 ID 설정
        memberDTO.setName(name);
        memberDTO.setPwd(pwd);
        memberDTO.setGender(gender);
        memberDTO.setEmail1(email1);
        memberDTO.setEmail2(email2);
        memberDTO.setTel1(tel1);
        memberDTO.setTel2(tel2);
        memberDTO.setTel3(tel3);
        memberDTO.setZipcode(zipcode);
        memberDTO.setAddr1(addr1);
        memberDTO.setAddr2(addr2);

        // DB
        MemberDAO memberDAO = MemberDAO.getInstance();
        memberDAO.memberUpdate(memberDTO);  // 회원 정보 업데이트

        HttpSession session = request.getSession();
        session.invalidate();
        
        return "none"; 
    }
}

nav.jsp

<c:if test="${memId != null}">
	<h3><a href="${ pageContext.request.contextPath }/member/updateForm.do">${memId }</a>님이 로그인</h3>
	<input type="button" value="로그아웃" id="logoutBtn"/><br/><br/>
	<input type="button" value="회원정보수정"
	       onclick="location.href='${ pageContext.request.contextPath }/member/updateForm.do'" /><br/><br/>
</c:if>

이름 누르면 회원정보 수정으로 가게하기 !


글쓰기

menu.jsp

<ul class="mainnav">
	<c:if test="${sessionScope.memId != null }">
		<li><a href="${ pageContext.request.contextPath }/board/boardWriteForm.do">글쓰기</a></li>
	</c:if>
	<li><a href="">목록</a></li>
</ul>

BoardWriteFormService.java

package board.service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.control.CommandProcess;

public class BoardWriteFormService implements CommandProcess {

	@Override
	public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Throwable {
		return "/board/boardWriteForm.jsp";
	}

}

boardWriteForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시글 작성 페이지</title>
<style type="text/css">
body {
    background-color: #FFE2FA;
    font-family: 'Arial', sans-serif;
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 80vh;
    flex-direction: column;
}

table {
    border-collapse: collapse;
    border-radius: 10px;
    background-color: white;
    width: 700px;
    padding: 20px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    margin: 0 auto;
}

th, td {
    padding: 10px 15px;
    text-align: left;
    font-size: 14px;
}

th {
    color: #333;
    font-size: 16px;
}

td {
    color: #333;
}

div {
    color: red;
    font-size: 8pt;
    font-weight: bold;
    margin-top: 5px;
}

input[type="text"], textarea {
    padding: 8px;
    margin-top: 5px;
    border: 1px solid #CCC;
    border-radius: 5px;
    box-sizing: border-box;
    width: 100%;
    font-size: 14px;
}

textarea {
    resize: none;
}

input[type="button"], input[type="submit"], input[type="reset"] {
    background-color: #FF9ADB;
    border: none;
    font-size: 14px;
    padding: 8px 12px;
    border-radius: 5px;
    cursor: pointer;
    color: white;
    transition: background-color 0.3s ease;
    margin: 5px;
}

input[type="button"]:hover, input[type="submit"]:hover, input[type="reset"]:hover {
    background-color: #FF70C0;
}

img {
    margin-bottom: 20px;
    cursor: pointer;
    display: block;
}

table td[colspan="2"] {
    text-align: center;
}
</style>
</head>
<body>
   <img src="../image/free-icon-love-4096198.png" alt="홈" width="60" height="60" onclick="location.href='${ pageContext.request.contextPath }/index.do'" />
   <form id="boardWriteForm" method="post">
      <table border="1">   
         <tr>
            <th>제목</th>
            <td>
               <input type="text" name="subject" id="subject" size="65" placeholder="제목 입력"/>
               <div id="subjectDiv"></div>
            </td>
         </tr>
         <tr>
            <th>내용</th>
            <td>
               <textarea name="content" id="content" cols="65" rows="15" placeholder="내용을 입력하세요"></textarea>
               <div id="contentDiv"></div>
            </td>
         </tr>
         <tr>
            <td colspan="2" align="center">
               <input type="submit" id="writeBtn" value="글쓰기" />
               <input type="reset" value="다시작성" />
            </td>
         </tr>
      </table>
   </form>

<script type="text/javascript" src="http://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="../js/board.js"></script>
</body>
</html>


boardWriteForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시글 작성 페이지</title>
<style type="text/css">
body {
    background-color: #FFE2FA;
    font-family: 'Arial', sans-serif;
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 80vh;
    flex-direction: column;
}

table {
    border-collapse: collapse;
    border-radius: 10px;
    background-color: white;
    width: 700px;
    padding: 20px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    margin: 0 auto;
}

th, td {
    padding: 10px 15px;
    text-align: left;
    font-size: 14px;
}

th {
    color: #333;
    font-size: 16px;
}

td {
    color: #333;
}

div {
    color: red;
    font-size: 8pt;
    font-weight: bold;
    margin-top: 5px;
}

input[type="text"], textarea {
    padding: 8px;
    margin-top: 5px;
    border: 1px solid #CCC;
    border-radius: 5px;
    box-sizing: border-box;
    width: 100%;
    font-size: 14px;
}

textarea {
    resize: none;
}

input[type="button"], input[type="submit"], input[type="reset"] {
    background-color: #FF9ADB;
    border: none;
    font-size: 14px;
    padding: 8px 12px;
    border-radius: 5px;
    cursor: pointer;
    color: white;
    transition: background-color 0.3s ease;
    margin: 5px;
}

input[type="button"]:hover, input[type="submit"]:hover, input[type="reset"]:hover {
    background-color: #FF70C0;
}

img {
    cursor: pointer;   
}

table td[colspan="2"] {
    text-align: center;
}
</style>
</head>
<body>
   <div id="header">
		<h1>
			<img alt="하트" src="${ pageContext.request.contextPath }/image/free-icon-love-4096198.png" width="60" height="60">
			MVC를 활용한 미니프로젝트
		</h1>
   </div>
   
   <div id="container">
   	<jsp:include page="../main/boardMenu.jsp" />
		<div id="section">
		  <%--  <img src="../image/free-icon-love-4096198.png" alt="홈" width="60" height="60" onclick="location.href='${ pageContext.request.contextPath }/index.do'" /> --%>
		   <form id="boardWriteForm" method="post">
		
		      <table border="1">   
		         <tr>
		            <th>제목</th>
		            <td>
		               <input type="text" name="subject" id="subject" size="65" placeholder="제목 입력"/>
		               <div id="subjectDiv"></div>
		            </td>
		         </tr>
		         <tr>
		            <th>내용</th>
		            <td>
		               <textarea name="content" id="content" cols="65" rows="15" placeholder="내용을 입력하세요"></textarea>
		               <div id="contentDiv"></div>
		            </td>
		         </tr>
		         <tr>
		            <td colspan="2" align="center">
		               <input type="submit" id="writeBtn" value="글쓰기" />
		               <input type="reset" value="다시작성" />
		            </td>
		         </tr>
		      </table>
		   </form>
   </div>
</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="../js/board.js"></script>
</body>
</html>


boardMenu.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<style>
#container {
	margin: auto;
	width: 1100px;
	height: 500px;
}

#container:after {
	content: '';
	display: block;
	clear: both;
	float: none;
}

#nav {
	margin-left: 10px;
	width: 25%;
	height: 100%;
	float: left;
}

#section {
	width: 70%;
	height: 100%;
	float: left;
}
</style>
<div id="nav">
	<h3>
		<p>글쓰기</p>
		<p>목록</p>
	</h3>
</div>

boardWriteForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시글 작성 페이지</title>
<style type="text/css">
body {
    background-color: #FFE2FA;
    font-family: 'Arial', sans-serif;
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 80vh;
    flex-direction: column;
}

table {
    border-collapse: collapse;
    border-radius: 10px;
    background-color: white;
    width: 700px;
    padding: 20px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    margin: 0 auto;
}

th, td {
    padding: 10px 15px;
    text-align: left;
    font-size: 14px;
}

th {
    color: #333;
    font-size: 16px;
}

td {
    color: #333;
}

.red{
    color: red;
    font-size: 8pt;
    font-weight: bold;
    margin-top: 5px;
}

input[type="text"], textarea {
    padding: 8px;
    margin-top: 5px;
    border: 1px solid #CCC;
    border-radius: 5px;
    box-sizing: border-box;
    width: 100%;
    font-size: 14px;
}

textarea {
    resize: none;
}

input[type="button"], input[type="submit"], input[type="reset"] {
    background-color: #FF9ADB;
    border: none;
    font-size: 14px;
    padding: 8px 12px;
    border-radius: 5px;
    cursor: pointer;
    color: white;
    transition: background-color 0.3s ease;
    margin: 5px;
}

input[type="button"]:hover, input[type="submit"]:hover, input[type="reset"]:hover {
    background-color: #FF70C0;
}

img {
    cursor: pointer;   
}

table td[colspan="2"] {
    text-align: center;
}

</style>
</head>
<body>
   <div id="header">
		<h1>
			<img alt="하트" src="${ pageContext.request.contextPath }/image/free-icon-love-4096198.png" width="60" height="60" onclick="location.href='${ pageContext.request.contextPath }/index.do'">
			MVC를 활용한 미니프로젝트
		</h1>
   </div>
   
   <hr/>
   
   
   <div id="container">
   	<jsp:include page="../main/boardMenu.jsp" />
		<div id="section">
		  <%--  <img src="../image/free-icon-love-4096198.png" alt="홈" width="60" height="60" onclick="location.href='${ pageContext.request.contextPath }/index.do'" /> --%>
		   <form id="boardWriteForm" method="post">
		
		      <table border="1">   
		         <tr>
		            <th>제목</th>
		            <td>
		               <input type="text" name="subject" id="subject" size="65" placeholder="제목 입력"/>
		               <div class="red" id="subjectDiv"></div>
		            </td>
		         </tr>
		         <tr>
		            <th>내용</th>
		            <td>
		               <textarea name="content" id="content" cols="65" rows="15" placeholder="내용을 입력하세요"></textarea>
		               <div class="red" id="contentDiv"></div>
		            </td>
		         </tr>
		         <tr>
		            <td colspan="2" align="center">
		               <input type="submit" id="writeBtn" value="글쓰기" />
		               <input type="reset" value="다시작성" />
		            </td>
		         </tr>
		      </table>
		   </form>
   </div>
</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="../js/board.js"></script>
</body>
</html>

 


board.js

$(function () {
    $('#writeBtn').on('click', function(event) {
        event.preventDefault();  // 기본 폼 제출 방지

        $('#subjectDiv').empty();
        $('#contentDiv').empty();
        let isValid = true;

        // 제목 검사
        if ($('#subject').val().trim() === '') {
            $('#subjectDiv').html('제목을 입력하세요.');
            $('#subject').focus();
            isValid = false;
        }

        // 내용 검사
        if ($('#content').val().trim() === '') {
            $('#contentDiv').html('내용을 입력하세요.');
            $('#content').focus();
            isValid = false;
        }

        // 유효성 검사를 모두 통과한 경우에만 ajax 요청 실행
        if (isValid) {
            $.ajax({
                type: 'post',
                url: '/projectMVC/board/boardWrite.do',
                data: {
					'subject' : $('#subject').val(),
					'content' : $('#content').val()
				},  
                success: function() {
                    alert('게시물 작성에 성공하였습니다!');
                    window.location.href = "../board/boardList2.jsp?pg=1";  
                },
                error: function(e) {
                    console.log(e);
                }
            });
        }
    });
});

command.properties

/board/boardWrite.do=board.service.BoardWriteService

BoardWriteService.java

package board.service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.control.CommandProcess;

import board.bean.BoardDTO;
import board.dao.BoardDAO;

public class BoardWriteService implements CommandProcess {

	@Override
	public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Throwable {
		HttpSession session = request.getSession();
		
		String id = (String) session.getAttribute("memId");
		String name = (String) session.getAttribute("memName");
		String email = (String) session.getAttribute("memEmail");
		
		String subject = request.getParameter("subject");
		String content = request.getParameter("content");
		
		System.out.println("subject = " + subject);
		System.out.println("content = " + content);
		System.out.println("id = " + id);
		System.out.println("name = " + name);
		System.out.println("email = " + email);
		
		BoardDTO boardDTO = new BoardDTO();
		boardDTO.setId(id);
		boardDTO.setName(name);
		boardDTO.setEmail(email);
		boardDTO.setSubject(subject);
		boardDTO.setContent(content);
		
		BoardDAO boardDAO = BoardDAO.getInstance(); 
		boardDAO.boardWrite(boardDTO);
		
		return "none";
	}

}

BoardDAO.java

	public void boardWrite(BoardDTO boardDTO) {
		SqlSession sqlSession = sqlSessionFactory.openSession(); //생성		
		sqlSession.insert("boardSQL.boardWrite", boardDTO);
		sqlSession.commit();
		sqlSession.close();
	}

boardMapper.xml

	<!-- 글쓰기 -->
    <insert id="boardWrite" parameterType="board.bean.BoardDTO">
        insert into board (seq, id, name, email, subject, content, ref)
        values(seq_board.NEXTVAL, #{id}, #{name}, #{email}, #{subject}, #{content}, seq_board.CURRVAL)
    </insert>

글목록

menu.jsp

<ul class="mainnav">
	<c:if test="${sessionScope.memId != null }">
		<li><a href="${ pageContext.request.contextPath }/board/boardWriteForm.do">글쓰기</a></li>
	</c:if>
	<li><a href="${ pageContext.request.contextPath }/board/boardList.do?pg=1">목록</a></li>
</ul>

command.properties

#글목록
/board/boardList.do=board.service.BoardListService

BoardListService.java

package board.service;

import java.text.SimpleDateFormat;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONArray;
import org.json.JSONObject;

import com.control.CommandProcess;

import board.bean.BoardDTO;
import board.bean.BoardPaging;
import board.dao.BoardDAO;

public class BoardListService implements CommandProcess {

	@Override
	public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Throwable {
		int pg = Integer.parseInt(request.getParameter("pg"));

		//1페이지당 5개씩
		int endNum = pg * 5;
		int startNum = endNum - 4;

		//DB
	    BoardDAO boardDAO = BoardDAO.getInstance();
	    List<BoardDTO> list = boardDAO.boardList(startNum, endNum);
	    
	    //페이징 처리
	    int totalA = boardDAO.getTotalA();
	    
	    BoardPaging boardPaging = new BoardPaging();
	    boardPaging.setCurrentPage(pg);
	    boardPaging.setPageBlock(3);
	    boardPaging.setPageSize(5);
	    boardPaging.setTotalA(totalA);
	    
	    boardPaging.makePagingHTML();
	    
	    request.setAttribute("list", list);
	    request.setAttribute("boardTotalA", boardPaging.getTotalA());
	    request.setAttribute("boardPagingHTML", boardPaging.getPagingHTML());
	    
	    return "/board/boardList2.jsp";
	}

}

BoardDAO.java

	public List<BoardDTO> boardList(int startNum, int endNum){
		Map<String, Integer> map = new HashMap<>();
		map.put("startNum", startNum);
		map.put("endNum", endNum);
		
		SqlSession sqlSession = sqlSessionFactory.openSession(); //생성
		List<BoardDTO> list = sqlSession.selectList("boardSQL.boardList", map);
		sqlSession.close();
		return list;
	}

boardMapper.xml

    <!-- 글목록 -->
	<select id="boardList" parameterType="java.util.Map" resultType="board.bean.BoardDTO">
	    <![CDATA[
	    	select * from (
	        select rownum rn, tt.* from (
	            select * from board order by ref desc, step asc
	        ) tt
	    	)where rn >= #{startNum} and rn <= #{endNum}
	    ]]>
	</select>

boardList2.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시물 목록</title>
<style type="text/css">
body {
    background-color: #FFE2FA;
    font-family: 'Arial', sans-serif;
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 70vh;
    flex-direction: column;
}

table {
    border-collapse: collapse;
    border-radius: 10px;
    background-color: white;
    width: 800px;
    padding: 20px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    margin: 0 auto;
}

th, td {
    padding: 10px;
    border: 1px solid #CCC;
    text-align: center;
    font-size: 14px;
}

th {
    background-color: #F2F2F2;
    color: #333;
    font-size: 16px;
}

td {
    color: #333;
}

#currentPaging {
	color: red;
	font-size: 15px;
	padding: 5px 8px;
	margin: 3px;
}

#paging {
	color: black;
	font-size: 15px;
	padding: 5px 8px;
	margin: 3px;	
}

span:hover {
	text-decoration: underline;
	cursor: pointer;
}

img {
    margin-bottom: 20px;
    cursor: pointer;
    display: block;
}
</style>
</head>
<body>
 <img src="../image/free-icon-love-4096198.png" alt="홈" width="60" height="60" onclick="location.href='../index.jsp'" />
    
    <table>
        <thead>
            <tr>
                <th>글번호</th>
                <th>제목</th>
                <th>작성자</th>
                <th>작성일</th>
                <th>조회수</th>
            </tr>
        </thead>
        <tbody>
        	<c:if test="${list != null}">
        		<c:forEach var="boardDTO" items="${list}">       		
        		 <tr> 
                     <td>${boardDTO.getSeq()}</td>
                     <td>
                         <a href="/projectMVC/board/boardDetail.do?seq=${boardDTO.getSeq()}">
                             ${boardDTO.getSubject()}
                         </a>
                     </td>
                     <td>${boardDTO.getName()}</td>
                     <td>
                     	${boardDTO.getLogtime()}
                     </td>
                     <td>${boardDTO.getHit()}</td>
                 </tr>
                 </c:forEach>
        	  </c:if> 	
        </tbody>
    </table>
	<div style="margin-top: 15px;">
		${boardPagingHTML}
	</div>

<script type="text/javascript">
function boardPaging(pg){
	location.href = "/projectMVC/board/boardList2.do?pg=" + pg;
}
</script>
</body>
</html>

BoardPaging.java

package board.bean;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class BoardPaging {
	private int currentPage; //현재페이지
	private int pageBlock; //[이전][1][2][3][다음]
	private int pageSize; //1페이지당 5개씩
	private int totalA; //총글수
	private StringBuffer pagingHTML;
	
	public void makePagingHTML() {
		pagingHTML = new StringBuffer();
		
		int totalP = (totalA + pageSize-1) / pageSize;
		
		int startPage = (currentPage-1) / pageBlock * pageBlock + 1;
		int endPage = startPage + pageBlock - 1;
		if(endPage > totalP)
			endPage = totalP;
		
		if(startPage != 1)
			pagingHTML.append("<span id='paging' onclick='boardPaging(" + (startPage-1) + ")'>이전</span>");
		
		for(int i=startPage; i<=endPage; i++) {
			if(i == currentPage)
				pagingHTML.append("<span id='currentPaging' onclick='boardPaging(" + i + ")'>" + i + "</span>");
			else
				pagingHTML.append("<span id='paging' onclick='boardPaging(" + i + ")'>" + i + "</span>");
		}//for
		
		if(endPage < totalP)
			pagingHTML.append("<span id='paging' onclick='boardPaging(" + (endPage+1) + ")'>다음</span>");
	}
}

BoardDAO.java

	public int getTotalA() {
		SqlSession sqlSession = sqlSessionFactory.openSession(); //생성
		int totalA = sqlSession.selectOne("boardSQL.getTotalA");
		sqlSession.close();
		return totalA;
	}

boardMapper.xml

	<!-- 총글수 -->
    <select id="getTotalA" resultType="int">
        select count(*) from board
    </select>

글 상세보기

command.properties

#글 상세보기
/board/boardDetail.do=board.service.BoardDetailService

BoardDetailService.java

package board.service;

import java.text.SimpleDateFormat;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.control.CommandProcess;

import board.bean.BoardDTO;
import board.dao.BoardDAO;

public class BoardDetailService implements CommandProcess {

	@Override
	public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Throwable {
		String seq = request.getParameter("seq");
		
		BoardDAO boardDAO = BoardDAO.getInstance();
		BoardDTO boardDTO = boardDAO.boardDetail(seq);
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
	    String logtime = sdf.format(boardDTO.getLogtime());
	        
	    request.setAttribute("boardDTO", boardDTO);
        request.setAttribute("logtime", logtime);
		return "/board/boardDetail.jsp";
	}

}

BoardDAO.java

	public BoardDTO boardDetail(String no) {
		SqlSession sqlSession = sqlSessionFactory.openSession(); //생성
		BoardDTO boardDTO = sqlSession.selectOne("boardSQL.boardDetail", no);
		sqlSession.close();
		return boardDTO;
	}

boardMapper.xml

<!-- 글 상세보기 -->
	<select id="boardDetail" parameterType="String" resultType="board.bean.BoardDTO">
 		select * from board where seq = #{no}
 	</select>

boardDetail.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
body {
    background-color: #FFE2FA;
    font-family: 'Arial', sans-serif;
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 80vh;
    flex-direction: column;
}

table {
    border-collapse: collapse;
    border-radius: 10px;
    background-color: white;
    width: 700px;
    padding: 20px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    margin: 0 auto;
}

th, td {
    padding: 10px 15px;
    text-align: left;
    font-size: 14px;
}

th {
    color: #333;
    font-size: 16px;
}

td {
    color: #333;
}

#contentDiv, #subjectDiv {
    color: red;
    font-size: 8pt;
    font-weight: bold;
    margin-top: 5px;
}

input[type="text"], textarea {
    padding: 8px;
    margin-top: 5px;
    border: 1px solid #CCC;
    border-radius: 5px;
    box-sizing: border-box;
    width: 100%;
    font-size: 14px;
}

textarea {
    resize: none;
}

input[type="button"], input[type="submit"], input[type="reset"] {
    background-color: #FF9ADB;
    border: none;
    font-size: 14px;
    padding: 8px 12px;
    border-radius: 5px;
    cursor: pointer;
    color: white;
    transition: background-color 0.3s ease;
    margin: 5px;
}

input[type="button"]:hover, input[type="submit"]:hover, input[type="reset"]:hover {
    background-color: #FF70C0;
}

img {
    margin-bottom: 20px;
    cursor: pointer;
    display: block;
}

table td[colspan="2"] {
    text-align: center;
}
</style>
</head>
<body>
    <img src="../image/free-icon-love-4096198.png" alt="홈" width="60" height="60" onclick="location.href='/projectMVC/index.do'" />

    <table border="1">
        <tr>
            <th>글 번호</th>
            <td>${boardDTO.seq}</td>
        </tr>
        <tr>
            <th>제목</th>
            <td>${boardDTO.subject}</td>
        </tr>
        <tr>
            <th>작성자</th>
            <td>${boardDTO.name}</td>
        </tr>
        <tr>
            <th>작성 일자</th>
            <td>${logtime}</td>
        </tr>
        <tr>
            <th>내용</th>
            <td>${boardDTO.content}</td>
        </tr>
        <tr>
            <td colspan="2" align="center">
                <input type="button" id="backBtn" value="뒤로 가기" onclick="window.history.back()" />
                <input type="button" id="updateBtn" value="수정" style="display: none;" />
                <input type="button" id="deleteBtn" value="삭제" style="display: none;" />
            </td>
        </tr>
    </table>
</body>
</html>
summ.n