mjeongriver
article thumbnail
Published 2022. 12. 7. 17:23
day46-jsp TIL/JSP

1. board에서 쓴 글 확인하는 조회

* boardController

else if( command.equals("/board/board_list.board")) { //목록화면
			
			//조회 메서드 - list를 화면으로 가지고 나가야 합니다. 
			ArrayList<BoardVO> list= service.getList(request, request);
			
			request.setAttribute("list", list);
			
			request.getRequestDispatcher("board_list.jsp").forward(request, response);

 

* boardservice

ArrayList<BoardVO> getList(HttpServletRequest request, HttpServletResponse response); //조회

 

* boardServiceImpl

@Override
	public ArrayList<BoardVO> getList(HttpServletRequest request, HttpServletResponse response) {
		//DAO 생성
		BoardDAO dao = BoardDAO.getInstance();
		//getlist를 arraylist의 list로 반환 
		ArrayList<BoardVO> list = dao.getList();
		
		return list;
	}

 

* boardDAO

//조회 메서드
		public ArrayList<BoardVO> getList() {
			
			ArrayList<BoardVO> list = new ArrayList<>();
			//번호 기준으로 거꾸로 뒤집어야 최신글이 제일 위로 올라옴
			String sql = "select * from board order by bno desc";
			
			try {
				conn = DriverManager.getConnection(URL, UID, UPW);
				pstmt = conn.prepareStatement(sql);
				rs = pstmt.executeQuery();
				
				//rs결과를 list에 담는다.
				while(rs.next()) {
					BoardVO vo = new BoardVO();
					vo.setBno( rs.getInt("bno"));
					vo.setTitle( rs.getString("title") );
					vo.setWriter( rs.getString("writer") );
					vo.setContent( rs.getString("content") );
					vo.setContent( rs.getString("regdate") );
					vo.setHit( rs.getInt("hit")) ;
                    
                    //list에 한줄씩 담아줌
					list.add(vo);
					
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				JDBCUtil.close(conn, pstmt, rs);
			}
			
			return list;
			
		}

 

* board_list.jsp

- 저 list가 DAO에 있는 list

<thead>
				<tr>
					<th>순서</th>
					<th>글 번호</th>
					<th>작성자</th>
					<th>제목</th>
					<th>날짜</th>
					<th>조회수</th>
				</tr>
			</thead>

			<tbody>
				<c:forEach var = "vo" items = "${list }" varStatus = "num">
				<tr>
					<td>${num.count }</td>
					<td>${vo.bno }</td>
					<td>${vo.writer }</td>
					<td>${vo.title }</td>
					<td>${vo.regdate }</td>
					<td>${vo.hit }</td>
				</tr>
				</c:forEach>
			</tbody>

 

* 날짜(board_list.jsp)

- UI를 생각 했을 때 이렇게 나오면 안됨

 - 지금 데이터 타입은 date, formatdate로 바꿔줄 것

 

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

- 위에 이거 추가해주고 밑에 이렇게 추가해줄 것

<td><fmt:formatDate value="${vo.regdate }" pattern = "yyyy-MM-dd HH시mm분ss초"/></td>

그러면 보기 편하게 변경됨

 

 

2. 제목을 누르면 상세보기로 넘어감

board_list.jsp

<a>태그로 감싸면 눌렀을 때 넘어갈 수 있음. 그리고 뒤에 .board니까 컨트롤러로 태움

<td><a href = "board_content.board">${vo.title }</a></td>

 

get 방식은 반드시 폼태그가 필요한 것은 아니며,
주소를 통해서 강제로 파라미터 값을 전달할 수 있습니다.
?변수명=값
여러 값이라면 &조건으로 연결
 
ex. <a href="req_get04.jsp?name=홍길동&age=20">get 방식 queryString 이용하기</a>

 

	<a href="board_content.board?bno=${vo.bno }">${vo.title }</a>

 

* boardService

//반환이 BoardVO=1행에 대한 데이터니까
	BoardVO getContent(HttpServletRequest request, HttpServletResponse response);

 

* boardDAO

public BoardVO getContent(String bno) {
			
			
			BoardVO vo = null;
			String sql = "select * from board where bno = ?";
			
			try {
				conn = DriverManager.getConnection(URL, UID, UPW);
				pstmt = conn.prepareStatement(sql);
				pstmt.setString(1, bno);
				
				//select니까 query
				rs = pstmt.executeQuery();
				
				if(rs.next()) {
					vo = new BoardVO();
					vo.setBno( rs.getInt("bno"));
					vo.setTitle( rs.getString("title") );
					vo.setWriter( rs.getString("writer") );
					vo.setContent( rs.getString("content") );
					vo.setRegdate( rs.getTimestamp("regdate") );
					vo.setHit( rs.getInt("hit")) ;
				}
				
			} catch (Exception e) {
				e.printStackTrace();
			}
			
			return vo;
			
		}

 

* boardServiceImpl

@Override
	public BoardVO getContent(HttpServletRequest request, HttpServletResponse response) {
		
		//a태그로 넘어오는 parameter
		String bno = request.getParameter("bno");
		BoardDAO dao = BoardDAO.getInstance();
		BoardVO vo = dao.getContent(bno);
		return vo;
	}

 

* boardController

else if( command.equals("/board/board_content.board")) { //상세 내용 화면
			//content 화면에서는 조회한 글에 대한 정보를 조회해야 합니다. 5번 글 눌렀으면 5번 글 나와야함
			//반환값이 있으니까 vo에 받아줌
			//조회한 글에 대한 정보 조회
			BoardVO vo= service.getContent(request, response);
			request.setAttribute("vo", vo);
			
			request.getRequestDispatcher("board_content.jsp").forward(request, response);

 

 

* board_content.jsp

<tr>
			<td width="20%">글번호</td>
			<td width="30%">${vo.bno }</td>
			
			<td width="20%">조회수</td>
			<td width="30%">${vo.hit }</td>
		</tr>
		<tr>
			<td>작성자</td>
			<td>${vo.writer }</td>
			
			<td>작성일</td>
			<td >${vo.regdate }</td>
		</tr>
		
		<tr>
			<td width="20%">글제목</td>
			<td colspan="3">${vo.title }</td>
		</tr>
		<tr>
			<td width="20%">글내용</td>
			<td colspan="3" height="120px">${vo.content }</td>
		</tr>

 

3.

목록, 수정, 삭제 기능 넣기

 

* board_content.jsp

- 목록은 list로 가게끔 href에 'board_list.board'로 보냄

- 수정 기능

<tr>
			<td colspan="4" align="center">
				<input type="button" value="목록" onclick = "location.href='board_list.board' ">&nbsp;&nbsp;
				<input type="button" value="수정" onclick = "location.href='board_modify.board?bno=${vo.bno}' ">&nbsp;&nbsp;
				<input type="button" value="삭제" onclick = "location.href='???' ">&nbsp;&nbsp;
			</td>
		</tr>

 

* boardcontroller

else if( command.equals("/board/board_modify.board")) { //수정 화면
			
			//조회한 글에 대한 정보 조회 재활용
			BoardVO vo= service.getContent(request, response);
			request.setAttribute("vo", vo);

			request.getRequestDispatcher("board_modify.jsp").forward(request, response);

 

* board_modify.jsp

			<%--
			화면에 보일 필요는 없는데, 데이터를 보내야 하는 경우 hidden 태그를 사용합니다.
			 --%>
			 
			<tr>
				<td>글 번호</td>
				<td>${vo.bno }
					<input type = "hidden" name = "bno" value = "${vo.bno }">
				</td>
			</tr>
			<tr>
				<td>작성자</td>
				<td><input type="text" name="writer" value="${vo.writer }" readonly></td>
			</tr>
			<tr>
				<td>글 제목</td>
				<td>
					<input type="text" name="title" value="${vo.title }">
				</td>
			</tr>
			<tr>
				<td>글 내용</td>
				<td>
					<textarea rows="10" style="width: 95%;" name="content">
					${vo.content }
					</textarea>
				</td>
			</tr>
			<tr>
				<td colspan="2">
					<input type="submit" value="수정 하기" onclick="">&nbsp;&nbsp;
					<input type="button" value="목록" onclick = "location.href='board_list.board'">        
				</td>
			</tr>

 

* boardservice

void update(HttpServletRequest request, HttpServletResponse response); //정보수정

 

* boardserviceImpl

	@Override
	public void update(HttpServletRequest request, HttpServletResponse response) {
		
		//화면에서 넘어오는 값
		String bno = request.getParameter("bno");
		String writer = request.getParameter("writer");
		String title = request.getParameter("title");
		String content = request.getParameter("content");
		
		
	}

 

* boardDAO

public void update(String bno, String title, String content) {
			
			String str = "update board set title = ?, content = ? where bno = ? ";
			
			try {
				conn = DriverManager.getConnection(URL, UID, UPW);
				pstmt = conn.prepareStatement(str);
				pstmt.setString(1, title);
				pstmt.setString(2, content);
				pstmt.setString(3, bno);
				
				pstmt.executeUpdate();
				
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				JDBCUtil.close(conn, pstmt, rs);
			}
		}

 

* boardserviceImpl에서 DAO 추가

@Override
	public void update(HttpServletRequest request, HttpServletResponse response) {
		
		//화면에서 넘어오는 값
		String bno = request.getParameter("bno");
		//String writer = request.getParameter("writer");
		String title = request.getParameter("title");
		String content = request.getParameter("content");
		
		//DAO
		BoardDAO dao = BoardDAO.getInstance();
		dao.update(bno, title, content);
		
		
	}

 

* boardcontroller

else if ( command.equals("/board/updateForm.board")) {
			
			//service와 연결
			service.update(request, response);
			
			//업데이트가 된 이후에 목록화면으로 보냄
			//이미 만들어져있는 list 화면으로 나가기 때문에 redirect 이용해야 함
			
			//1st.
			//response.sendRedirect("board_list.board");
			
			//2nd
            //화면에서 넘어오는 키값을 getParameter로 bno값 받아야 함
			response.sendRedirect("board_content.board?bno=" + request.getParameter("bno"));
		}

 

- 삭제

- 삭제는 원래 get방식으로 만들면 안됨.

 

* boardcontent

<tr>
			<td colspan="4" align="center">
				<input type="button" value="목록" onclick = "location.href='board_list.board' ">&nbsp;&nbsp;
				<input type="button" value="수정" onclick = "location.href='board_modify.board?bno=${vo.bno}' ">&nbsp;&nbsp;
				<input type="button" value="삭제" onclick = "location.href='board_delete.board?bno=${vo.bno}' ">&nbsp;&nbsp;
			</td>
		</tr>

 

* boardcontroller

else if ( command.equals("/board/board_delete.board")) {
			
		}

 

* boardservice

int delete(HttpServletRequest request, HttpServletResponse response); //글 삭제

 

* boardserviceImpl에서 오버라이드

@Override
	public int delete(HttpServletRequest request, HttpServletResponse response) {
		
		String bno = request.getParameter("bno");
		
		
		return 0;
	}

 

* boardcontroller

else if ( command.equals("/board/board_delete.board")) {
			service.delete(request, response);
		}

 

* boardDAO

public int delete(String bno) {
			
			int result = 0;
			String sql = "delete from board where bno = ?";
			
			try {
				conn = DriverManager.getConnection(URL, UID, UPW);
				pstmt = conn.prepareStatement(sql);
				pstmt.setString(1, bno);
				
				result = pstmt.executeUpdate();
				
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				JDBCUtil.close(conn, pstmt, rs);
			}
			
			return result;
			
		}

 

* boardserviceImpl

@Override
	public int delete(HttpServletRequest request, HttpServletResponse response) {
		
		String bno = request.getParameter("bno");
		
		//DAO
		BoardDAO dao = BoardDAO.getInstance();
		int result = dao.delete(bno);
		
		return result;
	}

 

* boardcontroller

else if ( command.equals("/board/board_delete.board")) {
			int result = service.delete(request, response);
			
			String msg = "";
			if(result == 1) { //삭제 성공
				msg = "삭제 성공";
			} else { //삭제 실패
				msg = "삭제 실패";
			}
			
			response.setContentType("text/html; charset = utf-8");
			PrintWriter out = response.getWriter();
			out.println("<script>");
			out.println("alert('"+ msg+"');");				
			out.println("location.href='board_list.board'; ");				
			out.println("</script>");
			
		}

 

4. 조회수 기능(중복 방지를 위해 쿠키를 써야함)

- update board set hit = hit + 1 where bno = 3;

 

5. filter

 

 

* boardController

 - 세션의 인증 방법을 사용해서 로그인을 해야 글을 쓸 수 있도록 해줌

- 세션이 필요한 곳과 필요 없는 곳을 나누어 생각할 것(등록, 수정..)

- 밑에 방법처럼 세션을 사용하면 하나씩 다 해줘야하기 때문에 복잡함

- 이걸 편하게 하기 위해서 filter 사용함

//세션
		HttpSession session = request.getSession();
		
		
		if( command.equals("/board/board_write.board")) { //등록 화면
			
			if(session.getAttribute("user_id") == null) {
				response.sendRedirect("../user/user_login.user");
				return;
			}

 

- 필터란? FrontController(서블릿) 으로 들어가기전 요청을 가로채 검사하는 역할

필터의 생성방법

1) 필터 클래스는 일반 자바 파일로 생성합니다.

2) Filter 인터페이스를 상속 받습니다

3) 일반적으로 doFilter메서드를 오버라이딩 합니다

4) 사용 후 doFilter(request, response); 메서드를 반드시 사용한다

 

- 방법 2개 중 하나를 선택함

* 어노테이션 방법 

- 따라서 webfilter에는 검사할 경로만 넣어줄 것

(중괄호 하면 배열처럼 여러개를 넣을 수 있음)

package com.example.util.filter;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpFilter;

//필터를 실행할 요청 경로
@WebFilter({"/board/board_write.board", 
			"/board/board_modify.board",
			"/board/registForm.board",
			"/board/updateForm.board",
			"/board/board_delete.board"
			})
public class AuthFilter implements Filter {
       
	//실제 필터가 해야할 일(오버라이딩 되어있음)
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
			
		System.out.println("필터 실행됨");
		//필터가 여러개라면 다음 필터로 연결함(꼭 써줘야함), 필터가 없으면 원래 요청이 들어오는 컨트롤러로 붙여줌
		chain.doFilter(request, response); 
	
	}

}

 

