- Korea times
- 끌리면 오라...BGM 광고음악 라이브러리
- KartOO visual meta search engi…
- E-Book
- Channel9
- MSDN
- 여리의 작업실
- 유경상의 .NET 블로그
- window 쪼물딱 거리기
- 블루 홈(소현이 누님)
- IT 관련 전반 내용(정환이네)
- 비너스의 정보 공유(유틸리티들)
- 형기의 자료공간(디지털ERA에서 콘텐츠ERA로)
- EzineArticles (여러 분야의 글들이 올라옴)
- Relationship을 보여주는 라이브러리
- OpenRCE
- 젠틀의 블로그(무선 통신의 모든것)
- 헐랭이와 IT보안
- 워니. 추억ㅇㅔ ㅂㅣ추ㅇㅓ.
- Computer Forensics
- 토익 광장(YBM)
- Korea Times 이용하기
- Larkware Software
- TCP/UDP
- Black Hat
- DEF CON
- Slashdot
- ReallyUsefulEbooks.com Update
- 실리콘밸리 뉴스
- Application Development Trends
- Visual Studio Hacks
- MIT OCW
- Redmond Developer News
- SecurityFocus
- Microsoft Window Hacking Porta…
- Darknet - Don't Learn to Hack …
- Windows Tips, Tricks and Hacks
- Hack In the Box
- (IN)SECURE Magazine
- SuperSite Windows Vista
- Government Security
- Life is Still Talking (Good)
- PHRACK
- Found+Read(resource for startu…
- Jonathan Boutelle
- Venture Hacks
- 스마트플레이스
- All about Intellipedia
- Undocumented Windows 2000 Secr…
- HexBlog (Decompiler)
- TED (Ideas worth spreading)
- Crash Dump Analysis and Debugg…
- Rootkit
- DDK Developers(MS)
- 미친 감자의 블로그
- The Art of Assembly Language
- Chpie (키보드 후킹)
- Drivers Online
- (음악) Delicate SONG
- Reverse Engineering Community
- Software Best Practices
- Sara Ford's WebLog
- Cheat Happens
- Debugging,Unpacking,Assembling…
- 윤석찬님 블로그
- OK 괜찮아 다 잘 될거야
- RingBlog
- Art Life :: 하늘소
- IT's Paradise
- John Robbins!
- Wintellect
- Hacked Gadgets
- 소프트웨어 이야기
- Ryan Naraine's Zero Day
- VULN
- Stay Secure
- EBS 영어 공부(블루워터)
- 101BLoG : "Bright Size Life" o…
- Hacker Challenge
- Hackers Center
- White Hat, Chicago Con
- Ethical Hacker Network
- ChaseNet (Security)
- TechTarget
- Entrepreneur
- Infopackets
- Popular Science
- Dark Reading - The Business of…
- How Stuff Works
- codeDriver - Crack (역공학)
- Gadget (Windows)
- Serious Code
- Iguacu Blog(블루문)
- SecurityProof
- Power of Community(Hacker)
- Crack ?
- Security Freak
- Data Network Resource
- FoundStone - Security Consulti…
- Google Online Security Blog
- (BOOK) Cool DogBooks
- SachaBarber (좋은 개발자)
- System Software Incorporation
- 스카이 벤처
- NewsTorrent
- 글로벌 IT 네트워크
- Ethical Hacking and Infosec
- Realms of Hacking tricks
- CodeBreakers Journal
- Anti Rootkit Blog
- The Reverse Code Engineering C…
- Anti-Debug Tools
- Reverse Code Engineering Video…
- Damn Vulnerable linux
- Security Problems
- French Reverse Engineering Tea…
- Monac
- Open Source Vulnerability Data…
- Viruschaser 검사(바이러스)
- Windows Tips
- 보안 대처 연습
- [Download] Kartz CD
- [Download] FlMS Download
- [Download] DDL2
- 중국 해킹 사이트(안전중국)
- 바이러스 분석
- Javascript 전문가
- Virus Alert Zone (바이러스 분석)
- Computer World
- 문스랩닷컴(보안)
- Unpack China
- Black Storm Reverse Engineerin…
- 역공학 Reverser
- 문화 망명지 - 시, 소설
- WPF MVP
- Research Channel
- The Problem Solver - C# MVP
- Reversing - 리버스 엔지니어링
- Nigel Spencer's Blog (.NET)
- Kirill Osenkov (.NET C# IDE Te…
- H33T (BitTorrnet 검색 사이트)
- ITL (해킹, 보안)
- ITL (Invisible Things Lab) Blo…
- ebook, pdf, chm
- 주식 - 멘토클리닉
- CherryLove - 바이러스, 백신, 악성코드
- PMP
- 영원한 해커, hacker
- 리버싱, PE
- 신호철 - dsphome
- TechEd 2009
- SHOUT
- [도서] 오디오북
- [도서] 전자책
- [도서] 국내도서요약
- [도서] 해외도서요약
- TopCorder - 프로그래밍 연습
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- C#
- 해킹
- .net framework 4
- Windows
- VSTS
- 닷넷
- MVP
- Windows 7
- Visual Studio
- 구글
- visual studio 2010
- VSTS 2010
- 마이크로소프트
- debugging
- .net
- 디버그랩
- .NET Framework
- Microsoft
- hacking
- 비주얼스튜디오
- security
- 역공학
- 책
- WPF
- 디버깅
- english
- 보안
- 비주얼 스튜디오
- Today
- Total
NaggingMachine
일목 요연하게 정리된 Google App Engine for Java 본문
GAE를 처음 사용하시는 분들보다는 알고 있는 내용들을 빠르게 찾아볼 수 있는 정리된 정보입니다.
좋네요~
http://www.vogella.com/articles/GoogleAppEngineJava/article.html
Google App Engine Tutorial for Java
Version 2.7
Copyright © 2009 - 2011 Lars Vogel
12.03.2010
Revision History | |||
---|---|---|---|
Revision 0.1 | 08.04.2009 | Lars Vogel | Created |
Revision 0.2 - 2.7 | 25.04.2009 - 12.03.2010 | Lars Vogel | bug fixes and enhancements |
Table of Contents
Google offers a cloud computing infrastructure called Google App Engine (App Engine) for creating and running web applications . App Engine allows the dynamic allocation of system resources for an application based on the actual demand. Currently App Engine supports Python and Java based applications. This includes Java Virtual Machine (JVM) based languages, e.g. Groovy or Scala. This article will cover the App Engine for Java (GAE/J)).
The App Engine offers frequently standard Java API's and App Engine specific API's for the same task. If you want to be able to port your application from the AppEngine to other webcontainers, e.g. Tomcat or Jetty, you should only use Java standard API.
App Engine uses the Jetty servlet container to host applications and supports the Java Servlet API in version 2.4. It provides access to databases via Java Data Objects (JDO) and the Java Persistence API (JPA). In the background App Engine uses Google Bigtable as the distributed storage system for persisting application data.
Google provides Memcache as a caching mechanism. Developers who want to code against the standard Java API can use the JCache implementation (based on JSR 107).
The App Engine provides several services. For example the Blobstore allows to upload and store and serve large data objects (blobs) with a limit of 2 Gigabyte. To create a blob you upload a file via an HTTP request.
Google App Engine supports the creation of several version of your application. In the Admin Console you can select which version should be active. Your active application "your-name" will be accessible via the URL "http://your-name.appspot.com". Each version can also be accessed for example to test a new version. The version are accessable via "http://versionnumber.latest.your-name.appspot.com" where version is for example "2" and "latest" is a fixed string.
App Engine runs a version of Java 6 but does not provide all Java classes, for example Swing and most AWT classes are not supported.
You cannot use Threads or frameworks which uses Threads. You can also not write to the filesystem and only read files which are part of your application. Certain "java.lang.System" actions, e.g. gc() or exit() will do nothing. You can not call JNI code. Reflection is possible for your own classes and standard Java classes but your cannot use reflection to access other classes outside your application.
See Java Whitelist for a full list of supported classes.
A servlet needs also to reply within 30 seconds otherwise a "com.google.apphosting.api.DeadlineExceededException" is thrown.
Google offers free hosting for websites which are not highly frequented, e.g. 5 Millions page views. The price model for the websites that exceed thier daily quota is listed on the Google billing documentation pages . The usage quotas of the App Engine are constantly changing but, at the time of this writing, are around 5 millions pages views per month, which translates approx. in 6.5 CPU hours and 1 gigabyte of outbound traffic.
Currently a user can create a maximum of 10 applications on the Google App Engine. The user can delete existing application in the Admin Console under Application Settings.
Google offers a Eclipse plug-in that provides both Google App Engine and GWT development capabilities. Install the plugins from http://dl.google.com/eclipse/plugin/3.7 via the Eclipse update manager.
The installation will also setup the GWT and App Engine SDK into your Eclipse preferences. To check this use Window -> Preferences -> Google -> App Engine / Web Toolkit. The SDK are delivered as plugins is included in your Eclipse installation directory under "/plugins/".
To deploy your application to the Google cloud you need a AppEngine account. To get such an account you need a Google email account. Open the URL http://appengine.google.com/ and login with your Google account information. You need to verify your account via a valid phone number. After providing your phone number, Google will text you a verification code via SMS. You will then type the verification code into the verification box online.
The process of creating an application on the Google App Engine involves the creation of an application on the Google App Engine website. Afterwards you can locally create an web application and upload this application to the created applicaton on the Google App Engine.
To create an application on the App Engine press the button "Create an application" and select an application name. You have to choose one which is still available. Remember this name because we will later use this in the creation of our demo application.
The Eclipse Plugin allows to run applications for the Google App Engine locally in an environment which simulates the environment on the App Engine. You also have a local admin console which allow you to see your local datastore, the task queue, inbound email and XMPP traffic. You find this local admin console on "http://localhost:8888/_ah/admin/".
GAE/J supports JPA (Java Persistence API) 1.0 for persisting data. As all data on the GAE/J are stored in Bigtable some features of JPA are not supported. See JPA on GAE/J for details. Alternatively to JPA you can also use JDO or the low-level API of the App Engine. The datastorage facility is described in Datastore Java API Overview .
The following will create a small "Todo" application using servlets and JSP's. The persistence will be handled by JPA. For an introduction into servlet and JSP programming please see Servlet and JSP development - Tutorial
Create a new project "de.vogella.gae.java.todo" via File > New > Web Application Project. Package name is "de.vogella.gae.java.todo".
The created project can already run. Right-click on your application, select run as-> Web Application
This should start Jetty on http://localhost:8888/ . Open the url in the browser and you should the possibility to select your servlet and to start it. If you select it you should see a "Hello, world" message.
Create the following class which will be our model. The JPA metadata is already added.
package de.vogella.gae.java.todo.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id;/** * Model class which will store the Todo Items * * @author Lars Vogel * */@Entity public class Todo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String author; private String summary; private String description; private String url; boolean finished; public Todo(String author, String summary, String description, String url) { this.author = author; this.summary = summary; this.description = description; this.url = url; finished = false; } public Long getId() { return id; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getShortDescription() { return summary; } public void setShortDescription(String shortDescription) { this.summary = shortDescription; } public String getLongDescription() { return description; } public void setLongDescription(String longDescription) { this.description = longDescription; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public boolean isFinished() { return finished; } public void setFinished(boolean finished) { this.finished = finished; } }
To use JPA in your project you must create the JPA configuration file "persistence.xml" in the "META-INF" directory. This file contains the configuration that tells JPA to use the App Engine datastore.
<?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>
The creation of the EntityManagerFactory is time-consuming therefore we buffer it.
package de.vogella.gae.java.todo.dao; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; public class EMFService { private static final EntityManagerFactory emfInstance = Persistence .createEntityManagerFactory("transactions-optional"); private EMFService() { } public static EntityManagerFactory get() { return emfInstance; } }
The following class provides the possibility to query for all todos and to add and delete todos.
package de.vogella.gae.java.todo.dao; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.Query; import de.vogella.gae.java.todo.model.Todo; public enum Dao { INSTANCE; public List<Todo> listTodos() { EntityManager em = EMFService.get().createEntityManager(); // Read the existing entries Query q = em.createQuery("select m from Todo m"); List<Todo> todos = q.getResultList(); return todos; } public void add(String userId, String summery, String description, String url) { synchronized (this) { EntityManager em = EMFService.get().createEntityManager(); Todo todo = new Todo(userId, summery, description, url); em.persist(todo); em.close(); } } public List<Todo> getTodos(String userId) { EntityManager em = EMFService.get().createEntityManager(); Query q = em .createQuery("select t from Todo t where t.author = :userId"); q.setParameter("userId", userId); List<Todo> todos = q.getResultList(); return todos; } public void remove(long id) { EntityManager em = EMFService.get().createEntityManager(); try { Todo todo = em.find(Todo.class, id); em.remove(todo); } finally { em.close(); } } }
Create the following two servlets. The first will be called if a new Todo is created the second one if a Todo is finished.
package de.vogella.gae.java.todo; import java.io.IOException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.google.appengine.api.users.User; import com.google.appengine.api.users.UserService; import com.google.appengine.api.users.UserServiceFactory; import de.vogella.gae.java.todo.dao.Dao; @SuppressWarnings("serial") public class ServletCreateTodo extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { System.out.println("Creating new todo "); User user = (User) req.getAttribute("user"); if (user == null) { UserService userService = UserServiceFactory.getUserService(); user = userService.getCurrentUser(); } String summary = checkNull(req.getParameter("summary")); String longDescription = checkNull(req.getParameter("description")); String url = checkNull(req.getParameter("url")); Dao.INSTANCE.add(user.getUserId(), summary, longDescription, url); resp.sendRedirect("/TodoApplication.jsp"); } private String checkNull(String s) { if (s == null) { return ""; } return s; } }
package de.vogella.gae.java.todo; import java.io.IOException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import de.vogella.gae.java.todo.dao.Dao; public class ServletRemoveTodo extends HttpServlet { private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { String id = req.getParameter("id"); Dao.INSTANCE.remove(Long.parseLong(id)); resp.sendRedirect("/TodoApplication.jsp"); } }
In the folder "war" create the following JSP "TodoApplication.jsp".
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page import="java.util.List" %> <%@ 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="de.vogella.gae.java.todo.model.Todo" %> <%@ page import="de.vogella.gae.java.todo.dao.Dao" %> <!DOCTYPE html> <%@page import="java.util.ArrayList"%> <html> <head> <title>Todos</title> <link rel="stylesheet" type="text/css" href="css/main.css"/> <meta charset="utf-8"> </head> <body> <% Dao dao = Dao.INSTANCE; UserService userService = UserServiceFactory.getUserService(); User user = userService.getCurrentUser(); String url = userService.createLoginURL(request.getRequestURI()); String urlLinktext = "Login"; List<Todo> todos = new ArrayList<Todo>(); if (user != null){ url = userService.createLogoutURL(request.getRequestURI()); urlLinktext = "Logout"; todos = dao.getTodos(user.getUserId()); } %> <div style="width: 100%;"> <div class="line"></div> <div class="topLine"> <div style="float: left;"><img src="images/todo.png" /></div> <div style="float: left;" class="headline">Todos</div> <div style="float: right;"><a href="<%=url%>"><%=urlLinktext%></a> <%=(user==null? "" : user.getNickname())%></div> </div> </div> <div style="clear: both;"/> You have a total number of <%= todos.size() %> Todos. <table> <tr> <th>Short description </th> <th>Long Description</th> <th>URL</th> <th>Done</th> </tr> <% for (Todo todo : todos) {%> <tr> <td> <%=todo.getShortDescription()%> </td> <td> <%=todo.getLongDescription()%> </td> <td> <%=todo.getUrl()%> </td> <td> <a class="done" href="/done?id=<%=todo.getId()%>" >Done</a> </td> </tr> <%} %> </table> <hr /> <div class="main"> <div class="headline">New todo</div> <% if (user != null){ %> <form action="/new" method="post" accept-charset="utf-8"> <table> <tr> <td><label for="summary">Summary</label></td> <td><input type="text" name="summary" id="summary" size="65"/></td> </tr> <tr> <td valign="description"><label for="description">Description</label></td> <td><textarea rows="4" cols="50" name="description" id="description"></textarea></td> </tr> <tr> <td valign="top"><label for="url">URL</label></td> <td><input type="url" name="url" id="url" size="65" /></td> </tr> <tr> <td colspan="2" align="right"><input type="submit" value="Create"/></td> </tr> </table> </form> <% }else{ %> Please login with your Google account <% } %> </div> </body> </html>
The JSP refers to a css file. Create a folder "war/css" and create the following file "main.css".
body { margin: 5px; font-family: Arial, Helvetica, sans-serif; } hr { border: 0; background-color: #DDDDDD; height: 1px; margin: 5px; } table th { background:#EFEFEF none repeat scroll 0 0; border-top:1px solid #CCCCCC; font-size:10pt; padding-left:5px; padding-right:4px; padding-top:4px; vertical-align:top; text-align:left; } table tr { background-color: #e5ecf9; font-size:10pt; } .topLine { height: 1.25em; background-color: #e5ecf9; padding-left: 4px; padding-right: 4px; padding-bottom: 3px; padding-top: 2px; } .headline { font-weight: bold; color: #3366cc; } .done { font-size:8pt; vertical-align: top; } .email { font-size:8pt; vertical-align: top; } form td { font-size:10pter; }
Change web.xml
in folder /war/WEB-INF" to the following. It will create the right servlet mapping and will set the JSP as start page.
<?xml version="1.0" encoding="utf-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <servlet> <servlet-name>CreateNewTodo</servlet-name> <servlet-class>de.vogella.gae.java.todo.ServletCreateTodo</servlet-class> </servlet> <servlet> <servlet-name>RemoveTodo</servlet-name> <servlet-class>de.vogella.gae.java.todo.ServletRemoveTodo</servlet-class> </servlet> <servlet-mapping> <servlet-name>RemoveTodo</servlet-name> <url-pattern>/done</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>CreateNewTodo</servlet-name> <url-pattern>/new</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>TodoApplication.jsp</welcome-file> </welcome-file-list> </web-app>
You should be able to run your application locally, login and create and delete "Todos".
To deploy your application to the GAE you need to maintain your application ID in the file "web/WEB-INF/appengine-web.xml". In the tag "application" maintain the application you have created in GAE/J Registration . In my example I use the application "vogellatodo".
<?xml version="1.0" encoding="utf-8"?> <appengine-web-app xmlns="http://appengine.google.com/ns/1.0"> <application>vogellatodo</application> <version>1</version> <!-- Configure java.util.logging --> <system-properties> <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/> </system-properties> </appengine-web-app>
Now deploy your application to the Google cloud. The following assumes that you have already created your account.
Right-click on your project and select Google > App Engine Settings... from the context menu. Check that the application ID is as you maintained it in "appengine-web.xml".
Right-click on your project, Select Google -> Deploy to App Engine. You need to login with your Google account information.
After the upload completes you will find your application online under http://application-id.appspot.com, e.g. in my case http://vogellatodo.appspot.com.
AppEngine allows your application to send and receive emails. We will use the receive email feature to be able to receive new Toods via email.
To receive emails in your application you have to declare that your application is allowed to use the mail service. Add the service "mail" to your "appengine-web.xml".
<?xml version="1.0" encoding="utf-8"?> <appengine-web-app xmlns="http://appengine.google.com/ns/1.0"> <application>vogellatodo</application> <version>1</version> <!-- Configure java.util.logging --> <system-properties> <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/> </system-properties> <inbound-services> <service>mail</service> </inbound-services> </appengine-web-app>
After redeploying your app you can check in the admin console of the appengine under Application Settings if incoming email is allowed.
After defining that your application can receive email you need to define the email address for your application. The email address would be:
user@appid.appspotmail.com
This address follows the pattern: "user@domain". The domainis based on the applicationid, e.g. "applicationid.appspotmail.com". Please note that string@appid.appspotmail.com appspotmail.com is different from appspot.com , which we use in the domain name of our application. You can add use any user you want as long as you provide a mapping to a servlet in web.xml
.
Via the web.xml
you define which servlet answers to which user. The url pattern must start with "/_ah/mail/" to tell AppEngine that this is a mapping for receiving emails. The url pattern can include wildcards.
We will define that one servlet receives the email for all users. Add the following servlet mappings to your web.xml
, make sure you replace the string "applicationid" with your real id. "
<?xml version="1.0" encoding="utf-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <servlet> <servlet-name>CreateNewTodo</servlet-name> <servlet-class>de.vogella.gae.java.todo.ServletCreateTodo</servlet-class> </servlet> <servlet> <servlet-name>RemoveTodo</servlet-name> <servlet-class>de.vogella.gae.java.todo.ServletRemoveTodo</servlet-class> </servlet> <servlet-mapping> <servlet-name>RemoveTodo</servlet-name> <url-pattern>/done</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>CreateNewTodo</servlet-name> <url-pattern>/new</url-pattern> </servlet-mapping> <servlet> <servlet-name>Email</servlet-name> <servlet-class>de.vogella.gae.java.todo.EmailServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Email</servlet-name> <url-pattern>/_ah/mail/*</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>TodoApplication.jsp</welcome-file> </welcome-file-list> </web-app>
Create the following servlet which will process your email.
package de.vogella.gae.java.todo; import java.io.IOException; import java.util.Properties; import javax.mail.Address; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.Part; import javax.mail.Session; import javax.mail.internet.MimeMessage; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.datanucleus.sco.simple.GregorianCalendar; import com.google.appengine.api.users.User; import de.vogella.gae.java.todo.dao.Dao; public class EmailServlet extends HttpServlet { private static final long serialVersionUID = 1L; public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { Properties props = new Properties(); Session email = Session.getDefaultInstance(props, null); try { MimeMessage message = new MimeMessage(email, req.getInputStream()); String summary = message.getSubject(); String description = getText(message); Address[] addresses = message.getFrom(); User user = new User(addresses[0].toString(), "gmail.com"); Dao.INSTANCE.add(user.getNickname(), summary, description, "", GregorianCalendar.getInstance()); } catch (Exception e) { e.printStackTrace(); } } private boolean textIsHtml = false;/** * Return the primary text content of the message. */private String getText(Part p) throws MessagingException, IOException { if (p.isMimeType("text/*")) { String s = (String)p.getContent(); textIsHtml = p.isMimeType("text/html"); return s; } if (p.isMimeType("multipart/alternative")) { // prefer html text over plain text Multipart mp = (Multipart)p.getContent(); String text = null; for (int i = 0; i < mp.getCount(); i++) { Part bp = mp.getBodyPart(i); if (bp.isMimeType("text/plain")) { if (text == null) text = getText(bp); continue; } else if (bp.isMimeType("text/html")) { String s = getText(bp); if (s != null) return s; } else { return getText(bp); } } return text; } else if (p.isMimeType("multipart/*")) { Multipart mp = (Multipart)p.getContent(); for (int i = 0; i < mp.getCount(); i++) { String s = getText(mp.getBodyPart(i)); if (s != null) return s; } } return null; } }
To test your email functionality start your application and open the admin console on "http://localhost:8888/_ah/admin/". Select Inbound Mail and maintain some test data. Make sure the To email address match the servlet mapping for the email address.
Deploy your application. Send an email to "whatever@applicationid.appspotmail.com". Login to your application. You should get a new Todo with the summary of the email header and the description of the email body.
You can define cron jobs in your application. Via a cron job on th AppEngine you can access a URL according to a time pattern which is defined similar to the cron jobs on Unix. You define your cron jobs in a file "cron.xml" in the WEB-INF
folder of you application.
<?xml version="1.0" encoding="UTF-8"?> <cronentries> <cron> <url>/count</url> <description>Calls the webpage /count every minute</description> <schedule>every 1 minutes</schedule> </cron> </cronentries>
This cron job will call the local website /count every minute.
You can check you cron jobs in the admin console.
Tip
Please note that you should avoid running unnecessary cron jobs as this increases the load of the AppEngine.You can use standard Java Logging for logging on the App Engine. For example to define a logger in your class EmailServlet use the following.
private static final Logger log = Logger.getLogger(EmailServlet.class.getName());
To log a message use the following.
log.info("Your information log message"); log.warning("Your warning log message"); log.severe("Your severe log message");
You find your logs on the Admin Console . the For further information see Java Logging Tutorial and Logging on the GAE/J.
The Admin Console provides you with a lot of information about your application. For example you can acces the data stored in the datastore or look at the log files of your application.
You can also use standard Java Logging for creating custom logs on the GAE/J. See Java Logging Tutorial andLogging on the GAE/J.
You can also extend the admin console with own pages. Create the following entry in "appengine-web.xml".
<admin-console> <page name="Static List" url="/static.html" /> </admin-console>
We will just use a static HTML for the example. Create the following file in the WEB-INF
folder.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>Integrated into the Admin Console</title> </head> <body> <h1>Hello Admin Console!</h1> <table> <tr> <td colspan="2" style="font-weight:bold;">This could be a dynamic site:</td> </tr> <tr> <td>But it isn't.</td> </tr> </table> </body> </html>
If you redeploy your application you have another entry in your Admin console.
Before posting questions, please see the vogella FAQ. If you have questions or find an error in this article please use thewww.vogella.com Google Group. I have created a short list how to create good questions which might also help you.
http://www.vogella.com/articles/GoogleAppEngine/article.html Google App Engine Development with Python
vogella Training Android and Eclipse Training from the vogella team
Android Tutorial Introduction to Android Programming
GWT Tutorial Program in Java and compile to JavaScript and HTML
Eclipse RCP Tutorial Create native applications in Java
JUnit Tutorial Test your application
Git Tutorial Put everything you have under distributed version control system
'TechnoBabbler' 카테고리의 다른 글
Internet Explorer 버전에 상관없이 jquery ajax 호출하기 (1) | 2013.07.16 |
---|---|
heroku clone (0) | 2013.06.18 |
레드마인에서 외부 git 서버 연결하기 (0) | 2013.05.02 |
Google App Engine에서 Python으로 작업시에 Custom Status Code 등록하기 (0) | 2013.04.25 |
간단하게 사용하는 iOS용 HTTP 요청 예제 (0) | 2013.04.08 |