• 카테고리
    • 전체 글

    • 카테고리1
    • 카테고리2
    • 카테고리3
    • 카테고리4
  • 태그
  • 방명록

'기술자료'에 해당되는 글 351건

  • 2010.01.30 [Google Apps Engine] 정적 파일 사용하기.
  • 2010.01.30 [Google Apps Engine] JDO를 이용하여 Datastore를 사용하기
  • 2010.01.30 [Google Apps Engine] JSP 사용하기
  • 2010.01.28 Connection 사이트 내 블로그에 Windows Live Writer로 쓰는 법.
  • 2010.01.26 [실험 중] DAMO(Domino Access for Microsoft Outlook) 8.0.2 설치.
  • 2010.01.22 [Google Apps Engine] Users Service 사용하기.
  • 2010.01.22 [Google Apps Engine] 프로젝트 생성하기.
  • 2010.01.21 우분투 9.04 에서 FreeNAS와 NFS로 Mount 하기.

[Google Apps Engine] 정적 파일 사용하기.

기술자료/Web 2010. 1. 30. 20:08

보통 웹 브라우저로 정적 파일을 그대로 전달하는 방법은 다양하게 있습니다. 이미지, CSS 스타일시트, 자바스크립트 코드, 동영상 및 플래쉬 애니메이션 등은 일반적으로 브라우저에서 내용 그대로 받게 됩니다. 그러므로 보다 효율적인 App Engine 운영을 하려면, 이런 정적 파일들을 각 서블릿과는 별개로 제공하는 방법이 좋습니다.


기본적으로 App Engine은 JSP와 WEB-INF/ 안의 파일들을 제외한 정적 파일들 모두 WAR 안에 만들게 됩니다. URL에 대한 요청들 중 정적 파일들에 해당하는 경로가 있으면, 그에 맞는 정적 파일들을 제공하게 됩니다.

서블릿 또는 필터된 매핑 또한 그런 규칙에 맞게 진행됩니다.

이것을 각 파일 별로 별도 구성하여 App Engine이 정적 파일들에 대해서 처리하지 않도록 구성할 수 있습니다. 그 설정은 appengine-web.xml 파일을 사용하여 구성하게 됩니다.


지금 부터 CSS 스타일 시트로 방명록 표현방법을 구성하도록 하겠습니다.
하지만, 이 예제에서는 정적 파일에 대한 설정을 다루지는 않습니다. 정적 파일과 자원 파일들에 대해 설정하기 위한 자세한 정보는 App Configuration을 보시기 바랍니다.


간단한 스타일시트

war/ 디렉터리 안에 stylesheets/ 라는 이름의 스타일 시트를 만드시기 바랍니다.  그리고 그 안에 main.css 파일을 생성한 뒤에 다음과 같은 내용으로 채우시기 바랍니다.

body {
    font-family: Verdana, Helvetica, sans-serif;
    background-color: #FFFFCC;
}

war/guestbook.jsp 파일을 연 뒤에 파일의 맨 위에 있는 <html> 줄 다음 줄을 다음과 같이 수정해주시기 바랍니다.

<html>
  <head>
    <link type="text/css" rel="stylesheet" href="/stylesheets/main.css" />
  </head>

  <body>
    ...
  </body>
</html>

자 이제 http://localhost:8080 으로 접근해보시기 바랍니다. 그러면 스타일 시트로 바뀐 새로운 화면을 보실 수 있습니다.


다음은...

이제 지금까지 구성한 내용을 실제 Google Apps Engine에 등록해 보도록 하겠습니다.


응용 프로그램 올리기에서 계속 됩니다.

728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

[Google Apps Engine] JDO를 이용하여 Datastore를 사용하기

기술자료/Web 2010. 1. 30. 19:09

원본글 : http://code.google.com/appengine/docs/java/gettingstarted/usingdatastore.html

 

NOTES: 지금까지 개인적으로 Google Apps를 이용하여 간단한 Application을 개발하고,

배포해서 적용해 봤습니다. 초라하고 엉성하기 그지 없지만, 나름 Google Apps Engine에

대한 생각이 정리되기 시작했습니다. 사실 이거 2009년 말에 모두 번역에서 등록하려고
했는데, 이 데이터 저장 부분은 번역하면서 막히기도 하고, 개념도 이해가 안가, 상당히

망설인 부분 이였습니다. 그래서 직접 몸으로 체험을 해봤습니다.
하지만 여전히 내용이 무척 어렵습니다. 짧은 Java 실력 때문에,
20세기 말에서 부터 지금까지 만들어진 각종 Java 표준을 거의 모르다 보니,
전혀 생뚱맞게도 번역되는 군요. 어느정도의 원리라도 알면 쉽게 번역 될텐데...

그냥 강행 하렵니다!!!!!!

 

확장성을 갖춘 웹 응용프로그램에서 데이터를 저장하는 방법은 약간의 편법이 요구 됩니다. 사용자가 요청한 작업을 처리하기 위한 웹 서버가 여러 대 인 경우, 그 사용자의 다음 요청에 대해서도 정상적인 처리 될 수 있도록 이전 요청 내용에 대해서 모든 웹 서버들이 알고 있어야 한다는 점입니다. 이 때문에 물리적으로 완전 분리되어 다른 지역에 있는 웹 서버일지라도 이 사용자 정보를 모두 공유해서 보유 해야 될 것입니다.

 

Google Apps Engine에서는 이런 분산 환경에 대한 문제에 대해 여러분이 걱정하지 않도록 도와드립니다. App Engine의 인프라 스트럭처에서는 단순한 API 뒤에서 동작되는 분산 환경의 관리, 데이터 복제 및 부하 분산까지 고려되어 제공됩니다. 물론 단순한 API라고 해도 강력한 query 엔진과 트랜젝션 관리를 처리할 수 있도록 도와드립니다.

 

Apps Engine의 데이터 저장은 두 가지 유형의 API를 통해 각종 저장 관련 서비스를 제공합니다. 그 API의 두 가지 유형에는 표준형 API와 저 수준(low-level) API가 있습니다. 
표준형 API를 사용한다면, 실제 구현한 내용 그대로, 다른 데이터베이스 기술과 호스팅 환경으로도 쉽게 이식 적용이 가능합니다. 표준 API는 App Engine서비스와 여러분의 응용 프로그램 간의 의존성을 최대한 낮추도록 설계되어 있습니다. 
물론 Apps Engine 에서 제공되는 서비스를 직접 활용할 수 있도록 저수준(low-level) API를 제공하고 있습니다. 이 저수준 API를 사용하여 새로운 아답터 인터페이스를 별도로 구현할 수 있으며, 직접 응용 프로그램 내에서 사용할 수도 있습니다.

 

App Engine은 두 가지의 다른 데이터 저장 표준 - Java Data Object(JDO)와 Java Persistence API(JPA) - 서비스를 포함하고 있습니다. 이들 인터페이스는 DataNucleus Access Platform을 기반으로 구성되어 있습니다. 이 DataNucleus Access Platform은 다양하게 있는  Java persistence 표준들을 구현한 오픈 소스로써 App Engine 저장소에서는 이 플랫폼에 대한 아답터를 사용하고 있습니다.

 

방명록에서는 JDO 인터페이스를 사용하여 사용자가 남긴 메시지를 다시 불러올 수 있도록 구성할 것입니다.

 

DataNucleus Access Platform 구성하기.

