본문 바로가기
웹 프로그래밍 기초/자바기반의 웹&앱 응용SW 개발자

자바기반의 웹&앱 응용 SW개발자 양성과정 41일차 -63

by oncerun 2020. 4. 28.
반응형

 

MVC MODEL2 방식으로 데이터베이스에서 데이터를 가져와 게시판을 만든 뒤

게시글을 클릭하면 작성자 정보가 나오는 실습.

 

 

1. MODEL2 방식이므로 컨트롤러와 뷰단을 분리해야 한다.

컨트롤러에는 자바 코드만을 넣고 뷰단에는 JSP로 작성한다.

 

준비물.

데이터베이스에서 데이터를 받을 클래스 파일 하나가 필요하다.

 

package com.newlec.web.entity;

import java.util.Date;

public class Notice {

	private int id;
	private String title;
	private String writerId;
	private String content;
	private Date regdate;
	private int hit;
	private String files;

	public Notice() {

	}

	public Notice(int id, String title, String writerId, 
			String content, Date regdate, int hit, String files) {
		this.id = id;
		this.title = title;
		this.writerId = writerId;
		this.regdate = regdate;
		this.hit = hit;
		this.files = files;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getWriterId() {
		return writerId;
	}

	public void setWriterId(String writerId) {
		this.writerId = writerId;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public Date getRegdate() {
		return regdate;
	}

	public void setRegdate(Date regdate) {
		this.regdate = regdate;
	}

	public int getHit() {
		return hit;
	}

	public void setHit(int hit) {
		this.hit = hit;
	}

	public String getFiles() {
		return files;
	}

	public void setFiles(String files) {
		this.files = files;
	}

	@Override
	public String toString() {
		return "Notice [id=" + id + ", title=" + title + ", "
				+ "writerId=" + writerId + ", content=" + content
				+ ", regdate=" + regdate + ", hit=" + hit + ", f"
						+ "iles=" + files + "]";
	}

}

 

2. JSP로 html 코드 작성

<%@page import="com.newlec.web.entity.Notice"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>




<!DOCTYPE html>
<html>

<head>
<title>코딩 전문가를 만들기 위한 온라인 강의 시스템</title>
<meta charset="UTF-8">
<title>공지사항목록</title>

<link href="/css/customer/layout.css" type="text/css" rel="stylesheet" />
<style>
#visual .content-container {
height: inherit;
display: flex;
align-items: center;
background: url("../../images/customer/visual.png") no-repeat center;
}
</style>
</head>

<body>
<!-- header 부분 -->

<header id="header">

<div class="content-container">
<!-- ---------------------------<header>--------------------------------------- -->

<h1 id="logo">
<a href="/index.html"> <img src="/images/logo.png" alt="뉴렉처 온라인" />

</a>
</h1>

<section>
<h1 class="hidden">헤더</h1>

<nav id="main-menu">
<h1>메인메뉴</h1>
<ul>
<li><a href="/guide">학습가이드</a></li>

<li><a href="/course">강좌선택</a></li>
<li><a href="/answeris/index">AnswerIs</a></li>
</ul>
</nav>

<div class="sub-menu">

<section id="search-form">
<h1>강좌검색 폼</h1>
<form action="/course">
<fieldset>
<legend>과정검색필드</legend>
<label>과정검색</label> <input type="text" name="q" value="" /> <input
type="submit" value="검색" />
</fieldset>
</form>
</section>

<nav id="acount-menu">
<h1 class="hidden">회원메뉴</h1>
<ul>
<li><a href="/index.html">HOME</a></li>
<li><a href="/member/login.html">로그인</a></li>
<li><a href="/member/agree.html">회원가입</a></li>
</ul>
</nav>

<nav id="member-menu" class="linear-layout">
<h1 class="hidden">고객메뉴</h1>
<ul class="linear-layout">
<li><a href="/member/home"><img
src="/images/txt-mypage.png" alt="마이페이지" /></a></li>
<li><a href="/notice/list.html"><img
src="/images/txt-customer.png" alt="고객센터" /></a></li>
</ul>
</nav>

</div>
</section>

</div>

</header>

<!-- --------------------------- <visual> --------------------------------------- -->
<!-- visual 부분 -->

<div id="visual">
<div class="content-container"></div>
</div>
<!-- --------------------------- <body> --------------------------------------- -->
<div id="body">
<div class="content-container clearfix">

<!-- --------------------------- aside --------------------------------------- -->
<!-- aside 부분 -->


<aside class="aside">
<h1>고객센터</h1>

<nav class="menu text-menu first margin-top">
<h1>고객센터메뉴</h1>
<ul>
<li><a class="current" href="/customer/notice">공지사항</a></li>
<li><a class="" href="/customer/faq">자주하는 질문</a></li>
<li><a class="" href="/customer/question">수강문의</a></li>
<li><a class="" href="/customer/event">이벤트</a></li>

</ul>
</nav>


<nav class="menu">
<h1>협력업체</h1>
<ul>
<li><a target="_blank" href="http://www.notepubs.com"><img
src="/images/notepubs.png" alt="노트펍스" /></a></li>
<li><a target="_blank" href="http://www.namoolab.com"><img
src="/images/namoolab.png" alt="나무랩연구소" /></a></li>

</ul>
</nav>

</aside>
<!-- --------------------------- main --------------------------------------- -->



<main class="main">
<h2 class="main title">공지사항</h2>

<div class="breadcrumb">
<h3 class="hidden">경로</h3>
<ul>
<li>home</li>
<li>고객센터</li>
<li>공지사항</li>
</ul>
</div>

<div class="search-form margin-top first align-right">
<h3 class="hidden">공지사항 검색폼</h3>
<form class="table-form">
<fieldset>
<legend class="hidden">공지사항 검색 필드</legend>
<label class="hidden">검색분류</label> <select name="f">
<option value="title">제목</option>
<option value="writerId">작성자</option>
</select> <label class="hidden">검색어</label> <input type="text" name="q"
value="" /> <input class="btn btn-search" type="submit"
value="검색" />
</fieldset>
</form>
</div>

<div class="notice margin-top">
<h3 class="hidden">공지사항 목록</h3>
<table class="table">
<thead>
<tr>
<th class="w60">번호</th>
<th class="expand">제목</th>
<th class="w100">작성자</th>
<th class="w100">작성일</th>
<th class="w60">조회수</th>
</tr>
</thead>
<tbody>

<%
List<Notice> list = (List<Notice>) request.getAttribute("list");
for (Notice n : list) {
pageContext.setAttribute("n", n);
%>
<tr>
<td>${n.id}</td>
<td class="title indent text-align-left"><a
href="detail?id=${n.id}">${n.title}></a></td>
<td>${n.writerId}</td>
<td>${n.regdate}</td>
<td>${n.hit}</td>
</tr>
<%
}
%>
</tbody>
</table>
</div>

<div class="indexer margin-top align-right">
<h3 class="hidden">현재 페이지</h3>
<div>
<span class="text-orange text-strong">1</span> / 1 pages
</div>
</div>

<div class="margin-top align-center pager">

<div>


<span class="btn btn-prev" onclick="alert('이전 페이지가 없습니다.');">이전</span>

</div>
<ul class="-list- center">
<li><a class="-text- orange bold" href="?p=1&t=&q=">1</a></li>

</ul>
<div>


<span class="btn btn-next" onclick="alert('다음 페이지가 없습니다.');">다음</span>

</div>

</div>
</main>


</div>
</div>

<!-- ------------------- <footer> --------------------------------------- -->



<footer id="footer">
<div class="content-container">
<h2 id="footer-logo">
<img src="/images/logo-footer.png" alt="회사정보">
</h2>

<div id="company-info">
<dl>
<dt>주소:</dt>
<dd>서울특별시</dd>
<dt>관리자메일:</dt>
<dd>admin@newlecture.com</dd>
</dl>
<dl>
<dt>사업자 등록번호:</dt>
<dd>111-11-11111</dd>
<dt>통신 판매업:</dt>
<dd>신고제 1111 호</dd>
</dl>
<dl>
<dt>상호:</dt>
<dd>뉴렉처</dd>
<dt>대표:</dt>
<dd>홍길동</dd>
<dt>전화번호:</dt>
<dd>111-1111-1111</dd>
</dl>
<div id="copyright" class="margin-top">Copyright ⓒ
newlecture.com 2012-2014 All Right Reserved. Contact
admin@newlecture.com for more information</div>
</div>
</div>
</footer>
</body>

</html>

 

<%
List<Notice> list = (List<Notice>) request.getAttribute("list");
for (Notice n : list) {
pageContext.setAttribute("n", n);
%>
<tr>
<td>${n.id}</td>
<td class="title indent text-align-left"><a
href="detail?id=${n.id}">${n.title}></a></td>
<td>${n.writerId}</td>
<td>${n.regdate}</td>
<td>${n.hit}</td>
</tr>
<%
}
%>

 

자바 코드와 html 코드를 분리하고 싶었지만 반복문을 돌기 위해서 어쩔 수 없이 java코드를 jsp에 넣게 되었다.

이것을 해결할 수 있는 JSTL라이브러리를 사용할 예정이다.

 

3. 게시판의 컨트롤러

package com.newlec.web.controller;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

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 com.newlec.web.entity.Notice;

@WebServlet("/notice/list")
public class NoticeListController extends HttpServlet {

List<Notice> list = new ArrayList<Notice>();

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String sql = "SELECT * FROM NOTICE";
String url = "jdbc:oracle:thin:@192.168.0.79:1521/xepdb1";
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con = DriverManager.getConnection(url, "lec", "111");
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(sql);

while (rs.next()) {
int id = rs.getInt("ID");
String title = rs.getString("TITLE");
String writerId = rs.getString("WRITER_ID");
String content = rs.getString("CONTENT");
Date regdate = rs.getDate("REGDATE");
int hit = rs.getInt("HIT");
String files = rs.getString("FILES");

Notice notice = new Notice(id, title, writerId, content, regdate, hit, files);
list.add(notice);
}

rs.close();
st.close();
con.close();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

request.setAttribute("list", list);

request.getRequestDispatcher("/WEB-INF/VIEW/notice/list.jsp").forward(request, response);
}

}

 

 

