달력

4

« 2024/4 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

이 글은 하얀말님의 2008년 9월 12일의 미투데이 내용입니다.

:
Posted by 하얀 말
  • 수영 12개월째, 1. 다른 이들이 “어깨가 각져지고 배는 평평해졌다”한다. (^o^) 2. 왜 몸무게는 거의 그대로냐고~ (T.T) 3. 수영 전후 샤워로 깨끗, 피부 개선, 기분 상쾌, 무좀 박멸 (^-^) 4. Salsa에 소홀해짐 (-.-)a(힘미투 수영)2008-09-11 13:19:48
  • 자주 쓰는 Eclipse Plugin Update Site, 이런 글 보면 반갑! Eclilpse Plugin이나 Firfox Extension 등은 너무 많아 이런 추천 글이 아주 쓸모있다.(Eclipse Plugin EclipsePlugin추천)2008-09-11 13:22:05
  • SK텔레콤이 Wibro에 관심 있을 턱이 있나~ Wibro는 휴대폰 시장 갉아 먹을 수 있는, 딱 Carnivalization 사업일껄? KT도 KTF랑 합병하면 Wibro 열심히 할라나?(뉴스 SK텔레콤 Wibro KT Carnivalization)2008-09-11 18:43:58

이 글은 하얀말님의 2008년 9월 11일의 미투데이 내용입니다.

:
Posted by 하얀 말
  • Google Chrome 설치 문제 경험담이다. beta라도 Game은 이랬다간 회사 게시판에 욕이 한가득인데, 이 글 쓴 분은 비판적이어도 전반적으로는 Chrome에 우호적인 것 같다. 정말 신기하다. Google이 이걸 돈 받고 팔 생각이 없어서 그런가?(Google Chrome BetaTest 역시10원이라도받으면반응이틀려)2008-09-09 09:31:39
  • ㅋㅋㅋ~. 개발자가 CIO를 바보라고 생각하는 이유라~. CIO뿐 아니라 개발자들 데리고 일하시는 분들은 새겨 들을 이야기!(개발자 CIO 개발자가CIO를바보라여기는이유)2008-09-09 11:19:41

이 글은 하얀말님의 2008년 9월 9일의 미투데이 내용입니다.

:
Posted by 하얀 말

이 글은 하얀말님의 2008년 9월 8일의 미투데이 내용입니다.

:
Posted by 하얀 말
  • MS의 Web Office 사업 강화는 어제 말한 Xerox처럼 MS에게도 “Office Suite냐 Web Office냐” 선택을 강요하고 있다. MSN을 버리고 Internet을 선택, 성공한 경험을 가진 MS지만 이번에는 더 결정이 어려울 듯.(WebOffice Office MS 혁신 도전과응전 갈등)2008-09-03 11:26:45

이 글은 하얀말님의 2008년 9월 3일의 미투데이 내용입니다.

:
Posted by 하얀 말
2008. 8. 29. 09:26

Programmer를 위한 글꼴 Computing에 관한 독백2008. 8. 29. 09:26

그동안 Programming을 하기 위해 편집기를 펴 놓고 source code를 보면서, 하라는 coding은 안하고 편집기의 글꼴(font)을 이것저것 바꾸는 짓을 꽤 많이도 했다.

나름대로 세운 programming을 위한 글꼴의 기준은 다음과 같다.


1. I(alphabet 대문자 i), 1(숫자 하나), l(alphabet 소문자 L) 구별이 쉬워야 한다.

2. O(alphabet 대문자 O),  o(alphabet문 소문자 o),  ㅇ(한글  자소 ㅇ)  구별이 쉬워야  한다.

3. 한글이건 alphabet이건 고정폭 글꼴이어야 한다. 왜냐하면 열(column)을 헤아려야 할 경우가 왕왕 있기 때문이다.

4. 한글과 alphabet이 이질감 없이 잘 어울려야 한다. 음.... 이건 좀 애매하구만.

5. 소괄호, 중괄호, 대괄호 구별이 잘 되어야 한다.

6. 마침표와 쉼표 구분이 잘 되어야 한다.

7. vertical bar(|)와 /(backslash) 구분이 잘 되어야 한다.

8. 글꼴 외곽이 또렷해야 한다.


