웹개발 수업/Server

[Day +84 / Server]사진 게시판 만들기1 // 내용추가하세요

Chole Woo 2021. 10. 23. 01:47
211022 금

 

 

1. 사진 게시판 썸네일 형식으로 만들기


1) SQL Developer

Board 테이블에 사진 게시판 가데이터 5행 삽입

BEGIN
    FOR I IN 1..5
    LOOP
        INSERT INTO BOARD 
        VALUES(SEQ_BID.NEXTVAL, 2, 10, '사진 제목' || I, '사진 내용' || I, 2, DEFAULT, SYSDATE, SYSDATE, DEFAULT);
     -SEQ_BID.NEXTVAL : 215~219 /  사진 제목 || I : 사진 제목 1~5 / DEFAULT : 0 (조회수) / DEFATLT : Y(STATUS)
   

        INSERT INTO ATTACHMENT 
        VALUES(SEQ_FID.NEXTVAL, SEQ_BID.CURRVAL, 'origin.png', 'change.png', 'resources/uploadFiles/',
        SYSDATE, 0, DEFAULT, DEFAULT);  

    END LOOP;
END;
/
COMMIT;
*PL/SQL 구조
-선언부(DECLARE SECTION) : DECLARE로 시작, 변수나 상수를 선언하는 부분
-실행부(EXCUTABLE SECTION) : BEGIN으로 시작, 제어문, 반복문, 함수 등의 로직을 기술
-예외처리부(EXCEPTION SECTION) : EXCEPTION으로 시작, 예외 상황 발생 시 해결하기 위한 문장 기술









*SEQ. : 시퀀스

: 자동 번호 발생기 역할을 하는 객체
-순차적으로 정수 값을 자동으로 생성해줌
-UNIQUE한 값을 컬럼에 입력할 수 있음 / 일반적으로 PRIMARY KEY 값을 생성하기 위해 사용

*CURRVAL, NEXTVAL
시퀀스명.CURRVAL : 현재 생성된 시퀀스 값
시퀀스명.NEXTVAL : 시퀀스 값을 증가 시킴. 기본 시퀀스 값에서 증가치만큼 증가한 값.


출처 : 본인 블로그 [Day +45 / SQL]SYNONYM, PL_SQL 참조


*|| : sql에서 텍스트 합치기 연결자

출처 : 
https://lcs1245.tistory.com/entry/SQL-%EB%AC%B8%EC%9E%90-%ED%95%A9%EC%B9%98%EA%B8%B0-%EC%8C%8D%ED%8C%8C%EC%9D%B4%ED%94%84-CONCAT

 


2) uploadFiles -> change.png 넣기


3) menubar.jsp

생략

   <nav id="nav">
      <ul>
         <li><a href="<%= request.getContextPath() %>">HOME</a></li>
         <li><a href="${ contextPath }/notice/list">공지사항</a></li>

         <li><a href="${ contextPath }/board/list">게시판</a></li>
         <li><a href="${ contextPath }/gallery/list">사진게시판</a></li>

       -client가 게시판 클릭시 galleryListServlet(/gallery/list)과 매핑      

</ul>
   </nav>
</div>
</body>
</html>


4) GalleryLIstServlet 생성

5) Attachment 생성자 만들기

package board.model.vo;

import java.sql.Date;