4. 게시글 클릭 시 보이는 페이지 JSP

 

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

<!DOCTYPE html>
<html>

<head>
<title>코딩 전문가를 만들기 위한 온라인 강의 시스템</title>
<meta charset="UTF-8">
<title>공지사항목록</title>

<link href="/css/customer/layout.css" type="text/css" rel="stylesheet" />
<style>

#visual .content-container{	
height:inherit;
display:flex; 
align-items: center;

background: url("../../images/customer/visual.png") no-repeat center;
}
</style>
</head>

<body>
<!-- header 부분 -->

<header id="header">

<div class="content-container">
<!-- ---------------------------<header>--------------------------------------- -->

<h1 id="logo">
<a href="/index.html">
<img src="/images/logo.png" alt="뉴렉처 온라인" />

</a>
</h1>

<section>
<h1 class="hidden">헤더</h1>

<nav id="main-menu">
<h1>메인메뉴</h1>
<ul>
<li><a href="/guide">학습가이드</a></li>

<li><a href="/course">강좌선택</a></li>
<li><a href="/answeris/index">AnswerIs</a></li>
</ul>
</nav>

<div class="sub-menu">

<section id="search-form">
<h1>강좌검색 폼</h1>
<form action="/course">
<fieldset>
<legend>과정검색필드</legend>
<label>과정검색</label>
<input type="text" name="q" value="" />
<input type="submit" value="검색" />
</fieldset>
</form>
</section>

