템플릿클래스 - 콘크리트클래스
템플릿메서드: 작업의 순서만 정의하고있을뿐 실제 작업은 후크메서드에서 구체화
지난 금요일
- 목표
- d:/contents 디렉토리에 존재하는 이미지들의 목록을 클라이언트에게 보여준 후, 클라이언트가 하나를 선택하면 해당이미지를 스트리밍하는 UI를 만들자
- 문제점
- UI를 만들기위해서는 html사용해야함
- 하지만 서블릿스펙만 사용한다면?
- java코드 안에 html, css, js 등 여러 코드가 섞이게됨 -> 서블릿 스펙의 문제점
- 해결방안
- 템플릿 구조를 사용해 책임을 분리하자!
- jsp 스펙과 유사함
방식
- .tmpl 확장자 파일을 만들고 치환될 데이터 부분을 %% 로 구멍을 뚫자
- 구멍이 뚫려있다는것은 완전한 형태의 ui가 아니라는것
- 완전하게 하려면 실제 데이터가 구멍에 치환되어야함
- '누군가'가 치환이된 완전한 소스를 응답데이터로 내보내야함
- 만약 이런 tmpl파일을 여러개 만든다면? 매번 비슷한 작업이 수행될 것
템플릿 메서드 적용
- 순서
- 1) 파일읽어들인다
- 2) %구멍%을 데이터로 치환하여 완전한 형태로 만듬
- 3) 응답데이터 송출
- 읽어들이고 내보내는건 같지만 데이터 치환하는 것이 다름 (데이터 형태 등등)
- 이것이 바로 템플릿메서드패턴
예제
imagelist.tmpl
- tmpl 소스에 변경(ex: onchange())이 있어도
- 재컴파일 필요 X
- 서버리스타트 필요 X
- => jsp의 장점들
UseTemplateServlet.java (템플릿클래스)
- 이 템플릿 메서드만 있다면 다른 개발자는 콘크리트클래스에서 후크메서드만 잘 만들면됨
- 이 것의 콘크리트클래스: ImageListServlet.java
Template Method: service
- 순서
- MIME셋팅
- 데이터맵
- 데이터치환
- 응답데이터송출
Hook Method: mime, getDataMap
ImageListServlet.java
util
templateutil.java
imagelist.tmpl에서만 쓸 수 있는 메서드
public static String replaceTemplateToData
(HttpServletRequest request, Map<String, Object> dataMap)
throws IOException {
String template = readTemplate(request);
String html = template.replace("%title%", (String) dataMap.get("title"));
html = html.replace("%optionData%", dataMap.get("optionData").toString());
return html;
}
정규식을 이용해 같은 형식의 tmpl 모두에서 쓸 수 있는 메서드
- %% 부분을 정규식으로 바꾸자
- 벨로시티, 타임마커, 어쩌구? 템플릿엔진을 실무에서 만날수도 있다
static Pattern pattern = Pattern.compile("%([a-zA-Z0-9_]+)%");
public static String replaceTemplateToData
(HttpServletRequest request, Map<String, Object> dataMap)
throws IOException {
String template = readTemplate(request);
Matcher matcher = pattern.matcher(template);
StringBuffer html = new StringBuffer();
while(matcher.find()) {
String dataname = matcher.group(1);
Object data = dataMap.get(dataname);
String value = Objects.toString(data, "");
matcher.appendReplacement(html, value);
}
matcher.appendTail(html);
return html.toString();
}
오늘 수업
- tmpl에 js넣기
- 파라미터 null처리하기
- 선택된 이미지 파라미터 받아서 원래 화면에 보여주기
클라이언트사이드 모듈 vs. 서버사이드 모듈
- 차이점: 실행시점의차이, 실행위치의 차이
- %title%라는 서버사이드모듈을 클라이언트사이드에서 쓸수있을까?
- NO!!! 이미 데이터로 치환되어서 브라우저에 도착
- 나중에 흔히 하는 실수: jquery로 이벤트처리하다가 jsp변수써도되냐고 물어봄
- 클모듈 서버모듈은 섞어쓸수없다!! 이유도알아야한다!!
콜백함수, 콜백메서드
- 개발자가 명시적인 코드로 호출하는게 아니고 시스템 내부적으로 특정이벤트가 발생됐을때 자동으로 호출되는 메서드(함수)
서블릿의 콜백메서드 종류
lifecycle callback (singleton): init, destroy
- 어플리케이션 전체를 통틀어 한번만 실행됨
- singleton: 서블릿 인스턴스가 하나로만 운영됨
request callback: service, doXXX
- 템플릿 메서드처럼 동착
- 1) service
- 단계적으로 동작한다.
- -> 어떤 request method를 호출할 지 판단 (get? post?...etc)
- -> 식별된 결과에따라 do[MethodName] 콜백을 호출하여 요청 처리 위임.
- 2) doXXX
- request method에 따라 처리될 구체적인 작업을 정의
리팩토링
디자인 패턴: MVC + 모델2
- java코드 | tmpl == mvc패턴+모델2구조
- 나중에 tmpl파일을 jsp로 바꾸면 spring mvc랑 존똑
MVC패턴
- Model: getDataMap()에서 만들어진 map
- View: tmpl
- Controller: imagelistservlet
모델2
- 클라이언트에게 요청이들어왔을 때, 요청과 응답에 대한 처리가 분리되어있는 구조
- 요청에 대한 처리(view=tmpl파일)
- 응답에 대한 처리(서블릿단)
자원의 종류와 주소 경로 체계
자원의 종류
File System Resource
- 파일시스템 절대 경로(drive)를 통해 접근
ClassPath Resource
- classpath 이후의 절대 경로(=qualified name)를 통해 접근
Web Resource
웹리소스 식별(identify) 방법
- 웹상에서 자원을 식별하기위한 모든 방법
- 자원을 식별하기 위한 방법의 포괄적인 개념
URL(Locator)
- 자원의 위치를 기준으로 식별
- protocol://IP[domainname]:port/depth.../name
URN(Name)
- 자원의 명칭을 기준으로 식별
- 문제점
- 1) 어딘가에 이름이 등록되어야만 쓸 수 있음(리소스 부하 야기)
- 2) 중복
URC(Content)
- 자원의 속성을 기준으로 식별
- ex. 도서 검색시 [출판사, 작가, 분류...]로 검색
- -> 결과가 다수로 나옴 = 식별성 자체가 의미가 없음
주소경로체계
- ★ 주소가 어느측면에서 사용될지를 생각하여 기술한다 ★
- key, value
- /imageView.do (서버가 사용하는 주소)
- 사용자가 이 주소치면 매핑된거에서 톰캣이 찾아서 요청처리 서버사이드주소
- img src=/webStudy01/images/cat1.jpg
- 저기로 요청날려서 받은 이진데이터를 그림으로 그리는게 브라우저(클라이언트)가 할일, 클라이언트사이드 주소
절대경로: 시작점부터 끝까지 다
- protocol://IP[domainname]:port/depth.../name
- 클라이언트 사이드
- 반드시 context root 부터 경로 기술
- 절대경로1: 개발시에는 localhost여도 되지만 배포후에는 바뀌기때문에 하드코딩NO
<img src="http://localhost/webStudy01/images/cat7.png" />
- 절대경로2: 브라우저가 이미 알고있는 주소는 생략 가능
<img src="/webStudy01/images/cat7.png" />
- 클라이언트사이드는 ip까지만 알고있기때문에 다써준다
- 배포가 이미됐기때문에 컨텍스트루트는 변동될일x
- 컨텍스트루트 반드시포함되어야함
<img src="<%=request.getContextPath() %>/images/cat7.png" />
- 하드코딩 하지 않도록 request객체 이용
- 서버 사이드
- context root 이후의 경로를 기술
String url = "/images/cat1.jpg";
- 절대경로, 자원접근시 절대로 변하지 않는 원칙: 변경되지않는 경로만을 이용하여 식별한다 (webStudy01은 변경가능)
상대경로
- browser의 주소를 기준으로 상대 경로가 시작됨. 이걸 써도 절대경로로 바뀐다.
- 서버사이드에서는 상대경로 절대 쓰지 않는다.
- ex) ../depth/name
- 상대경로1: WebContent는 이클립스 내에서만 쓰는 것, 컨텍스트루트까지 올라가야함
<img src="../images/cat7.png">
- 표현식 사용못하는 경우 상대경로 사용해야함
숙제
gugudan.tmpl
- 후크메서드의 시그니쳐를 어떻게 바꿔야 완성될까?
- 템플릿이 좀 변경될것임
- 요청처리과정에서 클라이언트데이터는 절대 믿으면안된다고했지? 그니까 클라이언트 데이터 검증 신경써라
- 응답처리때 비정상, 정상처리 상태코드 잘 보내라
- 내일 보강시간에 git : 수업시간에 만든소스 github이용해서 공유하도록할것
기타
1.8부터 constant pool 도 g.c의 대상이되기떄문에 string concat 사용가능하지만 어떤 자바버전을 쓰는지 확신이없을때는 string buffer쓰자