public class Attachment {

private int fid; // 첨부파일 pk
private int bid; // 참조 게시글 아이디
private String originName; // 파일 업로드 시의 원본 파일명
private String changeName; // 서버 저장시의 변경 파일명
private String filePath; // 파일 저장 경로
private Date uploadDate; // 업로드된 시간
private int fileLevel; // 대표 사진0, 내용 사진1
private int downloadCount; // 다운로드 횟수
private String status; // 삭제 여부

-SQLDeveloper에서 만든 Attachment 테이블의 컬럼명들을 생성자로 만들었음


public Attachment() {}


public Attachment(int fid, int bid, String originName, String changeName, String filePath, Date uploadDate,
int fileLevel, int downloadCount, String status) {
super();
this.fid = fid;
this.bid = bid;
this.originName = originName;
this.changeName = changeName;
this.filePath = filePath;
this.uploadDate = uploadDate;
this.fileLevel = fileLevel;
this.downloadCount = downloadCount;
this.status = status;
}


public int getFid() {
return fid;
}


public void setFid(int fid) {
this.fid = fid;
}


public int getBid() {
return bid;
}


public void setBid(int bid) {
this.bid = bid;
}


public String getOriginName() {
return originName;
}


public void setOriginName(String originName) {
this.originName = originName;
}


public String getChangeName() {
return changeName;
}


public void setChangeName(String changeName) {
this.changeName = changeName;
}


public String getFilePath() {
return filePath;
}


public void setFilePath(String filePath) {
this.filePath = filePath;
}


public Date getUploadDate() {
return uploadDate;
}


public void setUploadDate(Date uploadDate) {
this.uploadDate = uploadDate;
}


public int getFileLevel() {
return fileLevel;
}


public void setFileLevel(int fileLevel) {
this.fileLevel = fileLevel;
}


public int getDownloadCount() {
return downloadCount;
}


public void setDownloadCount(int downloadCount) {
this.downloadCount = downloadCount;
}


public String getStatus() {
return status;
}


public void setStatus(String status) {
this.status = status;
}


@Override
public String toString() {
return "Attachment [fid=" + fid + ", bid=" + bid + ", originName=" + originName + ", changeName=" + changeName
+ ", filePath=" + filePath + ", fileLevel=" + fileLevel + ", downloadCount=" + downloadCount
+ ", status=" + status + "]";
}
}

 


6) Board에  <list>타입의 photoList추가
-private list<Attachment> photoList;
-관련된 getter, setter, tostring 등 모두 바꾸기

package board.model.vo;

import java.util.Date;
import java.util.List;

public class Board {
   private int bid;         // 게시글 고유 번호
   private int btype;         // 게시글 타입(1. 일반게시판, 2. 사진 게시판)
   private int cid;         // 게시글 카테고리 id
   private String cname;      // 게시글 카테고리명(category 테이블 조인 결과 값 : id와 명칭을 같이 조인해서 가져옴)
   private String btitle;      // 게시글 제목
   private String bcontent;   // 게시글 내용
   private int bwriter;      // 게시글 작성자(user_no 참조 값)
   private String userName;   // 게시글 작성자명(Member 테이블 조인 결과 값)
   private int bcount;         // 게시글 조회수
   private Date createDate;   // 게시글 작성일 : sql Date 연월일 포맷되어서 2021-10-19 시분초 데이터 날라감
   private Date modifyDate;   // 게시글 수정일 : util Date를 사용해야 시분초 안날라감 대신 포맷팅이 안되어서 옴
   private String status;      // 게시글 상태(Y, N)
   
   
   private List<Attachment> photoList;      // 사진 게시판 첨부 파일 (게시글 하나에 여러 첨부 파일을 가질 수 있음)
   /*BID   NUMBER
   BTYPE   NUMBER
   CID   NUMBER
   BTITLE   VARCHAR2(100 BYTE)
   BCONTENT   VARCHAR2(4000 BYTE)
   BWRITER   NUMBER
   BCOUNT   NUMBER
   CREATE_DATE   DATE
   MODIFY_DATE   DATE
   STATUS   VARCHAR2(1 BYTE)*/
   
   
   public Board() {}
   
   public Board(int bid, int btype, int cid, String cname, String btitle, String bcontent, int bwriter,
         String userName, int bcount, Date createDate, Date modifyDate, String status) {
      super();
      this.bid = bid;
      this.btype = btype;
      this.cid = cid;
      this.cname = cname;
      this.btitle = btitle;
      this.bcontent = bcontent;
      this.bwriter = bwriter;
      this.userName = userName;
      this.bcount = bcount;
      this.createDate = createDate;
      this.modifyDate = modifyDate;
      this.status = status;
   }
   