Access Platform에는 JDO 구현에 대한 배경을 App Engine 저장소로 사용한다고 알려주기 위한 설정 파일이 필요합니다. 이 설정 내용은 최종 WAR 안에, war/WEB-INF/META-INF 디렉터리 안에 jdconfig.xml이라는 이름의 파일이 있어야 합니다. 

 

이클립스를 사용하신다면, 프로젝트 탐색기에서 src/META-INF 안 에 jdconfig.xml 파일을 생성해주시면 됩니다.

 

jdconfig.xml 파일에는 다음과 같은 내용이 담기면 됩니다.

<?xml version="1.0" encoding="utf-8"?>
<jdoconfig xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig">

    <persistence-manager-factory name="transactions-optional">
        <property name="javax.jdo.PersistenceManagerFactoryClass"
            value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/>
        <property name="javax.jdo.option.ConnectionURL" value="appengine"/>
        <property name="javax.jdo.option.NontransactionalRead" value="true"/>
        <property name="javax.jdo.option.NontransactionalWrite" value="true"/>
        <property name="javax.jdo.option.RetainValues" value="true"/>
        <property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/>
    </persistence-manager-factory>
</jdoconfig>

 

JDO Class 확장하기.

JDO 클래스를 만들 때, 어떻게 데이터가 저장되어 구현될지, 데이터를 조회할 때 다시 인스턴스를 만들지에 대하여 Java의 문법을 활용하여 구성할 수 있습니다. Access Platform에서 데이터 클래스와 컴파일 후 처리되는 단계의 구현물 간의 연결을 수행할 때 그 DataNucleus 를 "확장된" 클래스라고 부르게 됩니다.

 

이클립스와 Google Plugin을 사용하게 되면, 플러그인에서 JDO 클래스에 대한 확장 작업을 빌드 단계 때 자동으로 수행하게 됩니다. 이클립스가 없다면...  Ant를 사용하여 하게 되는데, 그 내용은 원본 문서를 활용해 주세요.

 

JDO 클래스의 확장에 대한 더 자세한 내용은 JDO를 사용하기(Using JDO)를 참고하시기 바랍니다.

 

POJOs 와 JDO 문법

DataNucleus Access Platform과 같은 JDO호환 아답터로 Java 객체(대부분 Plan Old Java Objects 또는 POJOs 라고 불린다.)를 JDO로 저장할 수 있습니다. App Engine SDK에는 App Engine 저장소를 위한 Access Platform 플러그 인이 포함되어 있습니다. 즉, App Engine 데이터 저장소에 정의하려는 내용을 클래스 형태로 구현하여 저장 할 수 있다는 것입니다.  마찬가지로 JDO API를 사용하여 객체를 통해 데이터를 가져올 수도 있다는 것입니다. Java 문법을 사용하여 만든 클래스의 인스턴스를 저장하거나 재 생성하는 방법만 JDO에 전달 할 수 있으면 되는 것입니다.

 

방명록에 올린 개별 메시지를 표시 할 때 사용될 Greeting 클래스를 만들어보도록 하죠.

 

일단 guestbook 패키지 안에 Greeting 이라는 클래스를 생성하시기 바랍니다. 이 클래스 안에 채울 내용은 다음과 같습니다.

package guestbook;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.users.User;

