Programming/JAVA2011. 8. 16. 00:22

JAVA 프로그래밍을 하기 위해서는 JAVA SE가 설치되어 있어야 한다.

JDK 파일 다운로드

http://java.sun.com/의 Downloads에서 원하는 버전의 JAVA SE를 다운받는다.

Latest Releases가 선택되어 있기 때문에 JDK 버튼을 누르면 최신버전의 JDK를 다운로드 할 수 있다.

Previous Releases를 선택하면 당연히 예전 버전의 JDK를 다운로드 할 수 있다.

자신의 OS와 License에 동의하는 체크를 하고 Download 버튼을 누른다.

* JDK를 설치하는 방법은 2가지가 있다.

Zip파일을 다운받아 압축을 풀어 원하는 위치에 파일을 놓는 방법과 exe파일을 다운받아 설치하는 방법이 있다.

편한대로 사용하면 된다. 나는 exe파일로 기본 설치경로인 C:\Program Files\Java\jdk1.6.0_13 에 설치.

* JDK 1.6_13 을 설치했더니 eclipse.ini 파일을 수정해도

Eclipse-jee-ganymede-SR2 에서 자꾸 heap memory가 부족하다는 error가 발생해서 JDK 1.5_22로 다시 설치.

JDK 1.5_22 Download Click

JDK 환경변수 설

* WinXP 기준

내컴퓨터 아이콘 위에서 마우스 오른쪽 버튼을 클릭해 속성을 선택.

고급 탭으로 들어가 환경 변수 버튼을 클릭.

나타난 환경 변수 창에서 사용자 변수 쪽에서 새로 만들기 버튼을 클릭해 환경 변수를 설정.

시스템 변수로 만들기도 하는데, 컴퓨터 사용자가 JDK를 설치하는 본인 계정 밖에 없다면 사용자 변수로 JAVA_HOME을 만들어도 무방.

환경 변수 이름

JAVA_HOME

C:\Program Files\Java\jdk1.6.0_13

PATH

C:\Program Files\Java\jdk1.6.0_13\bin; (기존 값에 추가)

CLASSPATH

.;%JAVA_HOME%\lib\tools.jar; (기존 값에 추가)

* 주의사항

  • C:Program FilesJavajdk1.6.0_13 는 내가 JDK를 설치한 경로이다. 다른 곳에 설치했으면 그 경로가 JAVA_HOME
  • PATH의 값 뒤에는 세미콜론(;)을 꼭 붙여야 한다.
  • CLASSPATH에 원래 지정된 값이 있다면 ex) C:Document and Settings;가 끝이라면 바로 뒤에 %JAVA_HOME%lib\tools.jar;를 붙이면 된다.
  • JAVA_HOME은 위에서 첫번째로 만든 JAVA_HOME 경로를 의미.

환경변수를 설정했으면 확인 버튼을 눌러 환경변수 창을 빠져나오고, 내 컴퓨터의 속성창에서 확인, 적용 버튼을 클릭해야

편집한 환경변수가 적용된다.

* JAVA EE 프로그래밍(JSP 사용)을 하려면

  • JRE_HOME이란 이름, C:\Program Files\Java\jdk1.6.0_13\jre 이란 JRE가 설치된 경로 값을 가진 환경변수를 추가.

JDK 설치 확인

시작 메뉴 > 실행을 누르고 cmd라고 쓴 다음 Enter 키를 누르면

위와 같은 MS Dos 창이 뜬다.

여기에 java -version이라는 명령어를 입력했을 때 설치한 JDK 버전이 나오면 JDK가 제대로 설치된 것이다.

그렇지 않다면!

제어판 > 프로그램 추가 삭제에서 설치한 JDK를 삭제하고 재부팅 한 다음 다시 JDK를 설치해야 한다.

출처 : http://blog.naver.com/ecarooce?Redirect=Log&logNo=140108643464 

Posted by 신의물방울
Programming/JAVA2011. 8. 6. 16:53
제가 알기로 String은 클래스이기때문에.. int로 명시적 다운캐스팅이 불가능합니다..

int a = (int)args[0]; 이 문장은 아마 안돌아갈듯 싶네요..

main의 매개변수로 스트링형 배열(String[] args) 말고 int형으로는 못받구요..

String을 int로 변환하려면 Integer 클래스의 parseInt 메서드를 사용하시면 됩니다..

예를 들어
public class ToInt{
public static void main(String args[]){
int a = Integer.parseInt(args[0]);
System.out.println(a);
}
}
하시면 원하시는 결과가 나오겠네요.
Posted by 신의물방울
Programming/Database2011. 8. 3. 15:30

http://blog.naver.com/donoteat84?Redirect=Log&logNo=20068381273

백업 복구 모두

 

실행  - cmd

 

 

창에서 exp  userid=  백업받을 계정 / 패스워드 file= 원하는 파일명.dmp

 

 

빨간 부분만 알아서 고치면 됩니다

 

백업하고 나면 파일이 생성되는데 파일 생성시 경로지정도 가능합니다

 

 

 

복구

 

역시 실행 - cmd  창에서

 

imp system/1111 fromuser=백업했던 계정 touser=테이블 복원할 계정 file=아까 그 덤프파일 .dmp

 

 

이렇게 빨간색부분만 본인이 원하는대로 복구하면 복구가 완료된다

 

 

 

 

 

* 백업(덤프 받기)
exp userid=계정명/패스워드 file=덤프파일명.dmp


* 복원
1.시스템 계정 사용시
imp system/시스템패스워드 fromuser=백업했던계정명 touser=복원할계정명 file=덤프파일명.dmp

2.일반 계정 사용시
imp 계정명/패스워드 file=덤프파일명


* 오라클 기본 설치시 TNS파일 위치
D:\oracle\ora92\network\admin\tnsnames.ora


(예제)

- cbs계정의 reserve_cbm, ch_info 테이블 백업하기
  exp userid=cbs/cbsora file='reserve_cbm.dmp' tables=(reserve_cbm, ch_info)

- 백업한 테이블 모두 복원하기
  imp userid=cbs/cbsora file='reserve_cbm.dmp' full=y

- 백업한 테이블 중 ch_info 테이블만 복원하기
  imp userid=cbs/cbsora file='reserve_cbm.dmp' tables=(ch_info)
 

- cbs계정소유 전체를 백업하기
  exp userid=cbs/cbsora file='cbs.dmp'

- 복원하기
  imp userid=cbs/cbsora file='cbs.dmp' full=y 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

행여나.. DB가 안되고 있다면;;

 

[Message]

Oracle.DataAccess.Client.OracleException

ORA-12528: TNS:리스너: 모든 해당 인스턴스가 새 접속을 차단하고 있음 

 

오라클이 가동중 혹은 다운 중(Pending) 인 경우 발생한다.

 

서비스 목록에는 시작됨으로 나오나 실제 접속하면

ORA-01033: ORACLE initialization or shutdown in progress

 

에러가 발생함을 볼 수 있었다.

 

해결 방법..

오라클 서비스를 재가동 시키면 정상적으로 수행된다.

