IBM®
메인 컨텐츠로 가기
    Korea [국가변경]    이용약관
 
 
   
        제품    서비스 & 솔루션    고객지원 & 다운로드    회원 서비스    
메인 컨텐츠로 가기

한국 developerWorks  >  오픈 소스 | 자바 | WebSphere  >

Apache Geronimo JNDI 네이밍과 자바 리소스 커넥션 풀(connection pool), Part 3: 메일 세션 (한글)

Geronimo와 JNDI를 사용하여 이메일 생성, 액세스, 확인하기

developerWorks
문서 옵션

JavaScript가 필요한 문서 옵션은 디스플레이되지 않습니다.

토론

샘플 코드

영어원문

영어원문


제안 및 의견
피드백

난이도 : 중급

Dale de los Reyes, Freelance Writer, Freelance

2007 년 10 월 16 일

본 시리즈에서는 데이터 소스 커넥션과 Java Message Service (JMS) 리소스 그룹을 구현하여, 이것이 Apache Geronimo와 Java™ Naming and Directory Interface (JNDI)에서 어떻게 작동하는지를 연구했습니다. 이번 시간에는, Apache Geronimo, JNDI, 메일 세션들이 어떻게 상호 연관되는지를 알아보기로 합니다. 메일 세션을 만들고 JNDI를 사용하여 간단한 Geronimo 애플리케이션에서 여기에 액세스 하는 방법을 설명합니다.

머리말

메일 세션은 JavaMail 리소스이다. JavaMail은 이메일 시스템을 모델링 하는 API이다. 본 시리즈 Part 2에서 다루었던 JMS API와는 달리, JavaMail에 의해 처리된 메시지들은 인간이 소비하는 용도로 쓰여진다. JavaMail API는 Sun 등에서 구현되었다. 하지만, Geronimo 역시 고유의 구현을 갖고 있고 이메일 메시지를 독립적으로 보낼 수 있을 정도로 성숙했다.

소셜 북마크

mar.gar.in mar.gar.in
digg Digg
del.icio.us del.icio.us
Slashdot Slashdot

이 글에서는 Part 2에서 논의되었던 부분을 계속 이어간다. 사용자가 이메일을 통해 특정 이익 집단(interest group)에 있는 고객들과 연락할 수 있도록 해주는 새로운 JavaServer Pages (JSP) 컴포넌트를 만들 것이다. 이 이메일은 Geronimo 애플리케이션 서버에서 Apache James Mail Server 2.2로 보내진다. 그런 다음, 콘솔 기반 클라이언트를 만들어서 James에서 이메일 메시지를 읽고 새로운 기능을 확인한다.

본 시리즈에 포함된 Customer Service 유틸리티는 사용자가 기본적인 고객 정보를 데이터베이스에 저장할 수 있도록 해주는 간단한 웹 애플리케이션이다. 이것을 Ant 1.6.5 와 Java 1.4.2_10을 사용하여 구현하고, Tomcat을 사용하여 Geronimo 1.1에 전개한다. Apache Derby 데이터베이스와 ActiveMQ JMS 프로바이더를 사용하게 되는데, 이 두 가지 모두 Geronimo에 포함되어 있다.




위로


James 설치하기