<nav id="acount-menu">
<h1 class="hidden">회원메뉴</h1>
<ul>
<li><a href="/index.html">HOME</a></li>
<li><a href="/member/login.html">로그인</a></li>
<li><a href="/member/agree.html">회원가입</a></li>
</ul>
</nav>

<nav id="member-menu" class="linear-layout">
<h1 class="hidden">고객메뉴</h1>
<ul class="linear-layout">
<li><a href="/member/home"><img src="/images/txt-mypage.png" alt="마이페이지" /></a></li>
<li><a href="/notice/list.html"><img src="/images/txt-customer.png" alt="고객센터" /></a></li>
</ul>
</nav>

</div>
</section>

</div>

</header>

<!-- --------------------------- <visual> --------------------------------------- -->
<!-- visual 부분 -->

<div id="visual">
<div class="content-container"></div>
</div>
<!-- --------------------------- <body> --------------------------------------- -->
<div id="body">
<div class="content-container clearfix">

<!-- --------------------------- aside --------------------------------------- -->
<!-- aside 부분 -->


<aside class="aside">
<h1>고객센터</h1>

<nav class="menu text-menu first margin-top">
<h1>고객센터메뉴</h1>
<ul>
<li><a class="current"  href="/customer/notice">공지사항</a></li>
<li><a class=""  href="/customer/faq">자주하는 질문</a></li>
<li><a class="" href="/customer/question">수강문의</a></li>
<li><a class="" href="/customer/event">이벤트</a></li>