Posted by 신의물방울
Programming2011. 8. 2. 04:15
http://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1040201&docId=72174333&qb=c3RydXRzMiBpbnRlcmNlcHRvci1yZWY=&enc=utf8&section=kin&rank=1&search_sort=0&spq=0&pid=gBkIEF5Y7v4ssuwanNRssc--328877&sid=Tjb6mnK-Nk4AACwFEj4
질문

struts2 <interceptor-ref name="prepare" /> 목적 내공30

ezpos1007 
2009.06.09 16:56
답변
 
1
 
조회
 
1,341

struts2 에서 <interceptor-ref name="prepare" />

                   <interceptor-ref name="modelDriven" />

                   <interceptor-ref name="params" />

 

이거 하는거랑

 

       public  TestAction extends ActionSupport implements Preparable , ModelDriven {

 

   public void prepare() throws Exception {

 

}

public member getModel()  {

 return mem ; 

}

public String execute() throws Exception{

return SUCCESS;

}

struts.xml 에서 <interceptor-ref> 를 설정 안해도 implements 에서 메소드가

있으먀 함으로 실행 되며 데이터도 이상없이 넘어 가던데요..

<interceptor-ref> 를 해야하는 이유를 알고 싶어요..

질문자 채택된 경우, 추가 답변 등록이 불가합니다.

질문자 채택

re: struts2 <interceptor-ref name="prepare" /> 목적

lmcshh1 
답변채택률 78.3%
 
2009.06.09 23:19

질문자 인사

정말 친절한 답변 감사드려요~ 감사 합니다.. 나중에 쪽지 보낼꼐요

<interceptor-ref> 이런걸 안써도 제대로 실행되어 집니다.

 

인터셉터는 struts2에서 자동적으로 처리가 되어집니가 결국은 갖다 쓰는것 밖에 안되는데..

 

인터셉터 개념을 먼저 잡으셔서 어떻게 돌아간다는걸 아시게 되면 

 

기본개념은 액션 단위의 작업을 수행할 때 기존 액션 처리 전과 후에 추가적인 작업을 지원하기 위한

 

방법이구요 인터셉터를 이용해서 훨씬더 나만의 방식으로

 

 

 

유연하게 프로그램을 작성하실수가 있습니다.

 

결론은..

 

<interceptor-ref name="prepare" />  1

<interceptor-ref name="modelDriven" /> 2

<interceptor-ref name="params" /> 3

 

이렇게 쓰면 실행되는 순서가 달라지게 됩니다.(아까설명드렸듯이 안써도 자동처리됩니다.)


<interceptor-ref name="prepare" />

는 Preparable 인터네시르를 구현하였다면  액션을 호출하기전에 실행되는 메소드이며 즉 초기화 작업을 많이 합니다.

<interceptor-ref name="modelDriven" />

는 ModelDriven 인터페이스를 구현하였다면 getModel()메소드의 반환 값을 밸류 스택에 넣는 역활입니다.

 

<interceptor-ref name="params" />

는 요청 파라미터를 액션에 저장하는 겁니다.

 

 

 

출처
 
직접 글 입력
lmcshh1 
초수
 
채택 46 (82.1%)
사진없음

입력된 URL이 없습니다.

입력된 자기 소개가 없습니다.

주요활동분야
Posted by 신의물방울
Programming2011. 7. 29. 12:14

이번엔 struts2의 s태그의 action이라는 속성을 이용하여 page include를 하여보자.

이건 뭐 생각보다 간단해서 설명을 해야 할까. 아니면 걍 소스만 올릴까 하다가 그래도 설명까지 해놓기로 한다.

일단은 struts2 + ibatis로 설정이 되어 있다는 가정하에 시작한다.

아! 이 전글인 s:url 과 sx:div를 읽어 보았다면 이 것은 뭐 누워서 껌뱉어서 다시 먹고 씹을 수 있는 그런게 아닐까 한다.

암튼 테스트방식은 db까지는 아니고 간단하게 본 페이지에서 action을 호출하여 뿌려지는 jsp 페이지를

include하는 형태의 테스트를 하겠다.

일단 testAction.java, actionLayout.jsp, actionTest.jsp 를 생성한다.

actionTest.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Action Test page</title>
</head>
<body>
<div style="background-color: silver">
actionLayout 페이지로 inlucde 되어질 페이지.<br/>
actionTest Action 호출 결과 값<br/>
<s:property value="test1" /><br/>
<s:property value="test2" />
</div>
</body>
</html>

여기는 별 내용없다. actionLayout.jsp 페이지에 include 되어질 페이지니까. 그냥 action에서 보낸 값만 뿌려는 페이지.

참고로 일단 div에 색을 입혀 놧다.

actionLayout.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Action Layout page</title>
</head>
<body>
actionTest 페이지를 호출하기 위한 페이지<br/><br/>

<div style="background-color: blue">
actionTest 호출
<s:action name="actionTest" executeResult="true" />
</div>
<br/>
<div style="background-color: yellow">
actionLayout Action 호출 결과 값 <br/>
<s:property value="layout1" /><br/>
<s:property value="layout2" />
</div>
</body>
</html>

여기서 s태그를 사용하기 위해서 빨간색 형광펜으로 된 것을 선언해준다.

그리고 빨간색 글씨가 s:action을 사용하는건데 name에는 호출할 action 명을 적어주면 된다.

여기서도 호출되어지는 부분을 div로 감싸서 색을 칠해줫다. 파란색으로.

왜 actionTest.jsp 랑 actionLayout에서 색을 칠하는 지는 아래에서 확인을 하자.

그리고 executeResult="true" 는 해당하는 action을 호출 후 result 되는 페이지를

이부분에 뿌려줄 것인가를 선택하는 것이다. true를 할경우 뿌리고 false로 하면 안뿌린다.

false를 하게 되면 action만 실행하게 되는 것이다.

testAction.java

public class testAction extends ActionSupport {
private String layout1;
private String layout2;
private String test1;
private String test2;

public testAction(){}

public String actionTest(){
test1 = "actionTest Action Method";
test2 = "TEST SUCCESS";

return SUCCESS;
}

public String actionLayout(){
layout1 = "actionLayout Action Method";
layout2 = "TEST SUCCESS";

return SUCCESS;
}



public String getLayout1() {
return layout1;
}
public void setLayout1(String layout1) {
this.layout1 = layout1;
}
public String getLayout2() {
return layout2;
}
public void setLayout2(String layout2) {
this.layout2 = layout2;
}
public String getTest1() {
return test1;
}
public void setTest1(String test1) {
this.test1 = test1;
}
public String getTest2() {
return test2;
}
public void setTest2(String test2) {
this.test2 = test2;
}
}

간단하게 jsp에서 action을 실행했을 경우 리턴값을 던져주는 형태이다.

뭐 실제로는 db까지 연동해서 원하는 값을 리턴해야겠지만.

테스트 형태이므로 간단하게~~

struts.xml 파일에 들어가는 result 코드는 생략하기로 한다.

워낙 간단하니까 욕먹을라.;;;ㅋㅋ

이렇게 하고 난후 실행을 시켜보자.

실행 url은 actioinLayout.action을 실행한다.

실행 화면은 다음과 같다.

여기서 보면 회색부분이 actionTest.action을 수행하고 들어 온 result 페이지이다.

result페이지는 아시다 싶이 actionTest.jsp.

원래 actionLayout.jsp에서 actionTest.action 호출하는 부분에 div로 파란색으로 감쌌는데.

actionTest.jsp에서 출력되는 곳을 회색으로 감쌌으므로 색은 당연히 회색으로 나오게 된다.

action을 수행 확인은 actionTest Action Method와 TEST SUCCESS 이다.

노란색 부분은 actionLayout.jsp에서 actionLayout.action 실행 확인차 해놓은 것임.

이로써 아주 간단한 s:action 에 대해서 알아보았다.

s:action 을 잘만 사용한다면 쉽게 쉽게 코딩을 할 수 있지 않을까 생각한다.

오늘은 시간이 없는 관계로 주절주절은 이만.ㅋㅋ;;;

그럼 다음엔 뭐 또 다른걸로 보자. ㅋㅋ

특별한 기능을 사용할때 다시 글을 쓰도록 하고~바이~

Posted by 신의물방울
Programming2011. 7. 29. 12:13

아~이건 쫌 나중에 올릴려고 했는데...시간이 남는 관계로 후딱 해치워 버려야겠다.

현재 Struts2 + ibatis를 이용하여 간단한 프로젝트를 진행중이다.

그러던 와중. DB의 값을 5초마다 불러와서 페이지에 뿌려줘야 하는 그런 상황이 발생하였다.

이걸 어떻게 할까.!-_ -+ 5초마다 action을 태워야 하는데. 그럴려고 하니 그 뿌려질 페이지가 include된 페이지 인데.

스크립트에서 인터발을 사용하여 5초마다 action을 돌리려고 하니. 전체 페이지가 리로드 되는 상황이 발생.ㅠ _ㅠ

즉. 현재의 상황이 어떻게 되었냐면...

이런것을 만들어야 하는데. 본 페이지가 있고, 본 페이지에서 게시판이 만들어 지고~

그 위에 다른 페이지를 include 시켜서 5초마다 뿌려줘야 하는 상황이다.

즉 본 페이지는 리로드가 없어야 하고, 불러와지는 저 부분만 계속 변화하해야 한다.

이때 문득 생각난것이 ajax 였으나. Struts2를 사용하는 나로써! Struts2의 기능을 사용하기로 결씸.-_ -v

Struts2에서 지원해주는 ajax를 이용하기로 맘 먹었다. 짝짝짝~ 개고생의 길이 열리기 시작함.;;;

무튼 이것 또한 struts2.0 과 struts2.1 의 차이가 있으니...이런 쉬벡.! 한 3일 고생...;;;

그 차이는 앞부분에서 설명한 것을 읽어보면 나름 차이를 느낄 수 있다고 생각하며

여기서 사용되어질 태그 및 속성은 s태그의 url 속성과 sx 태그의 div속성이다.

나중에 언급하겠지만 struts2.0대에서의 s:url, s:div를 이용하는 방법을 말하겠다. 이건 뭐 책에 있으니.;;;

일단은 struts2.1로 하는것.!!!!!

무튼 여기서도 lib를 점검을 해보자면 나는

struts2-core-2.1.8.1.jar

struts2-dojo-plugin-2.1.8.1.jar

를 사용한다. 또 이런거 보고 저거만 lib에 넣고 되니 안되니 하면 곤란하다.;;;

struts2 + ibaits 설정 관련해서 글 올린게 있으니 참고바람.

암튼 서론이 길었다. 코딩을 시작해보도록합시다.

여기서 테스트로 프로그램을 만들 것은 간단하게 하나의 jsp에서 다른 jsp를 ajax 형태로 불러와서

몇초간격으로 계속 호출(action 호출)하는 것을 만들어 보도록 하겠다. 어떻게 액션이 계속 실행이 되고 있느냐는

호출되어질 페이지에 date를 사용하여 시간이 변하는 것으로 확인이 가능하겠다.

일단 ajaxAction.java, ajaxLayout.jsp, ajaxTest.jsp 를 만든다.

ajaxLayout.jsp는 원래의 페이지이고, ajaxTest.jsp는 호출되어질 즉, include되어질 페이지이다.

ajaxLayout.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="sx" uri="/struts-dojo-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script language="javascript">

var controller = {
refresh : function() {},
start : function() {},
stop : function() {}
};

dojo.event.topic.registerPublisher("/refresh", controller, "refresh");
dojo.event.topic.registerPublisher("/startTimer", controller, "start");
dojo.event.topic.registerPublisher("/stopTimer", controller, "stop");

</script>
<sx:head parseContent="true" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>ajax page autoRefresh</title>
</head>
<body>
<s:form>
<div>
<table width="400" >
<tr>
<td align="center">
<s:url id="goAjaxTest" value="ajaxTest.action" />
<sx:div
id="divAjax"
href="%{#goAjaxTest}"
updateFreq="1000"
showLoadingText="false"
listenTopics="/refresh"
autoStart="true"
executeScripts="true"></sx:div>

</td>
</tr>
</table>
</div>

<div>
<table width="400" bgcolor="#999999">

<tr>
<td>ajaxLayout Jsp 페이지</td>
<td>에서 만들어지는 리스트</td>
</tr>
<tr>
<td><s:property value="layout1" /></td>
<td><s:property value="layout2" /></td>
</tr>
</table>
</div>
</s:form>
</body>
</html>

자 여기서 보자면 일단 빨간색 형광펜으로 해놓은 것 중에 sx 태그라이브러리 추가.

head에 뭐 이상한거 그게 ajax 즉, dojo를 이용하기 위해 설정해놓은 것이다.

s 태그라이브러리는 왜 추가했나요~라고 하는 사람은 당장 저기 오른쪽 상단 모서리에 있는 X를 눌러라.

글을 제대로 안읽으면 다음 부분을 읽을 필요도 없다. 암튼 앞에 언급했듯이 s:url을 쓰기 위해서다.-_ -+

그리고 빨간색 글자로 된 부분이 인클루드를 시키는 부분이다. 저 부분에 ajaxTest.jsp가 불러 와지는것이다.

그냥 jsp가 include되는 것이 아닌 action이 행해진 후 include가 되는 것이다.

<s:url id="goAjaxTest" value="ajaxTest.action" /> 은 id를 goAjaxTest 하고,

value는 액션의 값, 즉 실행되는 액션의 주소를 적는 부분이다. 저렇게 되어 있으면 struts.xml에 설정된 ajaxTest라는 액션을 실행한다.

그리고 밑에 sx:div 부분인데. 이게 원래 struts2.0 버전에서는 그냥 s:div로 되어 있단 말이지. 그렇게 된다면 head에 지금처럼

선언하는게 아닌 <s:head theme="ajax" />라고 선언해야 된다.

그리고 sx:div 태그에서 빠진 theme="ajax"라는 속성도 추가 해주어야 한다. 흠흠. 이건 struts2.0의 버전에서 하는 것이고

지금 우리는 2.1에서 하는 것이니 속성들을 살펴보도록 하자.

href="%{goAjaxTest}" 는 눈치 빠른 분들은 알겠지만 s:url에서의 id 값을 설정하게 되는 것이다.

그렇게 url값인 action을 호출하게 되는 것이다.

updateFreg 속성은 1/1000 초 단위로 1000을 설정하게 되면 1초마다 호출하겠다는 것이다.

showLoadingTest 는 ajax를 구동할때 시간 텀에 어떠한 텍스트를 보여준다. true로 한번 해보시라.;;;

listenTopics="/refresh" 이게 저기 위에 스크립트에 설정되어진 refresh함수를 호출해서 dojo 이벤트를 실행시키는 것이다.

autoStart="true" 당연히 true가 되어야 자동으로 돌아가겠지.

그리고 속성중에 indicator 이란게 있는데 이걸 <img src>로 이미지를 불러 놓고 id 를 설정해서

indicator="설정된 id" 를 해놓게 되면 그 왜 자주 보는거 있지 않나. 톱니바퀴 뱅그르르 돌아 가는거. 그게 실행이 된다.ㅋㅋ;;;

그리고 젤 중요한 이 씨발 속성.!-_ -+ executeScripts="true" 이게 되어 있어야 include 되는 페이지에서 script를 실행할 수 있다.

아놔. 이걸 몰라서 스크립트 실행 왜 안되냐고 졸라 썽냈네.;;; 아오.!!!!-_ -+ 정말 짜증나!ㅋㅋ

그리 밑에 div로 잡아 놓은 것은 ajaxLayout.action에서 들고오는 값들을 뿌리기 위해서 해놓은것.

저게 본페이지 액션을 호출하여 생성된 리스트다. 라고 생각하면 될듯.

ajaxTest.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>ajaxTest</title>
</head>
<script language="javascript">
function timer(){

var src = "<table border=0 width=400><tr>";
var color;
today=new Date();

y=today.getYear();
m=today.getMonth()+1;
d=today.getDate();

hh=today.getHours();
mmm=today.getMinutes();
ss=today.getSeconds();

if(ss % 2 == 0){
color = '#FFB6C1';
}
else{
color = '#40E0D0';
}

src += "<td align=center bgcolor=" + color + ">" + y + "년" + m + "월" + d + "일" + hh + ":"
+ mmm + ":" + ss + "</td>";
src +="</tr>";
src +="</table>";

document.getElementById('tb').innerHTML = src;

}
</script>

<body>
<script>timer();</script>
<div id="tb"></div>
<div><s:property value="test1"/>&nbsp; 오예 &nbsp; <s:property value="test2"/></div>
</body>
</html>

이 페이지는 역활은 ajaxTest.action을 타고 들어 오면 script를 바로 호출해서 시간을 뿌리는 형태이다.

그리고 s 태그라이브러리를 추가하여 ajaxTest.action 에서 값을 들고 오는 것을 뿌려준다. 하단에 <s:property value="test"/> 이부분.

그리고 스크립트를 바로 온로드 하기 위해서 <script>timer();</script> 이렇게 하였다. -_ -;;;

안다. body 부분에 onload="timer()" 로 안했나여~~ 왜 안했겠습니까? 안되니까.;;

안다. 그럼 script에서 window.onload = timer; 하면 되잖아여~ 왜 안했겠나. 안되니까.;;;

안다. 그럼 <body><script type="text/javascript"> window.onload = function(){ timer(); }; 로 하면 되잖아여~</script></body>

이런 씨발~! 안되잖아.!!!-_ -+ ㅎㅎㅎ 죄송..;;;

무튼 저렇게 스크립트로 작성된 것이 <div id="tb"> 라는 곳에 담겨서 시계가 출력이 되게 된다.

지금 ajaxLayout.jsp와 ajaxTest.jsp가 이렇게 되어 있다면 1초마다 ajaxTest.action을 호출 하게 될 것이고

include 된 페이지에서 시계가 출력되며 시계바탕 색이 계속 바뀌게 될 것이다.

ajaxAction.java

package sample;

import com.opensymphony.xwork2.ActionSupport;

public class ajaxAction extends ActionSupport {
private String layout1;
private String layout2;
private String test1;
private String test2;

public ajaxAction(){}

public String ajaxLayout(){
layout1 = "ajaxLayout Action Method";
layout2 = "TEST SUCCESS";

return SUCCESS;
}
public String ajaxTest(){
test1 = "ajaxTest Action Method";
test2 = "TEST SUCCESS";

return SUCCESS;
}


public String getLayout1() {
return layout1;
}
public void setLayout1(String layout1) {
this.layout1 = layout1;
}
public String getLayout2() {
return layout2;
}
public void setLayout2(String layout2) {
this.layout2 = layout2;
}
public String getTest1() {
return test1;
}
public void setTest1(String test1) {
this.test1 = test1;
}
public String getTest2() {
return test2;
}
public void setTest2(String test2) {
this.test2 = test2;
}
}

뭐 여기서는 특별한 것은 없고 각 액션 호출 했을때마다 값을 넘겨주는 것이랄까.

현재 기본은 이렇지만 이 액션 메소드들에서 많은 작업이 이루어 질 것이다.

DB값을 5초마다 뿌려줄려면 ajaxTest 메소드에서 DB값을 들고 오는 로직을 작성해야겟지.

뭐 기분으로 struts.xml 도 함 올리준다.

struts.xml

<action name="ajaxLayout" class="sample.ajaxAction" method="ajaxLayout">
<result>/sample/ajaxLayout.jsp</result>
</action>
<action name="ajaxTest" class="sample.ajaxAction" method="ajaxTest">
<result>/sample/ajaxTest.jsp</result>
</action>

action name이나 method는 같겠지만 class나 result 같은 값은 자기 속성에 잘 맞추도록.

아무튼 이렇게 그냥 jsp include가 아닌 액션이 이루어진 jsp를 include 하는 시간을 가져보았다.

이걸 좀더 유도리 있게 사용하게 되면 아주 괜찮은 프로그램이 나오지 않을까 생각한다.

예를 들면 10초 단위로 판매량이 DB에 값이 들어 온다고 치면

refresh를 30초 또는 1분으로 DB에서 판매량을 카운트해서 실시간 판매량을 보여준다던지.

딱 고부분만 변하게 되는 것이니까 웹페이지 자체가 리로딩 될 필요도 없고. 아주 멋지고 깔끔한게 탄생하지 않을까.ㅋ

음. 예제를 실행하기 전에 ajaxTest.jsp 페이지에서 <body onload="timer()">를 추가해주도록 하자.

원래는 액션을 어떤것을 호출해야 할까? 당연히 원래는 ajaxLayout.action을 실행하여야 한다.

하지만 ajaxTest라는 놈이 어떻게 생겼는가...확인 하기 위해서 일단은 ajaxTest.jsp 및 ajaxTest.action을 호출 하여 보자.

ajaxTest.jsp 실행 화면

이렇게 액션을 수행하지 않은 모습을 알 수 있다. 뭘로? s:property value="test1" "test2"의 값이 보이지 않으니까.

ajaxTest.action 실행 화면

성공적으로 action을 수행하였다. 저 보이는 값들.

그리고 이제 진짜 실행해야 할 것. ajaxLayout.jsp 와 ajaxLayout.action을 실행해보자.

jsp로 실행을 하던, action으로 실행을 하던 상단에 include되어 시계가 나올것이다.

왜냐. jsp를 호출하던 action으로 호출을 하던 ajaxLayout.jsp에 코딩되어진 s:url과 sx:div는 유지 되고 있기때문에

계속 ajaxTest.action을 호출을 하고 있기 때문이다.

다만 다른 것은 아래 회색의 텍스트 중에 .jsp로 실행을 하였을때는 ajaxLayout Action Method TEST SUCCESS가

보이지 않을 것이다. 이로써 action을 거치지 않고 그냥 jsp를 호출 했다는 것을 알 수 있다.

아래의 그림은 ajaxLayout.action을 실행한 최종 결과의 모습이다.

이미지의 시간은 다르지만. 실제 1초마다 분홍색과 초록색으로 색이 바뀌고 초시계도 1초단위로 변화하고 있을 것이다.

뭐 이 예제는 간결한 코딩으로 이루어져 있기때문에 1초마다의 변화가 눈에 보이겠지만 action단이나 serviceImple단, DB작업이

많은 경우에는 속도는 어느정도 느려질꺼라는 예상은 해야 할듯. 뭐 나는 참고로 DB 두번 돌리고 여러작업을 했는데 1초 단위로

작업 잘 되더라.ㅋ 그래도 혹여나 몰라서 5초단위로 바꿨지만.;;;

지금까지 struts2의 각 s:url 태그 및 sx:div 태그를 이용해서 자동 refresh 되는 것을 해보았다.

여러 속성들. 그리고 예상치 못한 일들이 많았지만 위 처럼하면 무리 없이 예제정도는 할 수 있으리라 생각한다.

정작 한건 별로 없는데 글만 디게 길어 졌구만.ㅋㅋ

이 글의 요는!!! 자동 refresh 기능도 struts2에서 지원한다.!

그리고 2.1과 2.0의 버전에서는 좀 다르게 사용해야 한다. 고정도만 알면 뭐 다 안거랑 마찬가지란 말.

그럼 수고하였소.!!!

다음엔 s:action에 대해서 알아보도록 합시다. 이것도 뭐 이번 예제인 include 하는 비슷한 상황인데.

사용법도 틀리고 사용하는 상황에서도 틀리니. 담에 기회되면 글을 남겨보도록 하겠소.

Posted by 신의물방울
Programming2011. 7. 29. 12:12

Struts2 + ibatis 연동을 하는 방법에 알아보도록 하자.

요즘 많이 사용하는 방법으로는 Struts2 + Spring2 + ibatis 를 이용을 하는 경우가 많다.

하지만 난..;;; Struts2 + ibatis에서 spring에서 필요한 부분만 빼와서 사용하거나

Spring2.5 + ibatis에서 Struts에서 필요한 부분만 사용했다.

아직 저렇게 3개를 연동하여 사용해본적이 없으므로 일단 위에것만 해보도록 하자.;;;

무튼 일단 필요한 lib 부터 챙기도록 하자. 필자가 말하는 lib는 꼭 필요한 lib이므로 하나라도 빼먹으면 아니된다.

참고로 난 어제 commons-pool.jar 이거 넣었는지 알고 빼먹었다가 2시간 캐삽질했다.

- Struts2 관련 lib

commons-fileupload.jar
commons-io.jar
freemarker.jar
ognl.jar
struts2-core.jar
xwork.jar

- ibatis 및 DB, odbc, pool dbcp 등 기타 lib

commons-dbcp.jar
commons-logging.jar
commons-pool.jar
ibatis-commons.jar
ibatis-dao.jar
ibatis-sqlmap.jar

다운 받았는가?

(* 참고 - eclipse에서 Dynamic Web Project를 생성하여 작업을 진행하고 있다.)

일단 다운 받은 lib들을 WebContent/WEB-INF/lib 폴더안에 싸그리 몽땅 넣어 버리자. ㅎㅎㅎ;;;

일단 Struts2 관련 한 것들 부터 천천히 차근차근히 해보도록 하자.

WEB-INF/Web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>Struts2_sample</display-name>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>

이 파일에서 struts2를 기동시키기 위한 자동필터 작업이 이루어지게 된다.

원래 저기 url parttern에 보면 struts1에서는 /*do 였나? 암튼 jsp.do 이런식으로 struts를 기동시켰다면

struts2에서는 jsp.action으로 기동을 시킨다.

src/struts.properties 파일 생성 및 작성

struts.i18n.reload=true
struts.devMode=false
struts.configuration.xml.reload=true
struts.continuations.package = org.apache.struts2.showcase
struts.custom.i18n.resources=globalMessages
struts.url.http.port = 8080
struts.serve.static=true
struts.serve.static.browserCache=false
struts.multipart.maxSize=10000000000

저기 위에 보면 devMode라고 있는데 false라고 꼭 해야 한다.

true라고 하니까 에러도 이상한 에러 뱉어내고 짜증난다.-_ -++

src/struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="sample" extends="struts-default">
<action name="sample" class="sample.sampleAction" method="sample_test">
<result>/sample/sample.jsp</result>
</action>
</package>
</struts>

음~여기서 jsp와 action 클래스와의 연동을 시켜주는 부분인데. 대충 설명을 하자고 하면 sample이라는 pakage에 있는

sampleAction이라는 클래스를 불러와서 그 안에 있는 sample_test라는 메소드를 참조 하겠다는 말이다.

그 결과는 어디로 주느냐!?!? result라고 되어 있는 sample폴더의 sample.jsp에 던져주겠다.라고 되어 있다. 그리고

action name. 이 부분이 이제 실제 url에서 구동시키는 부분이다. 여기서는 sample이라고 되어 있으니까 예를 들어

http://localhost:8080/sample(프로젝트명)/sample(jsp폴더명)/sample.action 이라고 하면 딱 된다는 말이지.

만약에 action name이 test였다면 당연히 test.action으로 해주어야 한다.!

그럼 일단 struts2 설정이 잘 되었나 확인을 해보도록 하자.

WebContent/sample/sample.jsp 생성 및 작성

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>sample page</title>
</head>
<body>
hello sample <s:property value="test"/>
</body>
</html>

저기 taglib 보이는가. 저게 스트럿츠 태그를 사용하도록 지정을 하는것이다.

그리고 action에서 얻어온 값을 <s:property value="test"/> 이런식으로 뱉어내게 된다.

근데 값에 왜 test가 들어 갔냐고? 아래 파일을 작성하다보면 쉬이 이해가 되리라.

src/sample/sampleAction.java

package sample;
import java.util.List;
import com.opensymphony.xwork2.ActionSupport;

public class sampleAction extends ActionSupport {

private String test;
public String sample_test() throws Exception{
test = "Good Struts2";
return SUCCESS;
}
public String getTest() { return test; }
public void setTest(String test) { this.test = test; }
}

저기 보면 ActionSupport를 상속받아서 스트럿츠2를 사용하게 될 수 있게 되었다.

그 결과를 보면 return SUCCESS 이 구절이 에러가 안나게 되는것이지.

test를 하나 만들어서 거기 Good Struts2라고 저장을 하자. 그리고 get set를 해서 던진다.

던질때의 내부 struts2 로직은 어떻게 되는지는 잘 모르나 저렇게 하면 넘어 간단다. 뭐 이정도만 알면 되는거 아이가.!ㅎㅎㅎ

음~요까지 했으면 일단 jsp로 접속을 하자. 우리가 만든 jsp는 sample 프로젝트의 sample 폴더에 sample.jsp이다.

아. sample이 너무 많이 겹치네. 암튼. http://localhost:8080/sample/sample/sample.jsp 에 접속을 하면

sample page의 타이틀에 hello sample 이라는 바디가 출력이 될것이다.

이제 struts2가 잘 되엇는지 확인한다. http://localhost:8080/sample/sample/sample.action 에 접속을 하게 되면

타이틀은 같을 것이고. hello sample Good Struts2 가 바디에 출력이 될 것이다.

struts2 성공! ㅋㅋ 이렇게 하면 쉽게 구현을 할 수 있지만 나름 힘든점이 많았다.

lib가 없어서 에러가 나고...struts.xml에 경로나 namespace같은 설정 때문에 어려움이 따랏다. 짜증나게.

무튼 이렇게 한번 하고 나니 쉽게 생각이 드는데 처음 하는 사람들은 나름 짜증 날 수도 있다.

설정 가르쳐 주는건 많은데 파일을 어느 경로에 생성해야 하고 그런걸 모르니까. 짜증이 나지. 암튼

다음 번에 ibatis를 연동하는 것으로 돌아 오겟다.

to be continue...

이 전페이지에서는 struts2를 설정을 해보았다면

여기서는 설정해 놓은 struts2에 ibatis를 연동을 한다.

일단 ibatis를 사용하면 dao라는 것도 사용하고 sqlmap, sqlmapconfig 뭐 등등 사용을 한다.

나름 복잡한듯보이지만 나중에 되면 엄청 간편하고 간결하게 코딩이 되어 진다.

암튼 잡소리 다 집어 치우고 바로 돌입한다.

이 전페이지에서 했던 것에 바로 하는 것이니 참고 하기 바람.

src/sample/dao.xml 파일 생성 및 작성

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE daoConfig
PUBLIC "-//iBATIS.com//DTD DAO Configuration 2.0//EN"
"http://www.ibatis.com/dtd/dao-2.dtd">

<daoConfig>
<context>
<transactionManager type="SQLMAP">
<property name="SqlMapConfigResource" value="sample/sql-map-config.xml"/>
</transactionManager>

<dao interface="sample.sampleDao" implementation="sample.sampleDaoImpl"/>
</context>
</daoConfig>

요기서 sqmlmapconfig를 참조함과 동시에 Dao를 각 클래스마다 잡아준다.

죠기 보이지~dao interface.... 등등. 저기서.

지금은 없지만 차차 Dao와 DaoImpl 파일을 만들게 될 것이다.

src/sample/sql-map-config.xml 파일 생성 및 작성

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN" "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<settings
cacheModelsEnabled="true"
enhancementEnabled="true"
lazyLoadingEnabled="true"
maxRequests="256"
maxSessions="64"
maxTransactions="16" />

<transactionManager type="JDBC">
<dataSource type="DBCP">
<property name="JDBC.Driver" value="oracle.jdbc.driver.OracleDriver"/>
<property name="JDBC.ConnectionURL" value="jdbc:oracle:thin:@localhost:orcl"/>
<property name="JDBC.Username" value="test"/>
<property name="JDBC.Password" value="test"/>
<property name="JDBC.DefaultAutoCommit" value="true"/>
<property name="Pool.MaximumActiveConnection" value="10"/>
<property name="Pool.MaximumIdleConnection" value="5"/>
<property name="Pool.MaximumCheckoutTime" value="120000"/>
<property name="Pool.TimeToWait" value="500"/>
</dataSource>
</transactionManager>

또 다른 DB 연동 방법
<!-- <transactionManager type="JDBC" commitRequired="false">
<dataSource type="JNDI">
<property name="DataSource" value="jdbc/wsp"/>
</dataSource>
</transactionManager> -->

<!-- sample -->
<sqlMap resource="sample/sample.xml"/>
</sqlMapConfig>

여기서는 DB를 연동하는 것인디~뭐 저기서 보고 자기 DB설정 관련해서 착착 넣어주면 될듯하다.

그리고 마지막에 보면 sqlMap resource가 있는데 현재는 없지만 흔희 말하는 sqlmap을 만들게 되면 여기에 등록을

해놓아야 사용을 할 수 있다. ㅇㅋ??

src/sample/DaoConfig.java 파일 생성 및 작성

package sample;
import com.ibatis.common.resources.Resources;
import com.ibatis.dao.client.DaoManager;
import com.ibatis.dao.client.DaoManagerBuilder;
public class DaoConfig {
public static DaoManager getDaomanager(){
return daoManager;
}
private static final DaoManager daoManager;
static {
try{
String resource = "/sample/dao.xml";
java.io.Reader reader = Resources.getResourceAsReader(resource);
daoManager = DaoManagerBuilder.buildDaoManager(reader);
}catch(Exception e){
throw new RuntimeExㅂception("Could not initialize DaoConfig. Cause: " + e);
}
}
}

ibatis 설정 확인 및 Struts2 연동 테스트

순차적으로 Action >> Model >> Service >> SeriveImpl >> Dao >> DaoImpl >> sqlMap >> jsp 으로 작성을 진행한다.

src/sample/sampleAction.java 수정

package sample;

import java.util.List;
import com.opensymphony.xwork2.ActionSupport;
public class sampleAction extends ActionSupport {

private String test;
private List sampleList;
private sampleService ss;

public String sample_test() throws Exception{
test = "Good Struts2";
ss = new sampleServiceImpl();
sampleModel sm = new sampleModel();
sampleList = ss.sample_test(sm);

return SUCCESS;
}

public String getTest() {
return test;
}
public void setTest(String test) {
this.test = test;
}
public List getSampleList() {
return sampleList;
}
public void setSampleList(List sampleList) {
this.sampleList = sampleList;
}
}

Action에서 서비스를 호출하고 model에 정의해놓은 값들을 이용한다.

src/sample/sampleModel.java 생성 및 작성

package sample;

public class sampleModel {
private String test1;
private String test2;

public String getTest1() {
return test1;
}
public void setTest1(String test1) {
this.test1 = test1;
}
public String getTest2() {
return test2;
}
public void setTest2(String test2) {
this.test2 = test2;
}
}

여기서는 모델 클래스에서는 실제 DB의 걸럼 명들과 같게 만들어 준다. 여기가 spring에서 보면 DTO라는 곳과 같은 곳이다.

나중에 sqlmap에서 result 또는 param으로 이것을 사용하기 때문이다.

src/sample/sampleService.java

package sample;

import java.util.List;
public interface sampleService {
public List sample_test(sampleModel sm);
}

service interface부분. 뭐 이렇다.ㅋㅋ

src/sample/sampleServiceImpl.java

package sample;

import java.util.List;
import com.ibatis.dao.client.DaoManager;

public class sampleServiceImpl implements sampleService{

private DaoManager daoManager;
public sampleServiceImpl() {
daoManager = DaoConfig.getDaomanager();
}

private sampleDao dao;
/** DAO를 설정한다. */
private sampleDao getDao() {
if(dao == null) {
dao = (sampleDao)daoManager.getDao(sampleDao.class);
}
return dao;
}

public List sample_test(sampleModel sm){
List list = getDao().sample_test(sm);
return list;
}
}