8번 항에 대해 더 이야기하면 외곽이 또렷하려면 antialiasing 먹인 글꼴, 이를테면 이번 Windows Vista의 기본 글꼴인 맑은 고딕 같은 글꼴은 대략... 그런데 개인적으로 antialiasing 먹인 글꼴이 미려해 보이긴 해서, 이건 좀 왔다리갔다리 한다. 그런데 확실히 눈은 antialiasing 먹인 글꼴이 더 피곤한 것 같다.

programming에 어울리는 글꼴이란 것은 비단 하얀 말만의 고민은 아니었나 보다. Web 검색 결과 국내외를 막론하고 해당 주제에 대한 많은 글들을 볼 수 있었으며, 보아하니 BitStream Vera Sans Mono라 는 글꼴들을 많이 쓰는 듯 하여 하얀 말도 채택하였다. 그런데 영문 글꼴이다 보니 한글은 여전히 떨떠름해 아쉽다. code야는 100% alphabet이지만 주석엔 한글도 써야 할 것 아닌가. 한글도 멋지게 쓸 수 있는 방법 아시는 분은 좀 알려주시라.

아래는 BitStream Vera Sans Mono 글꼴 예시.


사용자 삽입 이미지


(뱀발)

실은 한글 글꼴 중에도 마음에 드는 것이 있기는 있다. 우리글닷컴이 라는 회사가 만든 바탕체인데, 특히 이중에서 '우리신문'이라는 글꼴이 상당히 마음에 든다. 우리글닷컴 site 가 보면 인쇄용이 아닌 화면용 한글 글꼴에 대한 성찰을 꽤 많이 한 냄새가 여기저기 난다. 실제로 하얀 말도 화면용 영문 글꼴은 참 예쁜데 왜 한글용 한글 글꼴은 하나도 마음에 드는 것이 없는지 참 궁금했었는데 그러한 우리글닷컴의 주장이 그러한 궁금증을 많이 해소시켜 준 듯 하다. 한 번 쓰고 싶은 글꼴이다.

그런데 우리글닷컴의 한글 글꼴은 가변폭 글꼴이다 보니, programmer를 위한 글꼴로 적합할지는 잘 모르겠다.

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

예전 blog에다 2007년 7월 6일에 쓴 글을 약간 고쳐서 다시 올림

:
Posted by 하얀 말
  • 또 nVision 08 이야기. CUDA로 encoding 속도를 향상시킨 Video Encoder 소개가 있었단다. “데끼리~!”긴 한데 CUDA는 nVidia GPU에서만 돈다. CUDA도 소비자를 nVidia에 Lock-in 시키기는 도구인 거지.(nVision nVision08 CUDA)2008-08-28 11:32:25
  • 요새 ATI에 발리지만 nVidia의 S/W 역량은 ATI보다 나은 거 같아. driver의 성능, 안정성이 한동안 우위였고 Cg, CUDA 같은 것도 만들고 말야. 그 S/W 역량의 우위가 그간의 ATI에 대한 경쟁 우위의 이유 중 하나일 거야.(S/W역량 nVidia Cg CUDA 경쟁력)2008-08-28 11:36:13

이 글은 하얀말님의 2008년 8월 28일의 미투데이 내용입니다.

:
Posted by 하얀 말

이 글은 하얀말님의 2008년 8월 27일의 미투데이 내용입니다.

:
Posted by 하얀 말
/*
 * $HeadURL$
 * $Revision$
 * $Date$
 * ====================================================================
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

import java.io.File;
import java.io.InputStream;
import java.io.StringWriter;

import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.FileRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.w3c.dom.Document;

import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;

/**
 *
 * This is a sample application that demonstrates how to use the Jakarta
 * HttpClient API.
 *
 * This application sends an XML document to a remote web server using HTTP POST
 *
 * @author Sean C. Sullivan
 * @author Ortwin Glueck
 * @author Oleg Kalnichevski
 * @author Paul King
 */
public class PostSOAP {

