2016년 10월 5일 수요일

51day / WEB / Model2 게시판 만들기

# 주위 : 개인적인 낙서판 같은 블로그이지만 어쩌다가 들어오셔서 참고하시게 된다면
참고만 하시길 바랍니다. 기초가 많이 부족한 쓰레기 코드입니다.



  • 구동화면

초기화면
글 목록
글 제목을 클릭하면 NO 컬럼의 PK값과 함께 상세글보기로 이동한다
글쓰기

글 작성이 완료되면 작성한 글을 상세글 보기로 바로 이동시켜서 확인시킨다

상세글보기
1. 목록에서 제목을 클릭
2. 글 작성 후
3. 수정 후
볼 수 있으며
목록 / 삭제 / 수정 3가지의 버튼을 제공한다.

수정 or 삭제 전 비밀번호 체크
수정을 하거나 삭제를 할 때는 비밀번호를 필히 체크한다.

수정여부 체크 팝업
만약 비밀번호가 일치한다면.
삭제 -> 글 삭제 후 글 목록으로 이동한다.
수정 - > 수정 폼으로 이동시켜준다.

수정 폼 제공
글번호는 수정을 못하도록 막는다.
수정 or 글작성 후 확인은 상세글보기를 통함

수정화면 체크

  • Controll
Factory Pattern 적용
public class HandlerMapping {
    private static HandlerMapping instance = new HandlerMapping();
    private HandlerMapping() {
    }
    public static HandlerMapping getInstance() {
        return instance;
    }
    public Controller create(String command) {
        Controller c = null;
        if (command.equals("write")) {
            c = new WriterController();
        } else if (command.equals("list")) {
            c = new ListController();
        } else if (command.equals("detail")) {
            c = new DetailController();
        } else if (command.equals("update")) {
            c = new UpdateController();
        } else if (command.equals("updateCheck")) {
            c = new UpdateCheckController();
        } else if (command.equals("updateAccept")) {
            c = new UpdateAcceptController();
        } else if (command.equals("delete")) {
            c = new DeleteController();
        } else if (command.equals("deleteCheck")) {
            c = new DeleteCheckController();
        } 
        return c;
    }
}
cs

ModelAndView  적용

public class ModelAndView {
    private String viewName;//응답할 View url 할당 
    //Model 계층과 연동하여 View에 공유할 정보를 할당 
    //request.setAttribute(name,value) 할 정보가 저장된다 
    //다수의 정보가 request에 저장될 수 있으므로 Map에 저장한다
    private HashMap<String,Object> map
                    =new HashMap<String,Object>();    
    public ModelAndView(){}
    public ModelAndView(String viewName){
        this.viewName=viewName;
    }
    public ModelAndView(String viewName,String name,Object value){
        this.viewName=viewName;
        map.put(name, value);
    }    
    public ModelAndView(String viewName,HashMap<String, Object> map) {
        super();
        this.viewName = viewName;
        this.map = map;
    }
    //request.setAttribute(name,value) 할 정보가 저장된다
    public void addObject(String name,Object value){
        map.put(name, value);
    }
    public String getViewName() {
        return viewName;
    }
    public void setViewName(String viewName) {
        this.viewName = viewName;
    }
    public HashMap<String, Object> getMap() {
        return map;
    }
    public void setMap(HashMap<String, Object> map) {
        this.map = map;
    }
    @Override
    public String toString() {
        return "ModelAndView [viewName=" + viewName + ", map=" + map + "]";
    }
}

cs

글 목록을 보여준다

public class ListController implements Controller {
    @Override
    public ModelAndView execute(HttpServletRequest request, HttpServletResponse response)
        throws Exception {
        return new ModelAndView("board/list.jsp""list", BoardDAO.getInstance().getAllList());
    }
}
cs

상세글보기

public class DetailController implements Controller {
    @Override
    public ModelAndView execute(HttpServletRequest request, HttpServletResponse response)
throws Exception {
        // 상세정보가 조회될 글의 number
        int no = Integer.parseInt(request.getParameter("no"));
        BoardVO vo = BoardDAO.getInstance().getDetailByNo(no);
        return new ModelAndView("board/detail.jsp""vo", vo);
    }
}
cs


정보수정 Controller 구성