저기 위에 보면 daoManager를 이용하는게 보일것이다. 저게 아까 DaoConfig를 만든 이유라고나 할까.?

암튼 DaoManager를 이용하면 트랜잭션 처리가 훨씬 간편해진다. 그리고 Dao를 설정 후 Dao를 호출하는것.

src/sample/sampleDao.java

package sample;

import java.util.List;
import com.ibatis.dao.client.Dao;

public interface sampleDao extends Dao{
public List sample_test(sampleModel sm);
}

Dao interface 부분


src/sample/sampleDaoImpl.java

package sample;

import java.util.List;
import com.ibatis.dao.client.DaoManager;
import com.ibatis.dao.client.template.SqlMapDaoTemplate;

public class sampleDaoImpl extends SqlMapDaoTemplate implements sampleDao{

public sampleDaoImpl(DaoManager daoManager) {
super(daoManager);
}

public List sample_test(sampleModel sm) {
return ((List)queryForList("sample.getSample", sm));
}
}
실제로 Service에서 호출한 곳. 여기서 이제 DB. 음 그러니까 쿼리문 날리는 sqlmap을 호출한다.

간편하게 여기서는 일반적인 List형식의 queryForList를 사용한다. 이 부분은 나중에 보면 다른 여러가지가 있다.

그리고 뒤에 인자는 sqlmap 이름.