  /**
   *
   * Usage: java PostSOAP http://mywebserver:80/ SOAPAction c:\foo.xml
   *
   * @param args
   *            command line arguments Argument 0 is a URL to a web server
   *            Argument 1 is the SOAP Action Argument 2 is a local filename
   *
   */
  public static void main(String[] args) throws Exception {
    boolean isBeautify = false;

    if (args.length != 3 && args.length != 2) {
      System.out.print("Usage: java -classpath <classpath> [-Dorg.apache.");
      System.out.print("commons.logging.simplelog.defaultlog=<loglevel>] Post");
      System.out.print("SOAP <url> <filename> [<soapaction>] [-beautify]\n");
      System.out.print("<classpath> - must contain the commons-httpclient.jar");
      System.out.print(" and commons-logging.jar\n");
      System.out.print("<loglevel> - one of error, warn, info, debug, trace\n");
      System.out.print("<url> - the URL to post the file to\n");
      System.out.print("<filename> - file to post to the URL\n");
      System.out.print("<soapaction> - the SOAP action header value");
      System.out.print("(optional)\n");
      System.out.println("-beautify - show pretty result(optional)\n\n");
      System.exit(1);
    }
    // Get target URL
    String strURL = args[0];
    String strSoapAction = "";

    if (4 == args.length) {
      // Get SOAP action
      strSoapAction = args[2];

      if ("-beautify".equals(args[3])) {
        isBeautify = true;
      }
    }

    if (3 == args.length) {
      if ("-beautify".equals(args[2])) {
        isBeautify = true;
      } else {
        strSoapAction = args[2];
      }
    }


    // Get file to be posted
    String strXMLFilename = args[1];
    File input = new File(strXMLFilename);
    // Prepare HTTP post
    PostMethod post = new PostMethod(strURL);
    // Request content will be retrieved directly
    // from the input stream
    RequestEntity entity = new FileRequestEntity(input,
        "text/xml; charset=ISO-8859-1");
    post.setRequestEntity(entity);
    // consult documentation for your web service
    post.setRequestHeader("SOAPAction", strSoapAction);
    // Get HTTP client
    HttpClient httpclient = new HttpClient();
    // Execute request
    try {
      int result = httpclient.executeMethod(post);
      // Display status code
      System.out.println("Response status code: " + result);
      // Display response
      System.out.println("Response body: ");

      if (isBeautify) {
        System.out.println(PostSOAP.beautify(post
            .getResponseBodyAsStream()));
      } else {
        System.out.println(post.getResponseBodyAsString());
      }
    } finally {
      // Release current connection to the connection pool once you are done
      post.releaseConnection();
    }
  }

  public static String beautify(InputStream response) {
    StringWriter sFormattedXML = new StringWriter();

    try {
      Document oDocument = DocumentBuilderFactory.newInstance()
          .newDocumentBuilder().parse(response);
      OutputFormat format = new OutputFormat(oDocument, "UTF-8", true);
      format.setIndent(4);
      format.setIndenting(true);
      format.setPreserveSpace(false);

      XMLSerializer serial = new XMLSerializer(sFormattedXML, format);
      serial.asDOMSerializer();
      serial.serialize(oDocument.getDocumentElement());
    } catch (Exception e) {
      e.printStackTrace();
    }

    return sFormattedXML.toString();
  }
}

Apache HTTP Client의 예제 중 하나인 PostSOAP에 XML을 예쁘게 보여주는 beautify(InputStream) method를 추가했습니다. 참고로

import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;

이 두 import문에서의 OutputFormat, XMLSerializer의 package 이름은 IBM JDK 1.5(J9 VM이라고도 하죠)에 들어있는 Xerces의 OutputFormat이나 XMLSerializer의 package 이름을 따른 것입니다. 흔히들 많이 쓰는 Sun JDK의 Xerces는 package 구조를 Sun이 손을 댄 통에 package 이름이 다릅니다. 따라서 Sun JDK에서는 위 import문을 아래와 같이 바꾸세요.
import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;

:
Posted by 하얀 말
2008. 7. 21. 11:06

SAAJ Computing에 관한 독백2008. 7. 21. 11:06