* xml 방법

 

누르고 오른쪽 눌러서 generate deployment descriptor stub&nbsp; 누르면 xml 파일이 생성됨

  <!-- 필터 등록하는 방법과 필터체이닝 -->
  <filter>
  	<filter-name>A</filter-name>
  	<filter-class>com.example.util.filter.AuthFilter</filter-class>
  </filter>
  
  <filter-mapping>
  <filter-name>A</filter-name>
  <url-pattern>/board/board_write.board</url-pattern>
  </filter-mapping>
</web-app>

 

- filter2 만들기

package com.example.util.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class AuthFilter2 implements Filter{

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		
		System.out.println("필터 2 실행됨");
		
		chain.doFilter(request, response);
	}

}
 <filter>
  	<filter-name>A</filter-name>
  	<filter-class>com.example.util.filter.AuthFilter</filter-class>
  </filter>
  
  <filter-mapping>
  <filter-name>A</filter-name>
  <url-pattern>/board/board_write.board</url-pattern>
  </filter-mapping>
  
   <filter>
  	<filter-name>B</filter-name>
  	<filter-class>com.example.util.filter.AuthFilter2</filter-class>
  </filter>
  
  <filter-mapping>
  <filter-name>B</filter-name>
  <url-pattern>/board/board_write.board</url-pattern>
  </filter-mapping>