src/sample/sample.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="sample">
<typeAlias alias="sampleModel" type="sample.sampleModel"/>

<select id="sample.getSample" resultClass="sampleModel">
SELECT * FROM TEST
</select>
</sqlMap>

여기서 namesapce를 설정해주고. 이건 왠만하면 파일 이름으로 하는게 제일 좋다.

그리고 typeAlias 를 모델을 사용했는데 다른 사람들은 여기에 resultMap을 만들어서 resultMap에 DB에서 가져온 값을

저장해서 들고 가더라. 그런 2중 일은 피하도록 하기 위하여 바로.!!Model을 resultClass하여 사용한다.!

뭐 나중에 값을 들고 와서 where에서 이것저것 따질대 paramClass를 사용할 수 도 있지만 이때는 Model Class를 전체

들고 오는 것보다 그 부분만 들고 오는게 더 효율적일 것이다. 흠흠 무튼 이렇게 하고

WebContent/sample/sample.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>sample</title>
</head>
<body>
hello sample <s:property value="test"/>

<s:iterator value="sampleList" status="stat">
<s:property value="test1"/>
<s:property value="test2"/>
</s:iterator>
</body>
</html>

이 부분에서 <s:iterator value="sampleList" status="stat"> 이렇게 되어 있는데 Action에서 sampleList를 넘겨 주엇다.

