본문 바로가기

Programming/SERVER

DAY 124. MVC2 패턴 - 게시글 작성

게시글 작성

01. write.jsp

- <form> 태그의 action 속성에는 "${ pageContext.request.contextPath }/board/write" 를,

method 속성에는 "POST"를 적는다.

 

02. WriteServlet.java

com > kh > mvc > board> controller 밑에 작성

URL mapprings : /board/write | doGet, doPost 체크

 

1) get 요청이 오면 views/board/wirte.jsp를 열 수 있도록 forwarding 시킨다.

 

03. list.jsp

button 글쓰기가 눌렸을 때 페이지가 릴 수 있도록 onlick 이벤트를 지정한다.

<button type="button" onclick="location.href='${ pageContext.request.contextPath }/board/write'">글쓰기</button>

 

로그인 했을 경우에만 글쓰기 버튼이 보여야 하는데 url를 직접 입력하면 로그인 하지 않았을 때에도 글을 쓸 수 있는 상태이기 때문에, 로그인 체크하는 로직을 구현할 것이다.

 

04. WriteServlet.java

- doGet() 메소드에 조건문 로직을 구현한다.

- loginMember가 null이면 msg.jsp로 이동시키면서 msg 문구를 지정한다.

- 사용자가 보내주는 값을 받아보자. (폼 파라미터로 넘어온 값들은 파일에 대한 정보를 의미하지 않는다.)

** 이 때, 첨부파일이 있을 때 그냥 getParameter로 가져오면 String 값으로만 가져온다. 서버에 파일 전송 처리를 해야 할 때는 라이브러리를 사용한다. 

 

http://www.servlets.com

 

Servlets.com

Home What's New? COS File Upload Library Servlet Polls Mailing Lists Servlet Engines Servlet ISPs Servlet Tools Documentation Online Articles The Soapbox "Java Servlet Programming, Second Edition" "Java Enterprise Best Practices" Speaking & Slides About Ja

www.servlets.com

 

COS File Upload Library > cos-20.08.zip 파일 다운로드 > 압축 해제 > lib 폴더 안에 > cos.jar 를 프로젝트 라이브러리에 추가

 

05. write.jsp

- <form> 태그 안에 enctype="aaplication/x-www-form-urlencoded" 기본 값대로 넣으면 파일명만 전소오디기 때문에 파일 형태로 넘기기 위해서는  enctype="multipart/form-data" 로 바꿔야 한다. 

- 그러나 여기까지 했다고 해서 파일이 그냥 넘어가는 것은 아니다! null만 console에 찍힌다. 왜냐? 아직 cos.jar 라이브러리에서 제공하는 클래스를 활용하지 않았기 때문이다.

 

 

06. WriteServlet.java

- MultipartRequest 객체를 만들자.

- 다양한 매개 값에 대응하는 값들을 매개 값으로 넘겨주면 된다.

- 이 객체를 만드는 순간에, 파일을 지정한 경로 위치에 저장하게 될 것이다.

 

1) 파일이 저장될 경로

String path = getServletContext().getRealPath("/");

이 때, 저장될 경로를 만들어주는데 폴더가 없다면 미리 만들어야 오류가 발생하지 않는다.

 

2) 파일의 사이즈를 지정, 바이트(B) 단위로 지정한다.

int maxSize = 바이트값;

 

3) 문자에 대한 인코딩 설정

String encoding = "UTF-8";

 

MultipartRequest mr = new MultipartRequest(request, path, maxSize, encoding, new DefaultFileRenamePolicy());

 

** DefaultFileRenamePolicy

- 업로드 되는 파일에 대한 rename 처리에 사용

- 파일 구분을 위해서 중복되는 이름의 파일을 저장할 때, 이름 뒤에 0 ~ 9999 를 붙인다. 

 

- 파일에 대한 정보를 가져오는 필드를 지정한다.

 

ORIGINAL_FILENAME : 사용자가 서버에 보낼 때 사용한 파일명

RENAMED_FILENAME : 서버에 저장될 때 파일명( ** 실제 물리적으로 저장된 위치를 알아야 다운로드가 가능하다. )

 

07. FileRename.java

- com > kh > mvc > common > util 밑에 생성

- FileRenamePolicy 인터페이스를 구현하기 때문에, FileRename 클래스를 WriteServlet.java 파일에서 생성한 객체인 MultipartRequest의 매개변수에서 사용할 수 있다. (new DefaultFileRenamePolicy() -> new FileRename() 클래스로 변경)

- 여기까지 적용되면 파일 첨부해서 업로드된 파일 명이 물리적인 위치에 저장되는 이름의 정책대로 바뀌어서 파일 저장되는 경로 위치(데이터베이스)에 저장된다. 실제로 사용자가 다운로드할 때는 원본명 파일로 다시 바뀌어서 다운로드 할 수 있도록 해준다.

- File 객체를 리턴한다.

 

 

08. WriteServlet.java

- 로그인이 안 된 사용자가 게시글 작성이 불가능 하도록 체크하는 로직을 구현한다.

- session 객체 생성, loginMember가 null이 아닐 때,

- Board 객체를 만들고 필드를 set

- 로그인 안됐을 경우, alert 메시지 띄우는 로직 작성

- 게시글 등록은 서블릿에서 처리하지 않고 service 객체에게 위임하기 때문에 상단에 private BoardService service - new BoardService(); 객체를 만든다.

- 서비스 객체 service에 save() 메소드를 실행해서 board를 매개값으로 넘겨준다. 이 결과 값을 정수형 result 변수에 담아 준다. result = service.save(board);

- result 결과가 0보다 크면 게시글 등록에 성공, 아닐 경우 실패한 것이다라는 로직 작성

- save 메소드가 아직 없기 때문에, BoardService.java 에 int형 save 메소드 구현

 

09. BoardService.java

public int save(Board board){
	int result = 0;
    Connection connection = getConnection();
    
    // SAVE할 때 BOARD에 PK값인 NO가 0이면 INSERT, 0이 아니면 UPDATE 할 것이다.
    
    if(board.getNo() != 0 ){
    	result = dao.updateBoard(connection, board);
    } else {
    	result = dao.insertBoard(connection, board);
    }
    
    // 결과 값에 따라서 result가 0보다 크면 정상적으로 insert가 된 것이기 때문에
    // 데이터 베이스에 변경사항을 적용해서 확정한다. -> commit 아니면 rollback
    // close까지 모두 JDBCTemplate 에 만들어 놨다.
    
    if(result > 0) {
    	commit(connection);
    } else {
    	rollback(connection);
    }
    
    close(connection);

	return result;
}

 

10. BoardDao.java

- int형 insertBoard() 메소드 구현

public int insertBoard(Connection connection, Board board){
	int result = 0;
    
    // insert는 ResultSet은 필요 없지만 쿼리문 실행할 PreparedStatement는 필요
    PreparedStatement pstmt = null;
    String query = "INSERT 관련 쿼리문";
    
    // 사용자에게 받아서 데이터베이스로 넘길 값들만 set
    
    // pstmt = connection.prepareStatement(query); // 예외 처리 날 것
    
    try {
    	pstmt = connection.prepareStatement(query);
        
        // ?에 해당하는 값들 set
        pstmt.setInt(1, );
        pstmt.setString(2, );
        
        result = pstmt.executeUpdate();
        
    } catch (SQLException e) {
    	e.printStackTrace();
    } finally {
    	close(pstmt);
    }
    
    return result;
}