Spring - MVC - Board Write Practice

화이티 ·2023년 12월 27일

Spring

목록 보기
2/5



Practice MVC3

@@ Set up
1. model

  • Board.java
package com.smhrd.model;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.ToString;

@AllArgsConstructor
@NoArgsConstructor
@RequiredArgsConstructor
@Getter
@ToString
public class Board {

	private int num; // 인덱스
	@NonNull private String title; // 제목
	@NonNull private String writer; // 작성자
	@NonNull private String filename; // 파일이름
	@NonNull private String content; // 내용
	private String b_date; // 업로드 시각
	
}
  • BoardDAO.java
package com.smhrd.model;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import com.smhrd.db.SqlSessionManager;

public class BoardDAO {

	SqlSessionFactory sqlSessionFactory = SqlSessionManager.getSqlSession();
	SqlSession sqlSession = sqlSessionFactory.openSession(true);
	
	// 게시글 작성
	public int writeBoard(Board vo) {
		int cnt = 0;
		try {
			cnt = sqlSession.insert("com.smhrd.db.BoardMapper.writeBoard", vo);
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			sqlSession.close();
		}
		return cnt;
	}
	
	// 게시글 전체 조회
	public List<Board> allBoard(){
		List<Board> boards = null;
		try {
			boards = sqlSession.selectList("com.smhrd.db.BoardMapper.allBoard");
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			sqlSession.close();
		}
		return boards;
	}
	
	// 게시글 상세 조회
	public Board detailBoard(int num) {
		Board board = null;
		try {
			board 
			= sqlSession.selectOne("com.smhrd.db.BoardMapper.detailBoard", num);
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			sqlSession.close();
		}
		return board;
	}

}
  1. Database
  • SQLSessionManager.java
package com.smhrd.db;