대충 보앗다면 못 보앗을테지.-_ -;;;무튼 그게 List형식이니 for문을 돌려서 빼던가 해야 할텐데 struts2 이놈께서

편하게 하시라고 iterator라는 놈을 사용하여 자동으로 하게 해준다. "

<s:property value="test1"/>
<s:property value="test2"/> 요놈들은 Model에 있던 놈들. 만약에 DB에서 값을 받아 온놈이 test1만이였다면

test2는 굳이 안써도 되겠지.

무튼 이제 실행을 시킬차례.

http://localhost:8080/sample/sample/sample.action 실행을 해보자.

어떻게 나왔는가.

hello sample Good Struts2

Struts2 iBatis Good TEST SUCCESS

라고 나왓다. 첫줄은 이 전 게시물에서 struts2 셋팅하면서 했던것이고 2번째 줄은 DB에서 가져 온값이다.

아참.!! 내 프로젝 폴더를 포여줘야겠군. 이런게 궁금한 사람들도 엄청 많을 수 있으니.

대략 이정도로 되어 있다. 나는 지금 sample 이라는 곳에 다 밀어 넣엇지만 저건 안좋은 방법이다.

나중에 sample이라는 한 로직을 돌린다고 한다면 sample 패키지에 sampleAction, sampleModel, sampleService, sampleServiceImpl, sampleDao, sampleDaoImpl로 sample과 같은 경로에 db라는 패키지를 만들어서 그 곳에

