반응형

안녕들 하시죠 !

이번시간 부터는 Jsp/Servlet 등의 기술을 이용하여 개인 홈페이지를 구축해보겠습니다.

이번 게시물에서는 전체적인 앞단을, 다음 게시물부터는 뒷단위주로 작성하며 기능들을 추가해 보겠습니다.

오로지 기능구현에만 초점을 맞춘 게시물입니다.

사용언어와 문법

Oracle database, HTML5, Javascript, JSP/Servlet, JQuery, EL, JSTL 등

 

MVC 패턴사용

Servlet -> Service -> DAO 순으로 비지니스 로직을 분리하는 디자인 패턴을 사용.

 

앞단 구성에 사용될 .jsp와 .jar 파일들

 

Jsp/Servlet을 이용한 개인 홈페이지 만들기 --1의 결과물

메인 화면

로그인 화면

회원가입 화면

 

Database 구성

향후 게시판이나 관리자 페이지 등을 진행할 예정이지만 여기에선 회원(Customers), 우편번호(Post)만 만들겠습니다.

http://www.epost.go.kr/search/zipcode/cmzcd002k01.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
CREATE TABLE Customers(    
    customer_id VARCHAR2(50), -- 사용자 id
    customer_pwd VARCHAR2(50NOT NULL-- 사용자 pwd 
    customer_status NUMBER, -- 사용자 상태검사
    customer_addr VARCHAR2(100), -- 사용자 주소 + 상세주소
    customer_name VARCHAR2(30), -- 사용자 이름
    customer_buildingno VARCHAR2(100), -- 상세건물번호 
    constraint customers_pk PRIMARY KEY(customer_id) -- 사용자 id p키로 설정
);
 
CREATE TABLE post(
    zipcode varchar2(5),
    sido varchar2(21),
    sidoe varchar2(40),
    sigungu varchar2(20),
    sigungue varchar2(40),
    eupmyun varchar2(20),
    eupmyune varchar2(40),
    dorocode varchar2(12),  --도로명코드
    doro varchar2(80),  --도로명
    doroe varchar2(80),
    jiha varchar2(1),
    building1 varchar2(5), --건물번호 본번
    building2 varchar2(5), --건물번호 부번
    buildingno varchar2(25),  --건물관리번호
    daryang varchar2(40),
    building varchar2(200), --시군구용건물명
    dongcode varchar2(10),
    dong varchar2(20), --법정동명
    ri varchar2(20),
    dongadmin varchar2(40),
    san varchar2(1),
    zibun1 varchar2(4),
    zibunserial varchar2(2),
    zibun2 varchar2(4),
    zipoldcode varchar2(6),
    zipcodeserial varchar2(3));
cs

 

 

main.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
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="contextPath" value="${pageContext.request.contextPath}"/>
<style>
a{
text-decoration: none;
}
</style>
<body>
<header>
                                    <!-- 페이지 타이틀을 클릭하면 메인화면으로 이동 -->
    <p  style="text-align: center; "><a href='${contextPath}/main/main.jsp'> 
    <font color="black" id="HOME"> HONGPOSSIBLE HOMEPAGE </font></a></p>
    <div style="text-align: right;">
 
    <jsp:include page="menu.jsp"/> <!-- 상세메뉴인 menu.jsp를 include해 사용 -->
    </div>
    <hr>
    <br>
    <br>
</header>
<section><p style="text-align: center;">안녕하세요</p></section>
</body>
cs

 

menu.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
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="contextPath" value="${pageContext.request.contextPath}"/>
<script>
var loadMenu = function(u, callback){
    $.ajax({
        url: u,
        method: 'GET',
        success: function(data){
            callback(data);
        }
    });
};
 
var loadLogin = function(data){ // section 영역을 비우고 그 자리에 Login 페이지를 넣는다.
    $("section").empty();
    $("section").html(data);
};
var loadJoin = function(data){ 
    $("section").empty();
    $("section").html(data);
};
 
 
$(function(){
    var $menuArr = $("#coreTopMenu>span>a"); // 메뉴(Login, Join) 페이지를 찾아 배열형태로 변수에 저장.
    $menuArr.click(function(event){        
        var url = $(this).attr('href');
        switch(url){
        case '${contextPath}/main/login.jsp':
            loadMenu(url, loadLogin);
            break;
        case '${contextPath}/main/join.jsp':
            loadMenu(url, loadJoin);
            break;
        };
    return false;  //이벤트전달 중지
    });
});
</script>    
 
<div>
<ul  id="coreTopMenu">
<span><a href='${contextPath}/main/login.jsp'><font color="black"> 로그인 </font></a></span>&nbsp;&nbsp;
<span><a href='${contextPath}/main/join.jsp'><font color="black"> 회원가입 </font></a></span>
</ul>
</div>
cs

 

login.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
60
61
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <c:set var="contextPath" value="${pageContext.request.contextPath}"/>
<script>
$(function(){
    $("#loginbtn").click(function(){
        if($("#idid").val().trim() == 0){ // id 입력란이 공백인 상태로 로그인 버튼이 
                                          // 눌리게 되면 .focus()를 이용해 입력유도.
            $("#idid").focus();
        } else if($("input[name=pwd]").val().trim() == 0){
            $("input[name=pwd]").focus();
        } 
        else{
            $.ajax({ // 입력이슈가 발생하지 않는다면 ajax 요청
                url: '${contextPath}/login'//EL문법을 이용하여 경로지정, 
                                             // login Servlet으로 데이터 전송.
                method:'post'// post 방식으로 요청.
                data:$('form').serialize(), // form 태그안에 있는 입력된 값을 싹 긁어 전송. 
                                // 데이터 전달을 위해 name 속성을 꼭 작성해야한다.(다음게시물에서 설명)
                success: function(data){
                    var jsonObj = JSON.parse(data);
                    var msg = jsonObj.id + "님 로그인 ";
                    if(jsonObj.status == 1){ // 로그인 여부를 판단해주는 Service에서 설정한 status 
                                             //값이 1이면 로그인 성공. (다음게시물에서 설명)
                        msg += "성공";
                            location.href='${contextPath}/main/main.jsp';
                        alert(msg);
                    }else {
                        msg += "실패";
                        alert(msg);
                    }
                }
            });
         } 
        return false;
    });
});    
</script>
 
<div style="text-align: center;">
<form>
    <div>
        아이디 &nbsp;&nbsp; 
        <input type="text" placeholder="아이디를 입력하세요."  name="id" id="idid" 
        style="height: 30px; margin-left: 30px;"/>
    </div>
    <br>
    <div>
        비밀번호 &nbsp;&nbsp;
        <input type="password" placeholder="비밀번호를 입력하세요." name="pwd" 
        style="height: 30px; margin-left: 15px;"/>
    
    </div>
    <br>
    <div>
        <button type="submit" id="loginbtn">로그인</button>&nbsp;&nbsp;
        <button>회원가입</button>
    </div>
    </form>
</div>
cs

 

join.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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="contextPath" value="${pageContext.request.contextPath}"/>
<script>
$(function() {
       var $idObj = $("input[name=id]");
       var $submitObj = $("input[type=submit]");
       $submitObj.hide();
       
       $submitObj.click(function() {
        // 비밀번호 + 비밀번호 확인 검사
          if ( $("input[name=pwd]").val() != $("input[name=pwd1]").val()){ 
             alert("비밀번호가 일치하지 않습니다");
             return false;
          }
          $.ajax({
             url : '${contextPath}/join',
             method : 'POST',
             data : $("#joinform").serialize(),
             success : function(data) {
                var jsonObj = JSON.parse(data);
                if (jsonObj.status == 1) {
                      alert("회원가입 완료");
                   // 트리거이벤트 메인화면으로
                   var $main = $("#HOME");
                   $main.trigger('click');
                } else {
                   alert("필수 항목을 입력해 주세요!");
                }
             }
          });
          return false;
       });
       
       var $dupchkObj =  $("#dupchk");
       $dupchkObj.click(function(){ // 아이디 중복검사
          $.ajax({
             url:'${contextPath}/dupchk',
             method:'post',
             data:'id='+$("input[name=id]").val(),
             success:function(data){
                var jsonObj = JSON.parse(data);
                if(jsonObj.status == 1){
                   alert("사용할 수 있는 아이디 입니다");
                   $submitObj.show();                   
                }
                else if(jsonObj.status == -1){
                   alert("중복된 아이디 입니다 !!");
                   return false;
                }
             }
          });
       });
 
       var $searchZipObj = $("#searchZip");
       $searchZipObj.click(function() { // 우편번호 검색버튼 클릭
          $("#divSearchZip").show();
       });
       
       $("#divSearchZip form").submit(function(){ // 우편번호 검색 세부창
          $.ajax({
          url : '${contextPath}/searchzip',
          method : 'POST',
          data : 'doro='+ $("#divSearchZip .search_pop input[type=text]").val(),
          success : function(data) {
             var jsonObj = JSON.parse(data);
             var trs = "<tr><th>우편번호</th><th>주소</th></tr>";
             for (var i = 0; i < jsonObj.length; i++) {
                trs += "<tr id="+jsonObj[i].buildingno+"><td>"
                      + jsonObj[i].zipcode
                      + "</td>"
                      + "<td><div>"
                      + jsonObj[i].doroaddr
                      + "</div>"
                      + "<div>"
                      + jsonObj[i].buildingaddr
                      + "</div></td></tr>";
             }
             $("#divSearchZip>div>table").html(trs);
          }
          });
          return false;
       });
        // 검색 후 원하는 주소 클릭했을떄 값을 가져오는 기능.
       $("#divSearchZip>div>table").on("click","tr:not(:first-child)"function() {
             var children = $(this).children();
             var zipcode = children.eq(0).html();
             var doroaddr = children.find("div:first-child");
 
             $("input[name=zipcode]").val(zipcode);
             $("input[name=addr1]").val(doroaddr.html());
 
             $("#divSearchZip").hide();
             $("input[name=buildingno]").val($(this).attr("id"));
             console.log("빌딩번호 : " + $("input[name=buildingno]").val());
       });
       
       $("input[name=cancel]").click(function(){ // 취소버튼 클릭
          var $main = $("#HOME");
          $main.trigger('click');
       });
    });
</script>    
<style>
#divSearchZip {
   display: none;
}
 