import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class SqlSessionManager {
	
	public static SqlSessionFactory sqlSessionFactory;
	
	static {
		try {
			// mybatis 환경설정 파일 경로 
			String resource = "com/smhrd/db/mybatis-config.xml";
			
			// xml파일을 읽어내기 위해 inputStream 여는 것!
			InputStream inputStream = Resources.getResourceAsStream(resource);

			// SqlSessionFactory : connection객체가 여러개인 Connection Pool
			sqlSessionFactory =
			  new SqlSessionFactoryBuilder().build(inputStream);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static SqlSessionFactory getSqlSession() {
		return sqlSessionFactory;
	}
	
}
  • db.properties
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:xe
username=service
password=12345
  • mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 2. mybatis-config.xml만들기
		: mybatis의 환경설정 담당(중요한 파일) -->
<!-- 3. db.properties 만들기
		: db연결정보들을 가지고 있는 파일 -> 공백 주의할 것 -->
	<properties resource="com/smhrd/db/db.properties"> </properties>
				
	<typeAliases>
		
		<typeAlias type="com.smhrd.model.Board" alias="Board"/>
		
	</typeAliases>
					
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
   
    <mapper resource="com/smhrd/db/BoardMapper.xml"/>

  </mappers>
</configuration>
  • BoardMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
  
<mapper namespace="com.smhrd.db.BoardMapper">
	
	<insert id="writeBoard" parameterType="Board">
		insert into web_board1 
		values(num_board.nextval, #{title}, #{writer}, #{filename}, #{content}, sysdate)
	</insert>
	
	<select id="allBoard" resultType="Board">
		select * from web_board1
	</select>
	
	<select id="detailBoard" resultType="Board">
		select * from web_board1 where num=#{num}
	</select>
	
</mapper>
  1. frontController
  • ViewResolver.java
package com.smhrd.frontController;

public class ViewResolver {
// viewResolver: pojo가 반납한 viewname을 full name으로 만들어주는 역할
	//BoardMain - > MVC/WEB-INF/views/BoardMain.jsp
	public String makeViewName(String viewname) {
		return "WEB-INF/views/"+viewname+".jsp";
	}
}
  • interface command.java
package com.smhrd.frontController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public interface command {

	// 인터페이스 : 틀
	// 추상메소드 : 값은 없지만 메소드의 기본 값을 설정해주는 역할
	public String execute(HttpServletRequest request, HttpServletResponse response);
	
}
  • HandlerMapping.java
package com.smhrd.frontController;

import java.util.HashMap;

import com.smhrd.controller.BoardDetailService;
import com.smhrd.controller.BoardMainPageService;
import com.smhrd.controller.BoardWritePageService;
import com.smhrd.controller.BoardWriteService;

public class HandleMapping {

	// HandlerMapping: FrontController에게 어떤 POJO를 호출해야하는지 알려주는 역할
	//boardList.do -> BoardListController
	//boardInsert.do -> BoardInsertController
	//검색이빠른 hashmap 자료구조 사용
	// key: 요청이들어온주소(String)
	//value: 호출할 pojo(pojo의 상위클래스인command)
	private HashMap<String, command> mappings;
	// 생성자 만ㄷ,ㄹ기->객체가 생성에 될 때 key, value를 등록한느 영할
	public HandleMapping() {
		mappings = new HashMap<String,command>();
		//정부에 추가-> put메소드 사용
		mappings.put("BoardWriteService.do", new BoardWriteService());
		mappings.put("BoardWritePage.do", new BoardWritePageService());
		mappings.put("BoardMainPage.do", new BoardMainPageService());
		mappings.put("BoardDetailService.do", new BoardDetailService());	
	}
	//pojo를 frontcontroller에게 return 해주는 메소드
	public command getPOJO (String result){
			return mappings.get(result);
			//HashMap의get(key값): 해당 key의 value를 호출하는 메소드
		}
}
  • frontController.java
package com.smhrd.frontController;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("*.do")
public class frontcontroller extends HttpServlet {
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		System.out.println("[FrontContoller]");
		request.setCharacterEncoding("UTF-8");
		// 1. 요청 값 확인하기
		String requestURI = request.getRequestURI();
		String contextPath = request.getContextPath();
		String result = requestURI.substring(contextPath.length()+1);
		System.out.println("요청 서블릿 : " + result);
		
		
		//2. HandleMapping에게 어떤 pojo를 사용
		
		
		
		command service = null;
		HandleMapping mappings = new HandleMapping();
		service = mappings.getPOJO(result);
		//3. 업무를 할 pojo 실행시키기 -> pojo는 viewname을 반환
		String viewname = service.execute(request, response);
		
		//5. 페이지 이동
		if(viewname != null) {
			System.out.println("viewname: "+ viewname);
			//redirect방식: 다른controller(pojo)를 요청할 때
			if(viewname.contains(":/")) {
				response.sendRedirect(viewname.split(":/")[1]);
				
			}else {
				//forward방식:jsp를 요청할 때
				RequestDispatcher rd = request.getRequestDispatcher(
						new ViewResolver().makeViewName(viewname));
				System.out.println("full name: " +new ViewResolver().makeViewName(viewname));
				rd.forward(request, response);
			}
		}
		
	}
}
  1. controller
  • BoardMainPageService
package com.smhrd.controller;



import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.smhrd.frontController.command;
import com.smhrd.model.Board;
import com.smhrd.model.BoardDAO;

public class BoardMainPageService implements command {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) {
		//1. DB에서 게시글 데이터 가져오기
		List<Board> boards = new BoardDAO().allBoard();
		// 2. view에서 해당 게시글 데이터를 불러오기 위해 request객체에 객체 바인딩
		request.setAttribute("boards", boards);
		
		//3. Boardmain.jsp로 가기 위해 viewname 반환
		return "BoardMain";
	}

}
  • BoardWriteService
package com.smhrd.controller;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
import com.smhrd.frontController.command;
import com.smhrd.model.Board;
import com.smhrd.model.BoardDAO;

public class BoardWriteService implements command {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) {

		// 파일 업로드를 위한 변수 설정
		// 1. request 객체
		// 2. 파일을 저장할 경로(String)
		String savePath = request.getServletContext().getRealPath("./file");
		System.out.println("savePath : " + savePath);

		// 3. 파일 최대크기(int)
		int maxSize = 1024 * 1024 * 10;

		// 4. 인코딩 방식(String)
		String encoding = "UTF-8";

		// 5. 파일이름 중복제거
		DefaultFileRenamePolicy rename = new DefaultFileRenamePolicy();

		// 파일 업로드 해주는 객체 -> MultipartRequest
		MultipartRequest multi;
		try {
			multi = new MultipartRequest(request, savePath, maxSize, encoding, rename);
			// 요청 데이터 받아오기
			String title = multi.getParameter("title");
			String writer = multi.getParameter("writer");
			String filename = multi.getFilesystemName("filename");
			String content = multi.getParameter("content");
			
			Board vo = new Board(title, writer, filename, content);
			System.out.println(vo.toString());
			// DB에 넣어주기
			int cnt = new BoardDAO().writeBoard(vo);
			
			if (cnt > 0) {
				System.out.println("게시글 작성 성공");
			} else {
				System.out.println("게시글 작성 실패");
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// response.sendRedirect("BoardMain.jsp");

		return "redirect:/BoardMainPage.do";
		
	}

}
  • BoardWritePageService
package com.smhrd.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.smhrd.frontController.command;

public class BoardWritePageService implements command {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) {
		//BoardWrite.jsp로 이동시켜주는 역할
		//page를 요청하는 controller이기 때문에 내부에 코드작성
		
		
		
		
		
		
		return "BoardWrite";
	}

}
  • BoardDetailService
package com.smhrd.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.smhrd.frontController.command;
import com.smhrd.model.Board;
import com.smhrd.model.BoardDAO;

public class BoardDetailService implements command {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) {
		//1. 게시글의 고유번호 num받아오기
		int num = Integer.parseInt(request.getParameter("num"));
		//2. num을 가지고 db에서 관련 데이터 가져오기
		Board board = new BoardDAO().detailBoard(num);
		//3. view에서 보여주기 위해거 request객체에 객체
		request.setAttribute("board", board);
		//3. Boardmain.jsp로 가기 위해 viewname 반환
		return "BoardDetail";
		
	}

}