import java.util.Date;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Greeting {
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;

    @Persistent
    private User author;

    @Persistent
    private String content;

    @Persistent
    private Date date;

    public Greeting(User author, String content, Date date) {
        this.author = author;
        this.content = content;
        this.date = date;
    }

    public Key getKey() {
        return key;
    }

    public User getAuthor() {
        return author;
    }

    public String getContent() {
        return content;
    }

    public Date getDate() {
        return date;
    }

    public void setAuthor(User author) {
        this.author = author;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public void setDate(Date date) {
        this.date = date;
    }
}

 

인사말을 저장하기 위한 3가지의 간단한 속성(author:작성자, content:내용, date:작성일)을 클래스 안에 정의했습니다. 이 세가지 private 필드들은 각각 @Persistence 라는 문법을 추가하여 App Engine 저장소에 저장될 항목들임을 알려주게 됩니다.

 

이 클래스에는 이 속성 값을 가져오고 넣을 수 있는 인터페이스도 만들어서 넣었습니다. 하지만 이것은 응용프로그램 내에서 사용하는 내용일 뿐 JDO에서는 사용하지 않습니다. ( 즉 이름이 조금 틀려도 상관 없다는 의미입니다.)

 

여기서 주목해서 봐주시면 하는 것이 바로 key 라는 필드 입니다. key에서는 @Persistence 뿐만 아니라 @PrimaryKey라는 Java 문법이 추가되어 있습니다. App Engine 저장소에는 사용되는 각 Entity(레코드)를 고유하게 구분하기 위한 키라는 개념이 있는데, 이 키를 표현하는 방법이 객체에 따라 여러 가지 다른 방법들이 있습니다. App Engine 저장소에서 각종 키들을 표현하는 모든 방법은 Key 라는 클래스에 정의되어 있습니다. 방법 중에서 일반적으로 사용되는 방법은 객체가 저장 될 때 유일한 값을 자동적으로 정의해서 넣는 숫자형 ID를 주로 사용됩니다.

 

JDO 문법에 대하여 더 자세한 내용은 Data Classes를 정의하는 방법(Defining Data Classes)를 참고하시기 바랍니다. 

 

PersistenceManagerFactory에 대해

위와 같은 구조에서는 요청이 들어올 때 마다 저장소는 PersistenceManager 클래스의 새 인스턴스를 계속 생성하게 됩니다. 이를 위해서 PersistenceManagerFactory 클래스를 만들어 사용하면 더 간단하게 구성하실 수 있습니다. PersistenceManagerFactory 인스턴스는 초기화 될 때 만들어지게 됩니다. 다행히도, 응용 프로그램 내에서는 단 한 개의 인스턴스만 있으면 되기 때문에, 여러 클래스들과 여러 번의 요청에서도 사용될 수 있는 정적 변수 하나에 저장되어 있으면 됩니다. 이런 정적 인스턴스를 들고 있을 싱글톤 형태의 클래스만 생성하면  간단하게 처리됩니다.

 

guestbook 패키지 안에 PMF라는 이름의 새로운 클래스를 생성한 뒤(src/guestbook 디렉터리 안에 PMF.java라는 파일을 만들면 됨), 다음과 같은 내용을 넣어주시면 됩니다.

package guestbook;

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManagerFactory;

public final class PMF {
    private static final PersistenceManagerFactory pmfInstance =
        JDOHelper.getPersistenceManagerFactory("transactions-optional");

    private PMF() {}

    public static PersistenceManagerFactory get() {
        return pmfInstance;
    }
}

 

개체를 생성하고 저장하기.

Greeting 클래스에 적절한 위치에, DataNucleus를 사용하여 저장소에 새로운 인사말을 저장하기 위한 처리 로직을 구성하면 됩니다.  

 

일단 src/guestbook/SignGuestbookServlet.java 파일을 열어 다음과 같은 내용처럼 재구성해주시면 됩니다.

package guestbook;

import java.io.IOException;
import java.util.Date;
import java.util.logging.Logger;
import javax.jdo.PersistenceManager;
import javax.servlet.http.*;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;

import guestbook.Greeting;
import guestbook.PMF;


public class SignGuestbookServlet extends HttpServlet {
    private static final Logger log = Logger.getLogger(SignGuestbookServlet.class.getName());

    public void doPost(HttpServletRequest req, HttpServletResponse resp)
                throws IOException {
        UserService userService = UserServiceFactory.getUserService();
        User user = userService.getCurrentUser();

        String content = req.getParameter("content");
       
Date date = new Date();
        Greeting greeting = new Greeting(user, content, date);

        PersistenceManager pm = PMF.get().getPersistenceManager();
        try {
            pm.makePersistent(greeting);
        } finally {
            pm.close();
        }


        resp.sendRedirect("/guestbook.jsp");
    }
}

(굵은 글자의 표시가 불분명하여 밑줄을 추가했습니다.)

이 코드는 생성자를 호출하여 Greeting 클래스의 새로운 인스턴스를 만들 때 데이터를 채우게 됩니다. 그리고 저장소에 이 인스턴스의 내용을 저장하기 위해 PersistenceManagerFactory를 통해 PersistenceManager를 새로 생성 한 뒤, 데이터 인스턴스를 PersistenceManager의 makePersistence() 메소드에 넘기게 됩니다. 이제 클래스에서 정의된 Java 규칙에 맞게 바이너리 확장이 되고 데이터가 저장소로 전달되게 됩니다. makePersistent()를 갔다오게 되면 저장소에 데이터 내용이 저장되게 됩니다.

 

JDOQL로 데이터 조회하기.

JDO 표준에는  persistent 객체를 조회할 때 사용하는 매커니즘이 정의되어 있습니다. 이 매커니즘을 보통 JDOQL이라고 부릅니다. App Engine 저장소에 있는 entity들을 조회할 때 이 JDOQL을 사용하게 되면, JDO-확장 객체 형태의 결과 값을 돌려주게 됩니다.

여기서는 그 사용 예제를  guestbook.jsp에서 직접 쿼리 코드를 직접 다루어 처리하는 형태로 구성할 예정입니다. 하지만 일반적인 형태로 만들 경우에는 가급적 데이터 처리용 대리자 클래스를 별도로 구성하여 사용하는 것이 좋습니다.

일단 war/guestbook.jsp를 연 뒤에 다음 코드 형태대로 수정하시기 바랍니다.

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.List" %>
<%@ page import="javax.jdo.PersistenceManager" %>

<%@ page import="com.google.appengine.api.users.User" %>
<%@ page import="com.google.appengine.api.users.UserService" %>
<%@ page import="com.google.appengine.api.users.UserServiceFactory" %>
<%@ page import="guestbook.Greeting" %>
<%@ page import="guestbook.PMF" %>


<html>
  <body>

<%
    UserService userService = UserServiceFactory.getUserService();
    User user = userService.getCurrentUser();
    if (user != null) {
%>
<p>Hello, <%= user.getNickname() %>! (You can
<a href="<%= userService.createLogoutURL(request.getRequestURI()) %>">sign out</a>.)</p>
<%
    } else {
%>
<p>Hello!
<a href="<%= userService.createLoginURL(request.getRequestURI()) %>">Sign in</a>
to include your name with greetings you post.</p>
<%
    }
%>

<%
    PersistenceManager pm = PMF.get().getPersistenceManager();
    String query = "select from " + Greeting.class.getName();
    List<Greeting> greetings = (List<Greeting>) pm.newQuery(query).execute();
    if (greetings.isEmpty()) {
%>
<p>The guestbook has no messages.</p>
<%
    } else {
        for (Greeting g : greetings) {
            if (g.getAuthor() == null) {
%>
<p>An anonymous person wrote:</p>
<%
            } else {
%>
<p><b><%= g.getAuthor().getNickname() %></b> wrote:</p>
<%
            }
%>
<blockquote><%= g.getContent() %></blockquote>
<%
        }
    }
    pm.close();
%>


    <form action="/sign" method="post">
      <div><textarea name="content" rows="3" cols="60"></textarea></div>
      <div><input type="submit" value="Post Greeting" /></div>
    </form>

  </body>
</html>

쿼리를 준비하기 위해 먼저 PersistenceManager 인스턴스의 newQuery() 메소드를 호출합니다. 이 메소드에 실제로 쿼리로 사용할 Text 내용을 건네 주게 됩니다. 이 메소드의 실행 결과 값은 쿼리에 대한 개체 입니다. 쿼리 개체의 execute() 메소드를 호출하게 되면 정의한 쿼리 내용대로 실행하게 되며, 그 결과 값은 각 유형에 맞는 결과 개체를 List<>로 돌려주게 됩니다. 쿼리 문장에는 쿼리를 할 클래스의 전체 이름 - 패키지 이름까지 포함한 - 을 반드시 넣어주어야 합니다.

 

프로젝트를 다시 빌드한 뒤, 서버를 재시작합니다. http://localhost:8080/ 에 들어갑니다. 인사말을 넣고 submit을 하도록 합니다. 폼 위에는 인사말이 표시될 것입니다. 계속 각각 다른 인사말을 넣고 submit을 하도록 합니다. 그러면 입력했던 인사말들이 계속 표시됩니다. 이제는 로그인 했을 때 다른 인사말을 submit 해보고, 로그아웃 했을 때 다시 인사말을 넣고 submit을 해보도록 하세요.

 

Tip: 실제 사용되는 응용 프로그램에서는 HTML용 문자들(태그 등등)에 대해 Escape 처리하는 것이 좋습니다. JavaServer Pages Standard Tag Library(JSTL)에는 이런 Escape 처리를 위한 도구들을 제공합니다. App Engine에는 JSTL(및 기타 JSP 관련 런타임 JAR들)을 포함하고 있어, 이런 Escape 처리를 위해 별도로 관련 JAR들을 포함시킬 필요는 없습니다.  escapeXml 함수에 대한 자세한 설명은 태그 라이브러리http://java.sun.com/jsp/jstl/functions 에서 보시기 바랍니다.

더 자세한 내용은 Sun의 J2EE 1.4 튜토리얼을 참고하시기 바랍니다.

 

JDOQL 기초

방명록 예제에서는 시스템 내에 등록된 모든 메시지들을 보여주고 있습니다.이 메시지들이 표시되는 순서는 알 수 없는 순서로 나열되고 있는데, 이를 메시지가 생성된 순서대로 나열하도록 하겠습니다. 또 너무 많은 메시지가 저장되어 있을 때, 최신의 메시지가 맨 위에 오도록 하는 것이 좋을 것입니다. 이런 조정을 쿼리를 수정함으로써 간단하게 처리가 가능합니다.

SQL과 유사하게 생긴 쿼리 문법인 JDOQL을 이용하여 JDO 인터페이스에 처리를 요청하여 원하는 데이터 개체들을 조회하는 것입니다. 앞서 편집한 JSP 페이지의 코드 내용을 보시면 다음 내용과 같은 부분을 보실 수 있습니다.

String query = "select from " + Greeting.class.getName();

이 내용을 실행하면 query라는 변수 안에 다음과 같이 담기게 됩니다.

select from guestbook.Greeting

즉 이 쿼리 문장을 통해 조회하게 되면 Greeting 클래스를 이용하여 저장한 모든 데이터를 가져오게 됩니다.

결과물로 돌려줄 객체의 속성값을 제한 값으로 쿼리에 포함하게 되면, 결과 값을 제한시켜 받을 수 있게 됩니다. 예를 들면 Greeting 객체에 있는 author라는 속성 값이 alfred@example.com 인 개체만을 가져오려면 다음과 같이 쿼리를 만들면 됩니다.

select from guestbook.Greeting where author == 'alfred@example.com'

또 특정 속성값을 기준으로 순서에 맞게 정렬 할 수도 있습니다. 최신글을 맨위로 해서 정렬을 한다고 할 때는 다음과 같이 쿼리를 만들면 됩니다.

select from guestbook.Greeting order by date desc

또 쿼리 결과물 갯수를 제한할 수 있습니다. 만일 최신 메시지 5개까지만 가져오도록 하고 싶다면, order by 와 range를 동시에 써서 표현 하면 됩니다. 그 쿼리는 다음과 같습니다.

select from guestbook.Greeting order by date desc range 0,5

guestbook.jsp 안의 쿼리를 수정하여 위에서 언급한 대로 최근 메시지 5개만 뿌리도록 설정하도록 하죠.

그러려면 guestbook.jsp 안의 쿼리 부분을 아래와 같이 수정하시면 됩니다.

String query = "select from " + Greeting.class.getName() + " order by date desc range 0,5";

그러면 가장 최근에 등록된 인사말 중 5개까지만 나타나게 될 것입니다.

JDOQL에 대한 더 자세한 내용은 Query와 Index를 참고하시기 바랍니다.

 

다음은...

모든 웹 응용 프로그램들은 템플릿이나 기타 매커니즘을 통해 동적으로 생성된 HTML을 돌려주게 됩니다.하지만 여전히 많은 웹 응용 프로그램들은 추가적으로 정적 컨텐츠 - 이미지, CSS, JavaScript 파일 등등 - 역시 같이 제공되고 있습니다. 이 때 응용 프로그램 구성을 보다 효과적으로 하기 위해서는 이러한 정적 파일과 응용프로그램은 명확하게 구분하는 것이 좋습니다.

다음 내용에서는 CSS 시트를 생성하여 응용 프로그램과 분리하여 구성하는 방법을 소개해 드리겠습니다.

 

 

정적 파일 사용하기에서 계속 됩니다.

728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

[Google Apps Engine] JSP 사용하기

기술자료/Web 2010. 1. 30. 18:29

원본글 : http://code.google.com/appengine/docs/java/gettingstarted/usingjsps.html


Java 서블릿 코드로만 직접 HTML 코드를 작성하여 구성하려면, HTML에 대한 관리 작업이 무척 어려워 질 것입니다. 그래서 템플릿 시스템을 활용하면, 인터페이스에 대한 디자인과 구현을 데이터 추가와 같은 로직과 분리하여 응용 프로그램과는 다른 파일로 구성하실 수 있습니다. Java에서도 다양한 템플릿 시스템이 있으며, App Engine에서는 대부분의 시스템들과 정상적으로 동작합니다.


이 튜토리얼에서는 JavaServer Pages(JSP)으로 방명록에 대한 사용자 인터페이스를 구현하려 합니다. JSP는 서블릿 표준에 의거하여 제공됩니다. App Engine에서는 자동적으로 WAR에 있는 JSP 파일을 컴파일 하고, URL 경로에 연결하게 됩니다.


Hello, JSP!

방명록 응용 프로그램에서는 출력 스트림에 직접 문자열을 쓰고 있는데, 이 부분을 JSP로 변경하도록 합니다.  JSP 예제로 제공되는 최신 버전을 가져와서 시작하도록 하죠.


war/ 디렉토리에서 guestbook.jsp라는 이름의 파일을 생성하고, 다음과 같은 내용으로 구성해보시기 바랍니다.


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.google.appengine.api.users.User" %>
<%@ page import="com.google.appengine.api.users.UserService" %>
<%@ page import="com.google.appengine.api.users.UserServiceFactory" %>

<html>
  <body>

<%
    UserService userService = UserServiceFactory.getUserService();
    User user = userService.getCurrentUser();
    if (user != null) {
%>
<p>Hello, <%= user.getNickname() %>! (You can
<a href="<%= userService.createLogoutURL(request.getRequestURI()) %>">
sign out
</a>.)</p> <% } else { %> <p>Hello! <a href="<%= userService.createLoginURL(request.getRequestURI()) %>">
Sign in</a> to include your name with greetings you post.</p> <% } %> </body> </html>

기본적으로 war/ 내 여러 파일, 하위 디렉터리(WEB-INF/ 외의 디렉터리들)을 탐색하여, .jsp로 끝나는 파일들을 자동적으로 URL 경로에 연결하게 됩니다. 이 URL 경로라는 의미는 .jsp 파일이 있는 경로입니다. 그래서 JSP 자체의 경로는 URL 경로 뒤에 파일 이름까지를 의미하게 됩니다. 이 JSP 파일은 war/ 바로 밑에 있게 되므로, URL이 /guestbook.jsp 가 되게 됩니다.


만일 사용자가 URL 경로를 / 만 입력하게 되면(즉 파일이름을 없애고 입력하는 경우), 방명록 응용프로그램에 있는 home page를 호출하게 됩니다. 이 guestbook.jsp 를 홈페이지로 등록하시고 싶다면, web.xml 내에서 이 경로에 대해 정의를 해주시면 됩니다.

web/WEB-INF/web.xml을 열고 <welcome-file-list> 항목 안에 <welcome-file> 이라는 항목을 추가한 뒤, 저장해주시면 됩니다. 이 guestbook.jsp 파일만 홈페이지로 사용하려면, 기존에 있는 index.html 을 삭제해주시면 됩니다. 이렇게 편집한 부분을 간단하게 보시면 아래와 같습니다.

<welcome-file-list>
    <welcome-file>guestbook.jsp</welcome-file>
</welcome-file-list>
TIP : Ecipse 에서 XML을 편집할 때, 위와 같은 코드로 바로 보이지 않을 것입니다. 기본적으로 “Design” 모드로 시작되기 때문인데, 만일 위와 같은 소스로 보시려면 “Source” 모드로 변경하시면 위와 같은 코드를 보실 수 있습니다.

수정이 완료되었으면, 개발용 웹서버를 중지 시켰다가 다시 시작한 뒤, 다음 URL을 입력하시기 바랍니다.

http://localhost:8080/guestbook

(간혹 설정 상으로 http://localhost:9999/guestbook 일 수도 있습니다.  - 포트 번호는 각자 확인해보시기 바랍니다. )

 

이제 응용프로그램에서는 guestbook.jsp에 내용을 보여줄 것입니다. 만일 로그인 되셨다면, Nickname을 표시할 것입니다.

맨 처음 JSP를 실행하면, 개발 서버에서는 JSP를 Java 소스코드로 변경 시킵니다. 그리고 난뒤 Java 소스 코드를 Java bytecode로 컴파일 하게 됩니다. Java 소스와 컴파일 된 클래스들은 임시 디렉터리에 저장됩니다. 만일 원래 JSP 파일을 변경하게 되면, 개발 서버에서 자동적으로 JSP들을 재생성하고, 컴파일 하게 됩니다.

App Engine으로 응용 프로그램을 업로드 하게 되면, SDK에서 모든 JSP내용들을 bytecode로 컴파일하고, 이 컴파일 된 bytecode만 업로드 하게 됩니다. 즉, App Engine에서 동작중인 응용프로그램은 이미 컴파일 된 JSP 클래스들입니다.


방명록 Form

방명록 응용프로그램에서 새 인사말을 올리는 작업을 하려면, 사용자 입력 받을 수 있는 웹 폼이 필요합니다. HTML 기반의 폼은 JSP로 만들 수 있습니다. 여기서는 입력 폼의 위치를 새로운 URL, /sign 으로 구성하여, 이곳에서 새로운 서블릿 클래스로 동작할 수 있게 해줍니다. SignGuestbookServlet.SignGuestbookServlet에서는 값을 입력하는 폼 관련 처리를 수행한 뒤, 자동적으로 /guestbook.jsp 로 리다이렉트 될 수 있도록 합니다. 지금부터 새로운 서브릿에서는 등록된 메시지를 로그로 기록할 수 있게 합니다.


guestbook.jsp를 연 뒤, </body> 태그 위에다 아래의 코드를 넣어주시기 바랍니다.
( 굵게 표시된 <form> .. </form> 부분만 넣어주시면 됩니다. )

...

  <form action="/sign" method="post">
    <div><textarea name="content" rows="3" cols="60"></textarea></div>
    <div><input type="submit" value="Post Greeting" /></div>
  </form>

  </body>
</html>

guestbook 패키지 안에 SignGuestbookServlet 라는 이름으로 새로운 클래스를 만들어주시기 바랍니다. 클래스 내용은 다음과 같이 넣어주시면 됩니다.

package guestbook;

import java.io.IOException;
import java.util.logging.Logger;
import javax.servlet.http.*;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;

public class SignGuestbookServlet extends HttpServlet {
    private static final Logger log
= Logger.getLogger(SignGuestbookServlet.class.getName());

    public void doPost(HttpServletRequest req, HttpServletResponse resp)
                throws IOException {
        UserService userService = UserServiceFactory.getUserService();
        User user = userService.getCurrentUser();

        String content = req.getParameter("content");
        if (content == null) {
            content = "(No greeting)";
        }
        if (user != null) {
            log.info(
"Greeting posted by user "
+ user.getNickname() + ": " + content);
        } else {
            log.info("Greeting posted anonymously: " + content);
        }
        resp.sendRedirect("/guestbook.jsp");
    }
}

이제 새로 만든 서블릿 클래스를 설정하기 위해 war/WEB-INF/web.xml 을 열어 아래의 내용 처럼 SignGuestbookServlet 이라는 서블릿을 선언한 뒤, /sign URL에 연결합니다.

<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
    ...

    <servlet>
        <servlet-name>sign</servlet-name>
        <servlet-class>guestbook.SignGuestbookServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>sign</servlet-name>
        <url-pattern>/sign</url-pattern>
    </servlet-mapping>

    ...
</web-app>

새로운 서블릿은 java.util.loggin.Logger 클래스를 상속 받아 메시지를 쓰게 됩니다. loggin.properties 파일을 사용하여 이 클래스의 동작을 제어하게 되는데, 시 시스템 속성은 응용프로그램의 appengine-web.xml 파일에 설정할 수 있습니다.

<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
    ...

    <system-properties>
        <property name="java.util.logging.config.file" 
value="WEB-INF/logging.properties"/> </system-properties>
</appengine-web-app>

서블릿 로그 메시지는 로그 레벨을 INFO 형태로(log.info()를 사용함) 메시지를 기록합니다. 하지만, 기본적으로 출력되는 로그들은 최소한 WARNING 이상이 되어야 하기 때문에, 그냥 INFO로 로그를 기록하면 출력되지 않습니다. INFO 레벨의 로그도 출력되게 하려면, guestbook 패키지 안의 모든 클래스에 대한 로그 레벨을 logging.properties 파일을 열어 그 안에 guestbook.level 엔트리를 다음과 같이 수정해주셔야 합니다.

.level = WARNING
guestbook.level = INFO

...
TIP : AppCfg 라는 도구를 다운 받아 활성화 시켜주시면, App Engine에서는 java.util.logging.Logger API를 이용하여 기록하는 모든 로그 메시지를 the Admin Console 에서도 확인 할 수 있습니다. Admin Console에서도 로그 레벨에 따라 메시지를 찾아 보실 수 있습니다.

 

다시 빌드 하시고, 재 시작하신 뒤, http://localhost:8080/ 에 접속하시면 테스트를 하실 수 있습니다.(다시 또 언급 드리지만, 포트 번호 설정에 따라, http://localhost:9999 일수도 있습니다. 자세한 것은 web.xml에 설정한 포트 번호를 참고하시기 바랍니다. ). 입력 폼이 뜨면, 그 안에 적당한 문자열을 넣으시고 Submit을 해주세요. 웹 브라우저에서 폼에 입력한 내용이 응용프로그램에 전달하게 되면, 자동적으로 깨끗이 빈 폼으로 되돌아가게 됩니다. 이 때 로그 내용을 보시게 되면, 아까 입력한 문자열을 보실 수 있습니다.


다음은…

지금까지 사용자들이 인사말을 입력할 수 있도록 제공되는 사용자 인터페이스를 구성해 보았습니다. 이제 App Engine의 datastore를 사용하여, 사용자들이 입력한 인사말들을 저장하는 방법과, 그 내용을 다른 이들에게 보여주는 방법에 대해 살펴보도록 하겠습니다.


JDO를 이용하여 Datastore를 사용하기에서 계속되겠습니다.

728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

Connection 사이트 내 블로그에 Windows Live Writer로 쓰는 법.

기술자료/Web 2010. 1. 28. 11:42

IBM에서는 MS의 MOSS 2007의 대항마로 Lotus Connections 라는 도구를 들고 왔더군요.

회사내에서도 이것을 설치하여 운영 중인데, 커뮤니티 개념의 활동을 여기서 주로

할 수있도록 배려 해주더군요. 그런데 이 안에도 Blog가 있는데, 그 안에 탑재된 편집기가,

MOSS 2007의 편집기에 버금갈 정도로 불편하더군요 -_-;;;;;;

그래서 Live Writer를 붙이는 방법을 조금 조사해봤고, 그 결과를 Report 합니다.


(주의! 전 영문판이라서 양키 말로 나옵니다. 양해 바랍니다. 한글판 깔면 한글로 나와요 )



위의 선택사항 중 Other blog service (기타 블로그 서비스)를 선택하시면 됩니다. 그리고 다음~

다음과 같은 내용이 뜨는데, 이제 실제적인 블로그 설정 내용이 필요합니다.


위의 내용을 입력하기 앞서 먼저 그럼 필요한 설정 내용이 있어야 되겠군요.

그럼 이번엔 Connection 사이트에 접속합니다.

로그인 해주시고...

사이트에 들어가셨으면 맨 상위 툴바 메뉴 에 있는 "블로그" 클릭하시고

그 다음 아래쪽의 "내 블로그"를 클릭하세요.

그리고 난 뒤에 원하는 블로그의 링크를 클릭하세요.

이번에 컴퓨터 공학 관련 자료를 한번 정리하려고 만든 Computer Sciences 블로그를

예로 들어봐야 겠군요. 원하는 블로그를 클릭해서 들어갑니다.

자 여기서 주소줄의 내용을 긁어 옵니다.

제 블로그의 주소는 아래와 같습니다.

http://platon.mauminfo.com/blogs/6f782857b91c/?lang=ko_kr


일단 기억만 해두시고...

여기 블로그의 외부에 제공하는 API URL은 다음과 같습니다.

/blogs/services/xmlrpc">http://<hostname>/blogs/services/xmlrpc

굵은 글씨 부분이 바로 그 API 주소 입니다.
일단 저기까지 파악되셨으면 아까 설치하려다 만 부분으로 다시 돌아갑니다.

자 이제 다음과 같이 넣어 주시기 바랍니다.


Web address of your blog ( 여러분의 블로그의 웹 주소 )에는

http://platon.mauminfo.com/blogs/146c9570-be4f-6f782857b91c/?lang=ko_kr

를 넣고, 아이디와 암호를 넣은 뒤,

자, 다음을 눌러보시죠!


앗!!!! 그런데?!


이게 무신 일..... 애석하게도 Connect 에서 제공하는 블로그를 외부에서 접근하려면,

http가 아닌 https 여야 되는것 같더군요.

일단 OK를 클릭하시고! 아까 넣었던 주소 중에 이번에는 http를 https로 변경해서 넣어주세요.

https://platon.mauminfo.com/blogs/1457b91c/?lang=ko_kr

자 그럼 이번에 해보시면 무사히 무언가 자동으로 처리되어 넘어가고

다시 무언가 입력하는 화면이 나옵니다. 여기가 바로 블로그에서 제공하는 외부 API 설정입니다.

일단 Type of blog that your are using( 현재 사용 중인 Blog의 유형 )에서

Metaweblog API를 선택하세요. 그리고 안의 주소에 다음과 같이 넣어주세요.

http://platon.mauminfo.com/blogs/services/xmlrpc

여기서 주의할 것은 아까 처럼 https를 넣게 되면 위의 캡처 화면과 동일한 에러를 뿜는다는거.

꼭 http로 해주세요. 그럼 다음과 같이 정리될 겁니다.


다음을 눌러주시구요....

그러면 실제 사용할 블로그를 선택하는 창이 뜨는데 여기서 올바른 블로그를 선택해주세요.

(안그러면 어뚱한데 글이 올라갑니다)

선택 하 다음!

그러면 무언가 자동적으로 쭉 진행되다 다음과 같은 알림 창이 뜹니다.

현재 블로그의 테마나 기타 설정 내용 대로 Windows Live Writer에서도 사용할 꺼냐는 것입니다.

최소한 블로그를 보는 것 처럼 편집하려면 역시 이게 좋기 때문에, 가급적 Yes를 선택해주시면 됩니다.

자 그럼 쭉 프로그레스가 차면서 무언가 열심히 작업합니다.

끝나면 마침 확인 창 같은 화면이 뜹니다.

블로그 닉네임은 자신이 알아보기 쉬운 말로 적어주시면 됩니다. 뭐 Connect - Computer Sciences 라고 적으셔도 되고..

그냥 두셔도 됩니다. Finish 하시면 됩니다.


그러면 다음과 같은 훤한 입력을 위한 화면이 뜹니다.


이제 열심히 포스팅 해주시면 됩니다 ㅋ.

728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

[실험 중] DAMO(Domino Access for Microsoft Outlook) 8.0.2 설치.

기술자료/ETC 2010. 1. 26. 18:49

DAMO(Domino Access for Microsoft Outlook) 프로그램을 사용하여,

Outlook에서도 마치 Exchange 쓰듯 Lotus Domino 서버를 활용할 수 있다.

 

 

보통 XP의 Outlook 2003에서는 상당히 제정신으로 도는데,

MS에서도 밥벌어먹고 살려면 업그레이드를 해야 되겠고,

결국 덩달아 업그레이드를 하다 보니, 현재 구성은 Windows 7에 Outlook 2007이 되버렸다.

그러나 최적의 환경을 구성하기에는 너무 구닥다리 같은 UI와 기능들에

결국 꿋꿋하게 Windows 7의 Outlook 2007을 활용하려고 한다.

 

그러나 현재 Outlook 2007을 종료하면 자꾸 프로그램 오류가 발생한다.

에러 내용은 아래와 같다.

 

Faulting application name: OUTLOOK.EXE, version: 12.0.4518.1014, time stamp: 0x4542840f
Faulting module name: nwnspR32.dll_unloaded, version: 0.0.0.0, time stamp: 0x489c864f
Exception code: 0xc0000005
Fault offset: 0x01e82e74
Faulting process id: 0xcf4
Faulting application start time: 0x01ca9e6097aafc8d
Faulting application path: C:\Program Files\Microsoft Office\Office12\OUTLOOK.EXE
Faulting module path: nwnspR32.dll
Report Id: f39a9d85-0a53-11df-b241-001f3b661b0f

 

일단 현재까지 파악한 내용은 Windows 7(Vista 때 부터 담겼던) Windows Search가 Outlook 자원까지 찝적거린결과 였었다. 최소한 Windows Search가 찝적되면 Outlook이 제대로 작동하지 않는다.

 

이 것을 해결하는 방법은 아래의 레지스트리를 수정하면 된다.( 대개는 없으므로 추가해야 한다. )

 

[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search]
"PreventIndexingOutlook"=dword:00000001

 

그리고 난 뒤, Windows Search 서비스를 재 시작하거나, 아니면 컴퓨터를 리부팅 한다.

 

UPDATE: 2010-01-06 18:41

SP1을 적용했으나, 변화 없음 똑 같은 형태로 에러가 발생한다.

현재 설치된 버전의 About 내용은 아래와 같다.

   Outlook 2007

  DAMO 8.0.2

 

일단 현재 상황은 아직도 오류는 발생 오류 내용은 아래와 같다.

Faulting application name: OUTLOOK.EXE, version: 12.0.6316.5000, time stamp: 0x4833a470
Faulting module name: nwnspR32.dll_unloaded, version: 0.0.0.0, time stamp: 0x489c864f
Exception code: 0xc0000005
Fault offset: 0x02222e74
Faulting process id: 0x5d4
Faulting application start time: 0x01ca9e6b2826f17f
Faulting application path: C:\Program Files\Microsoft Office\Office12\OUTLOOK.EXE
Faulting module path: nwnspR32.dll
Report Id: c4be8a8d-0a5e-11df-9165-005056c00008

 

짐작이지만, Outlook 종료 때, 이 DAMO의 핵심 DLL인 nwnspR32.dll 이 지연되서 발생되는 문제같다. 아무래도 Notes와의 연결을 정리해야 하는데, 그 시간이 의외 많이 걸리는듯...

Outlook이 조금 천천히 종료되거나, 이 DAMO가 빨리 종료되면 문제가 없을 것 같은데...

역 어셈블해서 까야 되나... 일단 SP2를 한번 받아서 설치해보고 그 뒤를 보도록 하겠다.

728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

[Google Apps Engine] Users Service 사용하기.

기술자료/Web 2010. 1. 22. 16:35

원본글 : http://code.google.com/appengine/docs/java/gettingstarted/usingusers.html


Google App Engine에서는 Google 인프라 스트럭처를 활용한 몇몇 유용한 서비스를 제공합니다.

이 서비스들은 SDK에 포함된 라이브러리를 이용하여 응용 프로그램에서 접근 가능합니다.

Users Service와 같은 서비스는 Google 사용자 계정과 통합되어 여러분들의 응용 프로그램에서 활용할 수 있습니다. 그래서 응용 프로그램 내에 Google 계정을 이용해 가입된 사용자들의 정보를 활용할 수 있습니다.

이제부터 Users service를 이용하여, 개별 사용자 별로 인사말이 표시되게 끔 하는 방법을 구현하려 합니다.


Users 사용하기.

src/guestbook/GuestBookServlet.java를 편집하여 열어보면 다음과 같습니다.

package guestbook;

import java.io.IOException;
import javax.servlet.http.*;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
public class GuestbookServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
              throws IOException {
        UserService userService = UserServiceFactory.getUserService();
        User user = userService.getCurrentUser();

        if (user != null) {
            resp.setContentType("text/plain");
            resp.getWriter().println("Hello, " + user.getNickname());
        } else {
            resp.sendRedirect(userService.createLoginURL(req.getRequestURI()));
        }
    }
}


Eclipse를 이용한 디버거 내에 개발 서버가 실행되고 있다면,

이 파일을 변경/저장 후, Eclipse에서 새 코드에 대해 자동적으로 컴파일 되고

이미 동작중인 서버 내에 새로운 코드가 적용될 것입니다.

클래스, JSP, 정적 파일 및 appengine-web.xml 등이 변경되면 서버의 재 시작 없이 바로 서버에 적용됩니다. 하지만, web.xml 및 기타 설정 파일에 대해 설정한 내용은 반드시 서버를 재 시작 해야 합니다.

메시지를 표시하는 대신 서버에서 이메일을 표시하도록 합니다.
아무 이메일 주소(
alfred@example.com 등등)을 받고 “Log in”을 클릭합니다.
응용 프로그램에서는 메시지를 표시하게 되는데, 이 때, 여러분이 입력한 이메일 주소를 담게 됩니다.

GuestbookServlet 클래스에 대한 새로운 코드에서는
사용자가 Google Account에 가입되어 있는지를 확인하기 위해 Users API를 사용하게 됩니다.
만일 없다면, 사용자는 Google Account 가입 화면으로 리다이렉트 하게 됩니다. userService.createLoginURL(…)에서는 가입 화면으로 가는 URL을 돌려줍니다.
현재 페이지의 URL을 createLoginURL()에 넘겨 줌으로써
URL 별로 응용 프로그램이 다르더라도 적절한 URL로 리다이트렉트 하는데 상당히 편리합니다.

개발 서버는 Google Accouns의 가입 처리를 어떻게 적절히 맞추어 나타낼지 알고 있습니다.
여러분의 PC에서는 입력 받은 이메일 계정으로 가입 처리할 수 있도록, 가입 처리용 페이지로 이동하게 됩니다.

실제 App Engine 환경에서는 진짜 가압에 사용되는 곳으로 이동하게 됩니다.
즉  실제 Google Account 관리화면으로 넘어가게 됩니다.

테스트 응용 프로그램 상에서 가입이 되었다면 다시 한번 페이지를 불러 화면을 다시 표시해보도록 하세요.

사용자 로그 아웃 처리를 하려면, 이번에는 로그아웃 화면에 대한 링크를 제공해야 합니다.
이 링크는 createLogoutURL() 메소드로 생성됩니다.
참고로 로그 아웃 링크는 현재 사용자가 로그인 했던 모든 구글 서비스에 대해서 로그아웃 처리됩니다.


다음은…

이제 사용자의 정보를 어떻게 가져오는지 알았기 때문에,
방명록 상에 메시지를 게시할 사용자들을 초대할 수 있습니다.

이번에는 JavaServer Pages(JSP)를 사용하여

이 응용 프로그램에 대한 사용자 인터페이스를 설계하도록 하도록 하겠습니다.

JSP 사용하기 에서 계속됩니다.

728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

[Google Apps Engine] 프로젝트 생성하기.

기술자료/Web 2010. 1. 22. 15:53

원본글 : http://code.google.com/appengine/docs/java/gettingstarted/creating.html


App Engine Java 응용 프로그램은 Java 서블릿 표준을 이용하여 웹 서버 환경과 연동합니다.

컴파일 된 클래스, JAR, 정적 파일 및 설정 파일들을 포함한 응용 프로그램 파일들은

WAR 라는 자바 웹 응용 프로그램 표준 Layout을 이용하여 디렉터리 별로 정리되어 저장되게 됩니다.

이 WAR 디렉터리 구성은 다른 어떤 Java 웹 응용 프로그램 구성에서도 동일하게 적용됩니다.

( 애석하게도 SDK 에서는 이 WAR 저장 방식 파일에 대해서 지원되지 않습니다. )


프로젝트 디렉터리

현재 이 튜토리얼에서는 모든 프로젝트 파일들은 Guestbook/이라는 이름으로 된 단 하나의 디렉터리 안에 담겨 있습니다. src/ 라는 하위 디렉터리에는 Java 소스 코드들이 담겨 있으며, war/ 라는 하위 디렉터리에는 WAR 포맷에 맞게 구성된 응용 프로그램들이 담겨 있습니다.

Java 소스 파일들이 컴파일 되면 war/의 위치에 컴파일 된 파일들이 담기게 해야 합니다.


완전한 프로젝트 디렉터리는 다음과 같은 형태가 되어 있어야 합니다.

Guestbook/
  src/
    ...자바소스 파일들...
    META-INF/
      ...기타 설정 파일들...
  war/
    ...JSPs, 이미지, 데이터 파일...
    WEB-INF/
      ...응용 프로그램 설정 내용...
      lib/
        ...라이브러리 JAR들...
      classes/
        ...컴파일된 클래스들...

Eclipse 에서는 툴바에서 New Web Application Project 버튼()을 클릭하여 새로운 프로젝트를 생성하기만 하시면 됩니다. 새 프로젝트에 대한 설정 창에서 “Project Name”에는 Guestbook 을, “Package”에는 guestbook 을 넣어주시고 “Use Google Web Toolkit”의 체크를 풀어주시고, 대신 “Use Google App Engine”에 체크해주시기 바랍니다. 그러면 Eclipse의 Plugin에서 제공하는 마법사를 통해 위에서 언급한 디렉토리 구조를 구성하고 필요한 기본적인 파일들을 배치하게 됩니다.


SDK안에 포함된 새 프로젝트 템플릿을 직접 복사해서 구성하실 수도 있습니다.
이 템플릿은 appengine-java-sdk/demos/new_project_template/ 디렉터리에 위치해 있습니다.


서블릿 클래스

App Engine Java 응용 프로그램에서는 the Java Sevlet API를 이용하여 웹 서버와 직접적인 연결을 합니다. HTTP 서블릿은 응용 프로그램 클래스로 웹에서의 요청에 대한 응답 프로세스를 할 수 있습니다.
이런 요청 응답용 클래스는 javax.servlet.GenericServlet 클래스

또는 javax.servlet.http.HttpServlet 클래스를 상속 받은 클래스로 구성하게 됩니다.

예제로 구성된 방명록 프로젝트는 하나의 서블릿 클래스로 시작되어 있으며

단순한 서블릿을 사용하여 메시지를 출력하게 됩니다.


이 파일은 src/guestbook/ 디렉터리에 GuestbookServlet.java 파일로 다음과 같이 구성되어 있습니다.

package guestbook;

import java.io.IOException;
import javax.servlet.http.*;

public class GuestbookServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {
        resp.setContentType("text/plain");
        resp.getWriter().println("Hello, world");
    }
}

