JSP, Servlet, MySQL/JSP - webmarket
JSP Servlet 웹 MVC : 게시판 만들기 2
샤리미
2024. 3. 13. 01:19
728x90
반응형
04 웹 쇼핑몰 게시판 만들기
MVC 모델을 적용하여 게시판의 글 목록 보기, 글 등록하기, 게시글 내용 보기, 게시글 수정하기, 게시글 삭제하기 등
웹 쇼핑몰의 데이터베이스에 게시판 관리 테이블 만들기
WebMarket/WebContent/resourcess/sql/board.sql
create table board(
num int not null auto_increment,
id varchar(10) not null,
name varchar(10) not null,
subject varchar(100) not null,
content text not null,
regist_day varchar(30),
hit int,
ip varchar(20),
primary key(num)
)default CHARSET=utf8;
desc board;
-MVC 기반 웹 게시판의 기본 페이지 준비하기
1. 메뉴 페이지 수정하기
WebMarket/WebContent/menu.jsp
<li class="nav-item"><a class="nav-link" href="<c:url value="/BoardListAction.do?pageNum=1"/>">게시판</a>
2. web.xml 파일에 추가 작성하기
WebMarket/WebContent/WEB-INF/web.xml
<servlet>
<servlet-name>BoardController</servlet-name>
<servlet-class>mvc.controller.BoardController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BoardController</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
3.데이터베이스 연결 클래스 생성하기 :
WebMarket/src/mvc/database/DBConnection.java
package mvc.database;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.DriverManager;
public class DBConnection{
public static Connection getConnection() throws SQLException, ClassNotFoundException {
Connection conn = null;
String url="jdbc:mysql://localhost:3306/WebMarketDB";
String user = "root";
String password = "177100";
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url, user, password);
return conn;
}
}
4.게시판 데이터 클래스 생성하기
WebMarket/src/mvc/model/BoardDTO.java
package mvc.model;
public class BoardDTO {
private int num;
private String id;
private String name;
private String subject;
private String content;
private String regist_day;
private int hit;
private String ip;
public BoardDTO() {
super();
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getRegist_day() {
return regist_day;
}
public void setRegist_day(String regist_day) {
this.regist_day = regist_day;
}
public int getHit() {
return hit;
}
public void setHit(int hit) {
this.hit = hit;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
}
웹 게시판에 등록된 글 목록 보기
웹 게시판에 글 등록하기
웹 게시판에 등록된 글 확인하기
웹 게시판에 등록된 글 수정하기
웹 게시판에 등록된 글 삭제하기
1. 컨트롤러 작성하기
WebMarket/src/mvc/controller/BoardController.java
package mvc.controller;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import mvc.model.BoardDAO;
import mvc.model.BoardDTO;
public class BoardController extends HttpServlet {
private static final long serialVersionUID = 1L;
static final int LISTCOUNT = 5;
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String RequestURI = request.getRequestURI();
String contextPath = request.getContextPath();
String command = RequestURI.substring(contextPath.length());
response.setContentType("text/html; charset=utf-8");
request.setCharacterEncoding("utf-8");
if (command.equals("/BoardListAction.do")) {//등록된 글 목록 페이지 출력하기
requestBoardList(request);
RequestDispatcher rd = request.getRequestDispatcher("./board/list.jsp");
rd.forward(request, response);
} else if (command.equals("/BoardWriteForm.do")) { // 글 등록 페이지 출력하기
requestLoginName(request);
RequestDispatcher rd = request.getRequestDispatcher("./board/writeForm.jsp");
rd.forward(request, response);
} else if (command.equals("/BoardWriteAction.do")) {// 새로운 글 등록하기
requestBoardWrite(request);
RequestDispatcher rd = request.getRequestDispatcher("/BoardListAction.do");
rd.forward(request, response);
} else if (command.equals("/BoardViewAction.do")) {//선택된 글 상세 페이지 가져오기
requestBoardView(request);
RequestDispatcher rd = request.getRequestDispatcher("/BoardView.do");
rd.forward(request, response);
} else if (command.equals("/BoardView.do")) { //글 상세 페이지 출력하기
RequestDispatcher rd = request.getRequestDispatcher("./board/view.jsp");
rd.forward(request, response);
} else if (command.equals("/BoardUpdateAction.do")) { //선택된 글의 조회수 증가하기
requestBoardUpdate(request);
RequestDispatcher rd = request.getRequestDispatcher("/BoardListAction.do");
rd.forward(request, response);
}else if (command.equals("/BoardDeleteAction.do")) { //선택된 글 삭제하기
requestBoardDelete(request);
RequestDispatcher rd = request.getRequestDispatcher("/BoardListAction.do");
rd.forward(request, response);
}
}
//등록된 글 목록 가져오기
public void requestBoardList(HttpServletRequest request){
BoardDAO dao = BoardDAO.getInstance();
List<BoardDTO> boardlist = new ArrayList<BoardDTO>();
int pageNum=1;
int limit=LISTCOUNT;
if(request.getParameter("pageNum")!=null)
pageNum=Integer.parseInt(request.getParameter("pageNum"));
String items = request.getParameter("items");
String text = request.getParameter("text");
int total_record=dao.getListCount(items, text);
boardlist = dao.getBoardList(pageNum,limit, items, text);
int total_page;
if (total_record % limit == 0){
total_page =total_record/limit;
Math.floor(total_page);
}
else{
total_page =total_record/limit;
Math.floor(total_page);
total_page = total_page + 1;
}
request.setAttribute("pageNum", pageNum);
request.setAttribute("total_page", total_page);
request.setAttribute("total_record",total_record);
request.setAttribute("boardlist", boardlist);
}
//인증된 사용자명 가져오기
public void requestLoginName(HttpServletRequest request){
String id = request.getParameter("id");
BoardDAO dao = BoardDAO.getInstance();
String name = dao.getLoginNameById(id);
request.setAttribute("name", name);
}
// 새로운 글 등록하기
public void requestBoardWrite(HttpServletRequest request){
BoardDAO dao = BoardDAO.getInstance();
BoardDTO board = new BoardDTO();
board.setId(request.getParameter("id"));
board.setName(request.getParameter("name"));
board.setSubject(request.getParameter("subject"));
board.setContent(request.getParameter("content"));
System.out.println(request.getParameter("name"));
System.out.println(request.getParameter("subject"));
System.out.println(request.getParameter("content"));
java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy/MM/dd(HH:mm:ss)");
String regist_day = formatter.format(new java.util.Date());
board.setHit(0);
board.setRegist_day(regist_day);
board.setIp(request.getRemoteAddr());
dao.insertBoard(board);
}
//선택된 글 상세 페이지 가져오기
public void requestBoardView(HttpServletRequest request){
BoardDAO dao = BoardDAO.getInstance();
int num = Integer.parseInt(request.getParameter("num"));
int pageNum = Integer.parseInt(request.getParameter("pageNum"));
BoardDTO board = new BoardDTO();
board = dao.getBoardByNum(num, pageNum);
request.setAttribute("num", num);
request.setAttribute("page", pageNum);
request.setAttribute("board", board);
}
//선택된 글 내용 수정하기
public void requestBoardUpdate(HttpServletRequest request){
int num = Integer.parseInt(request.getParameter("num"));
int pageNum = Integer.parseInt(request.getParameter("pageNum"));
BoardDAO dao = BoardDAO.getInstance();
BoardDTO board = new BoardDTO();
board.setNum(num);
board.setName(request.getParameter("name"));
board.setSubject(request.getParameter("subject"));
board.setContent(request.getParameter("content"));
java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy/MM/dd(HH:mm:ss)");
String regist_day = formatter.format(new java.util.Date());
board.setHit(0);
board.setRegist_day(regist_day);
board.setIp(request.getRemoteAddr());
dao.updateBoard(board);
}
//선택된 글 삭제하기
public void requestBoardDelete(HttpServletRequest request){
int num = Integer.parseInt(request.getParameter("num"));
int pageNum = Integer.parseInt(request.getParameter("pageNum"));
BoardDAO dao = BoardDAO.getInstance();
dao.deleteBoard(num);
}
}
모델 작성하기
WebMarket/src/mvc/model/BoardDAO.java
package mvc.model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import mvc.database.DBConnection;
public class BoardDAO {
private static BoardDAO instance;
private BoardDAO() {
}
public static BoardDAO getInstance() {
if (instance == null)
instance = new BoardDAO();
return instance;
}
//board 테이블의 레코드 개수
public int getListCount(String items, String text) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
int x = 0;
String sql;
if (items == null && text == null)
sql = "select count(*) from board";
else
sql = "SELECT count(*) FROM board where " + items + " like '%" + text + "%'";
try {
conn = DBConnection.getConnection();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
if (rs.next())
x = rs.getInt(1);
} catch (Exception ex) {
System.out.println("getListCount() 에러: " + ex);
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception ex) {
throw new RuntimeException(ex.getMessage());
}
}
return x;
}
//board 테이블의 레코드 가져오기
public ArrayList<BoardDTO> getBoardList(int page, int limit, String items, String text) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
int total_record = getListCount(items, text );
int start = (page - 1) * limit;
int index = start + 1;
String sql;
if (items == null && text == null)
sql = "select * from board ORDER BY num DESC";
else
sql = "SELECT * FROM board where " + items + " like '%" + text + "%' ORDER BY num DESC ";
ArrayList<BoardDTO> list = new ArrayList<BoardDTO>();
try {
conn = DBConnection.getConnection();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
while (rs.absolute(index)) {
BoardDTO board = new BoardDTO();
board.setNum(rs.getInt("num"));
board.setId(rs.getString("id"));
board.setName(rs.getString("name"));
board.setSubject(rs.getString("subject"));
board.setContent(rs.getString("content"));
board.setRegist_day(rs.getString("regist_day"));
board.setHit(rs.getInt("hit"));
board.setIp(rs.getString("ip"));
list.add(board);
if (index < (start + limit) && index <= total_record)
index++;
else
break;
}
return list;
} catch (Exception ex) {
System.out.println("getBoardList() 에러 : " + ex);
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception ex) {
throw new RuntimeException(ex.getMessage());
}
}
return null;
}
//member 테이블에서 인증된 id의 사용자명 가져오기
public String getLoginNameById(String id) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String name=null;
String sql = "select * from member where id = ? ";
try {
conn = DBConnection.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, id);
rs = pstmt.executeQuery();
if (rs.next())
name = rs.getString("name");
return name;
} catch (Exception ex) {
System.out.println("getBoardByNum() 에러 : " + ex);
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception ex) {
throw new RuntimeException(ex.getMessage());
}
}
return null;
}
//board 테이블에 새로운 글 삽입히가
public void insertBoard(BoardDTO board) {
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = DBConnection.getConnection();
String sql = "insert into board values(?, ?, ?, ?, ?, ?, ?, ?)";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, board.getNum());
pstmt.setString(2, board.getId());
pstmt.setString(3, board.getName());
pstmt.setString(4, board.getSubject());
pstmt.setString(5, board.getContent());
pstmt.setString(6, board.getRegist_day());
pstmt.setInt(7, board.getHit());
pstmt.setString(8, board.getIp());
pstmt.executeUpdate();
} catch (Exception ex) {
System.out.println("insertBoard() 에러 : " + ex);
} finally {
try {
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception ex) {
throw new RuntimeException(ex.getMessage());
}
}
}
//선택된 글의 조회수 증가하기
public void updateHit(int num) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = DBConnection.getConnection();
String sql = "select hit from board where num = ? ";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, num);
rs = pstmt.executeQuery();
int hit = 0;
if (rs.next())
hit = rs.getInt("hit") + 1;
sql = "update board set hit=? where num=?";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, hit);
pstmt.setInt(2, num);
pstmt.executeUpdate();
} catch (Exception ex) {
System.out.println("updateHit() 에러 : " + ex);
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception ex) {
throw new RuntimeException(ex.getMessage());
}
}
}
//선택된 글 상세 내용 가져오기
public BoardDTO getBoardByNum(int num, int page) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
BoardDTO board = null;
updateHit(num);
String sql = "select * from board where num = ? ";
try {
conn = DBConnection.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, num);
rs = pstmt.executeQuery();
if (rs.next()) {
board = new BoardDTO();
board.setNum(rs.getInt("num"));
board.setId(rs.getString("id"));
board.setName(rs.getString("name"));
board.setSubject(rs.getString("subject"));
board.setContent(rs.getString("content"));
board.setRegist_day(rs.getString("regist_day"));
board.setHit(rs.getInt("hit"));
board.setIp(rs.getString("ip"));
}
return board;
} catch (Exception ex) {
System.out.println("getBoardByNum() 에러 : " + ex);
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception ex) {
throw new RuntimeException(ex.getMessage());
}
}
return null;
}
//선택된 글 내용 수정하기
public void updateBoard(BoardDTO board) {
Connection conn = null;
PreparedStatement pstmt = null;
try {
String sql = "update board set name=?, subject=?, content=? where num=?";
conn = DBConnection.getConnection();
pstmt = conn.prepareStatement(sql);
conn.setAutoCommit(false);
pstmt.setString(1, board.getName());
pstmt.setString(2, board.getSubject());
pstmt.setString(3, board.getContent());
pstmt.setInt(4, board.getNum());
pstmt.executeUpdate();
conn.commit();
} catch (Exception ex) {
System.out.println("updateBoard() 에러 : " + ex);
} finally {
try {
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception ex) {
throw new RuntimeException(ex.getMessage());
}
}
}
//선택된 글 삭제하기
public void deleteBoard(int num) {
Connection conn = null;
PreparedStatement pstmt = null;
String sql = "delete from board where num=?";
try {
conn = DBConnection.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, num);
pstmt.executeUpdate();
} catch (Exception ex) {
System.out.println("deleteBoard() 에러 : " + ex);
} finally {
try {
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception ex) {
throw new RuntimeException(ex.getMessage());
}
}
}
}
뷰 작성하기
WebMarket/WebContent/list.jsp
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page import="java.util.*"%>
<%@ page import="mvc.model.BoardDTO"%>
<%
String sessionId = (String) session.getAttribute("sessionId");
List boardList = (List) request.getAttribute("boardlist");
int total_record = ((Integer) request.getAttribute("total_record")).intValue();
int pageNum = ((Integer) request.getAttribute("pageNum")).intValue();
int total_page = ((Integer) request.getAttribute("total_page")).intValue();
%>
<html>
<head>
<link rel="stylesheet" href="./resources/css/bootstrap.min.css" />
<title>Board</title>
<script type="text/javascript">
function checkForm() {
if (${sessionId==null}) {
alert("로그인 해주세요.");
return false;
}
location.href = "./BoardWriteForm.do?id=<%=sessionId%>"
}
</script>
</head>
<body>
<jsp:include page="../menu.jsp" />
<div class="jumbotron">
<div class="container">
<h1 class="display-3">게시판</h1>
</div>
</div>
<div class="container">
<form action="<c:url value="../BoardListAction.do"/>" method="post">
<div>
<div class="text-right">
<span class="badge badge-success">전체 <%=total_record%>건 </span>
</div>
</div>
<div style="padding-top: 50px">
<table class="table table-hover">
<tr>
<th>번호</th>
<th>제목</th>
<th>작성일</th>
<th>조회</th>
<th>글쓴이</th>
</tr>
<%
for (int j = 0; j < boardList.size(); j++) {
BoardDTO notice = (BoardDTO) boardList.get(j);
%>
<tr>
<td><%=notice.getNum()%></td>
<td><a href="./BoardViewAction.do?num=<%=notice.getNum()%>&pageNum=<%=pageNum%>"><%=notice.getSubject()%></a></td>
<td><%=notice.getRegist_day()%></td>
<td><%=notice.getHit()%></td>
<td><%=notice.getName()%></td>
</tr>
<%
}
%>
</table>
</div>
<div align="center">
<c:set var="pageNum" value="<%=pageNum%>" />
<c:forEach var="i" begin="1" end="<%=total_page%>">
<a href="<c:url value="./BoardListAction.do?pageNum=${i}" /> ">
<c:choose>
<c:when test="${pageNum==i}">
<font color='4C5317'><b> [${i}]</b></font>
</c:when>
<c:otherwise>
<font color='4C5317'> [${i}]</font>
</c:otherwise>
</c:choose>
</a>
</c:forEach>
</div>
<div align="left">
<table>
<tr>
<td width="100%" align="left">
<select name="items" class="txt">
<option value="subject">제목에서</option>
<option value="content">본문에서</option>
<option value="name">글쓴이에서</option>
</select> <input name="text" type="text" /> <input type="submit" id="btnAdd" class="btn btn-primary " value="검색 " />
</td>
<td width="100%" align="right">
<a href="#" onclick="checkForm(); return false;" class="btn btn-primary">«글쓰기</a>
</td>
</tr>
</table>
</div>
</form>
<hr>
</div>
<jsp:include page="../footer.jsp" />
</body>
</html>
WebMarket/WebContent/view.jsp
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page import="mvc.model.BoardDTO"%>
<%
BoardDTO notice = (BoardDTO) request.getAttribute("board");
int num = ((Integer) request.getAttribute("num")).intValue();
int nowpage = ((Integer) request.getAttribute("page")).intValue();
%>
<html>
<head>
<link rel="stylesheet" href="./resources/css/bootstrap.min.css" />
<title>Board</title>
</head>
<body>
<jsp:include page="../menu.jsp" />
<div class="jumbotron">
<div class="container">
<h1 class="display-3">게시판</h1>
</div>
</div>
<div class="container">
<form name="newUpdate"
action="./BoardUpdateAction.do?num=<%=notice.getNum()%>&pageNum=<%=nowpage%>"
class="form-horizontal" method="post">
<div class="form-group row">
<label class="col-sm-2 control-label" >성명</label>
<div class="col-sm-3">
<input name="name" class="form-control" value=" <%=notice.getName()%>">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 control-label" >제목</label>
<div class="col-sm-5">
<input name="subject" class="form-control" value=" <%=notice.getSubject()%>" >
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 control-label" >내용</label>
<div class="col-sm-8" style="word-break: break-all;">
<textarea name="content" class="form-control" cols="50" rows="5"> <%=notice.getContent()%></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-sm-offset-2 col-sm-10 ">
<c:set var="userId" value="<%=notice.getId()%>" />
<c:if test="${sessionId==userId}">
<p>
<a href="./BoardDeleteAction.do?num=<%=notice.getNum()%>&pageNum=<%=nowpage%>" class="btn btn-danger"> 삭제</a>
<input type="submit" class="btn btn-success" value="수정 ">
</c:if>
<a href="./BoardListAction.do?pageNum=<%=nowpage%>" class="btn btn-primary"> 목록</a>
</div>
</div>
</form>
<hr>
</div>
<jsp:include page="../footer.jsp" />
</body>
</html>
WebMarket/WebContent/wirteForm.jsp
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
String name = (String) request.getAttribute("name");
%>
<html>
<head>
<link rel="stylesheet" href="./resources/css/bootstrap.min.css" />
<title>Board</title>
</head>
<script type="text/javascript">
function checkForm() {
if (!document.newWrite.name.value) {
alert("성명을 입력하세요.");
return false;
}
if (!document.newWrite.subject.value) {
alert("제목을 입력하세요.");
return false;
}
if (!document.newWrite.content.value) {
alert("내용을 입력하세요.");
return false;
}
}
</script>
<body>
<jsp:include page="../menu.jsp" />
<div class="jumbotron">
<div class="container">
<h1 class="display-3">게시판</h1>
</div>
</div>
<div class="container">
<form name="newWrite" action="./BoardWriteAction.do"
class="form-horizontal" method="post" onsubmit="return checkForm()">
<input name="id" type="hidden" class="form-control"
value="${sessionId}">
<div class="form-group row">
<label class="col-sm-2 control-label" >성명</label>
<div class="col-sm-3">
<input name="name" type="text" class="form-control" value="<%=name %>"
placeholder="name">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 control-label" >제목</label>
<div class="col-sm-5">
<input name="subject" type="text" class="form-control"
placeholder="subject">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 control-label" >내용</label>
<div class="col-sm-8">
<textarea name="content" cols="50" rows="5" class="form-control"
placeholder="content"></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-sm-offset-2 col-sm-10 ">
<input type="submit" class="btn btn-primary " value="등록 ">
<input type="reset" class="btn btn-primary " value="취소 ">
</div>
</div>
</form>
<hr>
</div>
<jsp:include page="../footer.jsp" />
</body>
</html>
728x90
반응형