레이블이 composition인 게시물을 표시합니다. 모든 게시물 표시
레이블이 composition인 게시물을 표시합니다. 모든 게시물 표시

2013년 8월 9일 금요일

[오라클자바커뮤니티, 닷넷교육, ORACLEJAVANEW.KR]닷넷 어셈블리(.NET Assembly)

오늘은 3일차로서 닷넷 어셉블리의 1부를 학습 하도록 합니다. 조금 어렵게 느낄수 있는데 자바를 하신 분들은 자바 프로그램의 배포를 위한 Jar 파일 포맷을 아실 겁니다. 유사하게 생각 하시면 되구요 닷넷 환경의 프로그램이 배포되는 단위라고 정리하시면 됩니다.~
닷넷 어셈블리 (Assembly)란?

오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  


닷넷에 대해 공부 하시다 보면 닷넷 어셈블리라는 말을 가끔식 보게 되실 겁니다. Low Level 언어인 Assembly는 절대 아니니 착오 없으시기를 바랍니다.어셈블리는 하나의 단일한 단위로 존재 하는 .NET 의 실행 가능한 프로그램 또는 실행 프로그램의 일부 입니다 . 결국 C# 프로그램의 실행 및 배포의 단위라고 할 수 있습니다 . C# 응용 프로그램 작성의 결과로 생긴 .exe 파일이 바로 하나의 어셈블리 이며 클래스 라이브러리 작성의 결과인 DLL(Dynamic Link Library) 도 하나의 어셈블리 입니다 . 하나의 단일한 어셈블리 안의 모든 코드는 하나의 단일한 단위로 빌드 , 배포되며 버전 번호가 부여되는데 각 어셈블리는 다른 프로그램들이 사용 할 수 있는 public class, 속성 , 메소드등을 노출하게 됩니다 . private 으로 선언된 것은 모두 어셈블리 안에 은폐 되는 것 입니다 .

다음은 구성요소 흔히 컴포넌트라고 하는것에 대해 잠시 정리하겠습니다.

MS 는 최초 DLL 을 도입하였는데 DLL 은 코드의 일부를 개별적인 파일로 분리 한 이며 프로그램이 같은 언어로 작성 되었을 때 기본적인 수준에서 동작하는 것 입니다 . 프로그램의 입장에서 자신이 사용하고자 하는 DLL 에 대해 많은 것을 알아야 하며 또한 프로그래머들이 서로의 데이터를 교환하는 용도로 DLL 을 사용 할 수 없습니다 .
데이터 교환의 문제를 해결 하기 위해 개발 된 것이 DDE(Dynamic Data exchange) 로 이것은 한 프로그램에서 다른 프로그램으로 데이터를 전송 하기 위한 형식과 메커니즘을 정의하는데 그리 유연하지는 않습니다 . 그 뒤로 OLE(Object Linkig and Embedding) 등장 하면서 Word 와 같은 문서가 다른 프로그램 (Excel) 을 자신안에 포함 할 수 있게 되었는데 비록 구성요소와 비슷한 개념을 지닌 기술이지만 OLE 1.0 을 진정한 범용적 구성요소로 보기는 어렵습니다 .
MS 최초의 진정한 구성요소의 표준은 1990 년대 중반에 나타난 COM(Component Object Model) 이라고 할 수 있습니다 . OLE 2.0 과 기타 여러 기술들은 COM 으로 통합 되었으며 COM 들이 네트웍 너머로 통신 할 수 있게 하는 DCOM, 다계층 환경에서 구성 요소 사이의 호출에 대해 높은 성능을 보장하는 서비스가 추가된 COM+ 가 등장 했습니다 .
COM 은 잘 동작하는 반면 배우기가 어렵고 사용하기도 어렵습니다 . COM 에서는 구성요소의 정보를 Windows Registry 에 등록해야 하는데 이는 구성요소의 설치와 삭제를 어렵게 하는 요인이 되었습니다 . COM 은 원래 C/C++ 를 위해 설계된 것이며 그 이후 VB 에서도 사용토록 개선 되었고 (“ 자동화 ” 라고 하는 것 ) 실제로 잘 동작 하고 있습니다 . 그 대신 C/C++ 로 VB 와 호환이 되는 구성요소를 만드는 것은 어려워 졌습니다 .( 예를 들어 다른 언어에서 정의된 클래스를 상속하는 것은 여전히 불가능 합니다 .)
또한 사용자가 MS 나 기타 회사들의 DLL 혹은 COM 구성 요소의 여러 버전을 설치하다 보면 문제가 발생 하는데 이는 버전이 다르더라도 DLL 파일의 이름은 동일 한데서 기인하는 것이 많습니다 . 그래서 이미 다른 프로그램에서 사용하는 DLL 을 덮어 씌워 버리는 경우가 자주 나타났으며 또한 시스템에 설치 된 DLL 정보를 관리하는 부담 때문에 구성요소의 업그레이드와 유지 보수가 갈수록 어려워 지는 것 입니다 . 결국 .NET 에서 이러한 문제들을 해결 할 수 있는 새로운 표준이 사용되는 것 입니다 .
다음은 닷넷어셈블리의 자기 서술적인 특징에 대해 알아 보겠습니다.
결국 어셈블리는 자바에서의 배포 단위인 Jar와 비숫하게 생각해 볼 수도 있습니다. Jar 파일에 Menifest 파일이 있어 그속에 JAr 파일의 구조에 대해 정의하고 있는데 이것을 자기 서술(Self Description) 이라고 합니다. 닷넷도 어셈블리 안에 자기서술적인 특징을 가지고 있습니다. 결국 기존의 DLL들 처럼 배포한 후 레지스터리에 등록하여 컴퓨터를 껐다 켜야 인식이 되는 것이 아니라 배포되는 닷넷 어셈블리안에 Self-Descriptiion을 하니까 그럴 필요가 없이 복사만 되면 발로 실행이 가능하다는것이 특징 입니다. 어셈블리에 어떤 것이 있는지가 .NET 어셈블리안에 있으므로 그것을 사용하는 프로그램이나 시스템은 레지스트리와 같은 외부 정보를 참조 할 필요가 없습니다 . 닷넷 어셈블리는 자신이 가지고 있는 개체와 메소드 뿐 아니라 매개변수의 데이터 형식까지 제공 합니다 . 또한 개체들의 버전 정보 , 보안정보도 제공하며 실제로 어셈블리의 설치는 기본적으로 대상 시스템에서 어센블리 파일을 복사하는 것으로도 충분 합니다 . 참고로 한가지 명심할 것은 네임스페이스와 어셈블리가 항상 일대일 대응을 이루는 것은 아니라는 것 입니다 . 예를들어 System.Data.dll 은 System.Data 와 System.Xml 네임스페이스의 일부를 구현하며 System.Xml 의 다른 루틴은 System.Xml.xll 에 구현되어 있습니다 .

다음은 교차 언어 프로그래밍에 대해 정리 하죠

구성요소는 어떠한 .NET 언어에서도 심지어 구성요소를 작성한 언어가 아닌 다른 언어에서도 호출 될 수 있습니다 . 이것 역시 어셈블리가 주는 장점 입니다 . 닷넷은 교차 언어적 프로그래밍을 가능하게 하는 아래와 같은 특징을 가지고 있습니다 .
• Cmmon language Runtime(CLR) : 모든 .NET 어셈블리의 실행을 관리
• Microsoft Intermediate Language(MSIL) : 모든 .NET 언어 컴파일러는 MSIL 을 생산 하며 이는 컴파일러가 생성하는 이진 코드의 표준으로 CLR 은 이 MSIL 코드에 기반하는 것입니다 . MSIL 은 또한 어셈블리의 메타 데이터를 저장 하는 형식을 정의 하는데 이는 어셈블리가 어떤 언어로 만들어 졌든 간에 공통의 형식으로 자신의 메타 데이터를 저장함을 의미 하는 것입니다 .
• Common Language Specification(CLS) : C#, VB, C++ 등 어떠한 닷넷 언어라도 CLS 를 만족 하기만 하면 언어의 경계를 넘어서 구성 요소들을 공유 할 수 있으며 언어의 경계를 넘어서 완전한 상속이 가능 합니다 .
• Common Type System(CTS) : 모든 .NET 언어들이 사용하는 기본 형식들과 자신의 클래스를 정의하는 규칙을 정의 한다 . 예를들면 어떤 언어가 문자열 형식을 비 호환적 방법으로 구현하는 일을 방지한다 . CLS 사양을 따르면 C# 으로 구성 요소를 작성 했을 때 그것을 담은 어셈블리는 VB.NET 같은 언어에서도 사용 될 수 있으며 마찬가지로 C# 은 VB.NET 이나 C++.NET 으로 작성된 구성요소를 사용 할 수 있습니다 . 또한 .NET Framework 에서는 이전에 만들어진 COM 에 대해서도 사용 할 수 있는 방법을 제공 하는데 이는 이전에 작성된 코드를 감싸는 인터페이스 역할을 하는 wrapper assembly 를 통해서 가능 합니다 . VS .NET 은 COM 구성요소에 대한 참조를 추가하면 자동적으로 래퍼 어셈블리를 만듭니다 .
오늘은 3일차로서 다분히 이론적인 내용 이었습니다. 다음 시간은 그림과 함께 닷넷 어셈블리에 대해 조금 더 깊이 살펴 보도록 하겠습니다.
수고하셨습니다.