   public Board(int bid, int btype, int cid, String cname, String btitle, String bcontent, int bwriter,
         String userName, int bcount, Date createDate, Date modifyDate, String status, List<Attachment> photoList) {
      super();
      this.bid = bid;
      this.btype = btype;
      this.cid = cid;
      this.cname = cname;
      this.btitle = btitle;
      this.bcontent = bcontent;
      this.bwriter = bwriter;
      this.userName = userName;
      this.bcount = bcount;
      this.createDate = createDate;
      this.modifyDate = modifyDate;
      this.status = status;
      this.photoList = photoList;
   }
   
   public int getBid() {
      return bid;
   }
   
   public void setBid(int bid) {
      this.bid = bid;
   }
   
   public int getBtype() {
      return btype;
   }
   
   public void setBtype(int btype) {
      this.btype = btype;
   }
   
   public int getCid() {
      return cid;
   }
   
   public void setCid(int cid) {
      this.cid = cid;
   }
   
   public String getCname() {
      return cname;
   }
   
   public void setCname(String cname) {
      this.cname = cname;
   }
   
   public String getBtitle() {
      return btitle;
   }
   
   public void setBtitle(String btitle) {
      this.btitle = btitle;
   }
   
   public String getBcontent() {
      return bcontent;
   }
   
   public void setBcontent(String bcontent) {
      this.bcontent = bcontent;
   }
   
   public int getBwriter() {
      return bwriter;
   }
   
   public void setBwriter(int bwriter) {
      this.bwriter = bwriter;
   }
   
   public String getUserName() {
      return userName;
   }
   
   public void setUserName(String userName) {
      this.userName = userName;
   }
   
   public int getBcount() {
      return bcount;
   }
   
   public void setBcount(int bcount) {
      this.bcount = bcount;
   }
   
   public Date getCreateDate() {
      return createDate;
   }
   
   public void setCreateDate(Date createDate) {
      this.createDate = createDate;
   }
   
   public Date getModifyDate() {
      return modifyDate;
   }
   
   public void setModifyDate(Date modifyDate) {
      this.modifyDate = modifyDate;
   }
   
   public String getStatus() {
      return status;
   }
   
   public void setStatus(String status) {
      this.status = status;
   }
   
   public List<Attachment> getPhotoList() {
      return photoList;
   }
   
   public void setPhotoList(List<Attachment> photoList) {
      this.photoList = photoList;
   }
   
   @Override
   public String toString() {
      return "Board [bid=" + bid + ", btype=" + btype + ", cid=" + cid + ", cname=" + cname + ", btitle=" + btitle
            + ", bcontent=" + bcontent + ", bwriter=" + bwriter + ", userName=" + userName + ", bcount=" + bcount
            + ", createDate=" + createDate + ", modifyDate=" + modifyDate + ", status=" + status + ", photoList="
            + photoList + "]";
   }

   

}
Q. photoList를 Board에 추가해준 이유가 뭘까? 

 

 

7) GalleryListServlet
List<Board> boardList = new BoardService().selectGalleryList(); / 3번의 menubar와 매핑

생략

/**
 * Servlet implementation class GalleryListServlet
 */
@WebServlet("/gallery/list")
public class GalleryListServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public GalleryListServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

/**
 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
 */
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Board> boardList = new BoardService().selectGalleryList();
-<board>클래스에  List타입의 boardList객체를 만들겠다. 그 값은 BoardService의 selectGalleryList에서 불러오겠다.(아직 만들어주지 않았음)

// System.out.println(boardList);

request.setAttribute("boardList", boardList);
request.getRequestDispatcher("/WEB-INF/views/gallery/galleryListView.jsp").forward(request, response);
}

/**
 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
 */
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}

}



8) BoardService

package board.model.service;

import java.sql.Connection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import board.model.dao.BoardDao;
import board.model.vo.Board;
import board.model.vo.PageInfo;
import board.model.vo.Search;
import notice.model.vo.Notice;