--------------------------------------- BoardMain.jsp

<%@page import="com.smhrd.model.Board"%>
<%@page import="java.util.List"%>
<%@page import="com.smhrd.model.BoardDAO"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isELIgnored="false"%>
<%@ 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>
      <title>Forty by HTML5 UP</title>
      <meta charset="utf-8" />
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <!--[if lte IE 8]><script src="assets/js/ie/html5shiv.js"></script><![endif]-->
      <link rel="stylesheet" href="assetsBoard/css/main.css" />
      <link rel="stylesheet" href="assetsBoard/css/board.css" />
     
      
</head>
<body>      
       
         <!-- Q18. 게시글 목록 세부페이지 기능(제목을 클릭하면 세부페이지 BoardDetail.jsp로 이동)-->
         <div id="board">
            <table id = "list">
               <tr>
                  <td>번호</td>
                  <td>제목</td>
                  <td>작성자</td>
                  <td>시간</td>
               </tr>
                                          <!-- 상태변수 -->
               <c:forEach var="b" items="${boards}" varStatus="s">
                  <tr>
                     <td>${s.count}</td>
                     <td><a href="BoardDetailService.do?num=${b.num}">${b.title}</a></td>
                     <td>${b.writer}</td>
                     <td>${b.b_date}</td>
                  </tr>
               </c:forEach>
               
      
            </table>
            
            <a href="BoardMainPage.do"><button id="writer">홈으로가기</button></a>
            <a href="BoardWritePage.do"><button id="writer">작성하러가기</button></a>
         </div>


         <!-- Scripts -->
         <script src="assets/js/jquery.min.js"></script>
         <script src="assets/js/jquery.scrolly.min.js"></script>
         <script src="assets/js/jquery.scrollex.min.js"></script>
         <script src="assets/js/skel.min.js"></script>
         <script src="assets/js/util.js"></script>
         <!--[if lte IE 8]><script src="assets/js/ie/respond.min.js"></script><![endif]-->
         <script src="assets/js/main.js"></script>
</body>
</html>
  • BoardWrite.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
      <title>Forty by HTML5 UP</title>
      <meta charset="utf-8" />
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <!--[if lte IE 8]><script src="assets/js/ie/html5shiv.js"></script><![endif]-->
      <link rel="stylesheet" href="assetsBoard/css/main.css" />
      <link rel="stylesheet" href="assetsBoard/css/board.css" />
      <!--[if lte IE 9]><link rel="stylesheet" href="assets/css/ie9.css" /><![endif]-->
      <!--[if lte IE 8]><link rel="stylesheet" href="assets/css/ie8.css" /><![endif]-->