Microsoft .NET Framework, C#, ASP.NET(C#교육, 닷넷교육, 자바교육, 오라클자바커뮤니티)

Microsoft .NET Framework, C#, ASP.NET

닷넷이란?
현재의 인터넷 환경을 혁신적으로 바꿀 차세대 MS의 제품군과 기술을 총칭하며
다음 세대의 플랫폼과 서비스를 위한 프레임웍이며 서비스로서의 소프트웨어의 Concret(공구리)

오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  


It’s a vision
- A new platform for the digital era

It’s a brand
- One applied to many things

It’s a set of products and technologies
- A concrete set of software

인터넷을 통해서 자유롭게 프로그램을 배포하고 개발하려면 하나의 언어만(예를들면 C#)알고 있으면 되고, .NET framework 에 의해서 동일한 컴파일된 코드를 만들수 있다면 모든 프로그램을 .NET 으로 통합할 수 있고 서비스 할수 있다.
(자바 진영의 경우 자바언어 하나만 알고 있으면 웹프로그래밍, 응용 프로그래밍, 모바일 프로그래밍
등등등 모두 개발이 가능 한데 MS의 종래 Visual C, Visual Basic등은 그러질 못했었습니다.)
또한 아래 정도의 개념으로 보시는것은 좀더 구체적 일겁니다.

Microsoft's new Internet and Web strategy
NOT a new operating system
new Internet and Web based infrastructure
delivers software as Web Services
framework for universal services
is a server centric computing model
will run in any browser on any platform
is based on the newest Web standards


Visual Studio.NET은 C#,Visual Basic.NET,C++,J#,Jscript 등 여러 언어들을 지원 합니다.닷넷 환경에서 어느 프로그래밍 언어로 작성하든 컴파일된 코드(MSIL, Microsoft Intermediate Language)는 같다는 것이아주 강력한 특징 입니다. 즉 프로그래머가 가장 자신있고 편한 언어로 개발 하는 된다는 거죠... 그렇지만 대부분 C#을많이 사용하고 있죠... 뒤에서 하나씩 배우겠지만 C#을 평가하자면....
자바의 강력한 객체지향 특징과 파워풀함 + C++의 강력함 + VB처럼 쉬운 통합환경 의 3가지 요소가 결함된 최고라고할 수 있습니다. 열심히들 공부 하시기 바랍니다






2013년 8월 8일 목요일

[오라클자바커뮤니티, JAVAORACLE교육]자바 JVM의 메모리 구죠, 자바교육

JAVA JVM의 메모리 구조


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  




JVM 의 실행 메모리 영역

메쏘드(method) 영역 : 클래스의 메소드에 대한 바이트코드, 전역변수(클래스 변수)
힙(heap) 영역 : 객체를 저장할때 사용하는 메모리
스택(stack) 영역 : 지역변수,함수의 인자,함수의 리턴값,리턴 번지
레지스터(registers) : 가상 머신의 현재 상태를 보여줌, 현재 실행되고 있는 메소드의 실행 포인터를 저장
실행 풀(Runtime Constant Pool) : 숫자 리터럴과 상수 필드 포함, 메소드 영역으로 부터 할당 받는다.


JVM 의 실행 메모리 영역 ]


메소드 내에서 객체 참조형으로 선언된 변수인 경우(String s = new String("abc") 일때의 s) 지역변수로서 스택에 위치하며 힙에 저장되어 있는 객체에 대한 참조값을 가지게 됩니다.
객체 참조형 변수의 값이 null 이라는 의미는 아무것도 참조하고 있지 않다는 의미 입니다.
New 연산자는 힙(heap) 메모리에 객체를 만들고 그 객체의 참조값을 반환 합니다.(Hello h = new Hello()) ---> Memory Heap에 Hello 클래스의 인스턴스(객체)를 만들고 그것을 스택에 있는 h라는 변수가 참조하도록 합니다. C에서의 포인터 변수와 유사 합니다.)
객체 참조 변수의 경우 대입, 메소드 호출시의 인자, 반환형 등으로 사용 될 때 참조 값만 전달 될 뿐, 객체 자체가 복제되어 전달되는 것은 아닙니다.
아래의 예제를 참고하세요

class C
{
public static void
main(String[] args)
{
int i = 3;
f(i);
}
static void f(int arg)
{
int i = 10;
double f = 3.14
}
}


이상 JVN의 메모리 영역에 대해 살펴 보았습니다.







[오라클자바커뮤니티,자바교육]자바의 자료형

JAVA자료형에 대해 계속 보도록 하겠습니다. 


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  



1. 정수 자료형 (byte,short,int,long)

자바에서 제공하는 정수 자료형은 byte, short, int, long 4가지가 있습니다.(1,2,4,8 바이트 순)

C언어의 unsigned는 지원하지 않습니다.

short, byte에 연산을 하면 무조건 int형이 됩니다. 아래의 예를 보죠...

short a=0, b=0;

short c = a + b;

만약 위의 코드 부분이 컴파일 되다면 다음과 같은 오류가 날것 입니다.

---------- javac ----------
test.java:10: possible loss of precision
found : int
required: short
short c = a + b;
^
1 error


int형이 아닌 long형으로 데이터를 다루기 위해선 숫자 끝에 소문자 l이나 대문자 L을 표시한다.

Int : 12 (10진수), 012 (8진수), 0x12 (16진수)

Long : 12L, 12l



2. 부동소수 자료형 (float ,double)

자바에서 제공하는 부동소수 자료형은 float와 double이 있습니다.
부동소수 자료형 뒤에 아무것도 붙이지 않거나 ‘d’ 또는 ‘D’ 가 붙으면 기본적으로 double 형이 되며 ‘f’, ‘F’를 붙이면 float 자료형이 됩니다.

유효 10진 자리수
float : 6자리, double : 15자리

2진수로 표현하므로 표현 오차 발생하며 보다 정확한 표현을 하려면 BigDecimal 이용하세요~

리터럴

float --> 1e1f, 2.F, .3f, 6.02E+23f, 1.4039846e-45f ~ 3.40282347e+38f
double --> 1e1, 2.D, .3, 6.02E+23d, 4.94065645841246544e-324 ~ 1.79769313486231570e+308



[예제]

// FloatPointTest.java

class FloatingPointTest
{
public static void main( String[] args )
{
System.out.println( 1.2345678901234567890123456789 ); // 1.2345678901234567
System.out.println( 2e3 ); // 2000.0
System.out.println( 0.1 + 1.6 ); // 1.7000000000000002
System.out.println( 3.0 / 0.0 ); // Infinity
System.out.println( 0.0 / 0.0 ); // NaN
}
}



3. 진리 자료형 (boolean)

boolean Literal : true, false

boolean 형은 다른 데이터형과 연산이 불가하며 boolean형은 boolean 형과 연산이 가능 합니다.

[예제]

public class BooleanTest {
public static void main(String[] args) {
boolean b1 = true; boolean b2 = !b1;
System.out.println("b1 : " + b1);
System.out.println("!b1 : " + b2);
System.out.println(b1 & b2);
System.out.println(b1 | b2);
System.out.println(b1 == b2);
System.out.println(" 6 < 7 : " + (6 < 7));
}
}