daoConfig, dao, sql-map-config.xml을 지정하고 sample.xml과 같은 sqlmap은 패키지를 따로 만들어서

sql맵들만 싸그리 모아놓는 것이 효율적일 것이다. 뭐 말로 하면 어려운데 막상 지금 하려고 하니 귀찮다;;;

무튼 쉽다고 하면 쉽지만 쉽지 않은게 환경설정이다. 사소한것 하나때문에 계속 에러가 날 수도 있고.

철자하나 틀려서 에러가 미친듯이 날 수도 있다. 그래도 어쩌랴. 해야만 하는 것임에 틀림없는것을...

오늘도 우리 동종업종의 많은 분들은 컴퓨터와 씨름을 하고 있겠군하.

아 우리 개발자들.! 프로그래머들.!! 화이팅이다.!!

Posted by 신의물방울
Programming2011. 7. 29. 11:55

< simple >

스트럿츠2 JSP 리절트 페이지에서 <s:form/> 태그를 사용할 theme 속성에 "simple" 테마를 사용하지 않을 경우에는 태그의 내용이 랜더링될 스트럿츠2 자동으로 페이지 레이아웃을 구성합니다. 예를 들면 <table>, <tr>, <td> HTML 태그를 사용하여 사용된 컨트롤과 레이블 출력을 위해 테이블 레이아웃을 구성하는 것을 있습니다. 것은 화면을 개발 시간과 노력을 들이지 않고 손쉽게 단순한 화면 레이아웃을 구성하기 쉽게 하기 위하여 지원하는 기능입니다.