비밀번호를 가져와준다
public class UpdateController implements Controller {
    @Override
    public ModelAndView execute(HttpServletRequest request, HttpServletResponse response)
        throws Exception {
        // 수정 될 글의 number
        int no = Integer.parseInt(request.getParameter("no"));
        // number의 password를 가져온다
        BoardVO vo = BoardDAO.getInstance().getPasswordByNO(no);
        // 비밀번호 체크 팝업으로 보낸다
        return new ModelAndView("board/update_before.jsp""vo", vo);
    }
}

비밀번호가 체크된 후 정보수정 폼으로 보내준다.

public class UpdateCheckController implements Controller {
    @Override
    public ModelAndView execute(HttpServletRequest request, HttpServletResponse response)
        throws Exception {
        int no = Integer.parseInt(request.getParameter("no"));
        BoardVO vo = BoardDAO.getInstance().getDetailByNo(no);
        return new ModelAndView("board/update.jsp""vo", vo);
    }
}
수정된 정보를 DB에 반영시킨 후 결과를 보여준다.

public class UpdateAcceptController implements Controller {
    @Override
    public ModelAndView execute(HttpServletRequest request, HttpServletResponse response)
        throws Exception {
        // 수정될 정보를 폼에서 가져온다
        int no = Integer.parseInt(request.getParameter("no"));
        String title = request.getParameter("title");
        String writer = request.getParameter("writer");
        String content = request.getParameter("content");
        BoardDAO.getInstance().update(new BoardVO(no, title, writer, content));
        // 수정완료가 된 후에 바로 수정된 정보를 확인한다
        return new ModelAndView("redirect:dispatcher?command=detail&no=" + no);
    }
}
cs

글 삭제 Controller 구성

글 삭제를 위하여 비밀번호를 가져온다
public class DeleteController implements Controller {
    @Override
    public ModelAndView execute(HttpServletRequest request, HttpServletResponse response)
throws Exception {
        // 삭제 될 글의 number
        int no = Integer.parseInt(request.getParameter("no"));
        // 글 number의 비밀번호를 가져온다
        BoardVO vo = BoardDAO.getInstance().getPasswordByNO(no);
        return new ModelAndView("board/delete_popup.jsp""vo", vo);
    }
}

글 삭제를 한 후 글 목록으로 보내준다.
public class DeleteCheckController implements Controller {
    @Override
    public ModelAndView execute(HttpServletRequest request, HttpServletResponse response)
throws Exception {
        // 삭제 될 글의 number
        int no = Integer.parseInt(request.getParameter("no"));
        BoardDAO.getInstance().delete(no);
        return new ModelAndView("board/list.jsp","list", BoardDAO.getInstance().getAllList());
    }
}
cs

글 작성 폼을 DB에 반영한 후 상세글보기를 통하여 결과조회
public class WriterController implements Controller {
    @Override
    public ModelAndView execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
        int no = BoardDAO.getInstance().seqCreate();
        
        String title = request.getParameter("title");
        String writer = request.getParameter("writer");
        String password = request.getParameter("password");
        String content = request.getParameter("content");
        
        BoardDAO.getInstance().write(new BoardVO(no, title, writer, password, content));
        
        return new ModelAndView("redirect:dispatcher?command=detail&no="+no);
    }
}
cs

  • Model