Apache James Mail Server는 간단한 테스트가 가능한 기본 설정 상태로 배포된다.

  1. 애플리케이션을 알맞은 위치에 설치하고 이름을 JAMES_HOME으로 한다.
  2. 콘솔에서 스크립트 JAMES_HOME/bin/run.bat을 실행하여 James를 시작한다. 그림 1은 James가 시작된 후에 콘솔 모습이다.
  3. 콘솔에서 Ctrl+C를 눌러 James를 중지한다.
  4. 디렉토리를 JAMES_HOME/work/james-<system generated id>/SAR-INF/lib으로 바꾼다. 이 디렉토리는 James가 처음 시작된 후에만 생성된다. activation.jar와 mail-1.3.1.jar 파일을 JAMES_HOME/lib으로 복사한다.
  5. James를 재시작 하고 Remote Manager Service용 포트 넘버를 기록해 둔다.
  6. James가 로컬 머신에 설치된 것으로 간주하고, telnet localhost 4555를 입력하여 Remote Manager Service로 연결한다. 기본 로그인과 패스워드인 rootroot을 사용한다.
  7. adduser [user] [password]를 입력하여 사용자 계정과 패스워드를 생성한다. adduser smith smith를 입력하면 smith라는 사용자 이름과 패스워드 smith가 생성된다. 필요할 경우 이 단계를 반복한다.
  8. Part 3의 CustomerService/resource/build.properties 파일을 수정하여 Geronimo와 James의 올바른 위치를 반영한다.

그림 1. Windows 콘솔에서 시작된 James
Windows 콘솔에서 시작된 James

James Mail Server는 이제 Geronimo에서 이메일을 받을 준비가 되었다. 기본 설정 파일은 JAMES_HOME/apps/james/SAR-INF/config.xml에 있다. 이 파일은 수정될 필요가 없다. James 설정을 추가로 수정할 경우에만 언급될 것이다.

이제, Geronimo 데이터베이스에서 테스트 고객을 생성 또는 편집해야 한다. http://localhost:8080/service의 Customer Service 유틸리티에 액세스 하여, Customer Processing Page로 가서 그림 2에 디스플레이 된 것과 같은 localhost에 있는 이메일 주소를 가진 고객을 생성한다.


그림 2. John Smith의 업데이트 된 이메일 주소
John Smith의 업데이트 된 이메일 주소

여기에서, John Smith라고 하는 고객은 방금 자신의 이메일 주소를 업데이트 했다. 도메인 이름은 localhost이다. 이것은 이 사람에 대한 인커밍 메일을 받을 때 이 도메인 이름을 기대하는 기본 James 설정과 매치된다. 다음 단계는 JNDI로 메일 세션을 선언하는 단계이다. 다음 섹션에서 자세히 설명하겠다.




위로


Geronimo 전개 디스크립터 생성하기

이 디스크립터 파일을 설정하는 것은 이러한 컴포넌트들이 Geronimo에서 사용될 수 있도록 하는 메커니즘이기 때문에 중요하다. 또한, JNDI 이름들이 주어진 자바 객체와 제휴되는 방식이기도 하다. Geronimo에 전개된 컴포넌트들은 일반적으로 두 개의 전개 파일을 갖고 있다. 표준 Java 2 Platform, Enterprise Edition (J2EE) 또는 Java Platform, Enterprise Edition (Java EE) 전개 디스크립터와 Geronimo 전용 전개 플랜.

새로운 JSP 인터페이스로는 사용자가 특별한 이익 그룹에 있는 고객에게 이메일을 보낼 수 있다. 이 이메일은 웹 티어의 CustomerServiceJavaBean 내에서 보내진다. Listing 1에는 표준 web.xml J2EE/Java EE 전개 디스크립터에 있는 JavaMail 리소스를 설정하는데 필요한 추가 태그들이 포함되어 있다.


Listing 1. web.xml의 일부
                
   <resource-ref>
      <res-ref-name>mail/CustomerServiceMailSession</res-ref-name>
      <res-type>javax.mail.Session</res-type>
      <res-auth>Container</res-auth>
      <res-sharing-scope>Shareable</res-sharing-scope>
   </resource-ref>

<resource-ref> 태그는 JNDI 이름을 리소스 객체의 유형과 연관 시키는데, 이 경우 javax.mail.Session이 이에 해당한다. 익숙하다면, 데이터 소스(JDBC를 위한) 또는 커넥션 팩토리(JMS를 위한) 같은 기타 리소스들의 객체 유형들을 선언할 때 사용되던 것과 같은 태그이기 때문이다. 이러한 리소스 유형들은 예제 애플리케이션 어디에서나 이미 사용되고 있다. Listing 2에는 상응하는 Geronimo 전용 플랜에 필요한 태그가 있다.