import static common.JDBCTemplate.*;

public class BoardService {

private BoardDao boardDao = new BoardDao();

public Map<String, Object> selectList(int page, Search search) {

// JDBCTemplate 임포트 필요
Connection conn = getConnection();

// 1. 게시글 총 개수 구하기
int listCount = boardDao.getListCount(conn, search);

// System.out.println(listCount);

// 2. PageInfo 객체 만들기
PageInfo pi = new PageInfo(page, listCount, 10, 10);

// 3. 페이징 처리된 게시글 목록 조회
List<Board> boardList = boardDao.selectList(conn, pi, search);

Map<String, Object> returnMap = new HashMap<>();

// System.out.println(listCount); //갯수 출력됨
// System.out.println(pi);
// System.out.println(boardList);

returnMap.put("pi", pi);
returnMap.put("boardList", boardList);

return returnMap;
}

생략

public List<Board> selectGalleryList() {
   Connection conn = getConnection();
   -Connection객체를 쓰겠다.
    How? JDBCTemplate에 저장해놨음

   List<Board> boardList = boardDao.selectGalleryList(conn);
   -BoardDao에서 selectGalleryList메소드를 통해 conn과 연결해서 본격적으로 사용하겠다. -> Dao로 감

   close(conn);
   -boardDao에서 돌아온 후 다 쓴 conn객체는 그만 쓰겠다. 

   return boardList;
   -boardDao까지 탐색해서 알아낸 boardList 값을 servlet으로 보내겠다.
}
}

 

 

9) board-query
select문 작성

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM
"http://java.sun.com/dtd/properties.dtd">
<properties>

생략
         
    <entry key="selectGalleryList">
    SELECT
    BID
  , CNAME
  , BTITLE
  , USER_NAME
  , BCOUNT
  , FILE_PATH
  , CHANGE_NAME
FROM BOARD B
JOIN CATEGORY USING(CID)
JOIN MEMBER ON(BWRITER=USER_NO)
JOIN ATTACHMENT USING(BID)
WHERE BTYPE = 2
AND B.STATUS = 'Y'
AND FILE_LEVEL = 0
ORDER BY BID DESC
    
    </entry>

</properties>

 

10) dao
PreparedStatement pstmt = null;
ResultSet rset = null;
List<Board> boardList = new ArrayList<>();
String sql = boardQuery.getProperty("selectGalleryList");

return boardList;

package board.model.dao;

import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import board.model.vo.Attachment;
import board.model.vo.Board;
import board.model.vo.PageInfo;
import board.model.vo.Search;

import static common.JDBCTemplate.close;

public class BoardDao {


생략


public List<Board> selectGalleryList(Connection conn) {

   PreparedStatement pstmt = null;
  -이제부터 PreparedStatment를 쓸 것이다. 준비해라(초기화해라) 

*PreparedStatement : sql에서 실행부분 담당

   ResultSet rset = null;

   List<Board> boardList = new ArrayList<>();
   Q. 이게 무슨 뜻일까


   String sql = boardQuery.getProperty("selectGalleryList");
 -board-query의 entry키가 selectGalleryList와 연결하겠다.

Q. 이름이 똑같지 않은데 board-Query.xml인지 어떻게 알았지?
A. 위쪽에 연결하는 코드 써줬음 이미

   
      try {
         pstmt = conn.prepareStatement(sql);
         -PreparedStatement 생성 후 실행할 쿼리 정보를 등록한다
         rset = pstmt.executeQuery();
         -rset에 쿼리에서 불러온 결과 값 담기
         
         while(rset.next()) {
        -row를 다음으로 이동시킨다. 리턴값은 true와 false

            Board board = new Board();
            board.setBid(rset.getInt("bid"));
            -rset(=sql)에서 얻어온 bid값을 board의 Bid에 넣는다.
             (int냐 String이냐 타입 맞춰줘야 함)
            board.setCname(rset.getString("cname"));
            board.setBtitle(rset.getString("btitle"));
            board.setUserName(rset.getString("user_name"));
            board.setBcount(rset.getInt("bcount"));
            
          Q. 여기 이름들은 어디서 가져온 이름일까?sql? jsp? 생성자?

            List<Attachment> photoList = new ArrayList<>();
            Attachment photo = new Attachment();
            photo.setFilePath(rset.getString("file_path"));
            photo.setChangeName(rset.getString("change_name"));
            photoList.add(photo);

            board.setPhotoList(photoList);
            boardList.add(board);
         }
         
      } catch (SQLException e) {
         e.printStackTrace();
      } finally {
         close(rset);
         close(pstmt);
      }
      
   
   return boardList;

}
*PreparedStatment와 ResultSet을 사용하는 이유

1) PreparedStatement
(1) 쿼리와 값(파라메터)을 따로 보낸다.
(2) 쿼리의 실행계획을 한번만 세우게 된다.