web.xml 파일에 대해

웹서버에서 요청을 받았을 때, 서블릿 클래스에서는 “웹 응용 프로그램 배치 설명자(web application deployment descriptor)” 라고 불리는 구성 파일을 사용하여 요청된 서블릿 클래스을 선택하게 됩니다.

이 파일은 보통 web.xml 이라고 이름 지어지며, WAR 파일 안에 있는 war/WEB-INF/ 디렉토리에 담기게 됩니다. WEB-INF/ 와 web.xml은 서블릿 규칙에 따라 이름 지어지고 위치된 것입니다.

war/WEB-INF/ 디렉토리에 있는 web.xml 내용을 대략적으로 보면 다음과 같습니다.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
    <servlet>
        <servlet-name>guestbook</servlet-name>
        <servlet-class>guestbook.GuestbookServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>guestbook</servlet-name>
        <url-pattern>/guestbook</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>/index.html</welcome-file>
    </welcome-file-list>
</web-app>


Eclipse에서 해당 XML을 열면 아래와 같이 보입니다.

이 web.xml 파일은 서블릿인 guestbook에 대한 선언을 담게 되며,

/guestbook 이라는 URL path와 연결되게 끔 구성하는 것을 보여주고 있습니다.

응용 프로그램의 WAR 안에 디렉토리 경로 상에서 없는 경로를 이용하여 서브릿과 연결하여,