</ul>
</nav>


<nav class="menu">
<h1>협력업체</h1>
<ul>
<li><a target="_blank" href="http://www.notepubs.com"><img src="/images/notepubs.png" alt="노트펍스" /></a></li>
<li><a target="_blank" href="http://www.namoolab.com"><img src="/images/namoolab.png" alt="나무랩연구소" /></a></li>

</ul>
</nav>

</aside>
<!-- --------------------------- main --------------------------------------- -->




<main>
<h2 class="main title">공지사항</h2>

<div class="breadcrumb">
<h3 class="hidden">breadlet</h3>
<ul>
<li>home</li>
<li>고객센터</li>
<li>공지사항</li>
</ul>
</div>

<div class="margin-top first">
<h3 class="hidden">공지사항 내용</h3>
<table class="table">
<tbody>
<tr>
<th>제목</th>
<td class="text-align-left text-indent text-strong text-orange" colspan="3">${title}</td>
</tr>
<tr>
<th>작성일</th>
<td class="text-align-left text-indent" colspan="3">${regdate}</td>
</tr>
<tr>
<th>작성자</th>
<td>${writerId}</td>
<th>조회수</th>
<td>${hit}</td>
</tr>
<tr>
<th>첨부파일</th>
<td colspan="3">${files}</td>
</tr>
<tr class="content">
<td colspan="4">
<div><br></div>
<div>${content}</div>
<div><br></div>
<div><a href="http://www.newlecture.com/resource/spring2.zip"></a></div>
<div><br></div>
<div><br></div>
</td>
</tr>
</tbody>
</table>
</div>

<div class="margin-top text-align-center">
<a class="btn btn-list" href="list">목록</a>
</div>

<div class="margin-top">
<table class="table border-top-default">
<tbody>

<tr>
<th>다음글</th>
<td colspan="3"  class="text-align-left text-indent">다음글이 없습니다.</td>
</tr>




<tr>
<th>이전글</th>
<td colspan="3"  class="text-align-left text-indent"><a class="text-blue text-strong" href="">스프링 DI 예제 코드</a></td>
</tr>


</tbody>
</table>
</div>			

</main>		

</div>
</div>

<!-- ------------------- <footer> --------------------------------------- -->



<footer id="footer">
<div class="content-container">
<h2 id="footer-logo"><img src="/images/logo-footer.png" alt="회사정보"></h2>