[결과]

b1 : true
!b1 : false
false
true
false
6 < 7 : true

4. 문자 자료형 (char)

자바는 유니코드를 지원하는데 JDK1.4부터는 Unicode 2.0까지 지원합니다.

한 문자를 표현할 때는 '와 ' 사이에 단 한 글자만이 올 수 있습니다.

자바에서 문자를 표현하는 방법은 두가지가 있는데 첫번째 방법은 있는 그대로 쓰는 것이며 두번째 방법은 유니코드로 표현하는 방법이다. 예)char c = ‘A’, char c = ‘\u0041’

[예]

class CharTest {
public static void main(String[] args) {
char c1 = 'A'; char c2 = '\u0041';
char c3 = '가'; char c4 = '\uac00';
System.out.println("c1:"+c1+",c2:"+c2);
System.out.println(c1 == c2);
System.out.println("c3:"+c3+",c4:"+c4);
System.out.println(c3 == c4);
}
}

[결과]

c1:A,c2:A
true
c3:가,c4:가
true

[오라클교육,자바교육,오라클자바교육,오라클자바커뮤니티]JAVA AWT 프로그래밍-Toolkit

이번 강좌에서는 Java.awt.Toolkit 에 대해 알아 보겠습니다.


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  

 

-------------------
Java.awt.Toolkit
-------------------

그래픽 자원관련 시스템 정보 제공 합니다.
new 명령으로 만들수 없으며 Component의 Method인 getToolkit()이나 Toolkit.getDefaultToolkit을 사용해야 합니다.( Toolkit 객체가 하나만 존재해야 하므로…)

beep() : beep 음 출력

createimage(), getImage() : 이미지를 만들거나 Network 경로를 통해얻을 사용 합니다.

getPrintJob() : 프린터와 연결된 객체인 java.awt.PrintJob을 얻게 해 줍니다.

getScreenSoze() : 실제 화면의 크기를 구해주며 스플레쉬(Splash) 윈도우를 만들때 유용 합니다.

getScreenResolution() : 현재 화면이 인치당 몇 개의 점이 들어가는 해상도인지 알려줌.

getSystemClipboard() : 클립보드 객체를 리턴해준다. 이 객체에 내용을 넣어 다른 프로그램등에 전달 해줄때 사용 합니다.



[예제]

/* 화면 한 가운데 width, height가 반인 윈도우 그리기 */
import java.awt.*;