외부에서는 전혀 다른 형태의 URL로 접근할 수 있도록 해줍니다.

하지만, 해당 하는 경로에 index.html 이 있다면, 서블릿 설정보다 index.html을 먼저 보여주게 됩니다.


appengin-web.xml 파일에 대해

App Engine은 추가적은 설정 파일이 하나 더 있습니다.

이 파일은 응용 프로그램을 어떻게 배포하고, 실행할지에 대해서 나타내는 설정 파일입니다.

반드시 이 파일은 web.xml 이 있는 WEB-INF/ 디렉토리 안에 위치해야 하며,

그 이름은 appengine-web.xml 이여야 합니다.

그 안에는 응용 프로그램의 등록 ID( Eclipse에서는 언제든지 채울 수 있도록 빈 ID를 생성하여 제공합니다. ), 정적 파일(이미지나 CSS 등등), 리소스 파일(JSP 파일이나, 기타 응용 프로그램 데이터)과 같이 명시적으로 나타낼 내용들을 담고 있습니다 .


war/WEB-INF/ 디렉터리 안에 있는 appengine-web.xml 이라는 파일은 다음과 같이 되어 있습니다.

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
    <application></application>
    <version>1</version>
</appengine-web-app>

appengine-web.xml 에는 App Engine에 대해 설명하는 내용을 담고 있지만,

