HTTP를 통한 리소스 액세스

Java ME 2007/04/10 17:53 Posted by Sun
저자 C. Enrique Ortiz  

HTTP(Hypertext Transport Protocol)는 매우 중요한 애플리케이션 레벨의 네트워크 프로토콜입니다. 웹 페이지, XML(Extensible Markup Language) 문서, 이미지, 전화벨소리, 배경 무늬 및 웹 서비스 등의 웹 리소스에 대한 대부분의 액세스는 HTTP를 통해 발생합니다.

MIDP(Mobile Information Device Profile)GCF(Generic Connection Framework) HttpConnection을 통해 HTTP 지원을 제공하는데 이는 HTTP에서 리소스를 GETPOST하는 메소드, HTTP 헤더를 읽고 쓰는 메소드, 리소스를 읽고 쓰는 여러 가지 메소드를 스트림 또는 바이트 어레이 등으로 제공합니다.

이 기술 팁에서는 몇 가지 HTTP 상수를 정의하는 NetworkUtils라는 도우미 클래스와, HttpConnection을 사용하여 HTTP에서 서버에 연결하고 리소스를 가져오고 이를 DatanIputStream으로 반환하는 도우미 메소드를 소개합니다.

이 주제와 관련하여 참고할 수 있는 기타 권장 기술 팁은 다음과 같습니다.

NetworkUtils.java 유틸리티 클래스

NetworkUtils 클래스는 다양한 HTTP 및 MIME 유형 상수와, HTTP에서 서버에 연결하여 지정된 리소스를 가져오는 정적 메소드 getResourcetOverHTTP()를 정의한다. 이 메소드는 원하는 방식으로 컨텐츠 스트림을 읽는 데 사용될 수 있는 DataInputStream을 반환한다.

/*
 * NetworkUtils.java
 *
 * Network Utilities. A simple method to get a resource over 
 * HTTP and return a DataInputStream is provided.
 */

package com.j2medeveloper.com.ttips.utils;

import java.io.IOException;
import java.io.DataInputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;

/**
 * Various network utilities. A simple method to get a resource over 
 * HTTP and return a DataInputStream is provided.
 *
 * @author C. Enrique Ortiz
 */
public class NetworkUtils {
   
    /////////////////////////////////////////////////////////////////
    // MIME Types
    /////////////////////////////////////////////////////////////////
    public static final String MIMETYPE_TEXT_PLAIN = "text/plain";
    public static final String MIMETYPE_TEXT_XML = "text/xml";
    public static final String MIMETYPE_APP_XML = "application/xml";
    public static final String MIMETYPE_IMAGE_PNG = "image/png";

    /////////////////////////////////////////////////////////////////
    // HTTP Contants
    /////////////////////////////////////////////////////////////////
    private static final String HTTPHDR_ACCEPT = "Accept";

    private static final String HTTPHDR_USER_AGENT = "User-Agent";
    private static String HTTPHDR_USER_AGENT_VALUE;
    
    private static final String HTTPHDR_CONNECTION = "Connection";
    private static final String HTTPHDR_CONNECTION_CLOSE = "close";
            
    private static final String HTTPHDR_CACHE_CONTROL = "Cache-Control";
    private static final String HTTPHDR_CACHE_CONTROL_NOTRANSFORM = 
            "no-transform";
    private static final String HTTPHDR_CONTENT_LEN = "Content-Length";
    
    static {
        // Retrieve the underlying profile and configuration for User Agent
        String p = System.getProperty("microedition.profiles");
        String c = System.getProperty("microedition.configuration");
        HTTPHDR_USER_AGENT_VALUE = "Profile/" + p + " Configuration/" + c;        
    }
        
    /**
     * Gets a Resource over HTTP, returing an <code>DataInputStream</code> to it
     *
     * @param uri is the URI to use to get the resource to retrieve
     * @pararm mimeType is the (possible) mime type(s) of the resource to retrieve
     *
     * @return an <code>DataInputStream</code> for the input resource
     *
     * @throws <code>IOException</code> is thrown if an error is encountered
     */
    static public DataInputStream getResourceOverHTTP(
            String uri, 
            String mimeType) throws IOException {

        HttpConnection connection = null;
        IOException ioException = null;
        DataInputStream is = null;

        try {
            connection = (HttpConnection) Connector.open(uri, Connector.READ, true);

            connection.setRequestMethod(HttpConnection.GET);

            connection.setRequestProperty(
                    HTTPHDR_ACCEPT, 
                    mimeType);

            connection.setRequestProperty(
                    HTTPHDR_USER_AGENT, 
                    HTTPHDR_USER_AGENT_VALUE);

            connection.setRequestProperty(
                    HTTPHDR_CONNECTION, 
                    HTTPHDR_CONNECTION_CLOSE);

            connection.setRequestProperty(
                    HTTPHDR_CACHE_CONTROL, 
                    HTTPHDR_CACHE_CONTROL_NOTRANSFORM);

            connection.setRequestProperty(
                    HTTPHDR_CONTENT_LEN, 
                    String.valueOf("0"));

            //////////////////////////////////////
            // Send GET, receive initial response
            //////////////////////////////////////
            int rc = connection.getResponseCode();

            /////////////////////////////////////////////////////////
            // If an HTTP error was encountered, stop, indicate error
            /////////////////////////////////////////////////////////
            if (rc != HttpConnection.HTTP_OK) {
                // Log error, throw IO exception
   ioException = new IOException("Http Error, response Code is " + rc);
                throw ioException;
            }
            is = connection.openDataInputStream();
        } catch (IOException ioe) {
            // Log error, throw IO exception
            throw ioe; // Propagate the IO Exception
        } finally {
            if (connection != null) connection.close();
            return is;
        }
    }
}
 