</head>
<body>
         <!-- Q16. 게시글 작성 기능(작성된 게시글은 DB에 저장) - 파일업로드 cos.jar 사용 -->
         <!-- enctype
            1) application/x-www-form-urlencoded
               -> form태그 안에서 보내는 요청데이터를 Key값과 Value값을 쌍으로 보냄
            2) multipart/form-data
               -> 사진파일과 같이 용량이 큰 데이터(파일)을 보낼 때 사용(무조건 post방식으로 보내야 함)
          -->
         <div id = "board">
            <form action="BoardWriteService.do" method="post" enctype="multipart/form-data">
            <table id="list">
               <tr>
                  <td>제목</td>
                  <td><input type="text" name="title"> </td>
               </tr>
               <tr>
                  <td>작성자</td>
                  <td><input  type="text" name="writer"> </td>
               </tr>
               <tr>
                  <td colspan="2">내용</td>
               </tr>
               <tr>
                  <td colspan="2">
                     <input  type="file" name="filename" style="float: right;">
                     <textarea  rows="10" name="content" style="resize: none;"></textarea>         
                  </td>
               </tr>
               <tr>
                  <td colspan="2">
                     <input type="reset" value="초기화">
                     <input type="submit" value="작성하기">
                  </td>
               </tr>
            </table>
            </form>
         </div>
         <!-- Scripts -->
         <script src="assets/js/jquery.min.js"></script>
         <script src="assets/js/jquery.scrolly.min.js"></script>
         <script src="assets/js/jquery.scrollex.min.js"></script>
         <script src="assets/js/skel.min.js"></script>
         <script src="assets/js/util.js"></script>
         <!--[if lte IE 8]><script src="assets/js/ie/respond.min.js"></script><![endif]-->
         <script src="assets/js/main.js"></script>
</body>
</html>
  • BoardDetail.jsp
<%@page import="com.smhrd.model.Board"%>
<%@page import="com.smhrd.model.BoardDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isELIgnored = "false"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
      <title>Forty by HTML5 UP</title>
      <meta charset="utf-8" />
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <!--[if lte IE 8]><script src="assets/js/ie/html5shiv.js"></script><![endif]-->
      <link rel="stylesheet" href="assetsBoard/css/main.css" />
      <link rel="stylesheet" href="assetsBoard/css/board.css" />
      <!--[if lte IE 9]><link rel="stylesheet" href="assets/css/ie9.css" /><![endif]-->
      <!--[if lte IE 8]><link rel="stylesheet" href="assets/css/ie8.css" /><![endif]-->
</head>
<body>
         <!-- Q19. 게시글 세부내용 조회 기능 -->   
        
         
         <div id = "board">
            <table id="list">
               <tr>
                  <td>제목</td>
                  <td>${board.title}</td>
               </tr>
               <tr>
                  <td>작성자</td>
                  <td>${board.writer}</td>
               </tr>
               
               <tr>
                  <td>다운로드</td>
                  <td><a href="./file/${board.filename}" download>${board.filename}</a></td>
               </tr>
               
               <tr>
                  <td colspan="2">내용</td>
               </tr>
               <tr>
                  <td colspan="2">
                     <h3>${board.content}</h3>
                     <img alt="" src="./file/${board.filename}">
                  </td>
               </tr>
               <tr>
                  <td colspan="2"><a href="BoardMainPage.do"><button>뒤로가기</button></a></td>
               </tr>
            </table>
         </div>
         <!-- Scripts -->
         <script src="assets/js/jquery.min.js"></script>
         <script src="assets/js/jquery.scrolly.min.js"></script>
         <script src="assets/js/jquery.scrollex.min.js"></script>
         <script src="assets/js/skel.min.js"></script>
         <script src="assets/js/util.js"></script>
         <!--[if lte IE 8]><script src="assets/js/ie/respond.min.js"></script><![endif]-->
         <script src="assets/js/main.js"></script>
</body>
</html>
profile
열심히 공부합시다! The best is yet to come! 💜

0개의 댓글