서블릿 표준에 포함되는 내용은 아닙니다.

SDK에 보시면 이 파일의 형식에 대해 명기되어 있는 XML 스키마 파일을

appengine-java-sdk/docs 안에서 찾을 수 있습니다.

이 파일에 대한 자세한 설명은 Configuring an App를 보시기 바랍니다.


프로젝트 실행하기.

App Engine SDK 에는 여러분이 만든 응용 프로그램을 테스트 할 수 있도록

제공되는 웹서버 응용 프로그램을 포함하고 있습니다.

이 서버는 sandbox 제약영역, 저장소, 기타 서비스 등

각종 App Engine 환경에서 제공되는 기본적인 기능들을 모두 제공합니다.


이 웹서버는 Eclipse의 Debugger로 간단하게 시작할 수 있습니다.

Run 메뉴 안에 있는 Debug As > Web Application을 선택하기만 하면 됩니다. 

디버그 관련된 설정 방법은 Google Plugin in Eclipse 사용하기를 참고하시기 바랍니다.



응용 프로그램 테스트 하기.

서버가 시작되면, 여러분의 브라우저를 이용하여 다음 URL을 입력해보시기 바랍니다.

http://localhost:8080/guestbook

(간혹 설정 상으로 http://localhost:9999/guestbook 일 수도 있습니다. 
  포트 번호는 각자 확인해보시기 바랍니다. )
