JCF3 MCC

From JCFWiKi

Jump to: navigation, search

그림:check.gif

  • 산출물 : JCF3.0™ MCC 가이드
  • 작성자: 송희정
  • 작성일 : 2007/12/03
  • 버전 : 0.9
  • 개정이력 :

Copyright © 2007 Daewoo Information Systems Co., Ltd.

목차

[편집] 개요 및 아키텍쳐

  • 기존 웹기반 JCF 구조에서는 Struts2, Spring, iBatis의 구조가 일반적이며,화면 구성은 Taglib를 활용한 JSP화면으로 개발한다.
  • 리퀘스트에 대해 어떤 JSP를 결과화면으로 보여주기 위한 컨트롤을 하는 것이 Struts2의 ActionClass 이다.
  • ActionClass에서는 Struts-config 파일을 통해 JSP를 forward 하게 된다.

그림:StandardArc.jpg

  • 최근에는 Miplatform을 비롯한 X-internet이라 불리는 솔루션들을 많이 사용함에 따라, 화면 처리부분의 JSP를 대체하는 경우가 있다.
  • 이러한 솔루션은 다음과 같은 특징을 가진다.
    • 대부분 예전 형태와는 달리 화면에 뿌려줄 데이터를 XML을 이용하여 값을 전송한다.
    • 화면의 이동은 화면에 임베딩되어 있는 모듈에서 처리하므로, Action 에서는 크게 화면의 이동에 대해 신경쓰지 않는다.
    • 따라서 JSP 포워딩 등의 화면 전환은 Action 코드와 Struts-config 에 존재하지 않는다.
    • Action 클래스는 단지 화면으로부터의 요청을 받아 서비스 클래스를 통해 데이터의 전달은 주로 하게 된다.
    • 즉, Presentation tier의 역할을 일부 X-internet 솔루션이 하고 있는 모양이나, 사용자 세션의 처리나 보안과 같은 부분에서의 기능이 미약하므로

Action에서는 그러한 부분을 커버하도록 한다.

그림:UxArc.jpg

[편집] JCF Package 구조

  • 솔루션 종속적인 형태의 XML 데이터와 개발시 구현한 특정 JavaBean 모델간의 변환을 자유롭게 하기 위해

변환을 위한 모듈을 JCF에서 제공한다.

  • 현재는 3가지 솔루션에 대한 모듈을 제공하고 있으면 솔루션명은 아래와 같다.
    • Miplatform
    • TrustForm
    • Gauce
  • 이들은 jcf.web.ux 패키지 아래에 존재한다.
(jcf.ux 패키지 구조)
depth1 depth2 depth3 depth4
jcf web ux miplatform
trustform
gauce

그림:Overview of miplatform.jpg

[편집] 처리방식

showcase 예제코드에서 용어관리 모듈을 보도록 하자. 화면은 Miplatform으로 되어 있으며 이 화면의 script 부분을 보면 서버에 요청하기 위한 Transaction이 선언되어 있다. 화면과 서버사이에서 주고 받는 데이터의 이름은 DS_XXX라는 형태로 선언이 되어 있으며 이것이 데이터 핸들링시 부르기 위한 id 인 셈이다.

[편집] UI에서의 호출 스크립트

  • 그리드 저장
    • 그리드의 내용은 여러건이 각각 등록/수정/삭제 등의 status를 가진다.
    • Status는 따로 화면 구성시 처리하지 않아도 솔루션에서 자동으로 각 row의 status를 가지고 있으며 서버로 넘겨줄 것이다.
    • "ds_term=ds_term:u" 에서 앞의 ds_term은 서버로 넘겨주는 이름, 뒤의 ds_term은 현재 화면에서의 실제 DataSet이다.
    • 두번째 ds_term의 뒤에 있는  :u 는 변경된 데이터만 넘겨주겠다는 의미이다.
function menuSave()
{
	Transaction("SAVE", 
        "Common::term/saveTerms.action", 
	"ds_term=ds_term:u", 
	"", 
	"",
	"trancallback");
}
  • 리스트 조회
    • 서버에서 리스트(java.util.List) 형태의 값을 xml 기반의 DataSet으로 변환하여 전달할 것이다.
    • DataSet을 받기 위해 Transaction의 네번째 parameter에 ds_term으로 받는 것을 볼 수 있다.
function menuFind()
{
	Transaction( 
	"FIND", 
	"Common::term/findTerms.action", 
	"", 
	"ds_term=ds_term", 
	"", 
	"callback");
}

[편집] struts-config

  • 앞서 언급한 바와 같이 화면간의 이동자체를 주로 Miplatform에서 하게 되므로 struts는 단지 리퀘스트를 받았을 때

처리할 특정 메소드의 액션매핑만을 처리하게 된다.

	<package name="/term" extends="jcf-default" namespace="/term">
		<action name="findTerms" class="jcf.biz.term.action.TermAction" method="findTerms"/>
		<action name="saveTerms" class="jcf.biz.term.action.TermAction" method="saveTerms"/>
	</package>

[편집] Request

  • 그리드를 저장하는 경우로 이 때 각 row의 status별로 등록/수정/삭제의 분기는 Service에서 할 것이다.
  • 여기서는 단순하게 넘어온 DataSet을 List 형태의 모델로 변환하는 작업만을 하고 있다.
  • 리스트 변환을 위해 MiRequest로 넘어온 req에서 extractObjectList라는 메소드를 사용한다.
  • extractObjectList의 각 Parameter의 의미는 다음과 같다.
    • 첫번째 parameter는 리스트 내에 저장되는 각 row가 담길 모델 클래스 명이다.
    • 두번째 parameter는 화면에서 넘겨준 DataSet의 id이다.
	public void saveTerms() {
MiRequest req = new MiRequest(getRequest());
List terms = null;
terms= req.extractObjectList(Term.class.getCanonicalName(), "ds_term");
termService.saveTerms(terms);

MiResponse res = new MiResponse(getResponse()); res.success();

}

[편집] Response

  • 화면으로 값을 넘겨주기 위해 다시 MiResponse 형태에 담아서 보내야 한다.
  • 먼저 HashMap 형태의 Map에 DataSet의 id를 키로 하여 넘겨줄 값을 담도록 한다.
  • 한 번에 여러 개의 DataSet을 넘겨줄 수 있으므로 Map에 넘겨줄 모든 DataSet을 put하도록 한다.
    • 이 때 주의할 점은 여기서 넘겨주는 id 명과 화면에서 transaction으로 받는 DataSet명이 같아야 한다.
	public void findTerms(){
		List terms = null;
		terms = termService.findTerms();		
HashMap dataSetMap = new HashMap();
dataSetMap.put("ds_term", terms);
MiResponse res = new MiResponse(getResponse());
res.send(dataSetMap);
}

[편집] 참고 : Service에서의 분기

  • Grid로 넘어온 여러 건의 row에 대해 각 row의 등록/수정/삭제 여부는 Action에서 체크하지 않고 서비스 클래스에서 하도록 한다.
  • status에 담겨있는 status를 보고 dao의 메소드를 달리 부르도록 한다.
	public void saveTerms(List terms) {
		Term term = null;		
		for (int i = 0; i < terms.size(); i++) {
			term = (Term) terms.get(i);
if("insert".equalsIgnoreCase(term.getRowStatus())) termDao.insertTerm(term);
else if("update".equalsIgnoreCase(term.getRowStatus())) termDao.updateTerm(term);
else if("delete".equalsIgnoreCase(term.getRowStatus())) termDao.deleteTerm(term.getTermNo());
else throw new BusinessException("Row Status" + term.getRowStatus() + " is not appropriate.");

}

}