2) ResultSet
(1) 쿼리한 테이블을 결과값을 반환함.
(2) 커서(cursor)가 위치함
-next(): 다음 위치를 가르키고, 데이터가 존재하면 true, 없다면 false 반환
-getxxx(): 데이터를 추출하기, (컬럼명 or 인덱스)
Ex) getInt("ID"); getString(2); .....

출처 : https://blog.kuby.co.kr/39

*PreparedStatement의 리턴값
(1) PreparedStatement.executeQuery()의 경우
ResultSet을 반환(=결과값이라는 뜻 ex. 3(3행)
(2) PreparedStatement.executeUpdate()의 경우
INSERT문, UPDATE문, DELETE문을 실행한다

*Properties
-키와 값을 String타입으로 제한한 Map컬렉션
-주로 Properties는 프로퍼티(*.properties)파일을 읽어 들일 때 주로 사용

*while 원리
( )안이 true가 되면 while문은 무한정 반복한다.
while문은 무한 루프에서 자주 사용된다. 끝나는 부분을 작성하지 않으면 while문은 무한히 반복한다는 뜻이다. 따라서 break;와 같은 명령문으로 종료시켜줘야 한다.
리턴값

1) pstmt
: oracle.jdbc.driver.OraclePreparedStatementWrapper@3a90b977

2) rset
: oracle.jdbc.driver.OracleResultSetImpl@60f5056d

3) boardList(전체 출력)
[Board [bid=219, btype=0, cid=0, cname=공통, btitle=사진 제목5, bcontent=null, bwriter=0, userName=홍길동, bcount=0, createDate=null, modifyDate=null, status=null, photoList=[Attachment [fid=0, bid=0, originName=null, changeName=change.png, filePath=/resources/uploadFiles/, fileLevel=0, downloadCount=0, status=null]]], 

Board [bid=218, btype=0, cid=0, cname=공통, btitle=사진 제목4, bcontent=null, bwriter=0, userName=홍길동, bcount=0, createDate=null, modifyDate=null, status=null, photoList=[Attachment [fid=0, bid=0, originName=null, changeName=change.png, filePath=/resources/uploadFiles/, fileLevel=0, downloadCount=0, status=null]]], 

Board [bid=217, btype=0, cid=0, cname=공통, btitle=사진 제목3, bcontent=null, bwriter=0, userName=홍길동, bcount=0, createDate=null, modifyDate=null, status=null, photoList=[Attachment [fid=0, bid=0, originName=null, changeName=change.png, filePath=/resources/uploadFiles/, fileLevel=0, downloadCount=0, status=null]]], 

Board [bid=216, btype=0, cid=0, cname=공통, btitle=사진 제목2, bcontent=null, bwriter=0, userName=홍길동, bcount=0, createDate=null, modifyDate=null, status=null, photoList=[Attachment [fid=0, bid=0, originName=null, changeName=change.png, filePath=/resources/uploadFiles/, fileLevel=0, downloadCount=0, status=null]]], 

Board [bid=215, btype=0, cid=0, cname=공통, btitle=사진 제목1, bcontent=null, bwriter=0, userName=홍길동, bcount=0, createDate=null, modifyDate=null, status=null, photoList=[Attachment [fid=0, bid=0, originName=null, changeName=change.png, filePath=/resources/uploadFiles/, fileLevel=0, downloadCount=0, status=null]]]]