public class BoardDAO {
    /**
     *  싱글톤 선언과 DB접속을 준비한다.
     */
    private static BoardDAO instance;
    private DataSource dataSource;
    private BoardDAO() {
        dataSource = DataSourceManager.getInstance().getDataSource();
    }
    public static BoardDAO getInstance() {
        if (instance == null)
            instance = new BoardDAO();
        return instance;
    }
    public Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    /**
     * 글 쓰기 후 먼저 시퀀스번호부터 생성한다.
     *
     * @return Sequence Number
     * @throws SQLException
     */
    public int seqCreate() throws SQLException {
        Connection con = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        int num = 0;
        try {
            con = getConnection();
            String sql = "SELECT board_seq.NEXTVAL FROM dual";
            pstmt = con.prepareStatement(sql);
            rs = pstmt.executeQuery();
            if (rs.next()) {
                num = rs.getInt(1);
            }
        } finally {
            closeAll(rs, pstmt, con);
        }
        return num;
    }
    /**
     * 글 작성을 위하여 DB에 Insert 하여 update한다.
     *
     * @param vo(폼에서 작성된 정보)
     * @throws SQLException
     */
    public void write(BoardVO vo) throws SQLException {
        Connection con = null;
        PreparedStatement pstmt = null;
        try {
            con = getConnection();
            String sql = "INSERT INTO board(no,title,writer,password,content,time_posted)"
                    + "VALUES(?,?,?,?,?,SYSDATE)";
            pstmt = con.prepareStatement(sql);
            pstmt.setInt(1, vo.getNo());
            pstmt.setString(2, vo.getTitle());
            pstmt.setString(3, vo.getWriter());
            pstmt.setString(4, vo.getPassword());
            pstmt.setString(5, vo.getContent());
            pstmt.executeUpdate();
        } finally {
            closeAll(pstmt, con);
        }
    }
    /**
     * 물고온 PK number를 통하여 글을 삭제한다.
     *
     * @param no (Sequence number or Primary key)
     * @throws SQLException
     */
    public void delete(int no) throws SQLException {
        Connection con = null;
        PreparedStatement pstmt = null;
        try {
            con = getConnection();
            String sql = "DELETE FROM board WHERE no = ?";
            pstmt = con.prepareStatement(sql);
            pstmt.setInt(1, no);
            pstmt.executeUpdate();
        } finally {
            closeAll(pstmt, con);
        }
    }
    /**
     * 필요한 컬럼만 가져와서 게시판 리스트를 구성한다.
     *
     * @return list(글 목록)
     * @throws SQLException
     */
    public ArrayList<BoardVO> getAllList() throws SQLException {
        Connection con = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        ArrayList<BoardVO> list = new ArrayList<BoardVO>();
        try {
            con = getConnection();
            String sql = "SELECT no,title,writer,hits,TO_CHAR(time_posted,'YYYY.MM.DD')"
                    + "FROM board ORDER BY no DESC";
            pstmt = con.prepareStatement(sql);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                BoardVO vo = new BoardVO(rs.getInt(1), rs.getString(2), rs.getString(3), rs.getInt(4), rs.getString(5));
                list.add(vo);
            }
        } finally {
            closeAll(rs, pstmt, con);
        }
        return list;
    }
    /**
     * 글 삭제 or 수정을 비밀번호 체크를 위해
     * 해당 서비스를 원하는 글의 비밀번호를 가져온다.
     *
     * @param no (Sequence number or Primary key)
     * @return vo (no의 password를 가져온다)
     * @throws SQLException
     */
    public BoardVO getPasswordByNO(int no) throws SQLException {
        Connection con = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        BoardVO vo = null;
        try {
            con = getConnection();
            String sql = "select password from board where no = ?";
            pstmt = con.prepareStatement(sql);
            pstmt.setInt(1, no);
            rs = pstmt.executeQuery();
            if (rs.next())
                vo = new BoardVO(no, rs.getString(1));
        } finally {
            closeAll(rs, pstmt, con);
        }
        return vo;
    }
    /**
     * 상세글 보기
     * 조회수도 1 증가 시킨다.
     *
     * @param no (Sequence number or Primary key)
     * @return vo (상세글보기에서 필요한 정보만 가져온다)
     * @throws SQLException
     */
    public BoardVO getDetailByNo(int no) throws SQLException {
        Connection con = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        BoardVO vo = null;
        try {
            con = getConnection();
            String hit = "UPDATE board SET hits = hits + 1 WHERE no = ?";
            String sql = "SELECT title,writer,content,hits,to_char(time_posted,'YYYY/MM/DD HH24:MI:SS') FROM board WHERE no=?";
            pstmt = con.prepareStatement(hit);
            pstmt.setInt(1, no);
            pstmt.executeUpdate();
            pstmt = con.prepareStatement(sql);
            pstmt.setInt(1, no);
            rs = pstmt.executeQuery();
            if (rs.next())
                vo = new BoardVO(no, rs.getString(1), rs.getString(2), rs.getString(3), rs.getInt(4),
                        rs.getString(5));
        } finally {
            closeAll(rs, pstmt, con);
        }
        return vo;
    }
    /**
     *
     * @param vo(수정 폼에서 제공받은 수정될 정보)
     * @throws SQLException
     */
    public void update(BoardVO vo) throws SQLException {
        Connection con = null;
        PreparedStatement pstmt = null;
        try {
            con = getConnection();
            String sql = "update board set title=?, writer=?, content=? where no = ?";
            pstmt = con.prepareStatement(sql);
            pstmt.setString(1, vo.getTitle());
            pstmt.setString(2, vo.getWriter());
            pstmt.setString(3, vo.getContent());
            pstmt.setInt(4, vo.getNo());
            pstmt.executeUpdate();
        } finally {
            closeAll(pstmt, con);
        }
    }
    /**
     * PreparedStatement AND Connection 연결을 끊어준다.
     *
     * @param pstmt
     * @param con
     */
    public void closeAll(PreparedStatement pstmt, Connection con) {
        if (pstmt != null) {
            try {
                pstmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (con != null) {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     *
     * ResultSet AND PreparedStatement AND Connection
     * 연결을 끊어준다.
     *
     * @param rs
     * @param pstmt
     * @param con
     */
    public void closeAll(ResultSet rs, PreparedStatement pstmt, Connection con) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        closeAll(pstmt, con);
    }
}
cs

public class BoardVO {
    // 글 Number 유일값
    private int no;
    // 제목
    private String title;
    // 작성자
    private String writer;
    // 비밀번호
    private String password;
    // 글 내용
    private String content;
    // 조회수
    private int hits;
    // 작성날짜
    private String time_posted;
    public BoardVO() {
        super();
    }
    public BoardVO(int no) {
        super();
        this.no = no;
    }
    // 비밀번호 겟! 생성자
    public BoardVO(int no, String password) {
        super();
        this.no = no;
        this.password = password;
    }
    // 수정 생성자!
    public BoardVO(int no, String title, String writer, String content) {
        super();
        this.no = no;
        this.title = title;
        this.writer = writer;
        this.content = content;
    }
    // 글 작성 생성자
    public BoardVO(int no, String title, String writer, String password, String content, String time_posted) {
        super();
        this.no = no;
        this.title = title;
        this.writer = writer;
        this.password = password;
        this.content = content;
        this.time_posted = time_posted;
    }
    // 글 작성 생성자
    public BoardVO(int no, String title, String writer, String password, String content) {
        super();
        this.no = no;
        this.title = title;
        this.writer = writer;
        this.password = password;
        this.content = content;
    }
    // 글 목록 생성자
    public BoardVO(int no, String title, String writer, int hits, String time_posted) {
        super();
        this.no = no;
        this.title = title;
        this.writer = writer;
        this.hits = hits;
        this.time_posted = time_posted;
    }
    // 글 Detail 생성자
    public BoardVO(int no, String title, String writer, String content, int hits, String time_posted) {
        super();
        this.no = no;
        this.title = title;
        this.writer = writer;
        this.content = content;
        this.hits = hits;
        this.time_posted = time_posted;
    }
    public int getNo() {
        return no;
    }
    public void setNo(int no) {
        this.no = no;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getWriter() {
        return writer;
    }
    public void setWriter(String writer) {
        this.writer = writer;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public int getHits() {
        return hits;
    }
    public void setHits(int hits) {
        this.hits = hits;
    }
    public String getTime_posted() {
        return time_posted;
    }
    public void setTime_posted(String time_posted) {
        this.time_posted = time_posted;
    }
    @Override
    public String toString() {
        return "BoardVO [no=" + no + ", title=" + title + ", writer=" + writer + ", password=" + password + ", content="
                + content + ", hits=" + hits + ", time_posted=" + time_posted + "]";
    }
}
cs

  • View(역할은 title참조)

<%@ 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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>초기화면</title>
<link rel="stylesheet" href="${initParam.root}css/board.css" type="text/css">
</head>
<body>
<c:import url="/template/header.jsp"></c:import>
<hr>
<h1>Model2 MVC Board</h1>
</body>
</html>
cs

<%@ 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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>글목록</title>
<link rel="stylesheet" href="${initParam.root}css/board.css" type="text/css">
<script type="text/javascript">
</script>
</head>
<body>    
<c:import url="/template/header.jsp"></c:import>
<hr>    
    <table class="list">
        <caption>목 록</caption>
        <thead>
        <tr>
            <th class="no">NO</th>
            <th class="title">제목</th>
            <th class="name">이름</th>
            <th class="date">작성일</th>
            <th class="hit">조회수</th>
            </tr>
        </thead>
        <tbody>            
    <c:forEach items="${requestScope.list}" var="board">
            <tr>
                <td>${board.no}</td>                
                <td><a href="${initParam.root}dispatcher?command=detail&no=${board.no}">
                ${board.title}</a></td>
                <td>${board.writer}</td>
                <td>${board.time_posted}</td>
                <td>${board.hits}</td>
            </tr>            
            </c:forEach>        
        </tbody>                    
    </table><br></br>    
    <a href="${initParam.root}board/write.jsp"><img src="글쓰기버튼" border="0"></a>
    <br><br>    
</body>
</html>
cs

<%@ 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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>상세정보</title>
<link rel="stylesheet" href="${initParam.root}css/board.css" type="text/css">
<script type="text/javascript">
    function sendList(){
        location.href = "${initParam.root}dispatcher?command=list";
    }
    function winOpen(url, no){
        window.open("${initParam.root}dispatcher?command="+url+"&no="+no, "popup",
        "width = 550, height = 350, top = 150, left = 200");
    }
</script>
</head>
<body>
<p>
<c:import url="/template/header.jsp"></c:import>
</p>        
    <table class="content">
        <tr>
            <td>NO : ${requestScope.vo.no}</td>
            <td colspan="2">제목 : ${requestScope.vo.title}</td>
        </tr>
        <tr>
            <td>작성자 : ${requestScope.vo.writer}</td>
            <td>${requestScope.vo.time_posted}</td>
            <td>조회수 : ${requestScope.vo.hits}</td>
        </tr>
        <tr>
            <td colspan="3">
            <pre>${requestScope.vo.content}</pre>
            </td>
        </tr>
        <tr>
            <td valign="middle" align="center" colspan="3">
             <img class="action" src="${initParam.root}img/list_btn.jpg" onclick="sendList()" >
             <img class="action"  onclick="winOpen('delete','${requestScope.vo.no}')"     src="${initParam.root}img/delete_btn.jpg" > 
             <img class="action"  onclick="winOpen('update','${requestScope.vo.no}')"  src="${initParam.root}img/modify_btn.jpg" ></td>
        </tr>
    </table>
</body>
</html>
cs

<%@ 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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게시글쓰기</title>
<link rel="stylesheet" href="${initParam.root}css/board.css" type="text/css">
<script type="text/javascript">
    function formCheck(){
        var title = document.write_form.title.value;
        var writer = document.write_form.writer.value;
         var pw = document.write_form.password.value;
         var content = document.write_form.content.value;
        
         if(title == ""){
             alert("제목을 입력하세요");
             return false;
         }
         if(writer == ""){
             alert("작성자를 입력하세요");
             return false;
         }
         if(pw == ""){
             alert("비밀번호를 입력하세요");
             return false;
         }
         if(content == ""){
             alert("내용을 입력하세요");
             return false;
         }
    }
        
    function cancel() {
        document.write_form.reset();
    }
</script>
</head>
<body>
<c:import url="/template/header.jsp"></c:import>
<hr>
 <br>
  <form action="${initParam.root}dispatcher" method="post" name="write_form" onsubmit="return formCheck()">  
   <table class="inputForm">
    <caption>글쓰기</caption>
    <tbody>
    <tr>
     <td>제목</td>
     <td colspan="3">
     <input type="text" name="title" size="48">
     </td>
    </tr>
    <tr>
     <td>이름</td>
     <td><input type="text" name="writer" size="20"></td>
     <td>비밀번호</td>
     <td>
     <input type="password" name="password" size="5">
     </td>
    </tr>
    <tr>
     <td colspan="4" align="left">
     &nbsp;&nbsp;
     <textarea cols="53" rows="15" name="content"></textarea>
     </td>
    </tr> 
    <tr>
     <td colspan="4" align="center" >
      <input type="hidden" name="command" value="write">
      <input type="image" class="action" src="${initParam.root}img/write_btn.jpg" alt="글입력">
      <img class="action" src="${initParam.root}img/cancel.gif" onclick="cancel()">      
     </td>  
    </tr>
    </tbody>
   </table>
  </form>
</body>
</html>
cs

<%@ 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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script>
    function deleteCk(vopw){
        var pw = document.checkForm.pw.value;
        
        if(pw!=vopw){
            alert("비밀번호가 일치하지 않습니다");
            return false;
        }else{
            if(confirm("삭제하시겠습니까?")){
                window.opener.location.href="${initParam.root}dispatcher?command=deleteCheck&no=${requestScope.vo.no}";
                self.close();
            }
        }
    }
</script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>delete_popup</title>
<link rel="stylesheet" href="${initParam.root}css/board.css" type="text/css">
</head>
<body>
    <hr>
    <form name = "checkForm" method = "post" action = "${initParam.root}dispatcher" onsubmit="return deleteCk()">
        <table class = "content">
            <tr>
                <td colspan = "2">비밀번호</td>
            </tr>
            <tr><td colspan = "2">
                <input type = "password" name= "pw"></td>
            </tr>
            <tr>
                <td colspan = "2">
            <input type = "hidden" name = "command" value = "deleteCheck">
            <input type = "hidden" name= "no" value = "${requestScope.vo.no}">
            <input type="button" value="삭제" class="action" onclick="deleteCk('${requestScope.vo.password}')">
            <input type="button" value="창끄기" onclick="javascript:self.close()">
            </td></tr>
        </table>
    </form>
</body>
</html>
cs

<%@ 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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script>
    function deleteCk(vopw){
        var pw = document.checkForm.pw.value;
        
        if(pw!=vopw){
            alert("비밀번호가 일치하지 않습니다");
            return false;
        }else{
            if(confirm("수정페이지로 이동하시겠습니까?")){
                window.opener.location.href="${initParam.root}dispatcher?command=updateCheck&no=${requestScope.vo.no}"
                self.close();
            }
        }
    }
</script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>delete_popup(비밀번호체크)</title>
<link rel="stylesheet" href="${initParam.root}css/board.css" type="text/css">
</head>
<body>
    <hr>
    <form name = "checkForm" method = "post" action = "${initParam.root}dispatcher" onsubmit="return deleteCk()">
        <table class = "content">
            <tr>
                <td colspan = "2">비밀번호</td>
            </tr>
            <tr><td colspan = "2">
                <input type = "password" name= "pw"></td>
            </tr>
            <tr>
                <td colspan = "2">
            <input type = "hidden" name = "command" value = "deleteCheck">
            <input type = "hidden" name= "no" value = "${requestScope.vo.no}">
            <input type="button" value="수정페이지로" class="action" onclick="deleteCk('${requestScope.vo.password}')">
            </td></tr>
        </table>
    </form>
</body>
</html>
cs

<%@ 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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Update Form</title>
<link rel="stylesheet" href="${initParam.root}css/board.css" type="text/css">
<script>
function formCheck(){
    var title = document.update_form.title.value;
    var writer = document.update_form.writer.value;
     var content = document.update_form.content.value;
    
     if(title == ""){
         alert("제목을 입력하세요");
         return false;
     }
     if(writer == ""){
         alert("작성자를 입력하세요");
         return false;
     }
     if(content == ""){
         alert("내용을 입력하세요");
         return false;
     }
}
</script>
</head>
<body>
<c:import url="/template/header.jsp"></c:import>
<hr>    
<form action="dispatcher" name = "update_form" method = "post" onsubmit="return formCheck()">        
    <table class="content">
    <tr> 
        <td>
            <table>
                <tr>
                    <td>
                    글번호: <input type=text name=no value="${requestScope.vo.no}" readonly></input>
                    타이틀: <input type=text name= title value="${requestScope.vo.title}">                    
                    </td>
                </tr>
    <tr>
        <td>
        <font size="2">작성자: <input type=text name = writer value="${requestScope.vo.writer}">
            | ${requestScope.vo.time_posted} </font>
        </td>
    </tr>
            <tr>
                <td>                        
    <textarea rows="15" cols="75" name="content" >${requestScope.vo.content}</textarea>
                    </td>
                </tr>
                <tr>
                <td valign="middle">            
                    <input type="hidden" name="command" value="updateAccept">
                    <input type="submit" value="수정하기" class="action">            
                    </td>                
                </tr>
            </table>
        </td>
    </tr>
</table>
</form>    
</body>
</html>
cs

2016년 10월 4일 화요일

50day / WEB / Model2 게시판 만들기

http://www.javatpoint.com

비로그인형 간단게시판 만들기 (계획)

  • 주요업무분석
  1. 글쓰기 -> 글 작성완료 후 결과화면은 (상세 글 보기) 
  2. 게시글목록에서 상세 글 보기로 링크 이동 

  • 기능구현 
  1. 글쓰기 
  2. 목록보기 
  3. 상세 글 보기 (의외로 가장 어려운 사항이였음) 

  • View 
  1. index.jsp 
  2. -> 초기화면 
  3. header.jsp 
  4. -> 상단 메뉴바 
  5. detail.jsp 
  6. -> 상세 글 보기 
  7. list.jsp 
  8. -> 게시글 목록 
  9. writer.jsp 
  10. -> 글 작성 폼
  11. update_popup.jsp
  12. -> 정보수정 폼
  13. delete_popup.jsp
  14. -> 게시물 삭제 비밀번호 입력 폼
  15. delete_checkpass_result.jsp
  16. -> 삭제 여부 질의 후 PK을 파라미터로 컨트롤러에 넘김
  17. update_checkpass_result.jsp
  18. -> 수정 여부 질의 후 PK을 파라미터로 컨트롤러에 넘김
  • Controller
1. IndexController.java
-> 초기화면을 이동해준다.

2. DetailController.java
-> 요청된 PK 값에 대한 상세글보기 페이지로 이동시켜주며 조회수를 증가시켜준다

3. ListController.java
-> 전체 글 목록을 ArrayList로 뽑아서 리턴해준다

4. WrteController.java
-> 게시물 등록 후 PK값과 함께 상세글보기 페이지로 이동한다.

5. HandlerMapping.java
-> 클라이언트의 요청에 대한 객체를 생성하여 리턴한다
(Singleton Pattern ,Factory Pattern 적용)

6. DispatcherServlet.java
-> 클라이언트의 요청을 받는 시작점이다 (Fronte Controller Pattern 적용) 
  요청상황에 따라 redirect하기도하고 forward하기도 한다.

7. ModelAndView.java
-> 컨트롤러 업무 수행 후 반환할 때 사용하는 객체이다. 반환결과를 저장한다.

8. DeletePostingController.java
-> PK값을 받아 해당 게시글을 삭제해준 후 전체 목록으로 이동시킨다.

9. DeleteCheckPasswordController.java
-> 게시물을 삭제해도 되는지 비밀번호로 판단하여 리턴한다.

10. UpdatePostingController.java
-> 입력받은 정보로 정보수정을 해준다

11. UpdateCheckPasswordController.java
-> 게시물을 수정해도 되는지 비밀번호로 판단하여 리턴한다.

12. UpdateViewController
-> 게시물을 수정에 접근할 수 있을 때만 게시물 수정 폼으로 이동시켜준다
  • Model
1. BoardDAO.java-> 게시판의 비즈니스 로직을 담당한다. (Singleton Pattern 적용)

2. BoardVO.java-> 게시판의 구성요소 객체

3. DataSourceManager.java-> 컨넥션 풀을 생성하여 공유하는 객체
(Singleton Pattern 적용)


# 코드 및 풀이 과정은 다음 게시물로 이어서..

2016년 10월 2일 일요일

개발자 커뮤니티 모음


개발자들이 현장에서 접하는 기술과 고민을 함께 공유하는 데뷰 행사를 통해 보다 활발한 기술 공유와 함께 동반 성장을 할 수 있는 밑거름이 되기를 바랍니다.
네이버 랩 연구센터장, 송창현 (http://www.zdnet.co.kr/news/news_view.asp?artice_id=20140915112248)

커뮤니티에서 사람들과 이야기하며, 기술을 공유하고 서로가 도움을 주면서 기술의 흐름과 현재 프로젝트의 동향 등을 파악하고 지금 자신이 개발 중인 기술이나 프로젝트와 비교하면서 스스로가 개발자로서 어떤 방향으로 나아가야 하고 어떤 것들을 공부해야 하는지도 깨달을 수 있다고 생각합니다.한국자바개발자 협의회 JCO 일동

2016년 9월 30일 금요일

2016년 9월 29일 목요일

2016년 9월 28일 수요일

2016년 9월 27일 화요일

2016년 9월 26일 월요일