<s:form>... </s:form> 또는, <s:formtheme="ajax">...</s:form> 등으로 사용하게 경우 안에서 사용한 UI 태그들의"key" 속성이나"label" 속성에 리소스 번들의 값을 정의하면 자동으로 해당 컨트롤의 앞에 레이블을 출력합니다. 그리고 자동으로 <table>, <tr>, <td> 태그로 컨트롤의 레이아웃을 구성합니다.

따라서 <s:form theme="simple">... </form> 태그를 사용하지 않는 이렇게 자동 레이아웃기능을 제공하기 때문에 혼동을 일으킬 있는 가능성이 있습니다. 자신이 직접 레이아웃을 구성하려면 <s:form /> 태그를 사용할 theme 속성에 simple 테마를 사용하여야 합니다. 만약 "simple"테마를 사용하였을 때는 <s:submit /> 버튼을 제외한 다른 UI 태그들의 key, label 속성에 설정한 리소스 번들의 내용이 화면에 출력되지 않습니다.

Posted by 신의물방울
Programming/Servlet/JSP2011. 7. 28. 13:52

<DB Table>

오라클기준입니다

-----------------------------------

create table smarteditor

(

ir1 varchar(100)

);

-----------------------------------

이제 바로 DAO클래스를 작성하겠습니다 iBatis를 이용했습니다