Listing 2. geronimo-web.xml의 일부
                
   <resource-ref>
      <ref-name>mail/CustomerServiceMailSession</ref-name>
      <resource-link>mail/CustomerServiceMailGBean</resource-link>
   </resource-ref>

<ref-name>은 web.xml의 <res-ref-name>에 상응하고, 이 메일 세션 리소스가 호출될 때 사용되는 JNDI 이름이기도 하다. <resource-link>MailGBean의 이름을 지정하는데, 이것은 JavaMail 세션을 생성하는 책임이 있다. 이 이름은 애플리케이션 레벨에서 선언되며 Listing 3에 포함되어 있다.


Listing 3. geronimo-appliction.xml의 리스팅
                <application 
xmlns="http://geronimo.apache.org/xml/ns/j2ee/application-1.1">
   <dep:environment 
xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.1">
      <dep:moduleId>
         <dep:groupId>default</dep:groupId>
         <dep:artifactId>CustomerService</dep:artifactId>
         <dep:version>1.0</dep:version>
         <dep:type>ear</dep:type>
      </dep:moduleId>

      <dep:dependencies>
         <dep:dependency>
            <dep:groupId>geronimo</dep:groupId>
            <dep:artifactId>geronimo-mail</dep:artifactId>
            <dep:version>1.1</dep:version>
            <dep:type>jar</dep:type>
         </dep:dependency>

         <dep:dependency>
            <dep:groupId>geronimo</dep:groupId>
            
<dep:artifactId>geronimo-javamail-transport</dep:artifactId>
            <dep:version>1.1</dep:version>
            <dep:type>jar</dep:type>
         </dep:dependency>
      </dep:dependencies>

      <dep:hidden-classes/>
      <dep:non-overridable-classes/>
   </dep:environment>

   <module>
      <connector>tranql-connector-1.2.rar</connector>
      <alt-dd>CustomerServicePool-alt.xml</alt-dd>
   </module>

   <gbean name="mail/CustomerServiceMailGBean" 
class="org.apache.geronimo.mail.MailGBean">
      <attribute name="transportProtocol">smtp</attribute>
      <attribute name="useDefault">false</attribute>
      <attribute name="host">localhost</attribute>
      <attribute name="properties">
         mail.debug=true
         mail.smtp.port=25
      </attribute>   
   </gbean>
</application>

geronimo-mail-1.1.jar와 geronimo-javamail-transport-1.1.jar용 두 개의 <dependency> 태그들은 각각 MailGBeanTransport용 구현을 포함하고 있기 때문에 필요하다. 두 개 모두 <gbean> 선언을 지원하는데 필요하다. 이 <gbean>의 이름은 geronimo-web.xml의 <resource-link>에 지정된 같은 이름이다.

transportProtocol 애트리뷰트는 프로토콜, smtp를 지정하는데, 이것은 이메일을 전송한다. host 애트리뷰트는 메일 서버가 배치된 도메인 이름 또는 IP 주소를 지정한다. 이 글에서는, James는 Geronimo 1.1과 같은 머신에 설치된다. 그렇지 않을 경우, 액세스 가능한 메일 서버가 사용될 수 있고, 실제 이메일 주소가 localhost 대신 사용될 수 있다. properties 애트리뷰트는 추가 애트리뷰트들이 이름/값 쌍을 사용하여 설정될 수 있도록 한다. 이 경우, 디버그 메시지들은 Geronimo 아웃풋 콘솔에 디스플레이 된다. smtp port는 James Mail Server의 같은 포트와 매치된다. 마지막으로, 이 <gbean>의 범위는 애플리케이션 레벨 전용이다. 애플리케이션 레벨 디스크립터에서 설정되기 때문이다. 관련 컴포넌트들이 설정되었으므로, JNDI를 사용하여 코드에서 이러한 객체들을 검색할 차례이다.




