복습
- 목록 가져오기 Service 클래스에서 목록 추출 후 결과를 공유설정
- View 페이지에서 EL 로 출력하기 전에 공유설정되어야함
Service 클래스에서 DTO 객체가 공유되면
request.setAttribute("board", board);
- View 페이지에서 ${공유되는 네임값.필드명} 으로 출력
<td>
<input name="board_name" id="board_name" type="text" size="10" maxlength="10"
value="${board.board_name}"/>
</td>
Spring 학습 전 앞으로 할 내용
Maven
- 라이브러리 관리자 중 하나
- Spring 프로젝트를 만들면 Maven 으로 라이브러리 관리하는게 기본
ORM 프레임워크 : MyBatis
- 기존의 DAO 클래스 안에 있는 내용을 xml 에 따로 뺀다, 간단해짐
- Spring 은 MyBatis 와 연동하는 경우가 많다
- 수정 폼, Controller 클래스에서 연결하는것도 다 구현했다
- 글 수정 Service 클래스, 수정하는 DAO 메소드만 구현하면 된다
게시판 프로그램 : 글 수정 Service 클래스
- service 패키지 안에 글 수정 Service 클래스인 BoardModifyjava.java 를 작성하자
- BoardModify.java (수정 후 1)
package service;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import dao.BoardDAO;
import model.BoardBean;
public class BoardModify implements Action{
@Override
public ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("BoardModify");
response.setContentType("text/html; charset=utf-8");
request.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
int board_num = Integer.parseInt(request.getParameter("board_num"));
String page = request.getParameter("page");
String board_pass = request.getParameter("board_pass");
BoardBean board = new BoardBean();
board.setBoard_num(board_num);
board.setBoard_name(request.getParameter("board_name"));
board.setBoard_subject(request.getParameter("board_subject"));
board.setBoard_content(request.getParameter("board_content"));
BoardDAO dao = BoardDAO.getInstance();
BoardBean old = dao.getDetail(board_num);
// 비번 비교
if(old.getBoard_pass().equals(board_pass)) { // 비번 일치시
int result = dao.update(board); // update SQL문 실행
if(result == 1) System.out.println("글수정 성공");
} else { // 비번 불일치
out.println("<script>");
out.println("alert('비번이 일치하지 않습니다');");
out.println("history.go(-1)");
out.println("</script>");
out.close();
return null;
}
ActionForward forward = new ActionForward();
forward.setRedirect(false);
forward.setPath("/BoardListAction.do?page=" + page);
// forward.setPath("/BoardDetailAction.do?board_num="+board_num+ "&page=" + page); // 상세정보로 갈 수도 있다
return forward;
}
}
1. 글 수정폼에서 입력된 정보들이 넘어오므로 한글값 인코딩을 한다
- 비번 불일치시 출력할 alert 창을 위해 out 객체를 생성하고 현재 문서 한글값 인코등을 한다
2. 글 수정 폼에서 hidden 으로 전달된 글 번호, 페이지 번호를 받아와서 저장한다
- 페이지번호, 글 번호는 목록 페이지 -> 상세 정보 -> 글 수정 폼 -> 글 수정 으로 넘어왔다
- 글 번호는 수정시에 필요하고, 페이지 번호는 수정 후 원래 페이지로 돌아갈 때 필요하다
3. DTO 객체 board 를 생성하고, 수정폼에서 넘어온 값들을 받아서 객체 board 에 저장
4. 사용자가 수정폼에 입력한 비번을 받고 DB에 저장된 비번과 비교해서 일치하는지 확인
- 사용자가 수정폼에 입력한 비번은 form 에서 넘어온 값이므로 request.getParamter("board_pass") 로 가져온다
- 상세정보를 가져오는 메소드 getDetail() 을 호출해서 DB 에 저장된 1개 글에 대한 정보를 가져와서 DTO 객체 old 에 저장
5. 비번 일치시 DAO 의 update() 메소드를 실행해서 실제 수정을 수행함
- 이후 DAO 에 갔다가 여기로 다시 돌아온다
6. 비번 불일치시 out 객체로 비밀번호가 틀렸다는 메세지를 뿌린 후 이전 페이지인 수정폼으로 돌아간다
- 비번 불일치시 포워딩 시키면 안되므로 포워딩 객체를 생성하기 전에 return null 로 함수 execute() 를 종료
7. 수정에 성공하면 목록 페이지로 가기 위해 "/BoardListAction.do" 로 요청하여 목록 가져오기를 한다
- 목록페이지 포워딩 시 원래 페이지로 가기 위해 페이지 번호를 get 방식 전달, 목록 페이지에서 그 페이지번호를 받아서 그 페이지에 해당하는 글들을 가져와서 출력해준다
- 상세페이지로 갈 수도 있다, 상세페이지로 갈때는 페이지번호 뿐 아니라 글번호도 가져가야한다
DAO 클래스 글 수정 기능 메소드 작성
- BoardDAO.java 전체 코드는 모두 구현 후 올리기
- BoardDAO.java 추가된 update() 부분 코드만
// 글 수정
public int update(BoardBean board) {
int result = 0;
Connection con = null;
PreparedStatement pstmt = null;
try {
con = getConnection();
String sql = "update model2 set board_name=?,board_subject=?,";
sql += "board_content=? where board_num=?";
pstmt = con.prepareStatement(sql);
pstmt.setString(1, board.getBoard_name());
pstmt.setString(2, board.getBoard_subject());
pstmt.setString(3, board.getBoard_content());
pstmt.setInt(4, board.getBoard_num());
result = pstmt.executeUpdate(); // SQL문 실행
} catch (Exception e) {
e.printStackTrace();
} finally {
if(pstmt != null) try { pstmt.close(); } catch(Exception e) {}
if(con != null) try { con.close(); } catch(Exception e) {}
}
return result;
}
- 수정 폼에서 수정을 위해 작성하는 값들은 이름, 제목, 내용 뿐이므로 이 값들만 update 해주면 된다
- DAO update()가 끝나고 Service 클래스로 돌아간다
- Service 클래스, DAO update() 작성 후 수정을 해보자
- index.jsp 실행해서 목록 페이지로 온 다음, 상세 페이지로 가고, 수정폼으로 가고, 수정해보기
- 수정이 잘 된다
문제점
- 수정 성공시 성공했다는 메세지가 뜨지 않음
- 수정 성공시 메세지는 alert() 으로 출력되지 않는다
문제 해결
response.sendRedirect("./board/updateresult.jsp?page="+page);
- 포워딩할때 Controller 클래스를 거치는 것이 원칙이지만 여기선 바로 수정 성공 메세지를 출력하는 View 페이지로 간다
- 포워딩 시에 페이지번호를 가져가서, 그 페이지 내에서 <script></script> 내에서 출력을 하고 목록페이지로 돌아가야함
- 만약 메세지를 띄우고 싶다면 출력을 담당하는 다른 페이지로 포워딩해서 이 메세지를 띄워야한다
+ 이 작업을 아래의 forward 객체로 포워딩하면 안된다, 여기서 바로 Redirect 방식으로 포워딩해야함
- 아래의 forward 코드는 주석으로 막고 return null 을 해야한다
- Controller 클래스에 "/update.do" 요청을 처리하는 코드를 작성하자
- 다음은 수정 성공 후 메세지를 출력할 updateresult.jsp 파일 생성
- updateresult.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<script>
alert(${param.page});
alert("글 수정 성공");
location.href = "<%=request.getContextPath()%>/BoardListAction.do?page="+ ${param.page};
</script>
- 글 수정을 하고 메세지 출력 후 목록페이지로 잘 가는지 확인해야한다
- 원래 페이지인 1 페이지로 돌아온다, URL 을 보면 알 수 있음
+ 7 페이지의 글을 수정해도 다시 7 페이지로 돌아왔음을 확인 했다
+ 나중에는 이렇게 복잡하게 메세지를 출력하지 않는다
게시판 프로그램 : 글 삭제
- 먼저 상세 페이지 View 페이지인 qna_board_view.jsp 의 버튼 중 '삭제' 버튼에 링크를 걸어야한다
- qna_board_view.jsp 부분
<input type="button" value="삭제"
onClick="location.href='./BoardDeleteAction.do?board_num=${board.board_num}&page=${page}'">
- 상세페이지에서 글번호 board_num 과 페이지번호 page 가 넘어온다
- 글 삭제 폼으로 가기 위해 "/BoardDeleteAction.do" 로 요청을 한다
Controller 클래스에서 글 삭제폼으로 가기 (BoardFrontController.java 부분)
- BoardFrontController.java 전체 코드는 나중에
- BoardFrontController.java 부분
- BoardDeleteAction.do 로 요청이 올때의 경우를 처리
// 삭제 폼
} else if(command.equals("/BoardDeleteAction.do")) {
try {
forward = new ActionForward();
forward.setRedirect(false); // dispatcher 방식으로 포워딩
forward.setPath("./board/qna_board_delete.jsp");
} catch (Exception e) {
e.printStackTrace();
}
}
- 삭제 폼은 DB와 연동할 필요가 없으므로 Service 클래스로 가지 않는다
- 요청을 Controller 페이지에서 받으면 바로 삭제폼 View 페이지 qna_board_delete.jsp 로 포워딩한다
- 여기서 forword 객체를 생성하고 포워딩 방식, 포워딩 페이지를 설정하면 아래 포워딩 코드에 의해 바로 View 로 포워딩 됨
- Dispatcher 방식으로 포워딩해야만 param 으로 값을 받을 수 있다
+ Dispatcher 방식으로 포워딩해야 호출하는 페이지의 request, response 객체를 공유하기때문이다
- board 폴더 안에 삭제폼 View 페이지인 qna_board_delete.jsp 생성 및 작성
- qna_board_delete.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<html>
<head>
<title>게시판 삭제</title>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="<%=request.getContextPath() %>/board/script.js"></script>
</head>
<body>
<!-- 글번호, 페이지번호를 request 객체로 받기 -->
board_num1 : <%=request.getParameter("board_num") %> <br>
page1 : <%=request.getParameter("page") %> <br>
<!-- 글번호, 페이지번호를 param 내장객체로 받기 -->
board_num2 : ${param.board_num} <br>
page2 : ${param.page }
<form action="<%=request.getContextPath() %>/BoardDelete.do" method="post">
<input type="hidden" name="board_num" value="${param.board_num}">
<input type="hidden" name="page" value="${param.page}">
<table cellpadding="0" cellspacing="0" align=center border=1>
<tr align="center" valign="middle">
<td colspan="5">게시판 삭제</td>
</tr>
<tr>
<td style="font-family:돋음; font-size:12" height="16">
<div align="center">비밀번호</div>
</td>
<td>
<input name="board_pass" id="board_pass" type="password" size="10" maxlength="10"
value=""/>
</td>
</tr>
<tr bgcolor="cccccc">
<td colspan="2" style="height:1px;">
</td>
</tr>
<tr><td colspan="2"> </td></tr>
<tr align="center" valign="middle">
<td colspan="5">
<input type=submit value="삭제">
<input type=reset value="취소">
</td>
</tr>
</table>
</form>
</body>
</html>
- qna_board_modify.jsp 를 복붙 후 수정
- 상세페이지에서 넘겨준 글번호, 페이지번호 를 받아서 글 삭제 Service 클래스 BoardDelete.do 로 넘겨준다
- 삭제 시 "/BoardDelete.do" 로 요청
- 삭제 시 삭제 Service 클래스인 BoardDelete.java 로 글 번호, 원래 페이지 번호, 비밀번호가 넘어가야한다
+ 삭제할 글 번호를 알아야하기때문에, 원래 페이지로 돌아가야하므로, 비밀번호 일치 확인을 해야하므로
- 입력양식은 비번 입력 양식만 남긴다
수정폼 vs 삭제폼
- 수정 폼은 DB와 연동해서 Service 클래스에서 객체 board 를 공유했고 그걸 수정폼에 뿌렸었다
- 삭제 폼은 DB와 연동하지 않았으므로 param 객체로 글번호, 페이지번호를 가져와서 hidden 으로 글 수정 Service 클래스로 넘긴다
+ Dispatcher 방식으로 포워딩했으므로 상세페이지의 request, response 객체를 공유하므로 param 으로 그 글의 글 번호, 원래 페이지 번호를 받아옴
param 내장 객체 (qna_board_delete.jsp 부분)
<!-- 글번호, 페이지번호를 request 객체로 받기 -->
board_num1 : <%=request.getParameter("board_num") %> <br>
page1 : <%=request.getParameter("page") %> <br>
<!-- 글번호, 페이지번호를 param 내장객체로 받기 -->
board_num2 : ${param.board_num} <br>
page2 : ${param.page }
- param 은 getParameter() 와 같은 코드
- 코드가 간단해짐
- 글 삭제 Service 클래스인 BoardDelete.java 를 service 패키지 안에 생성하자
게시판 프로그램 : 글 삭제 Service 클래스
- service 패키지 안에 글 삭제 Service 클래스인 BoardDelete.java 를 생성 및 작성하자
- BoardDelete.java
package service;
import java.io.File;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import dao.BoardDAO;
import model.BoardBean;
public class BoardDelete implements Action{
@Override
public ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("BoardDelete");
response.setContentType("text/html; charset=utf-8");
request.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
int board_num = Integer.parseInt(request.getParameter("board_num"));
String page = request.getParameter("page");
String board_pass = request.getParameter("board_pass");
String path = request.getRealPath("boardupload");
System.out.println(path);
BoardDAO dao = BoardDAO.getInstance();
BoardBean old = dao.getDetail(board_num); // 상세정보 구하기
System.out.println(old.getBoard_pass());
System.out.println(board_pass);
// 비번 비교
if(old.getBoard_pass().equals(board_pass)) { // 비번 일치시
int result = dao.delete(board_num); // delete SQL문 실행
if(result == 1) System.out.println("삭제 성공");
// 첨부파일이 있는 경우에 첨부파일 삭제
if(old.getBoard_file() != null) {
File file = new File(path);
file.mkdir();
// boardupload 디렉토리의 모든 첨부 구해오기
File[] f = file.listFiles();
for(int i=0; i<f.length; i++) {
if(f[i].getName().equals(old.getBoard_file())) {
f[i].delete(); // 첨부파일 삭제
}
}
}
} else { // 비번 불일치시
out.println("<script>");
out.println("alert('비번이 일치하지 않습니다.');");
out.println("history.go(-1);");
out.println("</script>");
out.close();
return null;
}
ActionForward forward = new ActionForward();
forward.setRedirect(false);
forward.setPath("/BoardListAction.do?page=" + page);
return forward;
}
}
1. 삭제 폼에서 한글값이 넘어올 수 있으므로 한글값 인코딩 처리를 한다
- 비번이 일치하지 않을때 alert 창에 출력하기 위해 문서 한글 인코딩 처리도 하고 out 객체도 생성한다
2. 삭제 폼에서 hidden 으로 넘어온 글 번호와 페이지 번호를 받아서 변수에 저장한다
- 목록 페이지 -> 상세페이지 -> 삭제폼 -> 삭제 Service 클래스 까지 글 번호와 페이지 번호가 넘어온 것이다
3. 삭제 폼에서 사용자가 입력한 비밀번호도 받아서 DAO 의 getDetail() 메소드로 상세정보를 구해온다
4. 비번 일치시 DAO 의 delete() 메소드를 호출하여 글을 삭제한다
- 매개변수로는 글 번호를 넘겨준다
5. 삭제한 글에 해당하는 첨부파일이 있다면 첨부파일도 지우도록 한다
* 첨부파일 지우기 설명은 아래에
6. 비번 불일치시 out 객체를 통해 alert 창에 메세지를 뿌리고 이전 페이지인 삭제 폼으로 돌아간다
- 이후 return null 을 작성 아래쪽의 포워딩 객체를 생성하고 설정하는 곳으로 가지 않고 함수를 종료시킨다
7. 글 삭제 성공 후 forward 객체를 생성하고 설정, 포워딩 페이지는 목록을 가져오는 "/BoardListAction.do" 로 한다
- get 방식으로 페이지 번호를 넘겨줘서, 원래 페이지로 돌아갈 수 있게 한다
첨부파일 지우기 (BoardDelete.java 부분)
// 첨부파일이 있는 경우에 첨부파일 삭제
if(old.getBoard_file() != null) {
File file = new File(path);
file.mkdir();
// boardupload 디렉토리의 모든 첨부 구해오기
File[] f = file.listFiles();
for(int i=0; i<=f.length; i++) {
if(f[i].getName().equals(old.getBoard_file())) {
f[i].delete(); // 첨부파일 삭제
}
}
}
- 첨부파일 지우기는 DAO 안에서 처리해도 되고, Service 클래스의 delete() 호출 아래에서 처리해도 된다
1) 첨부파일이 저장된 진짜 경로를 getRealPath() 로 구해서 path 변수에 저장한다
2) 상세정보를 구해온 객체 old.getBoard_file 을 통해 첨부파일이 있는지 없는지 판별가능, 있을때 삭제
3) File 객체 f를 생성할때 생성자의 매개변수에 생성될 디렉토리의 위치인 path 변수가 들어간다
4) file.listFiles() 로 boardupload 디렉토리의 모든 첨부파일을 구해온다
5. 반복문을 통해서 모든 파일을 돌면서, 파일명이 delete()로 삭제한 글의 DB 속에 저장된 파일명과 일치하면 파일 삭제
Controller 클래스에서 글 삭제 Service 클래스 BoardDelete.java로 전달 (BoardFrontController.java 부분)
- BoardFrontController.java 전체 코드는 나중에
- BoardFrontController.java 부분
- BoardDelete.do 로 요청이 올때의 경우를 처리
// 글 삭제
} else if(command.equals("/BoardDelete.do")) {
try {
action = new BoardDelete();
forward = action.execute(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
DAO 클래스 글 삭제 기능 메소드 작성
- BoardDAO.java 전체 코드는 모두 구현 후 올리기
- BoardDAO.java 추가된 delete() 부분 코드만
// 글 삭제
public int delete(int board_num) {
int result = 0;
Connection con = null;
PreparedStatement pstmt = null;
try {
con = getConnection();
String sql = "delete from model2 where board_num = ?";
pstmt = con.prepareStatement(sql);
pstmt.setInt(1, board_num);
result = pstmt.executeUpdate(); // SQL문 실행
} catch (Exception e) {
e.printStackTrace();
} finally {
if(pstmt != null) try { pstmt.close(); } catch(Exception e) {}
if(con != null) try { con.close(); } catch(Exception e) {}
}
return result;
}
- index.jsp 를 실행해서 목록페이지로 오고 10 페이지의 글 하나를 삭제해보자
- 삭제 후 다시 목록페이지로 왔다, 원래 페이지였던 10 페이지로 돌아왔다
C:\Users\admin\eclipse-workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\model2board\boardupload
- Desert21.jpg 첨부파일이 삭제되었는지 확인하기 위해 콘솔에 찍힌 path 를 탐색기에 검색
- 삭제 되었음을 확인 가능하다
JSP Model 2 끝
라이브러리 관리
- 지금까지는 Dynamic Web Project 를 만들고, 직접 라이브러리를 구해서 lib 폴더 안에 모든 라이브러리를 저장했다
- Spring 에서는 Maven 으로 라이브러리를 관리한다
- Maven 은 라이브러리 관리자 중 하나이다
라이브러리 관리자 maven
- spring project 에선 기본적으로 maven 으로 라이브러리를 관리함
- springboot project 에선 maven 또는 gradle 로 라이브러리를 관리함, 선택 가능
- 환경설정 파일 안에 라이브러리를 추가하는 식이다
라이브러리 관리자 gradle
- android project
- springboot projec
Maven 프로젝트 생성
Dynamic Web Project vs Maven Project
- 이때까지 Dynamic Web Project 로 프로젝트를 생성해 왔다
- 이젠 Maven Project 로 프로젝트를 생성하자
- Maven Project는 기본적으로 maven 으로 라이브러리를 관리하게끔 설정됨
- Maven Project는 Dynamic Web Project 와 폴더구조나 라이브러리 관리 방식이 크게 다르다
- Catalog 를 Internal 로 바꾼다
- 어떤 archetype 을 선택하냐에 따라 프로젝트 모양이 달라짐
- 일반적으로 웹 어플리케이션 프로젝트를 생성할때는 이 maven-archetype-webapp 를 선택
- Group id 값은 도메인명 역순을 주로 입력함. 현재는 com.myhome
- Artifact id 값은 프로젝트가 생성되면 프로젝트 명이 된다. 현재는 maventest
- Finish 누르면 maventest 프로젝트가 생성된다
- 기존의 Dynamic Web Project 와 구조가 다름
- pom.xml 파일이 Maven 의 환경설정 파일이다
+ 환경설정 파일은 xml 파일로 되어있는 경우가 많음
- 파일들에서 에러가 발생한다
maven project 에러발생
- maven 프로젝트 생성후 index.jsp 파일에 에러가 발생
- Libraries 에 Apache Tomcat Library 를 추가하면 에러가 사라진다.
- 여기 Apache Tomcat Library 가 없다
Apache Tomacat Library 추가하는 방법
- 그럼 빨간 에러가 사라진다
- index.jsp 를 실행해보자
Maven Project 구조
maintest/src/main 안의 3개 폴더
- 들어가는 내용들이 정해져 있다
1. java 폴더
- 확장자가 .java 인 모든 파일은 반드시 이 폴더 안에 저장
- dynamic web project 의 src 와 같은 역할
2. resources 폴더
- MaBatis 의 환경 설정 파일들이 주로 들어가있다
- 기존 DAO 클래스 안의 SQL문을 xml 파일로 따로 뺀다, 그 SQL문 파일들이 저장된다
3. webapp 폴더
- View 페이지가 저장되는 위치
- index 파일도 여기 안에 만들어야한다, webapp/WEB-INF 폴더 안에 index 파일저장
- 하지만 WEB-INF 폴더 안에 라이브러리는 더이상 없다, pom.xml 에서 라이브러리를 추가함
- dynamic web project 의 WebContent 와 같은 역할
pom.xml 파일
- maventest 프로젝트 하위
- Maven 의 환경설정 파일, 필요한 라이브러리를 여기에 추가한다
- 필요한 라이브러리를 pom.xml 추가시 원격 저장소에서 로컬 저장소로 다운받는다
- pom.xml 파일을 살펴보자
pom.xml 파일
- pom.xml (원하는 라이브러리 추가 전)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.myhome</groupId>
<artifactId>maventest</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>maventest Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>maventest</finalName>
</build>
</project>
- Maven 의 환경설정 파일
- 가장 바깥의 Root Element 가 project 이다, 전체가 <project></project> 로 덮여있다
- Maven Project 생성시 설정했던 내용들이 들어가있다, Group Id, ArtifactId 등
- Dependencies Element 안에 Dependency Element 들이 있다
- 이 Dependencies Element 안에 우리가 원하는 라이브러리를 추가해야함, 의존 라이브러리라고 부른다
- 여기선 junit 라이브러리 추가, junit 은 테스트 용도로 제공되는 라이브러리
라이브러리 가져오기
- 먼저 Maven Repository 에서 의존 라이브러리를 검색한다
- cos 라이브러리를 찾아서 가져와보자
Maven Repository: Search/Browse/Explore (mvnrepository.com)
- 이 버전을 클릭
- 복사한 코드를 pom.xml 의 dependencies element <dependencies></dependencies> 안에 추가한다
- 추가 후 저장시 원격 저장소에서 로컬 저장소(내 컴퓨터) 로 다운로드를 시작한다
- pom.xml (원하는 라이브러리 추가 후, 미완성)
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.myhome</groupId>
<artifactId>maventest</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>maventest Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<!-- https://mvnrepository.com/artifact/servlets.com/cos -->
<dependency>
<groupId>servlets.com</groupId>
<artifactId>cos</artifactId>
<version>05Nov2002</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>maventest</finalName>
</build>
</project>
- 이렇게 여기 dependency element 로 추가되는 라이브러리를 의존 라이브러리 라고 한다
+ Spring 에서는 maven 으로 라이브러리를 관리함
로컬 저장소 위치
- C:\Users\admin\.m2\repository
- 내 컴의 로컬 저장소(local repository) 위치이다.
- pom.xml 에 추가되어 원격 저장소에서 로컬 저장소로 다운받아진 라이브러리들이 여기 저장되어 있다.
- Windows - Preperences 로 들어와서 Maven -> Use Settings 선택
- 내 컴의 로컬 저장소 위치이다
- maven 으로 라이브러리 관리 시 기본적으로 이렇게 로컬 저장소가 생성된다
- 특정 라이브러리를 다운하다가 문제가 생기면 로컬 저장소 안의 파일들을 다 지워도 된다, 새로 실행시 처음부터 다시 다운받음
- 만약 특정 라이브러리가 다운이 안된다면, 이미 그 라이브러리를 잘 다운 받은 컴퓨터의 레파지토리를 복사해서 내 컴에 덮어씌운다
- 저 주소를 복사해서 탐색기에 쳐보자
- 라이브러리들이 보인다
- 로컬 저장소안의 라이브러리를 지우고 싶으면 이클립스를 종료하고 지워야함
- 이클립스를 종료하고 모두 삭제하면 다시 이클립스를 실행할때 다시 다 다운받는다
Oracle JDBC 라이브러리 추가
pom.xml 에 Oracle Repository 추가
- Oracle은 공식 저장소에서 지원되는 라이브러리들이 다운이 안되는 경우가 많이 발생함
- 그래서 비공식적인 오라클 Repository 를 먼저 따로 추가해야함
- pom.xml 의 dependencies Element "위"에 오라클 Repository 를 가져오는 이 코드를 복사
<!-- 오라클 repository -->
<repositories>
<repository>
<id>codelds</id>
<url>https://code.lds.org/nexus/content/groups/main-repo</url>
</repository>
</repositories>
- 그리고 오라클 JDBC 라이브러리를 dependencies Element 안에 추가
- 이 코드 잘 작동하지 않는다, 이미 다운받은 Repository 를 덮어쓰자
<!-- 오라클 JDBC Library -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency>
- pom.xml (오라클 Reopository 추가, 오라클 JDBC Library 추가)
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.myhome</groupId>
<artifactId>maventest</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>maventest Maven Webapp</name>
<url>http://maven.apache.org</url>
<!-- 오라클 repository -->
<repositories>
<repository>
<id>codelds</id>
<url>https://code.lds.org/nexus/content/groups/main-repo</url>
</repository>
</repositories>
<dependencies>
<!-- 오라클 JDBC Library -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/servlets.com/cos -->
<dependency>
<groupId>servlets.com</groupId>
<artifactId>cos</artifactId>
<version>05Nov2002</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>maventest</finalName>
</build>
</project>
- 오라클 JDBC 라이브러리를 다운받을때 문제가 생긴다
MySQL JDBC 라이브러리 추가
- 지금 설치한 mysql 버전이 8 점대 임을 고려해서 8 점대 중 8.0.28 버전 다운
- dependencies element 안에 이 코드를 복붙
프레임워크 MyBatis 라이브러리 추가
- 지금은 Spring 을 안쓰므로 MyBatis 만 있으면 된다
- dependencies element 안에 이 코드를 복붙
JSTL 라이브러리 추가
- 하나만으로 처리가 안되는 경우가 있으므로 두가지 라이브러리를 가져옴
- 나중엔 JSTL 연결 라이브러리도 필요
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jstl-impl</artifactId>
<version>1.2</version>
</dependency>
- 이걸 pom.xml 의 dependencies element 안으로 가져옴
문제점
- 오라클 JDBC 라이브러리를 가져올때만 문제가 생겼다
문제 해결 방법
- 이미 다운을 받은 레파지토리를 복사해서 내 레파지토리로 붙여넣는다
- 이미 오라클 JDBC 라이브러리를 다운받은 레파지토리를 클라우드에서 다운받아서 압축 해제하고 그 안의 내용을 모두 내 로컬 레파지토리로 복붙하자
- 이클립스를 종료하고 내 로컬 레파지토리의 내용은 모두 삭제 하고, 이 repository 압축 풀은 모든 내용을 복붙하기
- 다 삭제하고 복붙 완료한 내 레파지토리
- 다시 이클립스를 켠다
- 복붙한 라이브러리 버전과 다른 경우는 다시 pom.xml 에 쓰인 버전으로 다운받는다
- 그럼 오라클 JDBC 라이브러리 코드를 작성해도 에러가 나타나지 않음
- 빨간 에러가 사라졌다
- pom.xml 에 작성된 라이브러리들만 여기에 나타난다
- pom.xml (최종)
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.myhome</groupId>
<artifactId>maventest</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>maventest Maven Webapp</name>
<url>http://maven.apache.org</url>
<!-- 오라클 repository -->
<repositories>
<repository>
<id>codelds</id>
<url>https://code.lds.org/nexus/content/groups/main-repo</url>
</repository>
</repositories>
<dependencies>
<!-- 오라클 JDBC Library -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jstl-impl</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/servlets.com/cos -->
<dependency>
<groupId>servlets.com</groupId>
<artifactId>cos</artifactId>
<version>05Nov2002</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>maventest</finalName>
</build>
</project>
maven 프로젝트 vs spring 프로젝트
- 현재는 maven 프로젝트를 생성했을때 pom.xml 에 의존 라이브러리는 junit 만 있었다
- Spring 프로젝트 만들면 기본적인 라이브러리가 다 들어가있다
+ Spring 프로젝트도 라이브러리 관리는 maven 라이브러리 관리자를 사용
Spring 프로젝트 만들기
- Spring 프로젝트는 이클립스 메뉴 없어서 지금은 만들 수 없다
1. 플로그인에 추가
2. STS 란 프로그램 사용, SpringBoot 만들 수 있는 메뉴도 추가되어있다
maven 프로젝트 import, export
- maven 프로젝트를 import / export 할때 war 파일로 import / export 하면 안된다
- spring 프로젝트도 import / export 할때 war 파일로 import / export 하면 안된다
- maven 프로젝트를 war 파일로 import / export 하면 Maven Project 가 Dynamic Web Project 로 풀려버림
- war 파일로 export -> import 했을때 프로젝트는 Dynamic Web Project 가 된다
maven 프로젝트 export 하는 법
- maven 프로젝트를 export 할때는 프로젝트를 통째로 Ctrl + C 로 복사해서 다른 곳에(바탕화면) 붙여넣기 한다
- 이렇게 폴더로 나타난다
maven 프로젝트 import 하는 법
- 현재는 이미 이클립스에 maventest 라는 프로젝트가 있으므로 Finish 가 활성화되어있지 않음
- 이클립스의 maventest 프로젝트를 삭제 후 다시 import 하자
- maventest 프로젝트가 maven project 그대로 유지되면서 import 되었다