ctrl + t 누르면 최상위 인터페이스 확인 가능

* authfilter

package com.example.util.filter;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

//필터를 실행할 요청 경로
@WebFilter({"/board/board_write.board", 
			"/board/board_modify.board",
			"/board/registForm.board",
			"/board/updateForm.board",
			"/board/board_delete.board"
			})

public class AuthFilter implements Filter {
       
	//실제 필터가 해야할 일(오버라이딩 되어있음)
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
			
		//권한검사
		HttpServletRequest req = (HttpServletRequest)request;
		HttpServletResponse res = (HttpServletResponse)response;
		
		//req에서 세션을 얻는다.
		HttpSession session = req.getSession();
		String user_id = (String)session.getAttribute("user_id");
		
		//user_id == null이라면 권한이 없다는 의미
		if(user_id == null) {
			
			String path = req.getContextPath(); //컨택스트 패스			
			
			res.setContentType("text/html; charset = utf-8");
			PrintWriter out = res.getWriter();
			out.println("<script>");
			out.println("alert('권한이 필요한 기능입니다.');");
			//절대 경로 넣어줄 것(절대 경로여야지 안전함)
			out.println("location.href=' "+ path + "/user/user_login.user" + "';");				
			out.println("</script>");
			
			return; //함수를 종료하면 컨트롤러로 연결 되지 않음
			
			
		}
		