서버에서 서블릿을 호출하면, 브라우저 상에 메시지를 출력할 것입니다.


다음은…

여기 까지 오셨다면 기본적인 App Engine 응용 프로그램을 성공적으로 제작하신 것입니다!.
이제 이 내용을 배포만 하시면 전세계의 모든 사용자들과 권리를 누리며 나누실 수 있습니다.
이 응용 프로그램은 모든 사용자에 대한 일반적인 인사 내용을 보여줍니다.


이제부터는 인사말을 커스터마이징 하여,

Google Account로 접속한 사용자들에 대한 별도의 인사말을 만들어보도록 하겠습니다.


다음은, User Service를 사용하기 에서 계속 됩니다.

728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

우분투 9.04 에서 FreeNAS와 NFS로 Mount 하기.

기술자료/OS 2010. 1. 21. 15:23
FreeNAS를 구축한 뒤, 제일 먼저 NFS 서비스 부터 올렸다.
그 이유 중 하나가, 바로 지금 사용 중인 개발용 PC 자체가
Linux이다 보니, 일일히 FTP로 데이터를 주고 받는게 의외로 번거러웠다.
대부분의 설정은 Web GUI에서 동작했지만, 몇가지 설정 파일이나, 기타 구성 작업,
파일 접근 등에 있어, Web GUI로 일일히 접근하기도 불편했고,
기왕 쓰는 리눅스 끝까지 써보자는 기묘한 고집 발동으로 인해 결국 NFS 연결을 시도했다.

