앱엔진에 뭔가 제 사이트를 만들고 싶어서 이렇게 삽질을 하고 있는데, 망할 제한이 왜이렇게 많지-_-

암튼, "구글 앱 엔진"에서는 JPA를 지원합니다. 하지만, 이상하게도 잘 안됩니다-_- 굉장히 제한적으로 이것저것 막아둔 것 같습니다. 사실 구글 앱 엔진에서는 DataBase를 BigTable인지 뭐시기인지 그걸 사용하고, 직접적으로 접근을 못하기 때문에(전부 프로그래밍 또는 관리페이지(관리페이지도 매우 제한적인-_-)에서만 관리 가능), 이걸 이용하는 API에서도 엄청나게 뭔가 막아둔 것 같습니다.
뭐 좀 해보려고 하면 에러를 내뱉습니다. 검색해보면 구글앱엔진에서만 나는 에러입니다-_- 사실 아직 구글앱엔진이 프리뷰버전이기에 뭐라 따지지도 못하는 게 사실입니다^^ 정식버전(언제나오려나....Beta딱지 떼는데 10년넘게 걸리겠지-_-)나오면 매우 안정화가 되지 않을까 싶습니다^^

암튼, Spring3 + JPA의 조합으로 앱엔진에 올리는 건 성공했는데, 사실 스프링에서 제공하는 TransactionManager를 사용했어야 했는데, JPATemplate으로 뭔가 처리를 하면 잘 안되더군요-_- 일단 가져오고, persist하고, 이런건 잘 되는데, 왜 삭제가 안될까요-_- 삭제가 안되서 그냥JPATemplate빼고 했습니다-_-
JPATemplate사용해서 성공하신 분 트랙백좀 ㅠㅠ

0. 환경
Eclipse 3.5 + Google AppEngine Plugin + Spring 3.0.0
일단 스프링3다운로드 - http://www.springsource.org/download

1. 프로젝트 생성
New Project -> Google에 있는 Web Application Project 선택.
Project Name은 SosiSchedule. package는 com.mudchobo.
Use Google Web Toolkit은 체크해제. 사용안할꺼라....(이것도 언제한번 공부해야하는데-_-)
Finish.

2. 라이브러리 복사 및 build path추가
spring3에서는 spring.jar가 산산조각 났어요. 필요한 것만 넣으면 되는 듯.
일단 제가 사용한 것은....
org.springframework.asm-3.0.0.RELEASE.jar
org.springframework.beans-3.0.0.RELEASE.jar
org.springframework.context-3.0.0.RELEASE.jar
org.springframework.core-3.0.0.RELEASE.jar
org.springframework.expression-3.0.0.RELEASE.jar
org.springframework.orm-3.0.0.RELEASE.jar
org.springframework.web.servlet-3.0.0.RELEASE.jar
org.springframework.web-3.0.0.RELEASE.jar
그리고, jstl을 사용할 것이기에....
jstl.jar와 standard.jar
※이번버전에서는 lib폴더가 없습니다-_- 어디서 찾아야하는 거지-_- 암튼 그래서 2.5.6버전에서 가져왔습니다^^

앱엔진에서는 lib폴더 복사로 libpath가 잡히지 않네요. 그래서 각각 다 추가해줘야한다는...-_-
일단 war/WEB-INF/lib폴더에 복사 후에 복사한 파일 선택 후 오른쪽버튼 후, Build Path -> Add to Build Path 선택하면 됩니다^^