SAAJ는 SOAP with Attachments API for Java의 약자로, 말 그대로 SOAP with Attachment를 Java로 다루기 위한 API 모임입니다. 물론 JAXP나 HTTP로 생짜로 짤 수도 있겠습니만, 아무래도 class library가 있다면 좀 편하겠지요. SOAP with Attachment(이하 SwA)는 Web Service의 표준 protocol인 SOAP이, 첨부 file등을 붙일 수 있도록 확장한 것입니다. 비슷한 것으로는 DIME이 있긴 한데 아무래도 SwA가 더 힘을 받는 것 같습니다. 아울러,


  • SwA가 첨부 파일을 지원하는 mechanism은 e-mail에 file을 첨부하기 위해 고안한 MIME을 이용합니다. 이 사항은 SAAJ coding을 보면서 자세히 살펴보죠.
  • SAAJ가 지원하는 SOAP의 규격은 1.1, 1.2 모두를 지원하며 default는 1.1입니다. 이 글에서 명시적인 SOAP 명세 version이 없으면 1.1입니다.
  • Java SE 5 이하에서 SAAJ를 쓰려면 별도의 jar file이 필요했으나 Java SE 6부터는 기본으로 들어 있습니다. 따라서 본 글은 SAAJ를 Java SE에 포함시킵니다.
  • SOAP 자체에 대한 이해가 필요하시면 SOAP Tutorial을 공부하세요. 간단합니다.

SAAJ에서의 SOAP message 얼개#



SwA Message 얼개는 위 그림과 같습니다. 하나의 SOAP message는 1개의 SOAP part와 0개 이상의 Attachment Part로 나뉘며, SOAP Part는 SOAP Body는 꼭 있어야 하고 SOAP Header는 있어도 되고 없어도 됩니다. Attachment Part는 MIME Header들과 그에 따른 Content(즉 첨부 file)이 있습니다. SAAJ에는 이들 SOAP message, header, body, Attachment에 해당하는 class들이 존재하며 SAAJ를 쓴다는 것은 이들 class의 instance를 얻어 조작하는 것을 뜻합니다.


참고로 Attachment Part가 없는 SwA message는 아래 그림과 같이 SOAP Message 그 자체입니다.


SOAPMessage#


본격적으로 시작하기에 앞서, SAAJ에 관한 class들은 대부분 javax.xml.soap이라는 package 안에 들어있으며, 이 글에서 package에 대한 별도의 명명이 없는 class는 바로 이 javax.xml.soap package에 들어있다고 보시면 됩니다.


먼저 SOAP Message에 해당하는 객체를 획득해 보죠. 이 객체를 얻으려면 먼저 이 객체의 factory class인 MessageFactory 객체를 생성해야 합니다. MessageFactory 객체는 MessageFactory의 static method인 newInstance()라는 method를 호출함으로써 얻습니다. 그리고 우리가 정말로 얻고자 하는 객체인 Message를 표현하는 class는 SOAPMessage라는 class인데 이 class에 대한 객체는 MessageFactory의 createMessage()를 호출하면 얻을 수 있습니다. 이러한 동작을 수행하는 code는 아래와 같습니다.


  1. MessageFactory mf = MessageFactory.newInstance();
  2. SOAPMessage msg = mf.createMessage();

만약 SOAP 1.2 spec을 따르는 SOAP Message를 만들고 싶다면,

  1. MessageFactory mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
    

라고 하면 됩니다.


SOAPPart / SOAPEnvelope#

위에서 언급했듯, SOAP message는 SOAP Part와 Attachment Part로 이루어지고 SOAP Part는 반드시 존재합니다. 이 단락에서는 SOAP Part를 살펴보겠습니다. SOAP Part를 나타내는 class는 SOAPPart입니다. 그리고 SOAPPart 객체는 SOAPMessage 객체의 getSOAPPart() method를 통해 얻습니다. code로는 아래와 같죠.


  1. SOAPPart sp = mf.getSOAPPart();

SOAP spec을 보시면 아시겠지만 SOAP은 SOAP Envelope이라는 구조를 가지고 이 SOAP Envelope이 SOAP Header, SOAP Body를 rkwlrh 있습니다. SAAJ에서는 이 SOAP Envelope을 나타내는 class가 있으며 SOAPEnvelope이라 합니다. 이 SOAPEnvelope 객체는 다음과 같이 얻을 수 있죠.


  1. SOAPEnvelope se = sp.getEnvelope();

SOAP Envelope에 Namespace, Attribute 추가하기#