위로


Customer Service 유틸리티와 JavaMail

향상된 Customer Service 유틸리티가 거의 준비되었다. 다음 단계는 JNDI를 사용하여 메일 세션을 호출하여 JavaMail을 사용하여 메시지를 보내는 단계이다. 완전한 JNDI 스트링이 Listing 4에 나타나 있다.


Listing 4. customer.properties의 JNDI 이름
                # Specify JNDI names here
jndi.customer.ejb=java:/comp/env/ejb/CustomerEntityBean
jndi.process.ejb=java:/comp/env/ejb/ProcessCustomerSessionBean
jndi.group.ejb=java:/comp/env/ejb/InterestGroupEntityBean
jndi.jms.connector=java:comp/env/jms/CustomerServiceConnectionFactory
jndi.jms.topic=java:comp/env/jms/CustomerServiceTopic
jndi.mail.session=java:comp/env/mail/CustomerServiceMailSession

웹 압축 파일 디스크립터의 <ref-name> 태그에서 선언된 이름이 이제 완전한 JNDI 이름 콘텍스트에 리스팅 된다. 모든 이름들은 제안된 J2EE 네이밍 규약에 따라서 시작된다. Listing 5의 코드는 전체 JNDI 이름 콘텍스트를 사용하여 CustomerServiceMailSession의 검색을 수행하는 방법을 보여주고 있다.


Listing 5. JNDI 검색을 수행하는 CustomerServiceJavaBean.java
                public CustomerServiceJavaBean()
   {
      InitialContext initial = null;
      Object objref = null;

      bundle = ResourceBundle.getBundle("customer", Locale.getDefault(), 
CustomerServiceJavaBean.class.getClassLoader());
      JNDI_PROCESS_EJB = bundle.getString("jndi.process.ejb");
      JNDI_MAIL_SESSION = bundle.getString("jndi.mail.session");

      try
      {
         initial = new InitialContext();
         objref = initial.lookup(JNDI_PROCESS_EJB);
         processHome = (ProcessCustomerHome)PortableRemoteObject.narrow(objref, 
ProcessCustomerHome.class);
         System.out.println("looking up: " + JNDI_PROCESS_EJB);

         objref = initial.lookup(JNDI_MAIL_SESSION);
         mailSession = (Session)PortableRemoteObject.narrow(objref, 
javax.mail.Session.class);
         System.out.println("looking up: " + JNDI_MAIL_SESSION);
      } // end try

      catch (Exception e)
      {
         e.printStackTrace();
      } // end catch
   } // end CustomerServiceJavaBean

메일 세션을 검색하는 코드가 ProcessCustomerSessionBean을 검색하는 코드와 비슷하다. 수정해야 할 유일한 부분은 메일 세션에 대한 레퍼런스이다. Listing 6에는 Geronimo에서 실제 이메일을 보내는데 필요한 코드가 포함되어 있다.


Listing 6. 이메일을 보내는 CustomerServiceJavaBean.java 리스팅 일부
                  
private boolean sendEmail(String toAddress, String fromAddress, String 
subject, String content)
   {
      boolean status = false;

      try
      {
         Date dateStamp = new Date();
         MimeMessage email = new MimeMessage(mailSession);

         email.setFrom(new InternetAddress(fromAddress));
         email.setRecipients(Message.RecipientType.TO,
                             InternetAddress.parse(toAddress, false));
         email.setSubject(subject);
         email.setText(content);
         email.setHeader("X-Mailer", "JavaMailer");
         email.setSentDate(dateStamp);

         Transport.send(email);
         status = true;
      } // end try

      catch (Exception e)
      {
         status = false;
         e.printStackTrace();
      } // end catch

      return status;
   } // end sendEmail