		System.out.println("필터 실행됨");
		//필터가 여러개라면 다음 필터로 연결함(꼭 써줘야함), 필터가 없으면 원래 요청이 들어오는 컨트롤러로 붙여줌
		chain.doFilter(request, response); 
	
	}

}

 

6. 작성자 id 고정

* board_wirte.jsp 수정

	<tr>
				<td>작성자</td>
				<td>
					<input type="text" name="writer" value="${sessionScope.user_id }" size="10" readonly required>
				</td>
			</tr>

 

7. 로그인 된 사람만 글의 수정과 삭제 버튼을 볼 수 있도록 만들어줌 

 

 

* board_content(c:if로 감싸줌)

<td colspan="4" align="center">
				<input type="button" value="목록" onclick = "location.href='board_list.board' ">&nbsp;&nbsp;
				<c:if test = "${sessionScope.user_id != null }">
				<input type="button" value="수정" onclick = "location.href='board_modify.board?bno=${vo.bno}' ">&nbsp;&nbsp;
				<input type="button" value="삭제" onclick = "location.href='board_delete.board?bno=${vo.bno}' ">&nbsp;&nbsp;
				</c:if>
			</td>

 

8. 작성자가 다르면 수정, 삭제가 안되는 기능 추가

* AuthFilter2