<div id="company-info">
<dl>
<dt>주소:</dt>
<dd>서울특별시 </dd>
<dt>관리자메일:</dt>
<dd>admin@newlecture.com</dd>
</dl>
<dl>
<dt>사업자 등록번호:</dt>
<dd>111-11-11111</dd>
<dt>통신 판매업:</dt>
<dd>신고제 1111 호</dd>
</dl>
<dl>
<dt>상호:</dt>
<dd>뉴렉처</dd>
<dt>대표:</dt>
<dd>홍길동</dd>
<dt>전화번호:</dt>
<dd>111-1111-1111</dd>
</dl>
<div id="copyright" class="margin-top">Copyright ⓒ newlecture.com 2012-2014 All Right Reserved.
Contact admin@newlecture.com for more information</div>
</div>
</div>
</footer>
</body>

</html>

 

5.detail.jsp의 컨트롤러

 

package com.newlec.web.detail;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

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 com.newlec.web.controller.NoticeListController;
import com.newlec.web.entity.Notice;

@WebServlet("/notice/detail")
public class NoticeDetailController extends HttpServlet {

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String id_ = request.getParameter("id");

String sql = "SELECT * FROM NOTICE WHERE ID = ?";
String url = "jdbc:oracle:thin:@192.168.0.79:1521/xepdb1";

try {
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con = DriverManager.getConnection(url, "lec", "111");
PreparedStatement st = con.prepareStatement(sql);
st.setString(1, id_);
ResultSet rs = st.executeQuery();

if (rs.next()) {
int id = rs.getInt("ID");
String title = rs.getString("TITLE");
String writerId = rs.getString("WRITER_ID");
String content = rs.getString("CONTENT");
Date regdate = rs.getDate("REGDATE");
int hit = rs.getInt("HIT");
String files = rs.getString("FILES");

request.setAttribute("title", title);
request.setAttribute("writerId", writerId);
request.setAttribute("hit", hit);
request.setAttribute("files", files);
request.setAttribute("regdate", regdate);
request.setAttribute("content", content);

}

rs.close();
st.close();
con.close();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

request.getRequestDispatcher("/WEB-INF/VIEW/notice/detail.jsp").forward(request, response);
}

}

 

 

배운 요약정리.

 

서블릿은 자바 웹 서버 프로그램입니다.

자바 프로그램에 웹이라는 것을 기반으로 프로그램을 만드는 것을 배웠는데

웹 프로그램은 웹에서 입/출력을 하는 것을 말하며

콘솔 프로그램은 콘솔에서 입/출력을 하는 것을 말합니다.

 

웹에서의 입출력은 request, response로써 사용했습니다.

또한 한글 출력 부분에서 charSet을 UTF-8로 설정해주어 웹브라우저에게 보내는 방식과 작성할 때 UTF-8로 작성하는 법을 배웠으며 우리가 웹브라우저에게 사용자가 요청한 페이지를 문서 형태로써 보낼 때 서블릿은 HTML 코드 또한 OUT.WRITE()로 감싸주어야 하는 일이 불편하여 JSP에 코드 블록을 삽입하여 웹 프로그래밍을 하는 것을 배웠습니다.

 

그러다 JSP에 코드 블록이 많아지다 보니 스파게티 코드가 되어 유지보수 측면에서 단점이 발견됐고 컨트롤 단과 뷰단을 나눈 MVC MODEL2 패턴으로 물리적으로 컨트롤 단과 뷰단을 나누어주었습니다.

 

하지만 VIEW단에서는 코드 블록이 꼭 필요한 경우가 존재했는데

컨트롤러의 model 데이터 값을 출력을 도와주는 역할을 하는 EL (${})을 공부했으며

JSTL은 특정 출력을 제어해주는 태그 라이브러리를 사용했습니다.

 

또한 데이터베이스에서 레코드를 가져와 출력을 할 수 있는 방법 또한 배웠으며 

서블릿과 JSP의 두 개의 서블릿끼리 데이터를 공유할 수  있는 Forward와 

새로운 데이터를 가진 페이지를 보여줄 수 있는 Redirect를 배웠습니다.

반응형

댓글