장소 : 썬 교육센터
날짜 : 10.22 ~ 10.26
시간 : 09:30 ~ 17:30
내용 : Web Component Developement with Servlet and JSP Technologies
# Day 3
## EJB
SessionBean -+- Stateful, Stateless
|
EntityBean -+- CMP(Container Managed Persistence) -+- CMR
| |
| +- EJB-QL
+- BMP(Bean Managed Persistence)
Message Driven Bean
## JMS (Java Message Service)
: 비동기 메시지 처리
: Mail, Log 기록에서 유용
: P2P(Peer-to-Peer)
message 생산자 여러개, message 소비자 한개
: pub/sub (publisher/subscriber)
message 생산자 한개, message 소비자 여러개
* 동기 메시지 처리
메세지 생산자가 메시지 소비자의 응답을 기다린다.
ex) HTTP 웹 프로그램
* 비동기 메시지 처리
메시지 생산자가 메시지 소비자의 응답을 기다리지 않는다.
ex) AJAX
운영도구
: WebLogic 콘솔 관리자
Connection Factory
: P2P => javax.jms.QueueConnectionFactory
: pub/sub => javax.jms.TopicConnectionFactory
목적지
메세지를 처리하기 위한 자원
: P2P -> Queue
: pub/sub -> Topic
Connection
: P2P -> QueueConnection
: pub/sub -> TopicConnection
Session(통신 라인)
메시지를 생성하고 소비하기 위한 단일 스레드 환경
: P2P -> QueueSession
: pub/sub -> TopicSession
메시지 생산자
: P2P -> QueueSender.send()
: pub/sub -> TopicPublisher.publish()
메시지 소비자
: P2P -> QueueReceiver.receive()
: pub/sub -> TopicSubscriber.setMessageListener()
메시지
Header, Porperty, Body
TextMessage
MapMessage
ByteMessage
StreamMessage
ObjectMessage
Message
## JMS 서비스 설정
Store 설정
WebLogic 콘솔 -> Services -> JMS -> Stores -> create new File Store
디렉토리명 : myjmsfilestore
위치 : C:\bea\user_projects\domains\mydomain\myjmsfilestore
store name : MyJMSFileStore
Server 설정
WebLogic 콘솔 -> Services -> JMS -> Servers -> create new server
Persistence Store : 위에서 생성한 Store 명 지정
server name : MyJMSServer
Server에 목적지(Destination - queue/topic) 설정
WebLogic 콘솔 -> Services -> JMS -> Servers -> 위에서 생성한 Server -> Destination -> configure new JMS Queue
queue name : MyJMSQueue
WebLogic 콘솔 -> Services -> JMS -> Servers -> 위에서 생성한 Server -> Destination -> configure new JMS Topic
topic name : MyJMSTopic
* JMS Server -> Destination (queue/topic) -> File Store -> myjmsfilestore(C:\bea\user_projects\domains\mydomain\myjmsfilestore)
* 생산자 --> JMS Server
|
+---> Destination ( queue / topic )
|
+---> File Store
|
+---> myjmsfilestore
|
+---> 소비자
## Queue에 메세지 보내기
import java.io.*;
import javax.jms.*;
import javax.naming.*;
import java.util.Properties;
public class MessageQueueSender {
public static void main(String[] args) {
if( args.length != 1 ) {
System.out.println("Usage : java MessageQueueSender [Message]");
System.exit(0);
}
try {
// HTTP protocol을 이용하여 WegLogic에 접근하는 것이 아니기 때문에
// java application에서 WegLogic을 사용하기 위해 설정하는 부분
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
p.put(Context.PROVIDER_URL, "t3://localhost:7001");
Context ctx = new InitialContext(p);
QueueConnectionFactory factory = (QueueConnectionFactory)ctx.lookup("weblogic.jms.ConnectionFactory");
Queue queue = (Queue)ctx.lookup("jmsqueue");
QueueConnection con = factory.createQueueConnection();
QueueSession session = con.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
QueueSender qsender = session.createSender(queue);
TextMessage message = session.createTextMessage();
message.setText(args[0]);
qsender.send(message);
qsender.send(session.createMessage());
con.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}
# Queue에서 메세지 읽어오기
import java.io.*;
import javax.jms.*;
import javax.naming.*;
import java.util.Properties;
public class MessageQueueReceiver {
public static void main(String[] args) {
Queue queue = null;
QueueConnection con = null;
QueueSession session = null;
QueueReceiver qreceiver = null;
try {
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
p.put(Context.PROVIDER_URL, "t3://localhost:7001");
Context ctx = new InitialContext(p);
QueueConnectionFactory factory = (QueueConnectionFactory)ctx.lookup("weblogic.jms.ConnectionFactory");
queue = (Queue)ctx.lookup("jmsqueue");
con = factory.createQueueConnection();
session = con.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
qreceiver = session.createReceiver(queue);
con.start();
while(true) {
Message msg = qreceiver.receive(1);
if( msg != null ) {
if( msg instanceof TextMessage ) {
TextMessage tmpMsg = (TextMessage)msg;
System.out.println("읽어온 메시지 : " + tmpMsg.getText());
if( "exit".equals(tmpMsg.getText()) ) {
break;
}
}
} else {
Thread.sleep(500);
}
}
} catch(Exception e) {
e.printStackTrace();
} finally {
try {
con.close();
} catch(Exception e) {
}
}
}
}
# Topic 에 발행하기
import java.io.*;
import javax.jms.*;
import javax.naming.*;
import java.util.Properties;
public class MessageTopicPublisher {
public static void main(String[] args) {
BufferedReader br = null;
try {
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
p.put(Context.PROVIDER_URL, "t3://localhost:7001");
Context ctx = new InitialContext(p);
TopicConnectionFactory factory = (TopicConnectionFactory)ctx.lookup("weblogic.jms.ConnectionFactory");
Topic topic = (Topic)ctx.lookup("jmstopic");
TopicConnection con = factory.createTopicConnection();
TopicSession session = con.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
TopicPublisher publisher = session.createPublisher(topic);
String line = null;
br = new BufferedReader(new InputStreamReader(System.in));
while( (line = br.readLine()) != null ) {
TextMessage message = session.createTextMessage();
message.setText(line);
publisher.publish(message);
if( "exit".equals(line) ) {
break;
}
message = null;
}
con.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}
# Topic 에서 구독하기
import java.io.*;
import javax.jms.*;
import javax.naming.*;
import java.util.Properties;
public class MessageTopicSubscriber {
public static void main(String[] args) {
BufferedReader br = null;
try {
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
p.put(Context.PROVIDER_URL, "t3://localhost:7001");
Context ctx = new InitialContext(p);
TopicConnectionFactory factory = (TopicConnectionFactory)ctx.lookup("weblogic.jms.ConnectionFactory");
Topic topic = (Topic)ctx.lookup("jmstopic");
TopicConnection con = factory.createTopicConnection();
TopicSession session = con.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
TopicSubscriber subscriber = session.createSubscriber(topic);
subscriber.setMessageListener(new MessageListener() {
public void onMessage(Message message) {
try {
if( message instanceof TextMessage) {
TextMessage m = (TextMessage)message;
System.out.println("구독 내용 > " + m.getText());
}
} catch(Exception e) {
e.printStackTrace();
}
}
});
con.start();
while(true) {
char c = (char)System.in.read();
if( c == 'q') break;
}
con.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}
# 세션 빈의 구성과 용도
원격 인터페이스
javax.ejb.EJBObject 또는 javax.ejb.EJBLocalObject를 상속받는다.
클라이언트가 호출할 비즈니스 메소드를 정의하고 있다.
홈 인터페이스
javax.ejb.EJBHome 또는 javax.ejb.EJBLocalHome 를 상속받는다.
빈 클래스를 생성, 검색, 삭제할 수 있는 메소드를 선언한다.
빈 클래스
javax.ejb.SessionBean 인터페이스를 구현한다.
원격 인터페이스에서 선언한 비즈니스 메소드를 구현해야 한다.
(EJB 클래스는 원격 인터페이스를 구현하지 않는다.)
# 세션 빈 테스트
package kr.co.ejb.examples;
/**
* Remote Interface
*
* Client가 호출할 원격 인터페이스
* Client가 호출할 메소드만 정의함
*
* @author Lucky
*/
import java.rmi.RemoteException;
import javax.ejb.EJBObject;
public interface HelloWorld extends EJBObject {
public String helloWorld() throws RemoteException;
public String hello(String param) throws RemoteException;
public String getTime() throws RemoteException;
}
package kr.co.ejb.examples;
/**
* Bean Class
*/
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
public class HelloWorldBean implements SessionBean {
private SessionContext ctx;
public void setSessionContext(SessionContext c) {
ctx = c;
}
public String helloWorld() {
return "Hello World";
}
public String hello(String param) {
return "Hello " + param;
}
public String getTime() {
return (new java.util.Date().toString());
}
public void ejbCreate() {}
public void ejbRemove() {}
public void ejbActivate() {}
public void ejbPassivate() {}
}
package kr.co.ejb.examples;
/**
* Home Interface
*
* Client가 EJB를 생성시킬 때 사용하는 메소드 정의
*
*
* @author Lucky
*/
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
public interface HelloWorldHome extends EJBHome {
public HelloWorld create() throws CreateException, RemoteException;
}
# 위 java 파일들을 compile 한 후에
WebLogic Builder를 이용해서
descriptor file 작성# package 가 시작하는 폴더에서 META-INF 폴더와 같이 jar 생성
c:\> cd c:\java\classes\helloworld
c:\java\classes\helloworld> dir
kr META-INF
c:\java\classes\helloworld>
jar cvf helloworld.jar *
c:\java\classes\helloworld> dir
kr META-INF helloworld.jar
# WebLogic 관리 콘솔에서
EJB 로 배포함 mydomain -> Deployments -> EJB Modules -> Deploy a new EJB Modules