이 메소드는 지정된 URI(Uniform Resource Identifier)에 대한 HTTP 연결을 연 다음, HTTP 요청 헤더가 허용된 MIME 유형을 지정하도록 설정하고 연결 지속성을 비지속으로 설정하며 캐시 제어 옵션을 프록시가 컨텐츠를 변형 또는 압축하지 않도록 설정한다. GET 요청은 getResponseCode() 메소드를 호출하여 서버에 전송된다. 오류가 발생하지 않으면 DataInputStream이 반환되어 호출자에게 전달되고, 오류가 발생하면 IOException이 throw된다.

사용 방법: NetworkUtils.java

이 유틸리티 클래스와 해당 정적 메소드 getResourceOverHTTP()를 사용하려면 웹의 리소스에 대한 URI와 해당 MIME 유형을 제공하기만 하면 된다. 성공한 경우 메소드는 리소스에 대한 DataInputStream을 반환하고, 실패한 경우 처리되어야 하는 IOException을 throw한다. 모든 네트워크 작업은 다른 스레드의 차단을 막고 사용 완료 시 스트림을 닫을 수 있도록 별도의 실행 스레드에서 디스패치되어야 한다.

public final class MyClass implements Runnable {
:
    private String thPngUri; // URI used by thread
    :


    /**
     * Dispatches the thread to retrieve the resource over HTTP
     * 
     * @param uri the URI to the resource
     */
    private void dispatchGetResourceTh(String uri) {
        thPngUri = uri; // set class-wide member, that is used by thread
        Thread th = new Thread(this);
        th.start();
    }

    :

    /**
     * Thread of execution
     */
    public void run() {
        DataInputStream is = null;
        try {
            is = NetworkUtils.getResourceOverHTTP(
                    thPngUri, NetworkUtils.MIMETYPE_IMAGE_PNG);
        } catch (IOException ioe) {
            // Log error, exit
                return;
        }
        notifyRetrievalComplete(thUri, is);
    }
}
 

getResourceOverHTTP() 메소드가 리소스에 대한 DataInputStream을 성공적으로 반환하면 notifyRetrievalComplete() 메소드가 호출되어 리소스를 추가 처리한다. 예를 들어, 리소스가 이미지인 경우 다음과 같이 DataInputStream에서 Image를 생성한다.

private void notifyRetrievalComplete (
            String resourceName, DataInputStream is) {
    :

    // Create an Image from the DataInputStream.
    Image image = Image.createImage(is);
    :

    // Close the stream when done
    is.close();
    :
}
 

... 리소스가 MIDI 오디오 리소스인 경우 다음과 같이 DataInputStream에서 미디어 Player를 생성한다.

private static String mimeType = "audio/midi";
:

private void notifyRetrievalComplete (
            String resourceName, DataInputStream is) {

    // Create a Player to play back media from the DataInputStream.
    Player myPlayer = Manager.createPlayer(is, mimeType)
    :

    // Close the stream when done
    is.close();
    :
}
 
결론

이 기술 팁에서는 HTTP에서 DataInputStream의 형태로 리소스를 가져오는 데 사용할 수 있는 간단한 메소드를 소개했습니다. DataInputStream은 애플리케이션을 읽고 이에 따라 처리할 수 있는 비디오 스트림, XML 문서, 이미지 등의 다양한 데이터 유형을 나타낼 수 있습니다. 이 클래스는 추가 MIME 유형 및 기타 도우미 메소드(예: 리소스를 바이트 어레이로 가져오는 메소드 또는 좀더 복잡한 송수신 메소드)를 사용하여 확장할 수 있습니다.

 

"Java ME" 카테고리의 다른 글

2007/04/10 17:53 2007/04/10 17:53

TRACKBACK :: http://blog.sdnkorea.com/blog/trackback/368

댓글을 달아 주세요

  1. 김원일  수정/삭제  댓글쓰기

    위 기사에서 "모든 네트워크 작업은 다른 스레드의 차단을 막고" 라는 번역 부분은 자칫 오해를 가져올 수 있는 내용으로 보입니다.
    좀 더 정확히 하자면 "네트워크 작업에 의해 다른 스레드가 중단(block)되는 것을 피하기 위해 네트워크 동작은 별도의 스레드에서 수행한다" 정도의 의미로 표현되어야 할 것으로 보이는군요.

    2007/04/23 23:04
  2. 이우철  수정/삭제  댓글쓰기

    HTTP 프로토콜에 이런 기능도 있군요
    좋은 정보 배워갑니다~

    2007/09/07 20:02
  3. 고진구  수정/삭제  댓글쓰기

    쉬운 예제와 설명 잘 읽었읍니다. 큰 도움이 되겠어요.

    2007/09/09 23:05
  4. 권미자  수정/삭제  댓글쓰기

    많은것을배우고갑니다.

    2007/09/12 18:18
  5. 박정숙  수정/삭제  댓글쓰기

    좋은 정보 감사해요~

    2007/09/19 03:46
  6. 진정미  수정/삭제  댓글쓰기

    좋은 정보 많이 배워서 갑니다.~

    2007/09/19 23:05
[로그인][오픈아이디란?]

◀ Prev 1  ... 275 276 277 278 279 280 281 282 283  ... 626  Next ▶