이 SOAPEnvelope은 SOAP의 <SOAP-ENV:envelope/> element에 대응합니다. <SOAP-ENV:envelope/>이라는 element 이름을 보셔도 알 수 있듯, <SOAP-ENV:envelope/>은 SOAP-ENV라는 XML Namespace prefix가 걸려 있으며, 이 prefix에 대응하는 URI는 "http://schemas.xmlsoap.org/soap/envelope/" 입니다. 그런데 때때로 이 <SOAP-ENV:envelope/>에 또다른 Namespace나 attribute를 추가할 수도 있습니다. 이를 위해 SOAPEnvelope은 Namespace 추가용으로 addNamespaceDeclaration(String prefix, String uri), Attribute 추가용으로 addAttribute(Name attrName, String value), addAttribute(QName attrName, String value)라는 method를 가지고 있습니다. 이들에 대한 code 예시는 아래와 같습니다.


  1. /* schemaLocName은 xsi:schemaLocation 이라는 이름을 나타내는 Name, 또는 QName 객체 */
  2. se.addNamespaceDeclaration("eb", "http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd");
  3. se.addAttribute(schemaLocName, "http://schema.xmlsoap.org/soap/envelope http://www.oasis-open.org/committees/ebxml-msg/schema/envelope.xsd");

위 code는 <SOAP-Env:Envelope/>에 eb라는 Namespace와 xsi:schemaLocation이라는 attribute를 추가하는 일을 합니다. 그런데 addAttribute() method의 첫번째 인자로 들어가는 Name, QName은 무엇하는 객체일까요?


Name / QName#

element나 attribute를 만들기 위해서는 당연히 그 element나 attribute에 대한 이름이 필요합니다. 그런데 XML에서 element나 attribute에 대한 이름은 XML Namespace의 적용을 받습니다. 따라서 element나 attribute에 대한 이름은 단순히 이름을 나타내는 String으로는 부족하고 거기에 prefix, uri에 대한 정보를 함께 가지고 있어야 합니다. 이러한 이름 정보를 표현하기 위해 SAAJ에서는 Name이란 class를 제공하며 이 Name에 대한 객체는 아래 SOAPFactory라는 객체에서 얻을 수 있습니다. code로는 아래와 같습니다.


  1. Name schemaLocName = SOAPFactory.newInstance().createName("schemaLocation", "xsi", "http://www.w3.org/2001/XMLSchema-instance");

위 code는 xsi:schemaLocation이라는 이름을 생성합니다.


이러한 이름을 표현하는 방법에는 Name 대신 javax.xml.namespace.QName을 쓰는 방법도 있습니다. 위 code와 동일한 작용을 하는, QName을 쓰는 code는 아래와 같습니다.


  1. QName schemaLocName = new QName("http://www.w3.org/2001/XMLSchema-instance", "schemaLocation", "xsi");


SOAPHeader / SOAPBody#

SOAP message에서 실제 data를 탑재하는 부분은 SOAP Header와 SOAP Body입니다. SAAJ에서는 이들을 SOAPHeader, SOAPBody class로 표현하며 이들에 대한 객체는 아래 코드와 같이 얻을 수 있습니다.


  1. SOAPHeader sh = se.getHeader();
  2. SOAPBody sb = se.getBody();

SOAPHeader나 SOAPBody는 각각 <SOAP-ENV:header/>, <SOAP-ENV:body/>에 대응하며 <SOAP-ENV:envelope/>과 마찬가지로 addNamespaceDeclaration(String prefix, String uri), addAttribute(Name attrName, String value), addAttribute(QName attrName, String value)을 써서 필요로 하는 Namespace나 attribute를 추가할 수 있습니다. 그리고 하위 element도 추가할 수 있죠.


SOAP Header / SOAP Body에 data 싣기#

SOAPHeader나 SOAPBody에는 필요한 XML element 등을 만들어서 필요한 data를 SOAP message에 적재할 수 있습니다.


SOAP Header에 data 싣기#

SOAPHeader 객체의 addChildElement(Name), addChildElement(QName)이라는 method가 SOAP Header에 하위 element를 추가하는 일을 수행하며, 추가된 하위 element를 가리키는 SOAPElement 객체를 반환합니다.


아래 code는 SOAP Header에 하위 element로 <eb:CPAId/>라는 element를 추가하고, 거기에 "banca.03.N01.test"라는 text 값을 추가하는 예시입니다.


  1. SOAPElement messageHeader = sh.addChildElement(new QName("http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd", "MessageHeader", "eb"));