package com.example.util.filter;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

//수정, 업데이트, 삭제(경로)
@WebFilter({"/board/board_modify.board", 
	"/board/updateForm.board",
	"/board/board_delete.board"
}) //경로

public class AuthFilter2 implements Filter{

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		
		/*
		 * 세션의 user_id와 request로 넘어오는 작성자가 다르면 수정이 불가함.
		 * 
		 * 1. 각 요청 경로에서 writer가 파라미터로 반드시 전달되도록 처리.
		 * 
		 * 
		 */
		
		request.setCharacterEncoding("utf-8");
		
		//권한검사
		HttpServletRequest req = (HttpServletRequest)request;
		HttpServletResponse res = (HttpServletResponse)response;
		
		//각 요청에 넘어오는 writer 파라미터
		String writer = request.getParameter("writer");
		
		//세션에 저장된 user_id
		HttpSession session = req.getSession();
		String user_id = (String)session.getAttribute("user_id");
		
		
//		System.out.println("작성자" + writer);
//		System.out.println("세션ID" + user_id);

		//null이거나 다른 경우(내가 쓴 글이 아닐 때)에도 실패
		//세션이 없거나 or 작성자와 세션이 다른 경우
		if(user_id == null || !writer.equals(user_id) ) {
			String path = req.getContextPath(); //컨택스트 패스
			res.setContentType("text/html; charset = utf-8");
			PrintWriter out = res.getWriter();
			out.println("<script>");
			out.println("alert('권한이 필요한 기능입니다');");
			out.println("location.href='" + path + "/board/board_list.board" + "';");
			out.println("</script>");
			
			return;
		}

		chain.doFilter(request, response);
	}

}

 

* boardContent

<tr>
			<td colspan="4" align="center">
				<input type="button" value="목록" onclick = "location.href='board_list.board' ">&nbsp;&nbsp;
				<c:if test = "${sessionScope.user_id != null }">
				<input type="button" value="수정" onclick = "location.href='board_modify.board?bno=${vo.bno}&writer=${vo.writer }' ">&nbsp;&nbsp;
				<input type="button" value="삭제" onclick = "location.href='board_delete.board?bno=${vo.bno}&writer=${vo.wirter }' ">&nbsp;&nbsp;
				</c:if>
			</td>
		</tr>

 

'TIL > JSP' 카테고리의 다른 글

day45-jsp  (1) 2022.12.06
day44-jsp  (0) 2022.12.05
day43-jsp  (1) 2022.12.02
day42-jsp  (0) 2022.12.01
day41-jsp  (2) 2022.11.30
profile

mjeongriver

@mjeongriver

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그