3. web.xml파일 수정
web.xml
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/sosischedule/*</url-pattern>
</servlet-mapping>

<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>

일단 sosischedule/*요청은 spring이 받습니다.

4. dispacher-servlet.xml파일과 persistence.xml파일 생성
war/WEB-INF/폴더에 생성
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<context:component-scan base-package="com.mudchobo" />

<bean id="entityManager"
factory-bean="EMF"
factory-method="get" />

<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />
</beans>


src/META-INF/ 폴더에 생성
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">

<persistence-unit name="transactions-optional">
<provider>org.datanucleus.store.appengine.jpa.DatastorePersistenceProvider</provider>
<properties>
<property name="datanucleus.NontransactionalRead" value="true"/>
<property name="datanucleus.NontransactionalWrite" value="true"/>
<property name="datanucleus.ConnectionURL" value="appengine"/>
</properties>
</persistence-unit>
</persistence>


5. EMF클래스 생성.
이제 jpa접근할 수 있는 EntityManagerFactory클래스(EMF)를 생성해봅시다.
com.mudchobo.sosi.sosischedule.dao.EMF.java
package com.mudchobo.sosischedule.dao;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.springframework.stereotype.Component;

@Component
public final class EMF {
private static final EntityManagerFactory emfInstance =
Persistence.createEntityManagerFactory("transactions-optional");

private EMF() {}

public EntityManager get() {
return emfInstance.createEntityManager();
}
}


6. Entity클래스 생성
일단 Sosi와 Schedule이라는 Entity를 생성할 건데요. 둘의 관계는 1:N관계입니다.
com.mudchobo.sosischedule.entity.Sosi.java
package com.mudchobo.sosischedule.entity;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;

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

@Entity
public class Sosi implements Serializable {
private static final long serialVersionUID = 5448408922872112420L;

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Key key;

private String sosiName;

@OneToMany(mappedBy="sosi", cascade=CascadeType.ALL)
private List<Schedule> scheduleList = new ArrayList<Schedule>();

public Key getKey() {
return key;
}

public void setKey(Key key) {
this.key = key;
}

public List<Schedule> getScheduleList() {
return scheduleList;
}

public void setScheduleList(List<Schedule> scheduleList) {
this.scheduleList = scheduleList;
}

public String getSosiName() {
return sosiName;
}

public void setSosiName(String sosiName) {
this.sosiName = sosiName;
}

public Sosi() {

}

public Sosi(Key key, String sosiName) {
super();
this.key = key;
this.sosiName = sosiName;
}
}

com.mudchobo.sosischedule.entity.Schedule.java
package com.mudchobo.sosischedule.entity;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

@Entity
public class Schedule implements Serializable{
private static final long serialVersionUID = -8676837674549793653L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key key;

private String program;

@ManyToOne(fetch=FetchType.LAZY)
private Sosi sosi;

public Sosi getSosi() {
return sosi;
}

public void setSosi(Sosi sosi) {
this.sosi = sosi;
}

public Key getKey() {
return key;
}

public void setKey(Key key) {
this.key = key;
}


public String getKeyString() {
return KeyFactory.keyToString(key);
}

public String getProgram() {
return program;
}

public void setProgram(String program) {
this.program = program;
}

public Schedule() {
}

public Schedule(String program, Sosi sosi) {
this.program = program;
this.sosi = sosi;
}
}

일단 App Engine용 JPA에서는 ID 타입이 Long이면 관계형태를 사용할 수 없더라구요. 그래서 앱엔진에서 제공하는 Key타입이 있는데, 이걸 이용해야합니다.

7. Dao만들기
com.mudchobo.sosisochedule.SosiDao.java
package com.mudchobo.sosischedule.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.google.appengine.api.datastore.KeyFactory;
import com.mudchobo.sosischedule.entity.Schedule;
import com.mudchobo.sosischedule.entity.Sosi;

@Repository
public class SosiDao {
private EntityManager em;

@Autowired
public void setEntityManager(EntityManager em) {
this.em = em;

// 소시데이터 추가
addSosi(new Long(1), "효연");
addSosi(new Long(2), "윤아");
addSosi(new Long(3), "수영");
addSosi(new Long(4), "유리");
addSosi(new Long(5), "태연");
addSosi(new Long(6), "제시카");
addSosi(new Long(7), "티파니");
addSosi(new Long(8), "써니");
addSosi(new Long(9), "서현");
}

public void addSosi(Long id, String sosiName) {
em.getTransaction().begin();
em.persist(new Sosi(KeyFactory.createKey(Sosi.class.getSimpleName(), id), sosiName));
em.getTransaction().commit();
}

@SuppressWarnings("unchecked")
public List<Sosi> getSosiList() {
return em.createQuery("select s from Sosi s").getResultList();
}

public Sosi getSosi(Long sosiId) {
return em.find(Sosi.class, sosiId);
}

@SuppressWarnings("unchecked")
public List<Schedule> getScheduleList(final Long sosiId) {
Query q = em.createQuery("select s.scheduleList from Sosi s where s.key = :key");
q.setParameter("key", KeyFactory.createKey(Sosi.class.getSimpleName(), sosiId));
return (List<Schedule>) q.getSingleResult();
}

public void addSchedule(Long sosiId, String program) {
em.getTransaction().begin();
Sosi sosi = em.find(Sosi.class, sosiId);
sosi.getScheduleList().add(new Schedule(program, sosi));
em.getTransaction().commit();
}

public void deleteSchedule(String scheduleKey) {
em.getTransaction().begin();
Schedule schedule = em.find(Schedule.class, scheduleKey);
em.remove(schedule);
em.getTransaction().commit();
}
}

EntityManager받을 때 디폴트로 데이터를 넣어줘야 합니다(아까 위에서 말했듯이 프로그래밍적으로만 테이블을 생성할 수 있어서 이런 형태로 데이터를 넣어줘야합니다ㅠㅠ)

일단 실행해보고 데이터가 잘 생성되었는지 보려면 아래와 같은 주소로 접속해보면 됩니다.
http://localhost:8888/_ah/admin
일단 보고 삭제까지는 되는데, 테이블 생성같은 건 안되더라구요. 그리고 여기서 보여지는데에는 한글이 깨지는데 나중에 출력해보면 잘 나오니 걱정마시길-_-
사용자 삽입 이미지
8. Service 클래스 생성
com.mudchobo.sosischedule.service.SosiService.java
package com.mudchobo.sosischedule.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mudchobo.sosischedule.dao.SosiDao;
import com.mudchobo.sosischedule.entity.Schedule;
import com.mudchobo.sosischedule.entity.Sosi;

@Service
public class SosiService {

@Autowired
private SosiDao sosiDao;

public List<Sosi> getSosiList()
{
return sosiDao.getSosiList();
}

public Sosi getSosi(Long sosiId) {
return sosiDao.getSosi(sosiId);
}

public List<Schedule> getScheduleList(Long sosiId) {
return sosiDao.getScheduleList(sosiId);
}

public void deleteSchedule(String scheduleKey) {
sosiDao.deleteSchedule(scheduleKey);
}

public void addSchedule(Long sosiId, String program) {
sosiDao.addSchedule(sosiId, program);
}
}

Service에서 하는 역할은 뭐 없네요-_-

9. Controller생성
스프링3.0에서 새로 추가된 기능인 REST기능입니다.
com.mudchobo.sosischedule.controller.SosiController.java
package com.mudchobo.sosischedule.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.mudchobo.sosischedule.entity.Schedule;
import com.mudchobo.sosischedule.entity.Sosi;
import com.mudchobo.sosischedule.service.SosiService;

@Controller
public class SosiController {
private static String PREFIX = "/sosischedule";

@Autowired
private SosiService sosiService;

@RequestMapping(value="/", method=RequestMethod.GET)
public String index(Model model) {
List<Sosi> sosiList = sosiService.getSosiList();
model.addAttribute("sosiList", sosiList);

return "index";
}

@RequestMapping(value="/schedule/{sosiId}", method=RequestMethod.GET)
public String getSchedule(
@PathVariable("sosiId") Long sosiId,
Model model) {
Sosi sosi = sosiService.getSosi(sosiId);
List<Schedule> scheduleList = sosiService.getScheduleList(sosiId);
model.addAttribute("scheduleList", scheduleList)
.addAttribute("sosi", sosi);

return "sosi";
}

@RequestMapping(value="/schedule/{sosiId}/add", method=RequestMethod.POST)
public String addSchedule(
@PathVariable("sosiId") Long sosiId,
@RequestParam("program") String program,
Model model
) {
sosiService.addSchedule(sosiId, program);

return "redirect:" + PREFIX + "/schedule/" + sosiId;
}

@RequestMapping(value="/schedule/{sosiId}/{scheduleKey}", method=RequestMethod.GET)
public String removeSchedule(
@PathVariable("sosiId") Long sosiId,
@PathVariable("scheduleKey") String scheduleKey,
Model model) {
sosiService.deleteSchedule(scheduleKey);

return "redirect:" + PREFIX + "/schedule/" + sosiId;
}
}


10. View jsp파일 생성
소시 리스트를 보여주는 index파일 입니다.
war/WEB-INF/jsp/index.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="UTF-8"%>
<%@ page isELIgnored="false" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>소녀시대 스케줄</title>
</head>
<body>
<div>
스케줄 확인하기
<ul>
<c:forEach var="sosi" items="${sosiList}">
<li><a href="/sosischedule/schedule/${sosi.key.id}">${sosi.key.id}. ${sosi.sosiName}</a></li>
</c:forEach>
</ul>
</div>
</body>
</html>


해당 소시의 스케줄을 보여주는 스케줄 파일입니다.
war/WEB-INF/jsp/sosi.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="UTF-8"%>
<%@ page isELIgnored="false" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>소녀시대 스케줄</title>
</head>
<body>
<div>
스케줄 확인하기
<ul>
<c:forEach var="sosi" items="${sosiList}">
<li><a href="/sosischedule/schedule/${sosi.key.id}">${sosi.key.id}. ${sosi.sosiName}</a></li>
</c:forEach>
</ul>
</div>
</body>
</html>

리다이렉트를 위한 파일입니다. 기존 index.html파일 지우시고, index.jsp파일 생성
index.jsp
<% response.sendRedirect("/sosischedule/"); %>


앱엔진에 올려보았습니다.
http://2.latest.mudchobosample.appspot.com/sosischedule/

잘 되는 것 같네요.
머드초보 이 작성.

당신의 의견을 작성해 주세요.

  1. Comment RSS : http://mudchobo.tomeii.com/tt/rss/comment/470
  2. 비밀방문자 2010/02/08 20:00  편집/삭제  댓글 작성  댓글 주소

    관리자만 볼 수 있는 댓글입니다.

    • 머드초보 2010/02/12 00:05  편집/삭제  댓글 주소

      안녕하세요~ 답변이 늦었네요 ㅠㅠ
      근데, 파일 다 올린 것 같은데...
      저도 만들어놓고 그냥 올린거다보니 ㅠㅠ
      뭐가 빠진건가요? ㅠㅠ

[로그인][오픈아이디란?]
GTUG(Google Technology User Group)는 말 그대로 구글의 기술(Android, GWT, App engine, wave, 등등)을 사용하는 유저 모임입니다.

GTUG는 전세계적으로 존재하는 아이리스.......-_-가 아니고, 구글 기술을 사용하는 사용자들의 모임인데요. 지금 현재 한국에서만 없어서 이 모임을 만들게 되었다고 하네요. 음 좋은 현상이네요.

두번째 놀러간 구글코리아 사무실이군요.... 사장님께 건의해서 우리 회사 사무실도 구글처럼....-_- 왠지 미로처럼 느껴지는 사무실-_- 게다가 마음껏 먹을 수 있는 저 일용한 식량들-_-

GTUG Seoul 홈페이지입니다.
http://seoul.gtugs.org/

사용자 삽입 이미지

1. GTUG 소개 - 최우형(http://seanchoe.com/)
이 분도 sean이군요. 우리 사장님도 sean인데-_- Seoul GTUG가 생기게된 계기가 미키김씨의 트위터를 보고 왜 국내엔 없어? 라는 말 때문에 만들게 되었다고 하네요. 세계적으로 GTUG는 다음 DevDay와 같은 행사를 하는 듯 합니다. 캠프를 하면서 밤샘 코딩을 하고, 구글 기술을 이용해서 코딩을 하는 뭐 그런 행사를 하나 봅니다. 음....국내에서도 하면 재미있겠네요^^ 암튼, 모임이 활성화 되었으면 좋겠네요. 사실 구글 기술이 참 대단하지만, 국내에선 많이 사용하질 않아요. 이번 기회에 많이 활성화 되었으면 좋겠네요^^

2. Web2.0을 통한 발전적인 협업 - 강팀장(http://www.ebizstory.com/)
음 무슨 말인지는 잘 모르겠지만, 구글 캘린더, 닥스 등의 유틸을 이용해서 협업하자는 건가요?-_- 오픈 소스를 통해 예를 설명하셨는데, 오픈소스는 망이라는 인프라때문에 성장하게 되었는데, 사람간의 관계도 망으로 치면 협업으로 발전할 수 있다는 그런 얘기인 듯.
앞으로 서비스는 네트워크(sns 등)와 관련된 서비스가 뜰 것이라고 하는데, 요즘 계속 뜨고 있지 않나요-_-
그리고, 이런 도구를 이용해서 커뮤니케이션의 문제를 해결하는 것이 우선이라는 말인 듯 하네요. 개발과 기획의 트러블, 개발자들 간의 트러블 등 일하다보면 진짜 많은 충돌이 일어나죠^^ 커뮤니케이션의 부재라고 할 수 있죠^^
그리고, 마지막으로 공유의 중요성을 얘기했습니다. 저도 공유의 중요성을 실천하며 블로그에 저만의 삽질로그를 기록하는데-_- 방문자들과 커뮤니케이션을 하고 그러는데에 좀 도움이 되는 것 같네요^^

3. 스마트 폰으로 본 모바일 동향 - 최재규
요즘 최대의 관심사 스마트폰이군요. 아이폰이 출시되면서 국내에서도 스마트폰 급열풍이 불고 있죠^^ 재미있는 강의였어요^^ 현재 스마트폰의 벤더는 춘추전국시대인 듯-_-
Nokia, MS, Apple, Google, Samsung 등 다양하죠. 지금은 옛날 OS전쟁과 같은 전쟁을 하고 있다고 합니다. 앞으로 어떻게 될지 궁금하군요.
그리고, 내년되면 안드로이드폰이 많이 나올 것이라고 전망을 하는군요. 국내에서도 SKT나 KT, LGT 전부다 내년에 안드로이드비중을 늘리겠다는 뉴스가 나왔었죠. 안드로이드폰을 많이 도입하는 이유는 애플은 혼자서 다 먹는 수익모델인 반면, 안드로이드는 그렇지 않기 때문이죠. 사실 애플 아이폰을 KT에서 미친듯이 팔아도 KT에서 남는 건 별로 없다고 하죠. 하지만 안드로이드는 소스도 오픈되어 있고, 통신사 만의 커스텀마이즈가 가능하기 때문에(제발 SKT 드로이드폰에다가는 손대지 말아죠 ㅠㅠ), 뭐 다 같이 수익을 낼 수 있는 모델을 구성할 수 있다고 합니다. 게다가 MS Mobile처럼 os에 라이센스 비용도 들어가지 않구요. 구글은 모바일광고시장을 개척해서 돈을 벌게 될 것이라고 하고. 대세는 안드로이드인가.....-_-
게다가 아이폰 어플 개발은 Object-C라는 C기반 언어를 채용한 반면, 안드로이드는 Java를 채택했죠. 이 분말에 의하면 많은 개발자 포섭의 이유라고 하네요. Java개발자가 많아서 그런 듯.
암튼, 요즘 스마트폰은 계속 발전하고 있습니다. 근데 요즘은 스마트폰이아니라 그냥 작은 컴퓨터죠-_- 뭐 스마트폰으로 못하는 게 없어요. 소비자들의 니즈가 계속 변화하는데, 그 변화에 대한 빠른 대처만이 스마트폰의 전쟁에서 살아남을 수 있을 듯 합니다^^
그리고, 지금 플랫폼 전쟁이고, 차후에 컨텐츠 전쟁이라고 했는데, 지금 뭐 동시에 일어나는 것 같은 느낌이 좀 드는데-_- 앱스토어에서는 이미 많은 컨텐츠를 확보를 했죠. 이미 나올 수 있는 건 다 나온 상태인 듯 ^^ 뭐 암튼 전쟁입니다^^ 누가 승리하든간에 이 전쟁으로 많은 IT발전이 다가오겠죠^^

4. 구글 App Engine과 클라우드 컴퓨팅 소개 - 이현남(http://opencloud.kr/)
App Engine은 시간관계상 못했는데요. App Engine에 대해서 좀 더 듣고 싶었는데-_-
암튼, 클라우드 컴퓨팅. 효율적인 자원활용을 할 수 있게 도와주는 컴퓨팅이죠. 사실 사용자들은 이게 클라우드컴퓨팅인지 잘 모르지만, 뒷단에서는 클라우드 컴퓨팅인게 클라우드 컴퓨팅이죠(뭔소리야-_-). 암튼, App Engine도 클라우드 컴퓨팅 같은 것이라고 하네요. App Engine에 올린 웹서비스가 트래픽이 올라가면 구글에서 알아서 트래픽 조정 및 자원할당을 해주는 뭐 그런 형태죠^^ 암튼, 효율성을 높여서 비용을 낮추는.....-_-(비용을 낮춘다고 하면 고객들이 참 좋아하죠!)

5. About GWT(Google Web Toolkit) - 윤진호(http://blog.naver.com/bosimno1)
GWT가 뭔지 잘 몰랐는데, 설명을 듣고 나니 좀 알것 같네요. 그냥 클라이언트랑 서버랑 뭐 합체형태로 개발하는 툴킷인가보네요. 브라우저별로 JS파일도 따로 내려줘서 Cross Browsing까지 해결해주는 좋은 툴이네요. 여러가지 컴포넌트들도 있어 손쉽게 개발할 수 있는 것인 듯.
하지만, 오늘 예제가 없어서-_- 정확한 실체는 파악하지 못했군요 ㅠ 예제를 볼라고 했는데, 시간이 없어서 못했네요^^ 난 시간이 남아도는데, 그냥 좀 해주시지.....ㅠㅠ

오늘 모임에서 조금 아쉬웠던 것은 구글 기술에 대한 부재(?)입니다. 음 구글 기술에 대해 좀 더 발표를 했었으면 좋았을텐데^^ App Engine이나 GWT는 매우 흥미로운 기술인데, 좀 더 실체를 보고 싶네요. 구글 닥스와 캘린더 연동이나 구글wave 관련 효율적인 커뮤니케이션 예를 보여주면 매우 좋을 듯^^
그래도 많은 정보를 얻어간 세미나였던 것 같아요. 앞으로 계속 되었으면 좋겟네요^^
머드초보 이 작성.

당신의 의견을 작성해 주세요.

  1. Comment RSS : http://mudchobo.tomeii.com/tt/rss/comment/457
  2. OpenID Logo 외계인 2009/12/20 20:55  편집/삭제  댓글 작성  댓글 주소

    저희 학교 선배님도 갔었는데 사진 올려주신다고 하네요. 저도 다음에 꼭 가보고 싶어요.

  3. OpenID Logo http://seanchoe.myopenid.com/ 2009/12/21 17:52  편집/삭제  댓글 작성  댓글 주소

    와~ 참석해 주시고 좋은 후기도 남겨 주셔서 너무 감사해요!^^ 다음 모임에는 좀 더 구글 기술에 집중 할 수 있도록 잘 운영해 보도록 하겠습니다!

    • 머드초보 2009/12/22 10:04  편집/삭제  댓글 주소

      앗~ 운영자님께서~ ^^
      방문해주셔서 감사합니다 ^^ 저도 열심히 활동하고 싶네요^^

[로그인][오픈아이디란?]
구글은 참 재미있는 것을 많이 만드네요.
이번에 만든 구글웨이브도 참 재미있는 서비스입니다^^

사용자들과 쉽게 커뮤니케이션을 할 수 있는 방법을 생각해내다가 이런 서비스를 만들게 된게 아닌가 싶습니다.
근데, 처음에 접근하게 되면 이게 뭔가라는 느낌의 화면으로 다가옵니다. 처음에 접근할 때 조금 힘든 면이 있네요. 저도 누가 설명해주지 않았으면 대체 뭐하는 건지 몰랐을테니까요. 회사동료분의 설명으로 조금 이해를 했습니다-_-

아래 동영상을 보면 조금 이해가 갈지 모르겠네요. 하지만 써보지 않고 아래 동영상부터 본다면 혼란이 올 것 같기도 한데....우선 한번 써보게 되면 아래동영상이 좀 이해가 갈 듯

구글 웨이브의 기본적인 기능 15가지


우선 처음에 띄웠을 때 화면입니다.
사용자 삽입 이미지
우선 간단하게 Wave를 설명하자면, New Wave를 통해 새로운 Wave를 작성하게 되면 사용자를 초대해서 같이 글을 편집하고 얘기할 수 있는 실시간 커뮤니케이션 도구라고 보시면 됩니다.

상대방이 Replay을 작성하든, 글을 고치든 간에 실시간으로 편집하는 게 다 보입니다-_-
FireBug로 Net요청에 대해서 보게 되면 글을 쓸 때마다 해당 channel로 변경된 것을 날리나 봅니다. 그래서 해당 channel에 접속한 사용자에게 변화를 보여주게 되는 듯(개발자다보니 이런 것에만 관심이......-_-)
사용자 삽입 이미지
그리고 구글다운 사용자중심의 UI가 장점입니다. 구글 웨이브는 그런 UI의 결정판인 듯-_- UI도 많이 고민한 흔적이 보이네요^^ 저런 거 개발하려고 하면 정말 힘들텐데....역시 대단하네요^^

결론은 구글웨이브는 올인원(?)을 노리는 것 같습니다. 저 같은 경우에는 올인원을 좋아합니다-_- 올인원이라는 것을 처음 본 곳은 아마 Windows 설치이미지에서 본 것 같네요. 다양한 버전을 한 CD이미지에서 설치를 할 수 있는 것이였는데, 다 설치할 이유는 없었지만 모든 것이 하나에 다 있다는 것이 참 기분이 좋았어요.
이런 구글웨이브도 보면 문서편집(위키형태)과 사용자들과의 채팅 및 다양한 커뮤니케이션(위젯을 통해 게임 같은 것도 가능하겠죠^^), 이메일, 네이트온 같은 메신저 등~ 그냥 기존에 나와있는 SNS서비스를 버로우 시키기 위한 올인원 시스템인 듯 합니다.
하지만, twitter나 me2day와 같은 마이크로블로그, 싸이월드나 facebook같은 서비스도 SNS를 지향하고 있지만, 구글웨이브와는 조금 틀린 성격이라고 느껴지는군요. 이것들의 경쟁자라고 느껴지진 않네요. 서로 공존할 수 있는 부분인 듯 합니다. 하지만 구글웨이브에서 트위터같은 서비스도 맘만 먹으면 API를 이용해서 가져올 수 있는 서비스를 만들 수 있을 듯 합니다. 그렇게 되면 구글웨이브가 통합을 할 수 있을지도.....-_-
머드초보 이 작성.

당신의 의견을 작성해 주세요.

  1. Comment RSS : http://mudchobo.tomeii.com/tt/rss/comment/456
  2. 코즈 2009/12/16 13:03  편집/삭제  댓글 작성  댓글 주소

    그렇군요.
    도대체가 뭐하는 물건인지 당신은 설명을 들었건만,,
    왜 나에겐 알려주지 않는 겁니까 ㅋㅋ

  3. OpenID Logo 로로스타 2010/01/15 17:09  편집/삭제  댓글 작성  댓글 주소

    heojeongho@googlewave.com 친추 점요

[로그인][오픈아이디란?]
« Prev : 1 : 2 : 3 : 4 : Next »