위 code에 대응하는 XML 문서는 대략 다음과 같습니다.


  1. <SOAP-ENV:Header xml:eb="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd">
  2.   <eb:MessageHeader/>
  3. </SOAP-ENV:Header>

이 SOAPElement 객체에도 addChildElement(QName name), addChildElement(Name name), addNamespaceDeclaration(String prefix, String uri), addAttribute(Name attrName, String value), addAttribute(QName attrName, String value)이 있으며, 필요한 하위 Element, Namespace나 Attribute를 추가할 수 있습니다. 또한 SOAPHeaderElement에는 setTextContent(String content)라는 method가 있는데 이는 element에 문자열로 된 내용을 추가합니다.


아래는 <eb:MessageHeader/>에 <eb:CPAId>banca.03.N01.test</eb:CPAId>라는 하위 element를 만드는 code입니다.


  1. messageHeader.addChildElement(new QName("http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd", "CPAId", "eb")).setTextContent("banca.03.N01.test");

SOAPBody에 data 싣기#

SOAPBody에도 addChildElement(Name), addChildElement(QName)가 있으며 이 method들이 반환하는 SOAPElement 객체에 Attribute나 하위 element, content를 추가할 수 있는 것은 SOAPHeader와 같습니다. 그런데 SOAPBody에는 SOAPHeader에 없는 독특한 기능이 있는데, 바로 addDocument(org.w3c.dom.Document doc), addFault() method들입니다.


addDocument(org.w3c.dom.Document doc)는 XML 문서 자체를 한꺼번에 SOAPBody에 적재하는 method입니다. 편리하겠지요?


그럼 addFault()는 뭐하는 것일까요? SOAP spec을 보시면 아시겠지만 어떤 처리를 하다 error가 발생하면 그 error에 대한 정보를 SOAP message에 실을 수 있습니다. 바로<SOAP-ENV:Body/> element 안에 들어가는 <SOAP-ENV:Fault/> element죠. 바로 addFault()가 이 element를 추가하는 역할을 수행합니다. addFault()는 SOAPFault 객체를 반환하며 SOAPFault는 SOAPElement의 자식 class입니다.


AttachmentPart#

AttachmentPart는 쉽게 말해 첨부 file 부분을 말합니다. SwA를 통해 첨부 file을 붙이는 작업은 보통 다음의 4가지 일로 나눌 수 있습니다.


  1. SOAPMessage 객체에서 AttachmentPart 객체 얻어오기
  2. Content 추가하기
  3. Content-ID 설정하기
  4. 가공한 AttachmentPart를 SOAPMessage에 추가하기

하나의 SOAPMessage에 적재할 수 있는 AttachmentPart는 이론적으로는 제한이 없으므로, 추가하고 싶은 만큼 위 작업을 반복하면 됩니다.


각 단계에 대한 code 예시는 아래와 같습니다.


  1. attachment = msg.createAttachmentPart();
  2. attachment.setRawContent(new FileInputStream(contentFiles[inx]),"application/octet-stream");
    attachment.setContentId("<payload-" + inx + ">");
    msg.addAttachmentPart(attachment);

위 예에서는 content를 추가하는 작업으로 setRawContent() method를 썼습니다만 setContent(Object content, String mimeType)을 쓸 수도 있습니다. 이 두 method의 차이는, 전자의 경우는 Stream 형태 그대로 적재합니다만, 후자는 Java 객체로 적재할 data를 받습니다. 만약 Java 객체가 두번째 인자로 주어진 MIME Type과 맞지 않다면 setContent()는 SOAPException을 발생시킵니다. 위 예에서 setContent()를 쓸 경우, "application/octet-stream"이라는 MIME Type은 대응하는 Java 객체가 없기 때문에 SOAPException이 납니다.


만든 SOAP Message를 주고 받기#