#divSearchZip {
   padding: 8px;
   width: 300px;
   height: 300px;
   position: absolute;
   top: 150px;
   left: 750px;
   border: 1px solid transparent;
   background-color: #F5EDED;
}
 
#divSearchZip .search_pop input[type=text] {
   width: 80%;
   height: 36px;
   font-size: 14px;
   line-height: 16px;
   padding: 8px;
   margin: 0px;
   border: 2px solid #ee2e24;
   box-sizing: border-box;
   float: left;
}
 
#divSearchZip .search_pop button {
   width: 20%;
   height: 36px;
   background-color: #ee2e24;
   font-size: 14px;
   color: #fff;
   font-weight: bold;
   text-align: center;
   line-height: 32px;
   display: block;
   padding: 0px;
   margin: 0px;
   border: 0px;
   border: 2px solid #ee2e24;
   box-sizing: border-box;
   float: left;
}
 
#divSearchZip table {
   width: 100%;
   padding: 0px;
   margin: 10px 0px 20px 0px;
   border-bottom: 2px solid #888;
   color: #707070;
}
 
#divSearchZip tr:not (:first-child ):hover {
   cursor: pointer;
   font-weight: bold;
}
 
th, td {
   vertical-align: middle;
}
 
#divSearchZip>div {
   clear: both;
   overflow: auto;
   height: 80%;
}
</style>
<form id="joinform">
   <div>
      <div></div>
      <div class="joinTitle">
         <!-- 회원가입 텍스트 -->
         <div>
            <h2 style="margin-left: 230px;">회원 가입</h2>
         </div>
      </div>
      <!-- 회원가입 텍스트 -->
 
      <!-- <h4 style="margin : 20px 0 10px 5px; margin-left: 230px;" >필수 입력 정보</h4> -->
      <p class="required" style="text-align: right;  margin-right: 160px;">
         <font size="1px;">필수입력사항</font><img src="../images/ico_required.gif" alt="required Field">
      </p>
 
      <div class="joinInputArea">
         <!-- 가입 영역 -->
         <!-- 비밀번호 힌트 추가 ? -->
         <table width="940" style="padding: 5px 0 5px 0;" align="center">
 
            <tbody>
               <tr height="2" bgcolor="#FFC8C3">
                  <td colspan="2"></td>
               </tr>
               <tr>
               <tr>
                  <th scope="row">아이디 <img src="../images/ico_required.gif"
                     alt="required Field">
                  </th>
                  <td><input type="text" name="id" maxlength="16" required>
                     <button type="button" id="dupchk">중복확인</button>
                     <span style="font-size: 10px; margin-left: 7px; font-weight: bold;">
                     <img src="../images/ico_required.gif" alt="required Field">
                     중복확인을 성공해야 회원가입 버튼이 생성됩니다.</span></td>
               </tr>
 
               <tr>
                  <th scope="row">비밀번호 <img src="../images/ico_required.gif"
                     alt="required Field">
                  </th>
                  <td><input type="password" name="pwd" maxlength="16" required>
                  <span style="font-size: 10px; margin-left: 7px; font-weight: bold; margin-left: 83px;">
                     <img src="../images/ico_required.gif" alt="required Field">
                     중복확인 후에는 아이디를 수정할 수 없습니다.</span>
                  </td>
               </tr>
               
               <tr>
                  <th scope="row">비밀번호 확인 <img src="../images/ico_required.gif"
                     alt="required Field">
                  </th>
                  <td><input type="password" name="pwd1" maxlength="16"
                     required></td>
               </tr>
                <tr>
                  <th scope="row">이름 <img src="../images/ico_required.gif"
                     alt="required Field">
                  </th>
                  <td><input type="text" name="name" maxlength="16" required>
                     <br></td>
               </tr>
               <tr>
                  <th scope="row">주소 <img src="../images/ico_required.gif"
                     alt="required Field">
                  </th>
                  <td><input type="text" name="zipcode" readonly name="zipcode">
                     <button type="button" id="searchZip">우편번호 검색</button></td>
               </tr>
 
               <tr>
                  <th></th>
                  <td><input type="text" name="addr1" readonly name="addr1"
                     style="width: 270px;"></td>
               </tr>
 
               <tr>
                  <th></th>
                  <td><input type="text" name="addr2" style="width: 270px;" placeholder="나머지 주소"></td>
               </tr>
 
               <tr height="2" bgcolor="#FFC8C3">
                  <td colspan="2"></td>
               </tr>
               <tr>
                  <td colspan="2" align="center"><br> <input type="submit"
                     value="가입완료"> <input type="button" name="cancel"
                     value="취소"> <input type="hidden" name="buildingno"
                     value=""></td>
               </tr>
         </table>
      </div>
   </div>
</form>
<%-- 우편번호 찾기 영역 --%>
 
<div id="divSearchZip">
   <form>
      <div class="search_pop">
         <input type="text" placeholder="도로명 + 건물번호">
         <button>검색</button>
      </div>
 
   </form>
   <div>
      <table></table>
   </div>
</div>
cs

 

아마 위의 코드만 붙여넣기한다면 Servlet, Service, dao 가 없어 에러가 날 것입니다. 

당장 회원가입, 로그인 기능이 필요하신분들은 아래의 war 파일을 사용하시면 될 것 같습니다.

HomeEx.war
4.11MB

 

2019/09/01 - [꿀팁] - eclipse 프로젝트 war파일로 import, export 하기

 

다음 게시물에서 이어서 진행하겠습니다.

오늘은 여기까지입니다 감사합니다 !

 

 

 

+ Recent posts