먼저 회사 - 집 간의 거리 차를 좁히기 위해 먼저 집의 공유기에 VPN 설정을 했다.
(사실 이거 없으면 불가능했을지도...)
그리고 난 뒤, 다음과 같이 입력했다.

mount -t nfs 192.168.0.10:/mnt/mynas /media/mynas

그런데, 알 수 없는 File System 이라는 오류 메시지를 뿝는 것이다.
처음에는 내가 무언가를 설정을 잘못한 것인가 하면서 ( 예전에 공유기로 포트를 열어볼려고, services 항목을 수정한 적이 있다. )
이런저런 설정을 초기화 했는데, 여전히 안되는 것이다.
그래서 다각도로 확인 중에 우연히 FreeNAS의 File Format이 UFS 였다는 사실을 기억해 냈다.

애석하게도 기본으로 설치된 우분투에서는 이 UFS 파일 포멧을 인식하지 못하는 것!
이에 다시 체크들어갔고, "시냅틱 패키지 관리자"를 띄운 후 ufs로 검색했다.
그러니까 libufs2 라는 패키지가 보였다.
이거 설치하고, 다시 위의 명령을 치자! 바로 연결된다.

즉 우분투에서는 FreeNAS의 UFS 포멧을 즉시 인식을 못한 것이였고,
별도로 패키지를 설치하면 가능한 문제였던 것이였다.

참고.참고.

728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

  • «
  • 1
  • ···
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • ···
  • 44
  • »
250x250

블로그 내에 소스 코드 삽입 이사온 기념 스킨도... RSS 전문 기능 비활성화 관련. 스킨 바꾸어 보았습니다. 서버 파일 정리 좀 했습니다.

«   2025/05   »
일 월 화 수 목 금 토
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 31

불만 수 Tutorial Google Apps Engine 오류 me2photo 인터파크 2010 SharePoint 좀 친구 java Visual Studio me2dayzm twi2me 매뉴얼 windows me2sms Buscuit 블로그 e-book MOSS 2007 것 지름신 moss WSS 비스킷 협업 Azure 개발환경

  • Total :
  • Today :
  • Yesterday :

Copyright © 2015-2025 Socialdev. All Rights Reserved.

Copyright © 2015-2025 Socialdev. All Rights Reserved.

티스토리툴바