public class ToolkitExam extends Frame {
public ToolkitExam(String title) {
super(title);
}
public static void main(String[] args) {
ToolkitExam halfWindow = new ToolkitExam("Toolkit Sample");
Toolkit toolkit = halfWindow.getToolkit();
Dimension size = toolkit.getScreenSize();

halfWindow.setBounds(size.width/4, size.height/4,
size.width/2, size.height/2);
halfWindow.setVisible(true);

[ORACLEJAVANEW.KR]Struts DispacthAction 클래스

Struts DispacthAction 클래스 DispacthAction 클래스


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  


액션의 경우 하나의 클래스에 관련된 action이 정의 되어 있는 것이 좋은 방법인데  DispacthAction 클래스는 관련된 action은 하나의 클래스에 관리하는 방법을 제공 합니다.

DispacthAction 클래스는 추상 클래스 이므로 사용하기 위해서는 액션 클래스에서 오버라이드 해야 하며 DispacthAction 클래스에서는 어느 action이 불리어져야 하는지를 관리 하기 위해 hidden request parameter를 관리 합니다.

DispacthAction 을 상속 받은 하위 클래스로 넘어오는 hidden parameter는 스트럿츠 설정 파일에 있는 <action> 요소의 parameter 라는 속성의 값이 넘어 오게 됩니다.

결국 DispacthAction 클래스를 상속 받은 하위 클래스는 execute() 메소드와 signature가 같은 많은 메소드(각각의 Action이 수행 해야 하는 메소드)를 정의해야 합니다.


=================================================================

1. Action 처리를 위한 DispatchAction클래스의 하위 클래스를 작성

public class UserRegistrationMultiAction extends DispatchAction {
...
}

2. 관계된 action을 구현 합니다.

public ActionForward processPage1( ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
...
}

public ActionForward processPage2(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
...
}


3. Action Mapping을 작성 합니다. 이때 paramter라는 속성에 “action” 이라고 줍니다. 이 action이라는 파라미터와 그 값(이건 JSP에서 넘어 옵니다)이 위에서 구현한 DispatchAction 클래스를 상속한 UserRegistrationMultiAction 클래스에 넘어 가게 됩니다.
즉 paramter인 action의 값이 수행 하고자 하는 action이 되는 것 입니다.

<action path="/userRegistrationMultiPage1"
type="strutsTutorial.UserRegistrationMultiAction"
name="userRegistrationForm"
attribute="user"
parameter="action"
input="/userRegistrationPage1.jsp">
...
</action>

<action path="/userRegistrationMultiPage2"
type="strutsTutorial.UserRegistrationMultiAction"
name="userRegistrationForm"
attribute="user"
parameter="action"
input="/userRegistrationPage2.jsp">
...
</action>

4. 이젠 JSP에서 action이라는 히든 텍스트를 만들어 Action이 일어 날 때 Action을 처리하는  클래스(UserRegistrationMultiAction ) 로 넘기게 됩니다.

userRegistrationPage1.jsp 에 포함된 히든 태그

<html:hidden property="action" value="processPage1"/>

userRegistrationPage2.jsp 에 포함된 히든 태그

<html:hidden property="action" value="processPage2"/> 

Struts 커스텀 태그 개요 (custom tag)

JSP의 커스텀 태그에 관련 부분은 JSP강좌를 참고 하시기를 바라며 여기서는 Struts의 Taglib에 대해 살펴 보도록 하겠습니다.


------------------------------------------------------------------
먼저 TagLib을 위한 설치/사용 과정에 대해 잠시 정리해 보도록 하겠습니다.
------------------------------------------------------------------

1. taglib을 사용하기 위해서는 우선 JAR파일을 /WEB-INF/lib에 복사를 한 후 tld파일들은 꼭은 아니지만 대부분 /WEB-INF/ 폴더에 위치를 시킵니다.

2. 필수 사항은 아니지만 web.xml에 uri와 location을 설정 합니다. 아래의 예를 볼까요…

<web-app>
        <taglib-uri>/tags/struts-bean</taglib-uri>
        <taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</web-app>

이러한 식으로 매핑을 하게 되는데 이 과정을 생략하고 JSP에서 직접 tld 파일을 부르게 되는 경우에는 추후 파일의 이름이나 위치가 바뀌는 경우 모든 JSP 파일에서 일일이 수정을 해야 하는 번거로움이 있으니 web.xml에서의 매핑은 필요한 것 입니다. 또한 uri와 location을 같게 하면 추후 TLD 파일의 위치가 변경되면 문제가 발생할 수도 있습니다.

때에 따라서는 tld와 jar를 /WEB-INF/lib에 두기도 하며 tld를 위해 별도의 폴더를 만들기도 합니다.

3. 새롭게 정의한 taglib을 JSP에서 사용 하기
taglib을 가지고 올 때 web.xml의 uri를 통해 참조하게 되는데 taglib 지시자에서 다음과 같이 정의 합니다.

<%@ taglib uri=”/tags/struts-bean” prefix=”bean” %>

그런 다음 JSP페이지에서 prefix를 이용하여 다음과 같이 사용 합니다.

<bean:write name=”userInfo” property=”lastName”/>



--------------------------------
자바 빈 사용하기
--------------------------------

애플리케이션을 만들 때 스트럿츠에서 제공하는 태그 라이브러리만 이용하라는 법은 없습니다. SUN의 JSTL, Jakarta Taglibs, Improve의 Struts-Layout등의 다른 표준 태그 라이브러리도 이용 가능 합니다.

스트럿츠에는 bean, html, logic, nested와 같은 4가지의 핵심 태그 라이브러리를 제공 합니다.

bean : 자바빈의 프로퍼티에 접근하기가 용이하며 새로운 자바 빈을 정의하는데도 사용 됩니다.

html : 스트럿츠 프레임워크와 상호 작용 가능한 HTML 입력 폼을 생성하는데 사용 또는 HTML Tag와 관련된 태그

logic : 조건적인 결과물의 실행, 반복실행, 애플리케이션의 흐름을 관리하는 태그
nested : 다른 스트럿츠 태그들의 기능을 포함하는 확장된 성능을 제공 하는 태그


-------------------------------------------
Struts 태그와 함께 자바 빈 사용 하기
-------------------------------------------

대부분의 경우 태그 라이브러리에 있는 태그들을 자바 빈즈와 함께 사용 합니다. 태그들과 함께 사용되는 자바 빈즈는 HTML의 입력 폼 필드에 대응하는 ActionForm 일 수도 있지만 ActionForm이 아닌 경우 보통 MODEL Layer의 VO(Value Object) 입니다. 이러한 VO는 Page, Request, Session, Application등의 Scope안에 존재 할 수 있습니다.



오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  



1.        단순 프로퍼티의 접근


단순 프로퍼티의 접근은 JSP의 <jsp:getProperty>액션과 동일하게 수행 됩니다. “property=firstName”이라는 프로퍼티는 메소드 getForstName()이나 setFirstName()의 호출로 변환 됩니다.

2.        중첩된 프로퍼티의 접근

중첩된 프로퍼티들은 마침표(.)로 구분되는 이름 계층구조를 사용하여 프로퍼티에 접근 합니다. 다음과 같은 프로퍼티 레퍼런스가 있다면

“property=user.address.city” 이 레퍼런스는 다음과 같은 자바 구문으로 변환 됩니다.

getUser().getAddress().getCity()

만약 입력 폼에서 수행되는 setter에서 중첩된 레퍼런스를 사용 했다면 중첩된 레퍼런스의 맨마지막  프로퍼티에서는 setter가 호출 됩니다. 이 경우 앞의 프로퍼티 레퍼런스는 다음과 같은 자바 구문으로 변역 됩니다.

getUser().getAddress().setCity()

3.        인덱스 프로퍼티

인덱스가 있는 프로퍼티에서는 첨자를 사용하여 프로퍼티에 속한 각 요소에 접근 합니다. 예를 들어 다음과 같은 프로퍼티 레퍼런스가 있다고 할 때

“property=”address[2]”

이 레퍼런스 구문은 다음과 같은 자바 구문으로 변환 됩니다.

getAddress(2);

setter에서 같은 프로퍼티 레퍼런스를 사용했다면 setAddress(2, address); 와 같은 자바 구문으로 변환 됩니다. 

[자바교육,오라클자바커뮤니티]Log4J를 XML을 이용하여 설정하기

Log4J를 XML을 이용하여 설정하기 


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  
 
------------------------------------------------------------
1. log4j.configuration 파이를 /WEB-INF/classes 에 만듭니다.
------------------------------------------------------------

set CATALINA_OPTS=-Dlog4j.configuration=log4j.xml

------------------------------------------------------------
2. log4j.xml을 /WEB-INF/classes 에 만듭니다
------------------------------------------------------------

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>

<appender name="rolling" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="d:\myoutput.log"/>
        <layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern" value="=%d{ABSOLUTE} - %p %c - %m%n"/>
        </layout>
</appender>

<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern" value="%5p [%t] (%F:%L)- %m%n"/>
        </layout>
</appender>
<root>
<priority value ="INFO" />
<appender-ref ref="stdout" />
<appender-ref ref="rolling" />
</root>
</log4j:configuration>


------------------------------------------------------------
3. test용 JSP를 만듭니다.
------------------------------------------------------------

<%@ page import="org.apache.commons.logging.Log" %>
<%@ page import="org.apache.commons.logging.LogFactory" %>
<%-- Get a reference to the logger for this class --%>
<% Log logger = LogFactory.getLog( this.getClass( ) ); %>
<% logger.debug( "This is a debug message from a jsp" ); %>
<html>
<head>
<title>Using Commons Logging in a JSP page</title>
</head>
<body>
<% logger.info( "This is another log message in the jsp" );
%>
There should be two log messages in the log file.
</body>
</html>

콘솔 화면으로 로그가 출력 되면서 화일로도 출력이 되는 예제 입니다. 

[오라클자바커뮤니티강좌,자바교육]Struts에서의 예외처리-2

Struts에서의 예외처리(2)



오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  




스트럿츠가 제공 하는 예외 처리

스트럿츠 1.1. 이후에는 작지만 효율적인 예외처리 프레임워크를 추가 했습니다. 또한 org.apache.struts.util.AppException 클래스는 ActionError를 포함하며 java.lang.Exception을 확장한 클래스 입니다.

아래와 같이 스트럿츠에서 사용하면 되는데

throw new AppException(“error.password.invalid”);

생성자의 “error.password.invalid”는 리소스 번들의 key 이며 프레임웍에서는 자동적으로 예외의 ActionError 객체를 생성하고 적절한 scope에 저장 합니다. 물론 애플리케이션에서 AppException에 대해 확장이 가능 합니다.

----------------------------------------------------
선언적 예외 처리와 프로그램적 예외처리
----------------------------------------------------

선언적 예외처리는 struts-config.xml등에 예외에 대해서 정의 하는 것 입니다. 이에 반해 프로그램적 예외 처리는 선언적 예외 처리와 정반대되는 개념으로 애플리케이션에서 정의한 내부 코드를 통해 예외를 처리하는 전통적인 방법 입니다.

아래는 login Action에서 발생하는 세가지 예외를 정의한 것 입니다.

<action-mappings>
                <action
                        path="/login"
                        type="com.oreilly.struts.storefront.security.LoginAction"
                        name="loginForm"
                        scope="request"
                        input="/login.jsp">
               
                <!--The following exceptions can be thrown during the login action -->
                <exception
                        key="security.error.changepassword"
                        path="/changePassword.jsp"
        type="com.oreilly.struts.framework.exceptions.ExpiredPasswordException"/>

                <exception
                        key=" security.error.loginfailed"
                type="com.oreilly.struts.framework.exceptions.InvalidLoginException"
                        path="/login.jsp"/>

                <exception
                        key="security.error.accountlocked"
        type="com.oreilly.struts.framework.exceptions.AccountLockedException"
                        path="/accountLocked.jsp"/>
        </action>
</action-mappings>


위에서 exception 요소는 정의한 예외가 발생 할 경우 포워드할 경로를 액션 매핑이나 전역 예외에 정의 합니다. Login Action이 실행하는 동안 ExpiredPasswordException이 발생 한다면 컨트롤러의 제어를 changePassword.jsp로 포워드 됩니다.

예외를 Action 클래스에 프로그램 코드를 통해 코딩을 하지 않았다면 RequestProcessor는 정의한 예외 타입을 설정한 exception 요소가 있는지 확인 하며 만약 exception 요소가 있다면 컨트롤러는 exception 요소의 path 속성에 지정된 자원으로 포워드 합니다.

아래는 RequestProcessor 클래스의 processException() 메소드 입니다. 메소드의 시작 시점에 findException() 메소드가 ExceptionConfig 객체를 반환 하는데 ExceptionConfig 객체는 설정 파일에 기술된 exception 요소가 메모리에 있는 것으로 생각하면 됩니다.

만약 findException() 메소드가 발생한 예외와 대응하는 exception 요소를 찾지 못하면 스트럿츠 프레임워크에서의 예외 처리 없이 클라이언트에 반환 됩니다. 발생한 예외가 IOException이나 IOException 클래스의 서브 클래스가 아니면 ServletException 인스턴스로 감싸서 다시 던집니다.

만약 특정한 예외를 정의한 Action Mapping이 있다면 findException() 메소드를 통해 ExceptionConfig 객체를 반환 합니다.

getHandler() 메소드는 ExceptionConfig 객체를 추출하고 추출한 핸들러를 예외를 처리하는데 사용 합니다.

--------------------------------------------------------
protected ActionForward processException(HttpServletRequest        request,
                                        HttpServletResponse response,
                                        Exception exception,
                                        ActionForm form,
                                        ActionMapping mapping)
                                        throws IOException, ServletException {
        // Is there a defined handler for this exception?
        ExceptionConfig config =mapping.findException(exception.getClass( ));

        if (config == null){
                if (log.isDebugEnabled( )){
                        log.debug(getInternal().getMessage("unhandledException",exception.getClass( )));
                }

        if (exception instanceof IOException){
                throw (IOException) exception;
        }
        else if (exception instanceof ServletException){
                throw (ServletException) exception;
        }
        else{
                throw new ServletException(exception);
        }


        // Use the configured exception handling
        try {
                Class handlerClass = Class.forName(config.getHandler( ));
                ExceptionHandler handler =(ExceptionHandler)handlerClass.newInstance( );
                return (handler.execute(exception, config, mapping,        form,request, response));
        }
        catch (Exception e){
                throw new ServletException(e);
        }
}


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

스트럿츠 프레임워크에서는 예외 처리에 관한 환경 설정이 되어 있지 않은 경우 사용 가능한 기본 예외 처리 클래스를 포함 하고 있는데. org.apache.struts.action.ExceptionHandler가 기본 핸들러 입니다.

기본 핸들러의 execute() 메소드는 ActionError를 생성하고 적절한 scope에 저장한 다음 exception 요소의 path 속성에 할당 되어 있는 ActionForward 객체를 반환 합니다. 결국 Actionforward의 경로로 제어를 넘기게 됩니다.

예외가 발생 했을 때 다른 처리를 원한다면 exception 요소는 핸들러 클래스에 대한 오버라이드를 허용 합니다. 즉 struts-config.xml 파일에 exception 요소 안에서 handler 속성에 org.apache.struts.action.ExceptionHandler 클래스를 상속하는 클래스를 명시 함으로서 가능 합니다. Handler 클래스의 execute() 메소드를 오버라이드 함으로서 각각의 애플리케이션들은 기본 예외에서 확장된 예외 처리를 할 수 있습니다.



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

import java.util.List;
import java.util.ArrayList;
import java.io.PrintStream;
import java.io.PrintWriter;
/**
* 이 클래스는 애플리케이션 예외의 공통 슈퍼 클래스 입니다.
* 이 클래스와 이 클래스의 서브 클래스는 chained exception 기능을 제공
* chained exception 기능은 원래 문제를 이 클래스나 이 클래스의 서브 클래스로
* 감싸서 다시 실행 할 수 있습니다.
* 이 클래스는 exception을 List로 관리 함으로서 다중 예외 처리가 가능 합니다.
*/
public class BaseException extends Exception{
        protected Throwable rootCause = null;
       
        //예외를 여러 개 관리하고 나중에 ActionError를 만들 때도 반영
        private List exceptions = new ArrayList( );

        private String messageKey = null;
        private Object[] messageArgs = null;

        public BaseException( ){
                super( );
        }
       
        //생성자
        public BaseException( Throwable rootCause ) {
                this.rootCause = rootCause;
        }

        public List getExceptions( ) {
                return exceptions;
        }

        public void addException( BaseException ex ){
                exceptions.add( ex );
        }

        public void setMessageKey( String key ){
                this.messageKey = key;
        }

        public String getMessageKey( ){
                return messageKey;
        }
       
        //어떤 메시지는 아규먼트가 여러 개 일 수 있습니다.
        // 예를들면 나이는 0 ~ 99 사이의 수가 들어와야 합니다.
        public void setMessageArgs( Object[] args ){
                this.messageArgs = args;
        }

        public Object[] getMessageArgs( ){
                return messageArgs;
        }

        public void setRootCause(Throwable anException) {
                rootCause = anException;
        }

        public Throwable getRootCause( ) {
                return rootCause;
        }

        public void printStackTrace( ) {
                printStackTrace(System.err);
        }

        public void printStackTrace(PrintStream outStream) {
                printStackTrace(new PrintWriter(outStream));
        }

        public void printStackTrace(PrintWriter writer) {
                super.printStackTrace(writer);
                if ( getRootCause( ) != null ) {
                        getRootCause( ).printStackTrace(writer);
                }
                writer.flush( );
        }
}



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

아래에서 messageKey는 ActionError 클래스의 생성자에 전달되고 스트럿츠 프레임웍에서는 키와 리소스 번들의 메시지를 대응 시킵니다. 또한 클래스는 생성된 예외들을 추가 할 수 있는 객체 배열을 포함합니다.

객체 배열에 있는 예외 객체들은 MessageFormat을 기반으로 파라미터에 따라 리소스 번들의 메시지를 교환 할 수 있습니다. 번들 안에 있는 메시지는 다음과 같습니다.

global.error.invalid.price=The price must be between {0} and {1}.

아래는 기본 예외 핸들러 클래스를 확장 하고 ActionError 생성자 내부의 인자를 동적으로 생성하는 기능을 제공 합니다.

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

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ExceptionHandler;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionError;
import org.apache.struts.util.AppException;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.config.ExceptionConfig;
import com.oreilly.struts.framework.exceptions.BaseException;

public class SpecialExceptionHandler extends ExceptionHandler
{
        protected ActionForward execute(Exception ex,
                        ExceptionConfig config,
                        ActionMapping mapping,
                        ActionForm formInstance,
                        HttpServletRequest request,
                        HttpServletResponse response)
                                        throws ServletException {
                ActionForward forward = null;
                ActionError error = null;
                String property = null;

                /* input 속성이나 exception 요소에서 포워드할 path를 가져옴 */
                String path = null;
                if (config.getPath( ) != null) {
                        path = config.getPath( );
                }
                else{
                        path = mapping.getInput( );
                }

                // Construct the forward object
                forward = new ActionForward(path);

                /* Figure out what type of exception has been thrown.The Struts
                * AppException is not being used in this example.
                */
                if( ex instanceof BaseException) {
                        // ********* 특화된 처리 부분
                        BaseException baseException = (BaseException)ex;
                        String messageKey = baseException.getMessageKey( );
                        Object[] exArgs = baseException.getMessageArgs( );
                        if ( exArgs != null && exArgs.length > 0 ){
                        // If there were args provided, use them in the       
ActionError
                                error = new ActionError( messageKey, exArgs );
                        }
                        else{
                                // Create an ActionError without any arguments
                                error = new ActionError( messageKey );
                        }
                }
                else{
                        error = new ActionError(config.getKey( ));
                        property = error.getKey( );
                }

                // Store the ActionError into the proper scope
                // The storeException method is defined in the parent        class
                storeException(request, property, error, forward,
                config.getScope( ));
                return forward;
        }
}


스트럿츠의 예외 처리에 대해 정리해보면 Action에서 execute() 메소드를 실행 시 예외처리를 위해 try-catch로 쌉니다. 예외가 발생 했다면 RequestProcessor 클래스의 findException이 호출되어 ExceptioConfig 객체를 반환 합니다. 다음으로 getHandler() 메소드가 호출 되어 핸들러를 얻습니다. 다음으로 기본 핸들러만 정의되어 있다고 보면 핸들러 클래스의 execute() 메소드가 호출되고 여기에서 ActionError를 생성 후 적절한 scope에 저장 후 path 속성에 정의된 리소스로 제어를 넘깁니다.

 


-------------------------------
프로그램에서 오류 처리하기
-------------------------------

Action 클래스에서 예외가 발생 했을 때 만약 발생한 예외가 애플리케이션 예외 인 경우 로그를 남기고 ActionError를 생성하여 해당 스코프에 저장한 후 ActionForward를 통해 제어를 넘기는 식으로 처리 합니다.

예외의 효과적인 관리를 위해 최상위 래퍼 클래스(BaseException)를 하나 만들고 애플리케이션 예외를 모두 그 안에 두는 것 입니다. 이렇게 하면 catch 문에서 BaseException만 받아내면 될 것 입니다. (BaseException이 아니면 시스템 예외라고 가정 할 수 있으며 이렇게 처리 해야 합니다.)

시스템 예외 처리 방법은 예외를 로그로 남기고 시스템 에러 페이지를 만들어 그곳으로 포워드 시키면 됩니다.

아래는 Action안에서의 처리 입니다.

try{
        // Peform some work that may cause an application or system        exception
}
catch( BaseException ex ){
        // Log the exception
        // Create and store the action error
        ActionErrors errors = new ActionErrors( );
        ActionError newError = new ActionError( ex.getErrorCode(),ex.getArgs( ) );
        errors.add( ActionErrors.GLOBAL_ERROR, newError );
        saveErrors( request, errors );

        // Return an ActionForward for the Failure resource
        return mapping.findForward( "Failure" )
}
catch( Throwable ex ){
        // Log the exception
        // Create and store the action error
        ActionError newError = new        ActionError( "error.systemfailure" );
        ActionErrors errors = new ActionErrors( );
        errors.add( ActionErrors.GLOBAL_ERROR, newError );
        saveErrors( request, errors );
        // Return an ActionForward for the system error resource
        return mapping.findForward( IConstants.SYSTEM_FAILURE_PAGE );
}

Action마다 이렇게 한다는 것은 중복되는 코드가 발생 할 수 있는데 앞에서 설명 드린 선언적 접근 방법을 이용한다면 해결 할 수 있지만 Action의 최상위인 BaseAction을 하나 만들어 이를 해결 할 수 있습니다.

모든 action에 공통적으로 들어가야 할 기능이 있다면 (로그인 체크,접속/비 접속 체크,쇼핑 카트 등) 그것을 구현해 놓고(추상 클래스로), 다른 action들이 struts의 action을 상속받지 않고, 이 공통 action을 상속받게 합니다. 이것은 필수요소가 아니라 선택사항입니다. 공통사항이 없다면 하지 않아도 상관 없습니다.

아래에 최상위 Action에 관련된 예문이 있으니 참고 바랍니다.
 
//execute( ) method of the BaseAction(Action의 최상위 클래스로서 추상클래스 입니다.)
//아래의 경우 예외 발생시 execute 메소드의 catch에 의해 잡힙니다.
public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response) throws Exception {
ActionForward forwardPage = null;
        try{
                UserContainer userContainer = getUserContainer( request );
                // 이부분에 필요하다면 모든 액션들이 공통으로 확인해야 되는 사항이
                //있다면 처리 합니다.(로그인 여부, 장바구니 확인 등)

        // 별도로 선언된 executeAction을 실행 시킵니다.
        // executeAction은 서브 액션의 입맛에 맞게 적절히 구현해서 사용 합니다.
        //예를들면 게시판 기능이라면 게시물을 읽는 기능, 쓰는 기능, 삭제 기능, 수정 기능 등이  될 수 있습니다.
                forwardPage = executeAction(mapping, form, request,        response, userContainer);
        }
        //아래의 catch문이 모든 Action에 있어야 하는 겁니다.
        catch (BaseException ex){
                // Log the application exception using your logging        framework
                // Call the generic exception handler routine
                forwardPage = processExceptions( request, mapping,        ex );
        }catch (Throwable ex){
                // Log the system exception using your logging framework
                // Make the exception available to the system error page
                request.setAttribute( Action.EXCEPTION_KEY, ex );

                // Treat all other exceptions as system errors
                forwardPage =mapping.findForward( IConstants.SYSTEM_FAILURE_KEY );
        }
        return forwardPage;
}

//추상메소드로 선언하고 이 최상위 액션을 상속 받는 하위 액션들의 입맛에 맞게 구현토록 합니다.
abstract public ActionForward executeAction( ActionMapping mapping,
                                                                                        ActionForm form,
                                                                                        HttpServletRequest request,
                                                                                        HttpServletResponse response,
                                                                                        UserContainer userContainer )
throws BaseException;


다음은 execute() 메소드에서 예외가 발생 되었을 때 이것을 처리하기 위한 BaseAction의processException() 메소드를 보도록 합니다.

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

Action안에 정의 되어 있습니다. 이 메소드는 여러 개일지 모르는 예외를 찾아 예외의 수 만큼 processBaseException 이라는 메소드를 다시 불러 그곳에서 ActionError등에 저장 하는 기능 등을 수행하도록 합니다.

protected ActionForward processExceptions( HttpServletRequest request,
                                        ActionMapping mapping,
                                        BaseException ex )
{
        ActionErrors errors = new ActionErrors( );
        ActionForward forward = null;

        // 사용자의 지역 설정을 가지고 옵니다.
        Locale locale = getUserContainer( request ).getLocale( );
        if (locale == null){
                        // 지역이 설정되지 않았다면 기본 지역을 사용
                        environment locale = Locale.getDefault( );
        }

        processBaseException(errors, (FieldException) ex, locale);

        // 입력된 리소스와 failure 포워드를 반환 합니다.
        String inputStr = mapping.getInput( );
        String failureForward = mapping.findForward(IConstants.FAILURE_KEY);

        if ( inputStr != null) {
                forward = new ActionForward( inputStr );
        }
        else if (failureForward != null){
                forward = failureForward;
        }

        // 예외가 하위 예외를 포함하고 있는지 확인
        List exceptions = ex.getExceptions( );

        if (exceptions != null && !exceptions.isEmpty( ) ){
                int size = exceptions.size( );
                Iterator iter = exceptions.iterator( );

                while( iter.hasNext( ) ){
                        // 모든 하위예외들은 BaseException이어야 합니다.
                        BaseException subException =(BaseException)iter.next( );
                        processBaseException(errors, subException, locale);
                }
        }

        // Tell the Struts framework to save the errors into the request
        saveErrors( request, errors );

        // Return the ActionForward
        return forward;
}


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

processException 메소드의 수행 과정은 다음과 같습니다.

1.        사용자의 지역 확인
2.        Top레벨 예외의 processBaseException() 메소드를 수행
3.        다른 서브 예외가 있다면 각각의 예외를 수행
4.        생성한 모든 ActionError를 저장
5.        제어를 input 속성에 있는 리소스나 액션에 설정된 “Failure” Actionforward에 넘김


아래는 BaseAction의 processBaseException 메소드 입니다.


protected void processBaseException( ActionErrors errors,
                                                                        BaseException ex,
                                                                        Locale locale)
{

        // 추가될 ActionError의 레퍼런스 저장
        ActionError newActionError = null;

        // 에러 코드는 리소스 번들의 키값
        String errorCode = ex.getMessageKey( );

        /*MessageFormat 객체가 사용하는 추가적인 인자가 있다면
        * args에 예외를 추가
        */
        Object[] args = ex.getMessageArgs( );

       
        // ACtionError 클래스의 인스턴스 생성자
        if ( args != null && args.length > 0 ){
                // Use the arguments that were provided in the exception
                newActionError = new ActionError( errorCode, args );
        }
        else{
                newActionError = new ActionError( errorCode );
        }

        errors.add( ActionErrors.GLOBAL_ERROR, newActionError );

[오라클자바닷넷강좌]JAVA AWT Component 클래스

이번 강좌에서는 중요한 Component 클래스에 대해 알아 보겠습니다. 자바 클래스의 최상위 클래스가 Object인 것처럼, AWT의 GUI콤포넌트의 최상위 클래스는java.awt.Component입니다. Component의 하위클래스에는 다시 Button, Canvas, Checkbox, Choic, Label, List, Scrollbar, TextComponent 과 Container가 존재합니다. 그리고, 그중에서, Container콤포넌트는 Button, Canvas..와 같은 일반 콤포넌트와 달리, 다른 Component와 Container를 포함할수 있습니다.


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  




Component Class(Abstract)
- 자바의 모든 Component가 상속을 받는 클래스 -
- 이 클래스를 상속 받는 클래스가 적절히 Method 들을 Overriding 해줘야 함
- Component로서의 기본적인 기능들을 정의및 선언, 하위 클래스에 대한 공통적인 요소(Attribute)아 행동(Behavior, method)을 정의
- 이들 Component는 다른 Component를 자신안에 둘수 있는 컨테이너 콤 포넌트이고, 다른 하나는 컨테이너 역할을 할수 없는 단순한 Component
- 기존 OS 기반 위에서 만들어 지므로 OS가 가지고 있는 Component만을 지원
- Java.awt Package안에 포함되어 있습니다.

배치/위치와 관련된 Method
doLayout() : 이 컴포넌트를 배치하도록 배치 관리 프로그램에 프롬프트 합니다.
validate() : 컨테이너와 모든 부속 컴포넌트가 Valid Layout을 가짐을 확인 합니다. 컨테이너와 하부 컴포넌트를 다시 배치 합니다.
invalidate() : 컨테이너와 모든 부속 컴포넌트가 다시 그려져야 한다고 표시
setVisible(boolean?b) : b 가 true인 경우 Component를 보이게 설정, false인 경우 안보이게 설정
getLocation() : Component의 위치를 x,y형태의 Point 유형의 객체로 Return 합니다.
getLocation(Point ?rv) : Component의 위치를 x,y형태의 Point 유형의 객체로 Return 한다.
getLocationOnScreen() : 화면의 좌표 공간에 컴포넌트의 왼쪽 상단을 지정하여, 점 형식으로 이 컴포넌트의 위치를 가져 옵니다.
setLocation(int?x, int?y) : Component의 위치를 x ,y에 대응시킵니다.
setLocation(Point?p) : Component의 위치를 점 p에 대응시킵니다.
getBounds() : 객체의 위치와 크기를 Rectangle 유형의 객체로 Return 합니다.
getBounds(Rectangle ?rv) : 객체의 위치와 크기를 Rectangle rv로 Return 합니다.
setBounds(int?x, int?y, int?width, int?height) : Component 객체의 위치를 x,y에 위치시키고 그 크기는 width, height 로 합니다.
setBounds(Rectangle ?r) : Component 객체의 위치및 크기를 Rectabgle r로 합니다.
getX(), getY()


크기와 관련된 Method
getSize() : Component의 크기를 Dimension 객체(width, height)로 Return 합니다.
getSize(Dimension ?rv):Component크기를 Dimension객체 rv로 Return 합니다.
setSize(int?width, int?height) : component의 크기를 width와 height로 설정합니다.
setSize(Dimension ?d) : Component의 크기를 Dimention 객체의 width와 height로 설정 합니다.
getPreferredSize() : 이 컴포넌트의 선호 크기를 가져옵니다.
getWidth() : getHeight() :
getMaximumSize() : 이 컴포넌트의 최대 크기를 가져 옵니다.
getMinimumSize() : 이 컴포넌트의 최소 크기를 가져 옵니다.

Graphic과 관련된 메소드
getForeground() : 현재 전경색을 읽어 Color유형의 객체로 Return 합니다.
setForeground(Color c) : 현재 전경색을 Color유형의 객체 c 로 설정 합니다.
getBackground() : 현재 배경색을 읽어 Color 유형의 객체로 Return 합니다.
setBackground(Color c) : 현재 배경색을 Color 유형의 객체c로 설정 합니다.
getFont() : Component 객체의 글꼴을 Font 객체 형태로 Return 합니다.
setFont(Font f) : Component 객체의 글꼴을 설정한다.
getFontMetrics(Font font) : 지정된 글꼴의 글꼴 행렬을 가져 옵니다.
setCursor(Cursor cursor) : 커서 이미지를 사전 정의된 커서로 설정 합니다.
getCursor() : 커서가 이 컴포넌트상에 설정되도록 합니다.
paint(Graphics g) : 이 컴포넌트의 색상을 표시 합니다.
paintAll(Graphics g) : 이 컴포넌트와 모든 서브컴포넌트의 색상을 표시 합니다.
repaint() : 이 컴포넌트의 색상을 표시 합니다.
repaint(long tm) : 이 컴포넌트의 색을 다시 표시 합니다.
repaint(int x, int y, int width, int height) : 이 컴포넌트의 지정된 사각형 색상을 표시 합니다.
repaint(long tm, int x, int y, int width, int height) : tm 밀리쎄컨드 내에 이 컴포넌트의 지정된 사각형 색상을 표시 합니다.
print(Graphics g) : 이 컴포넌트의 색상을 표시 합니다.
printAll(Graphics g) : 이 컴포넌트와 모든 서브컴포넌트의 색상을 표시 합니다.
update(Graphics g) : 이 컴포넌트를 갱신 합니다.

Event와 관련된 메소드
processEvent(AWTEvent e) : 이 컴포넌트에서 발생하는 이벤트를 처리 합니다.
processComponentEvent(ComponentEvent e) : 등록된 ComponentListener 객체로 보내어, 이 컴포넌트에서 발생하는 컴포넌트 이벤트들을 처리 합니다.
processFocusEvent(FocusEvent e):등록된FocusListener객체로 보내어, 컴포넌트에서 발생하는 초점이벤트들을 처리
processKeyEvent(KeyEvent?e) : 등록된 KEYLISTENER객체로 보내어, 이 컴포넌트에서 발생하는 키 이벤트들을 처리.
processMouseEvent(MouseEvent e):등록된 MouseListener 객체로 보내어, 이 컴포넌트에서 발생하는 마우스이벤 처리
processMouseMotionEvent(MouseEvent e) : 등록된 MouseMotionListener 객체로 보내어, 이 컴포넌트에서 발생하는 마우스 모션 이벤트들을 처리 합니다.
processInputMethodEvent(InputMethodEvent e) : 등록된 InputMethodListener 객체로 보내어, 이 컴포넌트에서 발생하는 InputMethod 이벤트들을 처리 합니다.
addComponentListener(ComponentListener?l) : 이 컴포넌트로부터 컴포넌트 이벤트를 받기 위해 지정된 컴포넌트 수신기(listener)를 추가합니다.
removeComponentListener(ComponentListener l) :
addFocusListener(FocusListener l) :이 컴포넌트로부터 초점 이벤트를 받기 위해 지정된 초점 수신기를 추가 합니다.
removeFocusListener(FocusListener l)
addKeyListener(KeyListener l) : 이 컴포넌트로부터 키 이벤트를 받기 위해 지정된 키 수신기를 추가.
removeKeyListener(KeyListener l) :
addMouseListener(MouseListener l) : 이 컴포넌트로부터 마우스 이벤트를 받기 위해 지정된 마우스 수신기를 추가 합니다.
removeMouseListener(MouseListener l)
addMouseMotionListener(MouseMotionListener l) : 이 컴포넌트로부터 마우스 모션 이벤트를 받기 위해 지정된 마우스 모션 수신기를 추가 합니다.
removeMouseMotionListener(MouseMotionListener l) addInputMethodListener(InputMethodListener l) : 이 컴포넌트로부터 Input Method 이벤트를 받기 위해 지정된 Input Method 수신기를 추가 합니다.
removeInputMethodListener(InputMethodListener l)

addPropertyChangeListener(PropertyChangeListener listener) : 이 컴포넌트로부터 Property Change 이벤트를 받기 위해 지정된 Input Method 수신기를 추가 합니다.
removePropertyChangeListener(PropertyChangeListener listener)

getListeners(Class listenerType) : addXXXListener()로 추가된 리스너 들을 리스너 배열로 Return 합니다.
기타 메소드
addNotify() : 이 컴포넌트가 컨테이너에 추가되었고, 피어(peer)가 필요하면 작성해야 한다는 것을 이 컴포넌트에 알립니다.
removeNotify() : 이 컴포넌트가 컨테이너에서 제거되었고, 피어(peer)가 있으면 피어가 제거된다는 것을 이 컴포넌트에 알립니다.
add(PopupMenu popup) : 지정된 팝업 메뉴를 컴포넌트에 추가 합니다.
contains(Point p) : 이 컴포넌트에 지정된 점이 "포함"되어 있는지 점검합니다. 이 점의 x 및 y 좌표는 이 컴포넌트의 좌표 체계에 비례하여 정의 됩니다.
contains(int x, int y) : 이 컴포넌트에 지정된 점이 "포함"되어 있는지 점검합니다. 여기서 x와 y는 이 컴포넌트의 좌표 체계에 비례하여 정의 됩니다.
isEnabled() : 이 컴포넌트가 작동 가능한지 판별 합니다.
setEnabled(boolean b) : 매개변수 b 값에 따라 이 컴포넌트를 작동시키거나 작동 불가능하게 합니다.
getComponentAt(int x, int y) : 이 컴포넌트 또는 바로 아래 부속 컴포넌트 중 하나에 (x,?y) 위치가 있는지 판별 합니다. 있으면 포함된 컴포넌트를 리턴 합니다. .
getComponentAt(Point p) : 지정된 지점이 속해 있는 서브컴포넌트 또는 컴포넌트를 리턴 합니다.
getName() : 컴포넌트의 이름을 가져옵니다.
setName(String name) : 지정된 문자열로 컴포넌트 이름을 설정 합니다.
getParent() : 이 컴포넌트의 상위 컴포넌트를 가져 옵니다.
getToolkit() : 이 컴포넌트의 도구 킷을 가져 옵니다.
hasFocus() : 컴포넌트가 KeyBoard Focus를 가지고 있는지 boolean형 Return
isVisible() : 이 컴포넌트가 가시적인지 판별 합니다.
list() : 표준 시스템 출력 스트림 System.out으로 이 컴포넌트의 목록을 인쇄 합니다.
list(PrintStream out) : 지정된 출력 스트림으로 이 컴포넌트의 목록을 인쇄 합니다.
list(PrintStream out, int indent) : 지정된 들여쓰기 위치에서 시작하여 지정된 인쇄 스트림으로 목록을 인쇄 출력 합니다.
list(PrintWriter out) : 지정된 인쇄 작성자로 목록을 인쇄합니다.
list(PrintWriter out, int indent) : 지정된 들여쓰기 위치에서 시작하여 지정된 인쇄 작성자로 목록을 인쇄 합니다.
isShowing() : 이 컴포넌트가 화면에 표시되고 있는지 판별합니다. isValid() : 이 컴포넌트가 유효한지 판별 합니다.
isDisplayable() : 이 컴포넌트가 displayable 인지 판별
isLightweight() : native Peer Component를 가지지 않는 Component인지 판별 true if this component has a lightweight peer; false if it has a native peer or no peer. Component나 Container의 하위클래스중 Button이나 Scollbar 같은 것이외의 것들은 lightweight Component, 스윙 컴포넌트는 lightWeight Component 컴포넌트가 displayabke 이 아니면 false

아래의 예제를 참고 하세요~

import java.awt.*;
public class AwtTest extends Frame {
Button btn; Label lbl ; TextArea ta; TextField tf; Checkbox cb1, cb2;
Choice choice; List list;
AwtTest () {
btn = new Button("버튼");
lbl = new Label("라벨");
ta = new TextArea("TextArea", 5, 20); // 5행, 20열
tf = new TextField("TextField", 20); // 20칸
cb1 = new Checkbox("체크박스1");
cb2 = new Checkbox("체크박스2");
choice = new Choice();
list = new List(3,true); // 보여지는것은 2개이고 다중선택은 true로 지정
}
void display() {
setLayout(new FlowLayout()); // 컴포넌트 배치 설정
add(btn);
add(lbl);
add(ta);
add(tf);
add(cb1);
add(cb2);

choice.add("초록"); // 콤보박스에 항목 추가
choice.add("빨강");
choice.add("파랑");
add(choice);
list.add("봄"); // 리스트박스에 항목 추가
list.add("여름");
list.add("가을");
list.add("겨울");
add(list);
pack();
setVisible(true);
}
public static void main(String args[]) {
AwtTest myFrame = new AwtTest();
myFrame.display();
}
}








2013년 8월 5일 월요일

(자바스윈, 오라클자바교육, ORACLEJAVA EDU)JAVA Swing이란

이번 강좌에서는 전강좌에 이어 스윙에 대해 살펴 보도록 하겠습니다.



오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의) 

 www.onjprogramming.co.kr




컴포넌트와 컨테이너

Container로 부터 파생된 클래스는 다른 Component를 담을수 있으며, 컨테이너라고 부릅니다. 컨테이너는 다른 컨테이너를 포함할수도 있습니다(Window및 그하위 클래스는 예외) JFrame객체는 Application용 메인 윈도우를 나타내며, Window 객체는 그렇지않습니다. 윈도우를 만들기위해서는 항상 JFrame이 필요 합니다. 스윙의 독립 윈도우 컨테이너들은 AWT가 제공해주지 못하는 능력을 제공하기 위해 JFrame에 이미 JRootPane이라는것을 만들어 두었는데 여기에 프로그래머가 만든 컴포넌트는 JRootPane이 관리하고 있는 contantPane이라는것에 넣도록 하고 있습니다.. JFrame, JApplet, JWindow, JDialog등은 JComponent를 상속하지 않으므로 스윙의 능력을 직접 쓸수 없는 대신 JComponent를 상속받은 JRootPane을 미리 넣어 두는것 입니다. 그렇게 함으로서 독립적인 윈도우로 표시되는 컨테이너도 스윙의 기능을 사용할수 있으며 그렇게 하기위해서는 프로그래머가 만든 컴포넌트를 contentPane에 넣는 것 입니다.

JRootPane
- AWT의 경우 Frame에 직접 add를 사용하여 컴포넌트를 추가하였으나 JFrame의 경우엔 getContentPane()을 이용하여 contentPane을 얻은후 거기에 컴포넌트를 추가 합니다.
- JFrame, JApplet, JDialog, JWindow등은 RootPaneContainer 인터페이스를 구현하고 있으며 getXXXPane() 함수등으로 pane(창)을 얻은후 작업을 합니다. 이 인터페이스에는 setXXXPane메소드도 존재 합니다.
- glasspane(투명창) : 기본적으로 보여지지 않게 설정되었으며 보여지게 한다면 어떤 컴포넌트 등의 위에 그림을 그릴 수 있다. 또한 마우스 이벤트등을 가로채 반응을 안하게 할수있습니다.-
- layeredPane(다중창) : contentPane과 JMenuBar(생략가능)등을 담으며 다층레이어로 이루어져 팜업메뉴, ToolTip과 같은 컴포넌트가 contentPane위에 오도록 보장 합니다. 즉 서로다른 레이어를 가지는 컴포넌트를 담을수 있습니다.
- contentPane(내용창) : 루트창의 가시적인컴포넌트들(메뉴창 제외)을 담은 개체
- JMenuBar(메뉴바) : 컨테이너의 메뉴를 담습니다.
- JRootPane 개체는 직계 부속 컴포넌트를 가질 수 없으므로 JRootPane 에 컴포넌트를 직접 부착 할 수 없고 , 그에 따라 다음 표현은 틀린 것이다 . rootPane.add(child); 그 대신 JRootPane 의 contentPane 을 구해 여기에 컴포넌트를 부착 합니다 . rootPane.getContentPane().add(child);

 



2013년 8월 3일 토요일

[오라클Hint]ACCESS 경로를 변경하는 힌트(CLUSTER) , Oracle Tuning, Oracle Hint, OracleJava


구로디지털 오엔제이프로그래밍실무교육센터


클러스터 스캔을 이용해 데이터를 추출하도록 하는 힌트 문이며 INDEX CLUSTERED TABLE에서 사용 가능한 문장 입니다.

[형식]

아래의 예문을 참고 하세요

SELECT 
employees.last_name, department_id
FROM employees, departments
WHERE department_id = 10 
AND employees.department_id = departments.department_id;


아래 내용을 참고 하세요

인덱스 클러스터란(Index Cluster) ?
  - 클러스터 내의 데이터를 유지하기 위해 클러스터 인덱스라는 인덱스 사용
  - 클러스터 인덱스는 주어진 키 값을 가진 행을 포함하고 있는 블록을 가리키는데 사용
  - 클러스터 인덱스의 구조는 보통 인덱스의 구조와 비슷
     (보통 인덱스가 NULL 키 값을 저장하지 않지만 클러스터 인덱스는 NULL 키를 저장)
  - 클러스터로부터 행을 저장하고 읽어 들이기 위해 오라클 서버는 주어진 키 값을
갖는 첫 행을 가리키는 클러스터 인덱스를 사용


Cluster Index Table Index의 차이점
- 클러스터 Index는 클러스터 행당 하나의 입력 항목이 아닌 클러스터 키 값당 하나의
입력  항목을 포함.
- table Index
는 없어도 사용자에게 영향을 주지 않지만 Cluster Index는 없으면 클러스터화된 데이터에 액세스 불가능


[실습]

-      실습을 위한 예제 테이블 및 데이터는 아래 링크에서 확인 바랍니다.

myemp1 : 1000만건
myemp1_old : 100만건
mydept : 5

테스트환경 : oracle 11g
 


아래 예문을 따라 실습하세요.
create cluster myemp1_mydept1 (deptno number)

create table myemp3 (
empno number,
deptno number)
cluster myemp1_mydept1(deptno)

create table mydept3 (
    deptno number,
    dname varchar2(100)
) cluster myemp1_mydept1(deptno)

create index idx_myemp1_mydept1 on cluster myemp1_mydept1

insert into myemp3  select empno, deptno from myemp1 where rownum < 5000000
insert into mydept3 select deptno, dname from mydept1

select
       e.empno,
       d.dname
  from mydept3 d,
       myemp3 e
 where e.deptno = d.deptno ;


select
       e.empno,
       d.dname
  from mydept3 d,
       myemp3 e
 where e.deptno = d.deptno ;