복습
Class Path
- Virtual Machine의 컴파일러가 클래스를 찾을때 클래스를 찾기 시작하는 위치
- 클래스 검색의 시작점
-classpath (cmd)
Qualified Name
- 클래스 패스 이후의 이름
- 어떤 클래스 하나를 식별하기 위한 식별자를 사용할때도 qualified name을 적어줘야한다
import
- 심플네임으로 찾아낼 때, 위치를 특정하기 위해 전처리로 사용하는 구문
standalone 개발 vs. servlet/jsp 이용
standalone 개발 | Servlet/JSP 이용해 개발 |
---|
기본jar(se: standard edition)로가능 | 톰캣의 jar파일을 빌려씀(ex. servlet-api.jar) 톰캣이 필요한이유: - ee버전 jar의 일부를 대신할 수 있음 - 메인스레드를 WAS로 돌려서 웹어플리케이션 구동시킬 수 있음 |
WAS: Web Application Server
- 톰캣이 필요한 이유
- 톰캣으로 어떻게 어플리케이션을 운영하는지
역할
서버 설계법
- WAS의 앱베이스(= 독베이스, webapps)에 어플리케이션폴더를 만듬
- 독베이스에 Context (= 어플리케이션) 를 하나 생성하면, 새로운 Context Path 하나가 만들어진다.
- 서버를 구동시킨다
- 여기까지가 서버 설계 끝
설계한 서버 테스트
- 서버를 테스트하기 위해서는 클라이언트가 되어야한다.
- 커맨드형태: 주소 url
- 도메인 = 서버사이드독베이스에접근하기위한가상의주소체계
- localhost = IP 주소 + /webapps(독베이스)까지 포함하고 있음
- WEB-INF 하위 폴더 및 파일은 외부클라이언트가 url로 접근할 수 없음
서블릿 개발시 중요한 점!
1. HttpServlet 상속받기
- 톰캣(WAS)이 가지고있는 servlet-api.jar을 가져와서 쓰기위해 클래스패스 설정해야함
- 컴파일단계에서부터 나의 클래스패스 지정할수있어야함 (cmd명령어: -d)
2. WEB-INF: 약속되어있는 폴더
- 하나의 컨텍스트에서만 유효한 클래스패스(build-classes)를 운영하는 곳
- 어플리케이션 A안의 /WEB-INF/classes
- 어플리케이션 B안의 /WEB-INF/classes 는 서로 접근불가능
3. 컴파일 이후에는 서블릿을 등록해야함
- 톰캣은
바보니깐 서블릿컨테이너로서 서블릿을 인지해야하기때문에
4. 톰캣은 서블릿의 라이프사이클관리한다
- 1) 먼저 서블릿을 등록한다
- 인스턴스를 만드려면 클래스가 어디있는지 알아야함.
- 그래서 먼저 서블릿을 등록하는 것.
- 여기까지하면 톰캣이 내안에 어떤 퀄러파이드내임이있구나 알수있고 이제부터 객체생성준비가능
- 2) 웹상에서 네트워크 반대편에있는 클라이언트가 주소체계를 통해 요청을 발생시킴
- 어떤형태로 주소를 날릴지는 모름
- A라는 서블릿이 처리할 수 있는 요청을 제한해줘야하기때문에 URL매핑 (서블릿매핑) 을 해주는 것.
- 3) 톰캣은 서블릿에 최초 요청이 들어오면 객체를 생성한 후에 싱글톤 형태로 운영함
- 4) 톰캣은 서블릿 로딩을 위해 web.xml을 읽는 IO작업을 실시함.
- 하지만 IO작업은 퍼포먼스에 영향을 주기 때문에 서버 구동시에 딱 1번만 로딩함
- 그럼 서블렛 코드가 수정될 때마다 계속 리로딩해줘야함
여기까지가 서버구동 끝
이러다가 깨달은 서블릿의 단점
- 스레드pool 안의 스레드를 하나 꺼내서 해당 요청을 처리하는 것이 서버의 역할
- 하지만 이런 방식의 단점이 있음
- 수정시마다 재컴파일하는게 빡침
- 할일도 많고 복잡함
- 하나의 자바소스안에 여러가지언어 (ex. html)가 섞여있어서 가독성떨어짐
- 협업이 어려움
서블릿 단점 해결을 위해 JSP스펙 사용
- JSP 내 코드 구성
- 동적요소를 위해 스크립틀릿
- 스크립틀릿제외하고 80퍼센트이상이 정적 코드 -> 디자이너 편함
- JSP 태동 이유: 서블릿 단점 해결위해 나온 스펙
- JSP는 컴파일될까 안될까? -> 된다!
- work밑에가면 서블릿소스로 바뀐거있음 컴파일되서 클래스로바뀌어있음
- 인스턴스로 생성도 되어있는 것임
- 그럼 그안의 메서드도 실행되어있을것이고 그 메서드를 실행하기위한 스레드도 운영이 되고있었을 것이다
- 결론: 톰캣이 JSP컨테이너로서 이 모든걸 다해준거
톰캣 = jsp컨테이너 = was = 서블릿컨테이너 = 미들티어
dummy 프로젝트
1. 프로젝트 생성하기
- Dynamic Web Module Version: 서블릿스펙버전
- 서블릿3.1 = 톰캣8.5 | 서블릿4 = 톰캣9 | 서블릿5 = 10
- build path == class path == src
- src 내에 자바 소스를 만든 후, 저장하면 컴파일이 된다
- 컴파일 된 소스는 자동으로 classes에 저장이 되기때문에 여기를 빌드패스라고 하는 것
- 이클립스에서는 classes 폴더가 보이지 않음
- default output folder = build\classes
- 이클립스에서 저장하는 순간 자동 컴파일 되어 클래스파일이 만들어져서 build\classes에 잠시 저장됨
- 그래서 이 폴더(build\classes)가 클래스패스가 됨.
- 하지만 개발이후에 테스트시에, 서버를 통해 실행을 하려면 이클립스에서 갖고 있던 클래스파일들이 서버상 독베이스인 webapp으로 이동됨 (=배포되어야함)
- 정리: 이클립스 안에서는 build\classes에서 클래스 파일을 관리하고 있지만, 톰캣이 클래스를 지정하기 위해서는 WEB-INF/classes가 필요하기 때문에 배포시에 이클립스가 톰켓 서버 상의 WEB-INF/classes로 고스란히 이동시킨다.
- 소스폴더를 src, res로 구분시키는 이유
- 컴파일 후에는 두 폴더 모두 classes 밑으로 들어가지만, 개발시 관리를 편하게 하려고 만든 것임
- 실행시에는 src, res구분없음
- xml, properties 등을 res 밑에 관리하는 이유
- 클래스패스 리소스로 만들기 위해서
- 클래스패스 리소스 파일을 찾기위해서는 클래스패스에서부터 시작하기때문에 그이후 경로(qualified name)만 기술해주면 됨
여기서 잠깐! 리소스 구분
- 파일시스템 리소스: 모든 리소스는 파일시스템 리소스
- 클래스패스 리소스: 클래스패스 이후 qualified name으로 접근
- 웹 리소스: 네트웍상 url로 접근하는 리소스
2. 프로젝트 뜯어보기
- build는 개발자의 영역이 아닌 이클립스의 영역
- 하지만 Navigator를 이용하면 build 폴더의 내부도 확인할 수 있다.
WebContent (=웹리소스)
- 웹상에서 주소로 접근할수 있다
- jsp, css, js, html, img...
- 톰캣의 서버폴더에는 존재하지 않는 폴더.
- 이클립스내 임시 파일일뿐이다. 배포시에는 어짜피 Context Root 밑으로 간다
- WebContent 아래의 모든 녀석들은 클라이언트가 url을 통해 접근할 수 있는 파일들이다.
Java Resources (=클래스패스 리소스)
- 웹상에서 주소로 접근할수 없다
- classpath 아래에 배포가 되는 리소스
- classes 폴더 안에 있는 채로 배포되기때문이다
- java, xml, properties
- src밑에 kr.or.ddit나 res밑에 kr.or.ddit나 같음
HelloServlet.java 만들기
- wpwebapps/dummy01/WEB_INF/classes/kr/.... 여기에 클래스파일이 있는데 이클립스 build에는 없....는 줄 알았지만 view를 navigator로 보면 보인닷!!!
- 그래서 classes를 클래스패스라고 부를 수 있땅
sample.xml찾기 (Java Resource)
- kr/or/ddit/sample.xml : 클래스패스이후의 qualified name (=클래스패스리소스)
- class loader가 필요할 것
- A a = new A();
- A라는 클래스에 메모리공간에 적재할때 작동하는게 클래스로더
- 그럼 클래스로더가 클래스도 찾아야함, 어디서찾을까 -> 클래스패스에서 찾는다
- 예) ibatis용 sqlconfig.xml: 클래스패스 이후의 경로를 기술해둠
<sqlMap resource="kr/or/ddit/sqlmap/admin.xml"/>
web.xml 찾기 (WebContent)
- 웹리소스: url통해서 접근
- 네트워크 반대편 클라이언트는 불가능해도 서버에서는 접근가능함
- Context Root부터 시작해서 주소 찾기
- /WEB-INF/web.xml
- 근데 왜 url이면서 프로토콜(http)도, localhost(ip)도, Context name(dummy01)도 없을까
- -> 서버사이드에서 자원에 접근하는 것이기때문에 url이 다르게생김
MIME
- MimeDescriptionServlet.java
개념
- MIME: Multipurposed Internet Mail Extension
- 89년도 웹 태동시에는 웹 및 웹사이트가 활성화 되지 않아 html 혹은 이미지가 파일ㅇ 타입의 전부였음.
형식
- main_type/sub_type;charset=encoding
- resp.getWriter() 쓰고나서 close()필수 , 버퍼 8kb다안썼는데 그냥 두면 낭비니깐
응답 헤더 비교
- MIME 설정안하고 보냈더니 응답 데이터에 charset이 없음
톰캣의 web.xml 뜯어보기
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
- 이게 있어서 그동안 톰캣이 WAS임에도 불구하고 정적요청을 처리할 수 있었던 것
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
- 이 부분이 없으면 톰캣은 JSP컨테이너가 될 수 없음
- 이 부분을 통해 JSP파일을 컴파일할 수 있는 것임
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspx</url-pattern>
</servlet-mapping>
<mime-mapping>
<extension>123</extension>
<mime-type>application/vnd.lotus-1-2-3</mime-type>
</mime-mapping>
<mime-mapping>
<extension>3dml</extension>
<mime-type>text/vnd.in3d.3dml</mime-type>
</mime-mapping>
- 603라인부터 mime타입이 매핑되어있음 = 마임타입 데이터베이스
- hwp같은 커스텀파일은 따로 매핑해줘야함.
기타
reloadable
- 코드 수정시 classes 밑에 있는 애들이 수정되면 reloadable 설정때문에 reload가 되는데 100프로되는건 아니다
String vs. StringBuffer / String Builder
JVM과 연관된 설명
- 상수풀
- 상수, 바뀌지않는값들
- 가비지 컬렉션 불가 = 메모리 회수가 안됨
- String += (concat) 로 하면 상수풀로 들어감
- 힙메모리
- 객체, 메서드를 통해 상태 변경가능한 애들
- StringBuilder의 append 메서드를 이용해 문자열 추가
- 힙메모리영역에 객체 생성했다가 더이상 그 객체가 필요없으면 가비지컬렉션 가능
템플릿 메서드 패턴
과제
- 디자인패턴 공부: 각 패턴을 이용한 코드 예제 공부
- ibatis의 소스코드 인터넷 조사
- queryForList, queryForObject 등의 메서드의 소스가 템플릿메서드패턴인 것을 분석
- 정규표현식 patterns.api 미리 선행학습...
- 중프때 만든 servlet, jsp 동작구조를 다시한번 보도록
- 다음주 월요일에 템플릿을 수업때 완성하면 jsp의 동작원리를 잘 볼수있을 것이다!