설정파일을 셋팅하겠습니다(4개가 필요합니다)

1. SqlMapLocator.java (sqlMapConfig.xml 자원을 읽기 위한 리소스 클래스)

2. smart.xml (쿼리문이 있는 설정파일)

3. SqlMapConfig.properties (오라클 접속정보가있는 설정파일)

4. SqlMapConfig.xml (JDBC 설정파일)

각 설정파일은 첨부된거 확인해주세요~ 보시면 알거에요 :)

다 설명하면 너무 방대해서요;; 모르는거는 개인적으로 질문해주세요~~~ ㅎㅎ

다 설정이되었다면 SmartDAO클래스를 생성합니다

------------------------------------------------------------------

package com.dao;

import java.sql.SQLException;

import com.bean.*;
import com.util.SqlMapLocator;

public class SmartDAO
{
public void sInsert(SmartBean sb) throws SQLException
{
System.out.println("DAO통과1 "); //제대로 통과되었는지 확인
SqlMapLocator.getMapper().insert("insertSmart",(SmartBean)sb);
System.out.println("DAO통과2 -끝-");
}

}

------------------------------------------------------------------

smart.xml 에서 설정한 insert에서 "insertSmart"이름을 통해서 호출합니다

그리고 마지막으로 성공했는지 알수있도록 smart_ok.jsp 생성합니다

이파일은 앞서 코딩한 struts.xml 설정파일에 <result name="success">/smart_ok.jsp</result> success될경우

smart_ok.jsp로 이동합니다

--------------------------------------------------------------------

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>실행완료</title>
</head>
<body>
성공하셨습니다
</body>

</html>

--------------------------------------------------------------------

-END-


 

 

<--- DB에 값이 들어갔습니다

Posted by 신의물방울
Programming/Servlet/JSP2011. 7. 28. 13:49

앞서 쓰기를 코딩하셨으면 이제는 쓰기화면에서 [확인] 버튼을 눌르면 DB연동까지 해보겠습니다

<참조>

앞에서 코딩한거 중에서

-----------------------------------------------------------------------------

<body>

<form action="smartReg.action" method="post">

<textarea name="ir1" id="ir1" style="width:450px; height:150px; display:none;"/>
<input type="button" onclick="_onSubmit(this)" value="확인"/>

</form>

</body>

-----------------------------------------------------------------------------

form action="smartReg.action" 이부분은 위그림처럼 [확인]을 클릭할 경우 폼액션에서 작성한 .action이 호출됩니다

이부분은 차근차근 알아봅시다

순서를 알아보면

1.[확인]클릭

2. 폼액션을통해서 xml설정파일로 이동

3. xml설정에서 맵핑된 클래스로 이동

4. DAO 연동 후 DB저장

대략 이렇게 됩니다 그럼 우리는 2번을 해야합니다

.xml파일을 생성해주세요 저는 struts.xml 생성했습니다

--------------------------------------------------------------------------------------

<struts>
<constant name="struts.i18n.encoding" value="UTF-8"/><!-- 한글이 깨질 시 사용 -->
<package name="pack" extends="struts-default">
<!-- 404 혹은 500 에러시 나오는 페이지를 대체할 수 있다 -->
<default-action-ref name="error"/>
<action name="error">
<result>/error.jsp</result>
</action>

<action name="smartReg" class="com.action.SmartInert">
<result name="success">/smart_ok.jsp</result>
</action>
</package>
</struts>

--------------------------------------------------------------------------------------

이렇게 코딩해주시고 쓰기폼에서 smartReg.action을 적으신거 기억나시죠?

<action name="smartReg" class="com.action.SmartInert">

smartReg로 호출을 받아서 com.action.SmartInert 액션으로 연결해줍니다

자 이제 순서중에서 2번은 끝났고 3번으로 가겠습니다

딱보면 아~ SmartInert 클래스를 생성해야겠구나 생각하실거에요

네맞습니다

SmartInert.java를 생성합니다

하지만 제가 빼먹은게 있습니다 바로 빈파일을 빼먹었습니다 초보라서..ㅠㅠ

--------------------------------------------------------------------------------------

package com.bean;

public class SmartBean {

private String ir1;
public String getIr1()
{
return ir1;
}
public void setIr1(String ir1)
{
this.ir1=ir1;
}
}

--------------------------------------------------------------------------------------

이렇게 후딱 코딩해주세요 private String ir1; <--- 이변수는 뭔지아시죠? <textarea name="ir1"> 이거 입니다

다시 본론으로 들어가서 SmartInert.java를 생성합니다

--------------------------------------------------------------------------------------

package com.action;


import java.util.ArrayList;
import java.util.List;

import sun.misc.Request;

import com.dao.*;
import com.opensymphony.xwork2.ActionSupport;
import com.bean.*;

//POJO방식 종속적이지않다(extends사용하지않음)

public class SmartInert
{
private SmartBean smartbean; //빈즈클래스 객체화(인스턴스변수)
private String ir1;

public String execute() throws Exception
{
System.out.println("액션통과1"); //제대로 통과했는지 알아보기위해 찍었습니다
SmartDAO sDAO = new SmartDAO();
SmartBean sb = new SmartBean();
sb.setIr1(ir1);
sDAO.sInsert(sb);
return "success";
}

--------------------------------------------------------------------------------------

자아~ 여기서보면 DAO와 Bean 각각 인스턴스 변수를 생성했습니다

그리고 sb. 빈호출해서 setIr(ir1) 정보를 가져와서 sDAO. DAO클래스의 sInsert(sb) 담아서 return "success" 합니다

여기에서 "success"의 헬퍼인터페이스입니다

<참조>

리턴은 success 인자로 리턴한다 이걸 헬퍼인터페이스(또는 상태값)라고한다
헬퍼 인터페이스(상태값)는 "SUCCESS" , "NONE", "ERROR","INPUT","LOGIN"과 같은 상수로서 공통적인 결과를 제공한다
그리고 이 상수들은 반드시!!! execute() 메소드를 재정의해야한다

그러면 SmartDAO 클래스의 sInsert() 메소드를 코딩해야합니다

그건 다음페이지에서 작성하겠습니다 ~~

Posted by 신의물방울