SOAPMessage는 다른 system에 보내라고 만든 것이죠? SwA는 만들어진 SOAPMessage를 보내는 것에 대한 API도 제공하고 있습니다. 바로 예시 code로 들어갑시다.


  1. SOAPConnectionFactory scf =  SOAPConnectionFactory.newInstance();
  2. SOAPConnection conn = scf.createConnection();
  3. SOAPMessage responseMsg = conn.call(msg, new URL("http://127.0.0.1:27120/ebXML/msh));

그럼 받는 쪽은 어떻게 할까요? 이것에 대한 해답도 역시 SOAPConnection 객체에 있습니다. SOAPConnection 객체에는 get(Object to)이라는 method가 있는데, 이 method는 to에서 SOAP Message를 보낼 때까지 기다리다가 to에서 SOAP Message를 보내면 이를 받아내죠. to에 실제로 올 수 있는 type은 String 객체나 java.net.URL 객체이며 request를 보내는 곳의 URL을 표현합니다.


SwA 실례#

실제 SOAP with Attachment message가 어떻게 생긴 것인지 이해를 돕기 위해 아래에 실제 내용을 첨부합니다. 이 예에서는 Attachement Part가 두 개입니다.


  1. ------=_Part_0_8089714.1216110540156
    Content-Type: text/xml; charset=utf-8
    Content-Id: <SOAP_Part>

    <?xml version="1.0" encoding="utf-8" ?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schema.xmlsoap.org/soap/envelope http://www.oasis-open.org/committees/ebxml-msg/schema/envelope.xsd"><SOAP-ENV:Header xmlns:eb="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd" xsi:schemaLocation="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd"><eb:MessageHeader SOAP-ENV:mustUnderstand="1" eb:id="MessageHeader" eb:version="2.0"><eb:From><eb:PartyId eb:type="BANK_CD">03</eb:PartyId><eb:Role>BANK</eb:Role></eb:From><eb:To><eb:PartyId eb:type="INSR_CD">N01</eb:PartyId><eb:Role>INSR</eb:Role></eb:To><eb:CPAId>banca.03.N01.test</eb:CPAId><eb:ConversationId>20010215-111213-28572</eb:ConversationId><eb:Service>urn:bancassurance</eb:Service><eb:Action>100001_Request</eb:Action><eb:MessageData><eb:MessageId>20010215-111212-287572</eb:MessageId><eb:Timestamp>2008-07-15T17:29:00Z</eb:Timestamp></eb:MessageData></eb:MessageHeader><eb:SyncReply SOAP-ENV:actor="http://schemas.xmlsoap.org/soap/actor/next" SOAP-ENV:mustUnderstand="1" eb:id="10056109" eb:version="2.0"/></SOAP-ENV:Header><SOAP-ENV:Body xmlns:eb="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd" xsi:schemaLocation="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd"><eb:Manifest eb:id="Manifest" eb:version="2.0"><eb:Reference xmlns:xlink="http://www.w3.org/1999/xlink" eb:id="Reference-0" xlink:href="cid:payload-0" xlink:type="simple"><eb:Description xml:lang="ko_KR">IBK-0</eb:Description></eb:Reference><eb:Reference xmlns:xlink="http://www.w3.org/1999/xlink" eb:id="Reference-1" xlink:href="cid:payload-1" xlink:type="simple"><eb:Description xml:lang="ko_KR">IBK-1</eb:Description></eb:Reference></eb:Manifest></SOAP-ENV:Body></SOAP-ENV:Envelope>
    ------=_Part_0_8089714.1216110540156
    Content-Type: application/octet-stream
    Content-ID: <payload-0>

                긍정적인 밥

                                   함민복

    시 한편에 삼만원이면
    너무 박하다 싶다가도
    쌀이 두 말인데 생각하면
    금방 마음이 따뜻한 밥이 되네

    시집 한권에 삼천 원이면
    든 공에 비해 헐하다 싶다가도
    국밥이 한 그릇인데
    내 시집이 국밥 한그릇만큼
    사람들 가슴을 따뜻하게 덥혀줄 수 있을까
    생각하면 아직 멀기만 하네

    시집이 한 권 팔리면
    내게 삼백원이 돌아온다
    박리다 싶다가도
    굵은 소금이 한됫박인데 생각하면
    푸른 바다처럼 상할 마음 하나 없네
    ------=_Part_0_8089714.1216110540156
    Content-Type: application/octet-stream
    Content-ID: <payload-1>

                   가을

                                  함민복

    당신 생각을 켜놓은 채 잠이 들었습니다

참고 문헌#

http://java.sun.com/javaee/5/docs/tutorial/doc/bnbhf.html

이 글은 스프링노트에서 작성되었습니다.

:
Posted by 하얀 말