CustomerServiceJavaBean은 웹 티어의 일부이고, Geronimo는 이 레벨에서부터 이메일을 보낸다. mailSession은 이전 리스팅에 디스플레이 된 JNDI 룩업(lookup)을 통해서 획득되고, 이메일 메시지를 나타내는 실제 객체게 되는 MimeMessage를 만드는데 사용된다. 관련 애트리뷰트가 설정된 후에, 메시지는 Transport 객체를 통해 메일 서버로 보내진다.

메일 서버에 의해 메시지가 성공적으로 수신되었다는 것을 확인해야 한다. 메일 서버로 연결할 수 있는 콘솔 기반 클라이언트가 필요하고, 해당 사용자와 관련된 모든 메시지들을 추출하고, 각 메시지의 내용을 콘솔에 출력한다. Listing 7은 메일 세션을 생성하는 Reader라고 하는 클라이언트의 일부 모습이다.


Listing 7. JavaMail 세션을 생성하는 Reader.java 메소드
                private Session generateSession(String host, String user, String password)
   {
      authentication = new PasswordAuthentication(user, password);

      Properties properties = new Properties();
      properties.put("mail.host", host);
      properties.put("mail.debug", "false");
      properties.put("mail.user", user);
      properties.put("mail.store.protocol", "pop3");

      Session session = Session.getInstance(properties, this);

      return session;
   } // end generateSession

PasswordAuthentication은 주어진 사용자 이름과 패스워드를 확인한다. 이 메소드는 JNDI를 사용하지 않는다. 대신, 메일 세션을 생성하는데 사용되는 관련 프로퍼티를 설정한다. Listing 8은 이메일 메시지를 추출하는 실제 코드를 보여준다.


Listing 8. 주어진 사용자에 대한 모든 인커밍 이메일을 읽는 Reader.java 메소드
                  
protected void readEmail(String host, String username, String password)
   {
      Store store = null;
      Folder inbox = null;

      try
      {
         Session mailSession = generateSession(host, username, password);

         store = mailSession.getStore();
         store.connect();
         Folder folder = store.getDefaultFolder();
         inbox = folder.getFolder("inbox");

         inbox.open(Folder.READ_ONLY);
         Message[] messages = inbox.getMessages();

         System.out.println("Inbox for userID: " + username);
         System.out.println("inbox size: " + messages.length);
         System.out.println("*****");

         for (int x = 0; x < messages.length; x++)
         {
            MimeMessage email = (MimeMessage)messages[x];

            System.out.println("FROM: " + email.getFrom()[0].toString());
            System.out.println("TO: " + 
email.getRecipients(Message.RecipientType.TO)[0].toString());
            System.out.println("DATE: " + email.getSentDate());
            System.out.println("SUBJECT: " + email.getSubject());
            System.out.println("CONTENT: " + email.getContent());
         } // end for

         System.out.println("*****");
      } // end try

      catch (Exception e)
      {
         e.printStackTrace();
      } // end catch

      finally
      {
         try
         {
            inbox.close(true);
            store.close();
         } // end try

         catch (Exception e)
         {
            e.printStackTrace();
         } // end catch
      } // end finally
   } // end readEmail

메일 세션이 생성된 후에는, 이것은 메일 서버로 연결되는 메시지 스토어를 획득하기 위해 사용된다. 인박스는 폴더 이름을 위해 보유되고, 연결이 되면, 폴더에 있는 모든 메시지가 검색될 수 있다. 메시지가 검색된 후에, 그 내용을 콘솔에 디스플레이 하는 것은 식은죽 먹기다.

Customer Service 유틸리티는 이제 Geronimo에 전개될 준비가 되었다.

  1. CustomerService/resources/build.properties 파일을 수정하고, 디렉토리 위치가 올바르게 정의되었는지를 확인한다.
  2. 콘솔을 열고 CustomerService/build.xml의 위치로 디렉토리를 수정하고 ant를 입력한다. 이것으로 http://localhost:8080/service에 액세스 될 수 있는 애플리케이션이 구현 및 전개된다. 또한, 클라이언트 Reader 애플리케이션을 압축한다. 그림 3은 Groups Contact 페이지 모습이다.