4) board
Board [bid=219, btype=0, cid=0, cname=공통, btitle=사진 제목5, bcontent=null, bwriter=0, userName=홍길동, bcount=0, createDate=null, modifyDate=null, status=null, 
photoList=[Attachment [fid=0, bid=0, originName=null, changeName=change.png, filePath=/resources/uploadFiles/, fileLevel=0, downloadCount=0, status=null]]]

5) photoList
[Attachment [fid=0, bid=0, originName=null, changeName=change.png, filePath=/resources/uploadFiles/, fileLevel=0, downloadCount=0, status=null]]

6) photo
Attachment [fid=0, bid=0, originName=null, changeName=change.png, filePath=/resources/uploadFiles/, fileLevel=0, downloadCount=0, status=null]

 

 

11) servlet
-출력
-request.setAttribute("boardList", boardList);
request.getRequestDispatcher("/WEB-INF/views/gallery/galleryListView.jsp").forward(request, response);

package board.controller;

import java.io.IOException;
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 board.model.service.BoardService;
import board.model.vo.Board;

/**
 * Servlet implementation class GalleryListServlet
 */
@WebServlet("/gallery/list")
public class GalleryListServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public GalleryListServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

/**
 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
 */
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Board> boardList = new BoardService().selectGalleryList();

// System.out.println(boardList);

request.setAttribute("boardList", boardList);
request.getRequestDispatcher("/WEB-INF/views/gallery/galleryListView.jsp").forward(request, response);
}

/**
 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
 */
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}

}
*setAttribute 사용법
setAttribute(String name, Object value)

 


12) galleryListView.jsp
-<ul class="board_list">여기부터

<%@ 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>
<html>
<head>
<meta charset="UTF-8">
<title>사진 게시판</title>

생략

</head>
<body>
   <jsp:include page="/WEB-INF/views/common/menubar.jsp" />
   <div class="outer">
      <div class="wrap">
         <div class="board_area">
            <div class="board_title">
               <h1>사진 게시판</h1>
            </div>
            <div class="list_div">
               <ul class="board_list">
               <c:forEach var="board" items="${ boardList }">
               <li>
               <div class="box">
                  <img src="${ contextPath }${ board.photoList.get(0).filePath }${ board.photoList.get(0).changeName }">
                  <p class="category">[ ${ board.cname } ]</p>
                  <p class="title">${ board.btitle }</p>
                  <p class="writer">${ board.userName } | 조회수 : ${ board.bcount }</p>
               </div>   
               </c:forEach>
               </ul>
            </div>

         <c:if test="${ !empty loginUser }">
         <div class="btn_area">
            <button onclick="location.href='${contextPath }/gallery/insert'">작성하기</button>
         </div>
         </c:if>
         
         </div>
      </div>
   </div>
   
</body>
</html>
*<img src="${ contextPath }${ board.photoList.get(0).filePath }${ board.photoList.get(0).changeName }"> 의미

http://localhost:8801/jsp/resources/uploadFiles/change.png(url)
1) jsp = contextPath
2) /resources/uploadFiles/ = ${ board.photoList.get(0).filePath }
3) /change.png = ${ board.photoList.get(0).changeName }

 

결과)




2. 작성하기 
16.  galleryListview 
<c:if test="${ !empty loginUser }">
<div class="btn_area">
<button onclick="loction.href='${contextPath}/gallery/insert'">작성하기</button>
</div>

17.GalleryInsertSevlet
foward

18. galleryinserview


imagePreview 만들기


galleryInsertview
 <form method="post" action="${ contextPath }/gallery/insert"
               enctype="multipart/form-data">
                                 <div class="content">

 


3. 작성하기 페이지에 사진 첨부할 때 리네임해서 DB에 저장하기