ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 210628_1(model2_게시판만들기)
    HTML_JS(Sol)/model2 2021. 6. 28. 18:22

    글보기

    DAO : public BoardDataBean getArticle(int num) { }

             * 해당글의 조회수 증가

             * 해당글을 꺼냄

             * 빈에 담는다.

             * 빈을 리턴한다.

             

    Action : ContentAction implements CommandAction { 

                requsetPro() { //오버라이딩

                * Fc의 명령을 받는다

                * getArticle을 실행 

                * 리턴된 결과를 request영역에 저장한다

                * 기타 환경변수(페이징,답글관련)들을 request에 저장한다.

                * 해당 view값을 리턴한다. }  }

    View : content.jsp

                el,jstl을 이용해서, request에 저장된 데이터를 꺼내와 화면을 구성한다.

    mapping : CommandPro.properties 파일에 아래 매핑을 추가한다.

               /boardMvc2Ora/content.do=my.action.contentAction

     


    DAO : public BoardDataBean getArticle(int num) { }

             * 해당글의 조회수 증가

             * 해당글을 꺼냄

             * 빈에 담는다.

             * 빈을 리턴한다.

     

    	public BoardDataBean getArticle(int num)throws Exception{
    		Connection conn = null;
    		PreparedStatement pstmt = null;
    		ResultSet rs = null;
    		BoardDataBean article = null;
    		try {
    			conn = getConnection();
    			
    			pstmt = conn.prepareStatement(" update board3 set readcount = readcount + 1 where num = ?");
    			pstmt.setInt(1, num);
    			pstmt.executeUpdate();
    			
    			pstmt = conn.prepareStatement(" select * from board3 where num = ?");
    			pstmt.setInt(1, num);
    			rs = pstmt.executeQuery();
    			
    			if(rs.next()) {
    				article = new BoardDataBean();
    				article.setNum(rs.getInt("num"));
    				article.setWriter(rs.getString("writer"));
    				article.setEmail(rs.getString("email"));
    				article.setSubject(rs.getString("subject"));
    				article.setPasswd(rs.getString("passwd"));
    				article.setReg_date(rs.getTimestamp("reg_date"));
    				article.setReadcount(rs.getInt("readcount"));
    				article.setRef(rs.getInt("ref"));
    				article.setRe_step(rs.getInt("re_step"));
    				article.setRe_level(rs.getInt("re_level"));
    				article.setContent(rs.getString("content"));
    				article.setIp(rs.getString("ip"));
    			}
    			}catch(Exception ex) {
    				ex.printStackTrace();
    			}finally {
    				if(rs != null) try {rs.close();}catch(SQLException ex) {}
    				if(rs != null) try {pstmt.close();}catch(SQLException ex) {}
    				if(rs != null) try {conn.close();}catch(SQLException ex) {}
    					
    				}
    			return article;
    		} // BoardDateBean

    Action : ContentAction implements CommandAction {

                requsetPro() { //오버라이딩

                * Fc의 명령을 받는다

                * getArticle을 실행 

                * 리턴된 결과를 request영역에 저장한다

                * 기타 환경변수(페이징,답글관련)들을 request에 저장한다.

                * 해당 view값을 리턴한다. }  }

    package my.action;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import my.board.BoardDBBean;
    import my.board.BoardDataBean;
    
    public class ContentAction implements CommandAction{ //글 내용 처리
    	
    	public String requestPro(HttpServletRequest request , HttpServletResponse response)throws Throwable{
    		
    		int num = Integer.parseInt(request.getParameter("num")); // 해당 글번호
    		String pageNum = request.getParameter("pageNum"); //해당 페이지 번호
    		
    		BoardDBBean dbPro = BoardDBBean.getInstance(); // DB처리
    		BoardDataBean article = dbPro.getArticle(num); // 해당 글번호에 대한 레코드
    		
    		//해당 뷰에서 사용할 속성
    		request.setAttribute("num", new Integer(num));
    		request.setAttribute("pageNum", new Integer(pageNum));
    		request.setAttribute("article", article);
    
    		return "content.jsp"; //해당뷰
    	}
    
    }
    

    View : content.jsp

                el,jstl을 이용해서, request에 저장된 데이터를 꺼내와 화면을 구성한다.

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
        <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
        <%@include file="/view/color.jspf" %>
    
    <html>
    <head>
    <meta charset="UTF-8">
    <title>게시판</title>
    <link href="style.css" rel="stylesheet" type="text/css">
    </head>
    
    <body bgcolor="${bodyback_c}">
    <center><b>글 내용 보기</b></center>
    <br>
    <form>
    <table width="500" border="1" cellspacint="0" cellpadding="0" align="center">
    <tr height="30">
    <td align="center" width="125" bgcolor="${value_c}">글번호</td>
    <td align="center" width="125" align="center">${article.num}</td>
    <td align="center" width="125" bgcolor="${value_c}">조회수</td>
    <td align="center" width="125" align="center">${article.readcount}</td>
    </tr>
    <tr height="30">
    <td align="center" width="125" bgcolor="${value_c}">작성자</td>
    <td align="center" width="125" align="center">${article.writer}</td>
    <td align="center" width="125" bgcolor="${value_c}">작성일</td>
    <td align="center" width="125" align="center">${article.reg_date}</td>
    </tr>
    <tr height="30">
    <td align="center" width="125" bgcolor="${value_c}">글제목</td>
    <td align="center" width="375" align="center" colspan="3">${article.subject}</td>
    </tr>
    <tr>
    <td align="center" width="125" bgcolor="${value_c}">글내용</td>
    <td align="left" width="375" colspan="3"><pre>${article.content}</pre></td>
    </tr>
    <tr height="30">
    <td align="right" colspan="4" bgcolor="${value_c}">
    	<input type="button" value="글수정" onclick="document.location.href='/boardMvc2Ora/updateForm.do?num=${artielc.num}&pageNum=${pageNum}'">
    	&nbsp;&nbsp;&nbsp;&nbsp;
    	<input type="button" value="글삭제" onclick="document.location.href='/boardMvc2Ora/deleteForm.do?num=${artielc.num}&pageNum=${pageNum}'">
    	&nbsp;&nbsp;&nbsp;&nbsp;
    	<input type="button" value="답글쓰기" onclick="document.location.href='/boardMvc2Ora/writeForm.do?num=${artielc.num}&ref=${article.ref}&re_step=${article.re_step}&re_level=${article.re_level}'">
    	&nbsp;&nbsp;&nbsp;&nbsp;
    	<input type="button" value="글목록" onclick="document.location.href='/boardMvc2Ora/list.do?pageNum=${pageNum}'">
    
    </td>
    </tr>
    </table>
    </form>
    </body>
    </html>

    mapping : CommandPro.properties 파일에 아래 매핑을 추가한다.

               /boardMvc2Ora/content.do=my.action.ContentAction

     


    글수정

    글보기+글쓰기

    DAO : 원글을 가져온다 public BoardDBBean updateGetArticle(){}

     

             

    Action : 원글을가져와서 request에 저장하고, 수정폼 뷰값을 리턴한다.

     

    View : edit.jsp

              원글보기+글쓰기

    mapping : CommandPro.properties 파일에 아래 매핑을 추가한다.

           /boardMvc2Ora/updateForm.do=my.action.UpdateFormAction


    DAO : 원글을 가져온다 public BoardDBBean updateGetArticle(){}

    	public BoardDataBean updateGetArticle(int num)throws Exception{
    		Connection conn = null;
    		PreparedStatement pstmt = null;
    		ResultSet rs = null;
    		BoardDataBean article = null;
    		
    		try {
    			conn = getConnection();
    			pstmt = conn.prepareStatement(" select * from board3 where num = ?");
    			pstmt.setInt(1, num);
    			rs= pstmt.executeQuery();
    			
    			if(rs.next()) {
    				article = new BoardDataBean();
    				article.setNum(rs.getInt("num"));
    				article.setWriter(rs.getString("writer"));
    				article.setEmail(rs.getString("email"));
    				article.setSubject(rs.getString("subject"));
    				article.setPasswd(rs.getString("passwd"));
    				article.setReg_date(rs.getTimestamp("reg_date"));
    				article.setReadcount(rs.getInt("readcount"));
    				article.setRef(rs.getInt("ref"));
    				article.setRe_step(rs.getInt("re_step"));
    				article.setRe_level(rs.getInt("re_level"));
    				article.setContent(rs.getString("content"));
    				article.setIp(rs.getString("ip"));
    			}
    			}catch(Exception ex) {
    				ex.printStackTrace();
    			}finally {
    				if(rs != null) try {rs.close();}catch(SQLException ex) {}
    				if(rs != null) try {pstmt.close();}catch(SQLException ex) {}
    				if(rs != null) try {conn.close();}catch(SQLException ex) {}
    					
    				}
    			return article;
    		} // updateGetArticle

             

    Action : 원글을가져와서 request에 저장하고, 수정폼 뷰값을 리턴한다.

    package my.action;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import my.board.BoardDBBean;
    import my.board.BoardDataBean;
    
    public class UpdateFormAction implements CommandAction { // 글 수정 폼
    	
    	@Override
    	public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Throwable {
    		// 제목글과 답변글의 구분
    		int num = Integer.parseInt(request.getParameter("num"));
    		String pageNum = request.getParameter("pageNum");
    		
    		BoardDBBean dbPro = BoardDBBean.getInstance();
    		BoardDataBean article = dbPro.updateGetArticle(num);
    		
    		
    		// 해당뷰에서 사용할 속성
    		request.setAttribute("pageNum", new Integer(pageNum));
    		request.setAttribute("article", article);
    	
    
    		return "updateForm.jsp"; // 해당 뷰
    
    	} 
    } //class

    View : edit.jsp

              원글보기+글쓰기

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
            <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
        <%@include file ="/view/color.jspf" %>
    
    <html>
    <head>
    <meta charset="UTF-8">
    <title>게시판
    </title>
    <link href="style.css" rel="stylesheet" type="text/css">
    <script type="text/javascript" src="script.js"></script>
    </head>
    <body bgcolor="${bodyback_c}">
    
    <b>글수정</b>
    <br>
    <form method="POST" name="writeform" action="/boardMvc2Ora/updatePro.do?pageNum=${pageNum}" onsubmit="return writeSave()">
    <table width="400" border="1" cellspacing="0" cellpadding="0" align="center">
       
        <tr>
            <td width="70" bgcolor="${value_c}" align="center">이 름</td>
            <td width="330">
                <input type="text" size="10" maxlength="10" name="writer" value="${article.writer}">
                <input type="hidden" name="num" value="${article.num}">
            </td>
        </tr>
    
        <tr>
            <td width="70" bgcolor="${value_c}" align="center">제 목</td>
            <td width="330">    
                <input type="text" size="40" maxlength="50" name="subject" value="${article.subject}">
            </td>
        </tr>
    
        <tr>
            <td width="70" bgcolor="${value_c}" align="center">Email</td>
            <td aling="lesf" width="330">
                <input type="text" size="40" maxlength="30" name="email" value="${article.email}">
            </td>
        </tr>
    
        <tr>
            <td width="70" bgcolor="${value_c}" align="center">내 용</td>
            <td  algin="left" width="330">
                <textarea name="content" rows="13" cols="40">${article.content}</textarea>
            </td>
        </tr>
    
        <tr>
            <td width="70" bgcolor="${value_c}" align="center">비밀번호</td>
            <td aling="left" width="330">
                <input type="password" size="8" maxlength="12" name="passwd">
            </td>
        </tr>
        <tr>
        <td colspan=2 bgcolor="${value_c}" align="center">
        <input type="submit" value="글수정">
        <input type="reset" value="다시작성">
        <input type="button" value="목록보기" onclick="document.location.href='/baardMvc2Ora/list.do?pageNum=${pageNum}'">
    </td>
    </tr>
    </table>    
    </form>
    
    
    </body>
    </html>

    mapping : CommandPro.properties 파일에 아래 매핑을 추가한다.

           /boardMvc2Ora/updateForm.do=my.action.UpdateFormAction

     

    수정폼까지 아래부터 수정처리


    수정처리

    DAO : public int updateArticle(Bean){}

    Action : UpdateProAction implements CommandAction{

               requestPro(){ //오버라이딩

               * encoding

               * 전달된 객체로부터 데이터를 꺼내서 bean에 저장한다.

               * dao 객체 반환

               * 비지니스 메서드 실행

               * 결과를 저장

               * 뷰값 리턴   } }

    View : updatePro.jsp

               결과가 1이면 : 성공메시지, 이동 -- 글보기

                         0이면 : 결고메시지, 이동 -- 수정폼

    mapping : CommandPro.properties 파일에 아래 매핑을 추가한다.

                  /boardMvc2Ora/updatePro.do=my.action.UpdateProAction


    DAO : public int updateArticle(Bean){}

    	public int updateArticle (BoardDataBean article)throws Exception{
    		Connection conn = null;
    		PreparedStatement pstmt = null;
    		ResultSet rs = null;
    		
    		String dbpasswd="";
    		String sql="";
    		int x = -1;
    		try {
    			conn = getConnection();
    			pstmt = conn.prepareStatement(" select passwd from board3 where num = ? ");
    			pstmt.setInt(1, article.getNum());
    			rs = pstmt.executeQuery();
    			
    			if(rs.next()) {
    				dbpasswd = rs.getString("passwd");
    				if(dbpasswd.equals(article.getPasswd())) {
    					sql = " update board3 set writer=?, email=?, subject=?, passwd=? ";
    					sql += " , content=? where num=?";
    					pstmt = conn.prepareStatement(sql);
    					pstmt.setString(1, article.getWriter());
    					pstmt.setString(2, article.getEmail());
    					pstmt.setString(3, article.getSubject());
    					pstmt.setString(4, article.getPasswd());
    					pstmt.setString(5, article.getContent());
    					pstmt.setInt(6, article.getNum());
    					pstmt.executeUpdate();
    					x=1;
    				}else {
    					x=0;
    				}
    			}
    		}catch(Exception ex) {
    			ex.printStackTrace();
    		}finally {
    			if(rs != null) try {rs.close();}catch(SQLException ex) {}
    			if(rs != null) try {pstmt.close();}catch(SQLException ex) {}
    			if(rs != null) try {conn.close();}catch(SQLException ex) {}
    		}
    		return x;
    	} //updateArticle

    Action : UpdateProAction implements CommandAction{

               requestPro(){ //오버라이딩

               * encoding

               * 전달된 객체로부터 데이터를 꺼내서 bean에 저장한다.

               * dao 객체 반환

               * 비지니스 메서드 실행

               * 결과를 저장

               * 뷰값 리턴   } }

    package my.action;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import my.board.BoardDBBean;
    import my.board.BoardDataBean;
    
    public class UpdateProAction implements CommandAction{
    	
    	public String requestPro (HttpServletRequest request, HttpServletResponse response)throws Throwable{
    		request.setCharacterEncoding("utf-8");
    		
    		String pageNum = request.getParameter("pageNum");
    		
    		BoardDataBean article = new BoardDataBean();
    		article.setNum(Integer.parseInt(request.getParameter("num")));
    		article.setWriter(request.getParameter("writer"));
    		article.setEmail(request.getParameter("email"));
    		article.setSubject(request.getParameter("subject"));
    		article.setContent(request.getParameter("content"));
    		article.setPasswd(request.getParameter("passwd"));
    		
    		BoardDBBean dbPro = BoardDBBean.getInstance();
    		int check = dbPro.updateArticle(article);
    		
    		request.setAttribute("pageNum", new Integer(pageNum));
    		request.setAttribute("check", new Integer(check));
    
    		return "updatePro.jsp";
    	}
    }
    

    View : updatePro.jsp

               결과가 1이면 : 성공메시지, 이동 -- 글보기

                         0이면 : 결고메시지, 이동 -- 수정폼

    <%@ 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 = "${check==1}">
    	<meta http-equiv="Refresh" content="0;url=/boardMvc2Ora/list.do?pageNum=${pageNum}">
    </c:if>
    <c:if test = "${check==0}">
    비밀번호가 다릅니다.
    <br>
    <a href="javascript:history.go(-1)">[글 수정으로 돌아가기]</a>
    </c:if>

    mapping : CommandPro.properties 파일에 아래 매핑을 추가한다.

                  /boardMvc2Ora/updatePro.do=my.action.UpdateProAction

     

     


    글 삭제

    Action : DeleteFormAction implement CommandAction

                환경변수 저장 (글번호, 페이지번호)

                뷰값리턴

    View : deleteForm.jsp

               암호입력폼 구성 + 글번호

    mapping : /boardMvc2Ora/deleteForm.do=my.action.DeleteFormAction

     

    글 삭제처리

    DAO : public int deleteArticle (int num, String passwd){

             * 암호비교 (참 : 삭제실행 1리턴, 거짓 : 0리턴)  }

    Action : DeleteProAction implement CommandAction

               * FC의 명령을 받아서

               * DAO의 deleteArticle을 실행하고 

               * 결과를 request영역에 저장, + 환경변수(글번호,페이지번호,,,)

               * 뷰페이지 이름을 리턴한다.  

    View : deletePro.jsp

              * el을 통해서 결과를 읽어온다.

                 1) 결과가 참이면, 성공메시지 -- 이동 글목록

                 2) 결과가 거짓이면, 경고메시지 -- 이동 삭제폼(history.back();)

    mapping : /boardMvc2Ora/deletePro.do=my.action.DeleteProAction


    글 삭제

    Action : DeleteFormAction implement CommandAction

                환경변수 저장 (글번호, 페이지번호)

                뷰값리턴

    package my.action;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class DeleteFormAction implements CommandAction { //글삭제 폼
    	
    	public String requestPro(HttpServletRequest request, HttpServletResponse response)throws Throwable{
    		
    		int num = Integer.parseInt(request.getParameter("num"));
    		String pageNum = request.getParameter("pageNum");
    		
    		//해당 뷰에서 사용할 속성
    		request.setAttribute("num", new Integer(num));
    		request.setAttribute("pageNum", new Integer(pageNum));
    		
    		return "deleteForm.jsp"; //해당뷰 
    
    	}
    	
    
    }
    

    View : deleteForm.jsp

               암호입력폼 구성 + 글번호

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@include file ="/view/color.jspf" %>
    
    <html>
    <head>
    <meta charset="UTF-8">
    <title>게시판</title>
    <link href="style.css" rel="stylesheet" type="text/css">
    
    <script type="text/javascript">
    <!--
    function deleteSave(){
    	if(document.delForm.passwd.value==''){
    		alert("비밀번호를 입력하십시오.");
    		document.delForm.passwd.focus();
    		return false;
    	}
    }
    // -->
    </script>
    </head>
    <body bgcolor="${bodyback_c}">
    
    <b>글삭제</b>
    <br>
    <form method="POST" name="delForm" action="/boardMvc2Ora/deletePro.do?pageNum=${pageNum}" onsubmit="return deleteSave()">
    <table border="1" align="center" cellspacing="0" cellpadding="0" width="360">
    <tr height="30">
    <td align="center" bgcolor="${value_c}">
    <b>비밀번호를 입력해 주세요,</b></td>
    </tr>
    
    <tr height="30">
    <td align="center">비밀번호 :
    <input type="password" name="passwd" size="8" maxlength="12">
    <input type="hidden" name="num" value="${num}"></td>
    </tr>
    
    <tr height="30">
    <td align="center" bgcolor="${value_c}">
    <input type="submit" value="글삭제">
    <input type="button" value="글목록" onclick="document.location.href='/boardMvc2Ora/list.do?pageNum=${pageNum}'">
    </td>
    </tr>
    </table>
    </form>
    </body>
    </html>

    mapping : /boardMvc2Ora/deleteForm.do=my.action.DeleteFormAction

     

    글 삭제처리

    DAO : public int deleteArticle (int num, String passwd){

             * 암호비교 (참 : 삭제실행 1리턴, 거짓 : 0리턴)  }

    	public int deleteArticle(int num, String passwd) throws Exception{
    		Connection conn = null;
    		PreparedStatement pstmt = null;
    		ResultSet rs = null;
    		String dbpasswd="";
    		int x= -1;
    		try {
    			conn = getConnection();
    			pstmt = conn.prepareStatement("select passwd from board3 where num = ?");
    			pstmt.setInt(1, num);
    			rs = pstmt.executeQuery();
    			
    			if(rs.next()) {
    				dbpasswd = rs.getString("passwd");
    				if(dbpasswd.equals(passwd)) {
    					pstmt = conn.prepareStatement(" delete from board3 where num = ?");
    					pstmt.setInt(1, num);
    					pstmt.executeUpdate();
    					
    					x=1; //글삭제 성공
    				}else
    					x=0; //비밀번호 틀림
    					
    			}
    		}catch(Exception ex) {
    			ex.printStackTrace();
    		}finally {
    			if(rs != null) try {rs.close();}catch(SQLException ex) {}
    			if(rs != null) try {pstmt.close();}catch(SQLException ex) {}
    			if(rs != null) try {conn.close();}catch(SQLException ex) {}
    		}
    		
    		return x;
    	}

    Action : DeleteProAction implement CommandAction

               * FC의 명령을 받아서

               * DAO의 deleteArticle을 실행하고 

               * 결과를 request영역에 저장, + 환경변수(글번호,페이지번호,,,)

               * 뷰페이지 이름을 리턴한다.  

    package my.action;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.sun.javafx.image.impl.IntArgb;
    
    import my.board.BoardDBBean;
    
    public class DeleteProAction implements CommandAction { //글삭제
    	
    	public String requestPro (HttpServletRequest request, HttpServletResponse response)throws Throwable{
    		
    		request.setCharacterEncoding("utf-8");
    		
    		int num = Integer.parseInt(request.getParameter("num"));
    		String pageNum = request.getParameter("pageNum");
    		String passwd = request.getParameter("passwd");
    		
    		BoardDBBean dbPro = BoardDBBean.getInstance();
    		int check = dbPro.deleteArticle(num, passwd);
    		
    		//해당 뷰에서 사용할 속성
    		request.setAttribute("pageNum", new Integer(pageNum));
    		request.setAttribute("check", new Integer(check));
    		
    		return "deletePro.jsp"; //해당뷰
    	}
    
    }
    

    View : deletePro.jsp

              * el을 통해서 결과를 읽어온다.

                 1) 결과가 참이면, 성공메시지 -- 이동 글목록

                 2) 결과가 거짓이면, 경고메시지 -- 이동 삭제폼(history.back();)

    <%@ 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="${check==1}">
    <meta http-equiv="Refresh" content="0;url=/boardMvc2Ora/list.do?pageNum=${pageNum}">
    </c:if>
    <c:if test="${check==0}">
    비밀번호가 다릅니다.
    <br>
    <a href="javascript:history.go(-1)">[글삭제 폼으로 돌아가기]</a>
    </c:if>
    

    mapping : /boardMvc2Ora/deletePro.do=my.action.DeleteProAction

     

     


    검색기능 만들기

    'HTML_JS(Sol) > model2' 카테고리의 다른 글

    210625_1(mvc2_board_ 글입력처리)  (0) 2021.06.25
    210624_2(MVC2 게시판 만들기)  (0) 2021.06.24
    210624_1(model2_jstl)  (0) 2021.06.24
    210623_1(EL, XML매핑, JSTL)  (0) 2021.06.23
Designed by Tistory.