그림 3. Groups Contact 페이지를 통해 고객에게 이메일 보내기
Groups Contact 페이지를 통해 고객에게 이메일 보내기

여기에서, 사용자는 자바 특별 이익 집단에 있는 모든 고객들을 검색했다. 사용자는 하나의 이메일을 고객 John Smith에게 보내기로 했다. 필요할 경우, 사용자는 디스플레이 된 모든 고객들을 선택할 수 있고, 도메인 이름(localhost)가 유효하고 사용자 ID가 메일 서버에 생성되어 있다면, 같은 이메일이 이들 각자에게로 간다. 이메일이 보내진 후에, 디버그 메시지가 Geronimo 아웃풋 콘솔에 디스플레이 된다. (그림 4)


그림 4. JavaMail 디버그 메시지를 나타내는 Geronimo 콘솔
JavaMail 디버그 메시지를 나타내는 Geronimo 콘솔

위 아웃풋에 따르면, John Smith에 대한 메시지는 James Mail Server로 성공적으로 보내졌다. 다음 단계는 메일 서버를 검사하여 이메일이 James에 있는지를 확인하는 단계이다. client localhost smith smith로 Reader를 실행한다. 이렇게 하면, 그림 5에 보이는 것과 비슷한 결과가 나온다.


그림 5. James에서 받은 이메일용 클라이언트 아웃풋
James에서 받은 이메일용 클라이언트 아웃풋

Group Contacts 페이지에서 John Smith로 보내진 모든 메시지들은 클라이언트의 아웃풋에 디스플레이 되어야 한다. Geronimo에서 보내진 이메일 메시지들은 James Mail Server로 성공적으로 보내졌다. 이것이 바로 JNDI에 있는 JavaMail 리소스에 액세스 하는 방법이다!




위로


요약

이 글에서, JavaMail 리소스 그룹을 설정 및 호출하는 방법을 배웠다. Customer Service 유틸리티는 웹 인터페이스에서 Apache James Mail Server로 이메일을 보내는 것으로 JNDI에서 이러한 리소스에 액세스하는 방법을 설명했다. 전용 콘솔 애플리케이션을 구현하여, 인커밍 이메일이 수신되었는지를 확인했다. 본 시리즈 마지막 기술자료에서는 URI 커넥션으로의 JNDI 액세스를 설명할 것이다.





위로


다운로드 하십시오

설명이름크기다운로드 방식
Part 3 소스 코드CustomerService-part3.zip589KBHTTP
다운로드 방식에 대한 정보


참고자료

교육

제품 및 기술 얻기

토론


필자소개

Dale de los Reyes는 1996년, California Polytechnic State University, 컴퓨터 공학과를 졸업했다. J2EE, C++ for Microsoft® Windows®, COBOL for Mainframes 등으로 애플리케이션을 개발했다. 여가 시간에는, 사진을 찍거나, 무술을 연습한다.




기사에 대한 평가


보다 나은 서비스를 제공하기 위함이오니 잠시 짬을 내어 이 양식을 제출하여 주십시오.



아니오잘 모르겠음
 


 


12345
 



위로


IBM, the IBM logo, and WebSphere are a registered trademarks of IBM in the United States, other countries or both. Java is a trademark of Sun Microsystems in the United States, other countries, or both. 기타 회사, 제품, 및 서비스명은 다른 상표나 서비스 마크일 수 있습니다.

developerWorks 콘텐트를 다른 사이트에 전재하기:
developerWorks 콘텐트에 대한 저작권은 IBM에 있습니다. IBM의 서면 허가나 원본 저자의 허락이 없이는 전재를 금합니다. 저희 콘텐트를 전재하시려면 IBM developerWorks 담당자 에게 문의하십시오.
    IBM 소개 개인정보 보호정책 문의