형상관리서버(협업툴) : 소스, 버전등 변경 관리 (클라이언트에서는 eclipse를 이용해 작업)
IMPORT : 클라이언트 → 서버 (팀장이 만든 프로젝트를 최초에 한번 전송)
CHECKOUT : 클라이언트 ← 서버 (서버에 존재하는 프로젝트를 팀원이 다운로드)
COMMIT : 클라이언트 → 서버 (작업한 파일을 서버로 전송 : 자주 실행 - UPLOAD)
UPDATE(PATCH) : 클라이언트 ← 서버 (서버에 변경된 파일을 클라이언트로 전송 : 자주 실행)
Visual SVN Server 서버 설치 (브라우저가 아닌 이클립스로 접속하는 것)
https://www.visualsvn.com/server/download/ 에서 서버 프로그램 다운로드 및 설치
user 생성 및 group 생성 후 user를 group에 포함
repertory를 생성하여 그룹(사용자)에 권한 부여
URL를 이용해 확인 → https://www.itwill.xyz/svn/XXX (XXX: repertory이름)
Help - Eclipse Marketplace 클릭
[Find] : svn 검색 → [Subversive - SVN Team Provider 4.0.5] → Install (전체 선택 후 confirm → yes → finish)
[Subversive - SVN Team Provider 4.0.5] 설치 후 Eclipse 재실행 (restart)
Window → Preferences → Version Control(Team) → SVN → SVN Connector → [Get Connectors] → [SVN Kit 1.8.14] 선택 → Finish
[SVN Kit 1.8.14] Connector 설치 후 이클립스 재실행
확인 : Window → Preferences → Version Control(Team) → SVN → SVN Connector 확인
- IMPORT 작업 : 프로젝트를 서버에 전송하는 작업(한번만 실행) - 팀장이 실행
프로젝트 생성(메인페이지 작성) → 프로젝트 오른쪽 버튼 → Team → Share Project → SVN 선택 → URL, 계정, 암호 입력 (sava authentication ... 체크 , browse에서 url주소 확인 후 항상 trust) → next → simple mode 체크 (참고: trunk(현재폴더), branches(향후폴더) and tags(백업폴더)) → finish → import(서버에 파일 전송) → Visual SVN Server 또는 웹브라우저에서 확인
revision number : 파일에 붙은 숫자 → commit 할 때 마다 숫자가 증가
전송하고자 하는 디렉토리에 파일이 하나도 없다면 전송되지 않는다.
미전송 파일을 계속 업로드 하지 않도록 설정
- CHEKOUT 작업 : IMPORT된 프로젝트를 클라이언트로 전송(클라이언트가 틀린 경우에만 사용) - 팀원만 적용
프로젝트 exlplore 오른쪽 버튼 → New → Other → SVN → Project From SVN → Next → 인증 → URL(서버)입력 후 Browse 클릭 하여 확인 → user, password 입력 → save authentication 체크 → next → 원하는 프로젝트 선택 후 head revision 체크 → finish
- COMMIT 작업 : 프로젝트에서 파일을 변경한 후 서버로 파일을 전송
- UPDATE 작업 : 서버에 저장된 파일을 전송 받는 작업(프로그램 변경 전에 한 번 실행한 후 사용하는 것이 좋다.)
주의). Commit 할 경우 상위 revision number가 존재하는 경우 Commit 에러 발생 (충돌 발생)
작업디렉토리 백업 필수!
해결1 : Window → Show View → Other → Team → Synchronize View 선택 → 오른쪽 버튼 → Synchronize 선택
→ 문제가 되는 파일이 존재 → 오른쪽 버튼 → Override and Commit(또는 Override and Update) 선택
해결2 : 문제가 되는 파일이 존재 → 더블 클릭 → 화면에서 프로그램 비교후 파일 내용 변경 → Make as Merged
→ commit 가능(나중에 수정 가능)
package explorer에서 update한 경우 동일한 라인의 데이타를 변경한 경우 충돌 발생 → 문제 파일 수정 후 오른쪽 버튼
incomming(update 목록) 또는 outgoing(commit 목록) 확인 → Synchronize View에서 선택하여 전체 update 또는 commit 가능
SVN 영역
trunk : 소스의 주 개발 작업을 진행하는 폴더
branches : 소스의 실험적인 작업을 진행하는 폴더
tags : 현재 릴리즈된 소스를 관리하기 쉽게 따로 보관하는데 사용
개발을 위한 것이 아니라 보관을 위한 것이기 때문에 export만 해야 한다
체크아웃하여 커밋 할 경우 경고 메시지가 출력된다.
다른 작업으로 변환
프로젝트 → 오른쪽 버튼 → Team → switch → URL 또는 revision 변경 후 finish
프로젝트 완성하면 프로젝트를 war파일로 저장하여 서버의 webapps에 전송하면 된다.
- HttpServlet 클래스 (J2EE or Apache Tomcat)를 상속받은 자식클래스 작성 (서블릿 클래스)
public class Servlet extends HttpServlet {private static final long serialVersionUID = 1L;}
- doGet() 메소드 또는 doPost() 메소드(요청처리메소드)를 오버라이드 선언
@Override//doGet 메소드 오버라이드
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { }
- 클라이언트에게 응답할 결과에 대한 파일의 형식(MimeType)을 설정(변경)
response.setContentType("text/html;charset=utf-8");
- 클라이언트 요청에 의해 생성될 응답파일에 대한 출력스트림을 반환받아 저장
PrintWriter out=response.getWriter();
- 요청에 대한 처리와 처리에 대한 결과를 출력스트림을 사용하여 응답파일 생성
out.println("<!DOCTYPE html>");
- 서블릿 클래스를 서블릿(웹프로그램)으로 실행되도록 설정
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
//1. HttpServlet 클래스 상속, serialVersionUID 필드 선언
@Override//2.doGet 메소드 오버라이드
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//HttpServletRequest : 리퀘스트 메세지(요청 관련 정보)를 표현한 객체 - 입력
//HttpServletResponse : 리스폰즈 메세지(응답 관련 정보)를 표현한 객체 - 출력
//3.클라이언트에게 응답할 결과에 대한 파일의 형식(MimeType)을 설정
response.setContentType("text/html;charset=utf-8");
//4.클라이언트 요청에 의해 생성될 응답파일에 대한 출력스트림을 반환받아 저장
PrintWriter out=response.getWriter();
//5.요청에 대한 처리와 처리에 대한 결과를 출력스트림을 사용하여 응답파일 생성
out.println("<!DOCTYPE html>");
//출력스트림으로 문자열(HTML 태그)을 전달하여 문서파일 작성
out.println("<html>");
out.println("<head>");
out.println("<meta charset='UTF-8'>");
out.println("<title>Servlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>서블릿(Servlet)</h1>");
out.println("<hr>");
out.println("<p>Hello, Servelt!!!</p>");
out.println("</body>");
out.println("</html>");
//6.서블릿 클래스를 서블릿(웹프로그램)으로 실행되도록 설정
// → [web.xml] 파일에서 URL 주소를 매핑 설정
}
}
web.xml 더블클릭 해서 하단 source 확인
web.xml : 현재 프로젝트가 WAS 프로그램에 의해 웹자원(WebContext)로 변형될 때 필요한 정보를 제공하기 위한 환경설정파일 - XSD 파일(XML 스키마 파일)에 선언된 태그(엘리먼트)만 사용 가능(web-app_4_0.xsd)
servlet : 서블릿 클래스를 서블릿(웹프로그램)으로 등록하기 위한 엘리먼트
<servlet-name>hello</servlet-name>
<servlet-class>xyz.itwill.servlet.HelloServlet</servlet-class>
servlet-mapping : 서블릿을 실행하기 위한 요청 URL 주소의 패턴을 등록하기 위한 엘리먼트
<servlet-name>hello</servlet-name>
<url-pattern>/hello.itwill</url-pattern>
welcome-file-list : 기본 웹프로그램을 등록하기 위한 엘리먼트
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns=
"http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation=
"http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/
javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>servlet</display-name><!-- 보여지는 이름으로 의미없음 -->
<!-- servlet : 서블릿 클래스를 서블릿(웹프로그램)으로 등록하기 위한 엘리먼트 -->
<servlet>
<!-- servlet-name : 서블릿을 구분하기 위한 식별자(중복x)를 설정하는 엘리먼트 -->
<servlet-name>hello</servlet-name>
<!-- servlet-class : 서블릿으로 등록될 서블릿 클래스를 설정하는 엘리먼트 -->
<servlet-class>xyz.itwill.servlet.HelloServlet</servlet-class>
</servlet>
<!-- servlet-mapping : 서블릿을 실행하기 위한 요청 URL 주소의 패턴을 등록 -->
<servlet-mapping>
<!-- servlet-name : 요청 URL 주소에 의해 실행될 서블릿의 이름을 설정 -->
<servlet-name>hello</servlet-name>
<!-- url-pattern : 서블릿을 실행하기 위한 URL 주소의 패턴을 설정 -->
<!-- / : context root -->
<url-pattern>/hello.itwill</url-pattern>
</servlet-mapping>
<!-- welcome-file-list : 기본 웹프로그램을 등록하기 위한 엘리먼트-->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.jsp</welcome-file>
<welcome-file>default.htm</welcome-file>
</welcome-file-list>
</web-app>
→ URL mappings: /first.itwill 을 등록하면 자동적으로 FirstServlet 클래스와 매핑됨
→ 선언할 메소드 선택
→ finish
어노테이션(Annotation) : API 문서에 특별한 설명을 제공하기 위해 만들어진 기능
@WebServlet : 서블릿 클래스를 서블릿으로 등록하고 URL 주소를 매핑하기 위한 어노테이션
@WebServlet(name = "first",value = "/first.itwill")
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { 명령; }
package xyz.itwill.servlet;
//@WebServlet : 서블릿 클래스를 서블릿으로 등록하고 URL 주소를 매핑하기 위한 어노테이션
//@WebServlet 어노테이션의 속성을 사용하여 서블릿 이름과 요청 URL 주소 설정
//@WebServlet(name = "first",value = "/first.itwill")
@WebServlet("/first.itwill")
public class FirstServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
//클라이언트의 모든 요청방식에 의한 요청을 처리하기 위해 자동 호출되는 메소드 (요청 처리 메소드)
// → 클라이언트 요청에 대한 처리 명령과 응답결과를 생성하기 위한 명령 작성
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//클라이언트에게 응답할 결과에 대한 파일형식과 응답파일을 생성하기 위한 출력스트림을 반환
//→ 클라이언트 요청에 대한 응답결과를 파일로 생성하지 않을 경우 생략 가능
//(클라이언트에게 URL 주소로 응답)
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
//요청에 대한 처리와 응답을 위한 결과파일 생성
//→ 서블릿은 모든 클라이언트에게 일관성 있는 처리결과를 동적으로 생성하여 제공
Date now=new Date();//서버 시스템의 날짜와 시간이 저장된 Date 객체 생성
//날짜와 시간 관련 패턴정보가 저장된 SimpleDateFormat 객체 생성
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy년 MM월 dd일 HH시 mm분 ss초");
//SimpleDateFormat 객체의 format() 메소드를 호출하여 매개변수로 전달받은 Date 객체를
//SimpleDateFormat 객체에 저장된 패턴의 날짜와 시간 형식의 문자열로 변환하여 반환
String displayNow=dateFormat.format(now);
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<meta charset='UTF-8'>");
out.println("<title>Servlet</title>");
out.println("<style type=\"text/css\">");
out.println("p {");
out.println("width: 600px;");
out.println("margin: 0 auto;");
out.println("padding: 30px 0;");
out.println("font-size: 2em;");
out.println("font-weight: bold;");
out.println("text-align: center;");
out.println("border: 2px solid black;");
out.println("}");
out.println("</style>");
out.println("<script type='text/javascript'>");
out.println("setInterval(function() { location.reload(); }, 1000);");
out.println("</script>");
out.println("</head>");
out.println("<body>");
out.println("<h1>서블릿 시계</h1>");
out.println("<hr>");
out.println("<p>"+displayNow+"</p>");
out.println("</body>");
out.println("</html>");
}
}
서블릿(웹프로그램)은 클라이언트 요청에 의해 WAS 프로그램에 등록된 서블릿 클래스를 읽어 메모리에 저장하고 서블릿 객체로 생성하여 요청 처리 메소드를 호출
WAS 프로그램의 주요 기능 중 하나는 서블릿 객체를 관리하는 웹컨테이너(WebContainer) 기능 제공
생성자(Constructor) : 클래스 자료형으로 객체를 생성하기 위한 특별한 메소드
클라이언트 요청에 대한 처리와 처리 결과를 파일로 응답하기 위한 명령을 작성하는 메소드
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {명령;}
WAS 프로그램에 의해 서블릿 객체를 생성한 후 가장 먼저 한번만 자동 호출되는 메소드
public void init(ServletConfig config) throws ServletException{}
생성자 대신 init() 메소드로 초기화 작업 명령을 작성하는 이유
ServletConfig.getServletContext() : ServletContext 객체를 반환하는 메소드
ServletContext.getInitParameter(String name) : [web.xml] 파일에서 context-param 엘리먼트로 제공되는 값을 얻어와 반환하는 메소드
value=config.getServletContext().getInitParameter("name");
package xyz.itwill.servlet;
@WebServlet("/life.itwill")
public class LifeCycleServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private String name;
//기본생성자 : 클래스 자료형으로 객체를 생성하기 위한 특별한 메소드 (한번만 호출)
public LifeCycleServlet() {
System.out.println("서블릿 객체 생성");
//name="홍길동";
}
//init 메소드 오버라이드 : 서블릿 객체를 생성한 후 가장 먼저 한번만 자동 호출
//서블릿은 생성자 대신 init() 메소드를 이용하여 초기화 작업 명령을 작성하는 것을 권장
//init() 메소드의 매개변수로 ServletConfig 객체를 전달받아 메소드에서 사용 가능
//[web.xml] 파일에서 제공되는 값을 얻어와 서블릿 클래스에서 사용 가능
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("init() 메소드 호출");
//name="홍길동";
//ServletConfig.getServletContext() : ServletContext 객체를 반환
//ServletContext.getInitParameter(String name) : [web.xml] 파일에서
//context-param 엘리먼트로 제공되는 값을 얻어와 반환 (name=임꺽정)
name=config.getServletContext().getInitParameter("name");
}
//destroy 메소드 오버라이드 : 서블릿 객체가 소멸되기전 마지막으로 한번만 자동 호출
@Override
public void destroy() {
System.out.println("destroy() 메소드 호출");
}
//client 요청에 대한 결과를 응답하기 위한 명령을 작성하는 메소드 (요청마다 반복 호출)
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("service() 메소드 호출");
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<meta charset='UTF-8'>");
out.println("<title>Servlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>서블릿의 생명주기(LifeCycle)</h1>");
out.println("<hr>");
out.println("<p>"+name+"님, 안녕하세요.</p>");//임꺽정님 안녕하세요
out.println("</body>");
out.println("</html>");
}
}
web.xml : 현재 프로젝트가 WAS 프로그램에 의해 웹자원(WebContext)로 변형될 때 필요한 정보를 제공하기 위한 환경설정파일 - XSD 파일(XML 스키마 파일)에 선언된 태그(엘리먼트)만 사용 가능
context-param : 현재 프로젝트에 작성된 모든 웹프로그램에게 필요한 값을 제공하기 위한 엘리먼트
init-param : 현재 서블릿(웹프로그램)에게 필요한 값을 제공하기 위한 엘리먼트
servlet : 서블릿 클래스를 서블릿(웹프로그램)으로 등록하기 위한 엘리먼트
servlet-mapping : 서블릿을 실행하기 위한 요청 URL 주소의 패턴을 등록하기 위한 엘리먼트
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation=
"http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns
/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>servlet</display-name><!-- 보여지는 이름으로 의미없음 -->
<!-- context-param : 현재 프로젝트에 작성된 모든 웹프로그램에게 필요한 값을 제공 -->
<context-param>
<param-name>name</param-name>
<param-value>임꺽정</param-value>
</context-param>
<!-- servlet : 서블릿 클래스를 서블릿(웹프로그램)으로 등록하기 위한 엘리먼트 -->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>xyz.itwill.servlet.HelloServlet</servlet-class>
<!-- init-param : 현재 서블릿에게 필요한 값을 제공하기 위한 엘리먼트 -->
<init-param>
<param-name>title</param-name>
<param-value>서블릿</param-value>
</init-param>
</servlet>
<!-- servlet-mapping : URL 주소의 패턴을 등록하기 위한 엘리먼트 -->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello.itwill</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.jsp</welcome-file>
<welcome-file>default.htm</welcome-file>
</welcome-file-list>
</web-app>
- 클라이언트에게 이미지 파일이 응답되도록 설정 (응답될 파일형식(MimeType) 변경)
- 이미지 파일(이진 파일 - Binary File)로 응답하므로 캐릭터셋 미설정
response.setContentType("image/jpeg");
- 응답될 이미지 파일을 생성하기 위한 값(원시데이타 - 1Byte)를 전달하는 출력스트림(ServletOutputStream 객체)을 반환받아 저장
- ServletOutputStream out=response.getOutputStream();```
- 서버에 저장된 이미지 파일의 파일 시스템 경로를 반환받아 저장
- HttpServletRequest.getServletContext() : ServletContext 객체를 반환하는 메소드
- ServletContext 객체 : 웹자원(WebContext)을 관리하기 위한 객체 (WAS)
- 웹자원(WebContext) : 웹서버(WebServer)가 사용할 수 있는 자원 (웹에서 사용 가능한 리소스 파일)
- ServletContext.getRealPath(String contextPath) : 매개변수로 전달받은 웹자원 관련 파일의 시스템 경로를 반환하는 메소드
String filePath=request.getServletContext().getRealPath("/WEB-INF/abc.jpg");
- 이미지 파일을 읽기 위한 입력스트림 생성
FileInputStream in=new FileInputStream(filePath);
- 입력스트림으로 원시데이타를 읽어서 출력스트림으로 전달 (반복 처리)
- 서버에 저장된 이미지 파일을 읽어 클라이언트에게 응답되도록 생성
while(true){int readByte=in.read(); if(readByte==-1) break; out.write(readByte);}
- 파일 입력스트림 제거
in.close();
package xyz.itwill.servlet;
//클라이언트 요청에 대해 이미지 파일로 응답하기 위한 서블릿
@WebServlet("/image.itwill")
public class SendImageServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//클라이언트에게 이미지 파일이 응답되도록 설정 - 응답될 파일형식(MimeType) 변경
response.setContentType("image/jpeg");
//이미지 파일을 생성하기 위한 값(원시데이타)을 전달하는 출력스트림을 반환받아 저장
ServletOutputStream out=response.getOutputStream();
//서버에 저장된 이미지 파일의 파일 시스템 경로를 반환받아 저장
//HttpServletRequest.getServletContext() : ServletContext 객체를 반환하는 메소드
//ServletContext.getRealPath(String contextPath):웹자원 관련 파일의 시스템 경로 반환
String filePath=request.getServletContext().getRealPath("/WEB-INF/Koala.jpg");
//System.out.println("filePath = "+filePath);
//이미지 파일을 읽기 위한 입력스트림 생성
FileInputStream in=new FileInputStream(filePath);
//입력스트림으로 원시데이타를 읽어서 출력스트림으로 전달 (반복 처리)
while(true) {
int readByte=in.read();
if(readByte==-1) break;
out.write(readByte);
}
//파일 입력스트림 제거
in.close();
}
}