App Engine的Java网络应用使用了Java Servlet标准接口来和应用服务器交互。一个应用由一个或多个servlet类组成,每个都扩展了(extend)servlet基类。使用一个叫做部署描述(deployment descriptor)的标准配置文件,也就是web.xml,Servlets被映射到URLs。当App Engine接受到一个Java应用请求时,它会根据URL和部署描述来决定使用哪个servlet类,实例化这个类,然后调用servlet对象中的恰当的方法。

Java应用所有的文件,包括编译的Java类,配置文件,静态文件,用一个叫做Web Application Archive或”WAR“的标准目录结构来管理。在WAR目录中的所有东西都被部署到App Engine上。通常在你的开发工作流程中使用一个自动化构建过程或可识别WAR的开发工具根据一组源代码文件来构建WAR的内容。

如果你使用带有Google插件的Eclipse IDE,你可以使用Web Application向导来创建一个新项目。单击Google下拉按钮,然后选择New Web Application Project。(可选择的是,从File菜单选择New,然后是Web Application Project)在这个打开的窗体中,输入一个项目名(比如Clock)和一个包名(比如clock)。

不勾选“Use Google Web Toolkit"复选框,并确保“Use Google App Engine”复选框被勾选。(如果你让GWT复选框被选中,这个新项目将会用GWT启动文件创建。这是很酷的,但是它超出了本章的范围)图2-8显示了创建Clock应用的完成后的对话框。单击Finish来创建这个项目。

如果你不使用Google Plugin for Eclipse,你需要另外创建这个目录和文件。如果你已经对Java网络开发很熟悉,你可以使用你已有的工具和处理(tools and processes)来生成最终的WAR。这个小节的剩余部分,我们假定你使用由Eclipse插件创建的目录结构。

图2-9显示了这个项目文件的结构,在Eclipse包浏览窗口中被描述了。

这个项目的根路径(Clock)包含两个主要的子目录:src和war。src/目录包含项目所有的类文件,并使用了Java包结构。在clock包路径中,Eclipse在文件clock/ClockServlet.java中创建了一个叫做ClockServlet的Servlet类的源代码。

war/目录包含应用的完整的最终内容(the complete final contents)。Eclipse从src/自动编译源代码并将编译了的类文件放到war/WEB-INF/classes/目录,在Eclipse的包浏览窗口中默认是隐藏的。Eclipse也自动拷贝src/META-INF/的内容到war/WEB-INF/classes/META-INF中。其他的所有内容,比如CSS或JavaScript文件,必须在war/目录的预定位置中被创建。

让我们用一个简单的显示当前时间的Servlet开始我们的时钟应用。打开并编辑src/clock/ClockServlet.java文件(有必要的话,创建它),给它类似于例2-9的内容。

例2-9.一个简单的Java servlet

package clock;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.SimpleTimeZone;
import javax.servlet.http.*; @SuppressWarnings("serial")
public class ClockServlet extends HttpServlet{
public void doGet(HttpServletRequest req,HttpServletResponse resp)
throws IOException{
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSSSSS");
fmt.setTimeZone(new SimpleTimeZone(0,"")); resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("<p>The time is: " + fmt.format(new Date()) + "</p>");
}
}

这个servlet类继承自javax.servlet.http.HttpServlet,复写了它打算支持的HTTP 方法(overrides methods for each of the HTTP methods it intends to support.)。这个servlet复写了doGet()方法来处理HTTP GET请求。服务器用HttpServletRequest和HttpServletResponse对象作为参数来调用这个方法。这个HttpServletRequest包含请求的信息,比如URL,表单参数,和cookies。使用HttpServletResponse中方法,比如setContentType()和getWritter(),为响应做准备。当这个servlet方法退出时,App Engine发出响应。

为了告诉App Engine调用这个servlet来处理响应,我们需要一个部署解释器(development descriptor):一个描述哪些URLs调用哪些servlet类的XML配置文件,除了其他事情之外(among other things)。这个部署解释器是servlet标准的部分。打开或创建war/WEB-INF/web.xml文件,并添加类似例2-10的内容:

例2-10.web.xml文件,也就是所谓的部署解释器,将所有的URLs映射到ClockServlet。

<?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>clock</servlet-name>
<servlet-class>clock.ClockServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>clock</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

Eclipse可以在它的XML设计视图中打开这个文件,像表格一样显示元素和值。在编辑面板的底部选择Source tab来编辑XML源代码。

web.xml是一个根元素为<web-app>的XML文件。为了映射URL模式到servlets,你要用<servlet>元素声明每个servlet,然后用<servlet-mapping>元素声明映射。servlet映射的<url-pattarn>可以是一个完整的URL路径,或在开头或末尾有一个*来表示路径一部分的URL路径。在这个例子中,URL模式/仅仅匹配根URL路径。

※确保你的每一个<url-pattern>值以正斜杠开始。忽略这个开始斜杠在开发网络服务器上可能是正常的,但是在App Engine上表现出非预期的行为。

App Engine需要一个额外的配置文件,它不是servlet标准的一部分。打开或创建war/WEB-INF/appengine-web.xml文件,并添加类似例2-11的内容。

例2-11.appengine-web.xml文件,是Java应用的App Engine指定的配置。

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

在这个例子中,这个配置文件告诉App Engine这是clock应用的版本1。我们也声明应用是线程安全的,授权App Engine重复利用一个应用实例为多个同时的请求提供服务。(当然,这样做了之后,我们也必须确保我们的代码是线程安全的。)你也可以使用这个配置文件来控制其他的行为,比如静态文件和会话(sessions)。更多的信息,参见第3章。

应用的WAR必须包括一些来自App Engine SDK的JARs:Java EE实现JARs,和App Engine API JAR。Eclipse插件会自动安装这些JARs到WAR中。如果你不使用Eclipse插件,你必须手动拷贝这些JARs。查看SDK的目录lib/user和/lib/shared/subdirectories。从这些目录中拷贝每个.jar文件到你的项目的war/WEB-INF/lib/目录中。

最后,这个servlet类必须被编译。Eclipse按需自动编译你的所有类。如果你没有使用Eclipse,你大概想用一个编译工具,比如Apache Ant来编译源代码和执行其他的编译任务。查看官方App Engine的关于使用Apache Ant来编译App Engine项目的文档信息。

我认为解释如何在命令行中使用javac命令来编译Java项目是一个传统。你可以通过将war/WEB-INF/lib/和war/WEB-INF/classes目录下的每个JARs放到classpath下,并确保被编译的类(end up in the classes/ directory)最终处于classes/目录下。但是在真实世界中,你想要你的IDE或一个Ant脚本来为你照看这些事。

还有一件事,Eclipse用户要知道:Eclipse的新项目向导创建了叫做war/index.html的一个静态文件。在项目浏览窗口中通过在它上面右击,选择Delete,单击OK来删除。(如果你不删除它,这个静态文件会优先于我们刚刚创建的servlet映射)

是时候使用开发网络服务器来测试这个应用了。Eclipse插件可以在Eclipse调试器中运行这个应用和开发服务器。为了启动它,选择Run菜单,Debug As,Web Application。这个服务器启动,然后在控制台面板中输出下面的信息:

The server is  running at http://localhost:8888/

如果你使用的不是Eclipse,你可以使用dev_appserver命令启动开发服务器(对Mac OS x或Linux使用dev_appserver.sh)。这个命令将WAR目录路径作为参数,想这样(This command takes the path to the WAR directory as an argument,like so):

dev_appserver war

这个命令工具与Eclipse 插件相比,使用不同的默认端口(8080而不是8888)你可以使用命令行工具的--port argument改变这个端口,比如:--port=8888。

通过在浏览器中查看这个服务器URL来测试你的应用:

http://localhost:8888

浏览器显示类似Python例子的一个页面,在前面的图2-4中。

<Chapter 2>2-2-2.开发Java应用(Developing a Java App)的更多相关文章

  1. 《连载 | 物联网框架ServerSuperIO教程》1.4种通讯模式机制。附小文:招.NET开发,结果他转JAVA了,一切都是为了生活

    参考文章: 1.SuperIO通讯框架介绍,含通信本质 2.C#跨平台物联网通讯框架ServerSuperIO(SSIO) 一.感慨 上大学的时候,没有学过C#,花了5块钱在地坛书市买了一本教程,也就 ...

  2. Neo4j图数据库管理系统开发笔记之一:Neo4j Java 工具包

    1 应用开发概述 基于数据传输效率以及接口自定义等特殊性需求,我们暂时放弃使用Neo4j服务器版本,而是在Neo4j嵌入式版本的基础上进行一些封装性的开发.封装的重点,是解决Neo4j嵌入式版本Emb ...

  3. C# 开发XML Web Service与Java开发WebService

    一.web service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量 ...

  4. Amoeba是一个类似MySQL Proxy的分布式数据库中间代理层软件,是由陈思儒开发的一个开源的java项目

    http://www.cnblogs.com/xiaocen/p/3736095.html amoeba实现mysql读写分离 application  shang  2年前 (2013-03-28) ...

  5. 【小白的java成长系列】——java ide 开发工具eclipse的操作

    今天看了一下自己的博客文章,里面的内容还是比較杂的,有好多技术,有好多语言,都没有突出自己的强项,能够说,从博客里面,看不出我究竟是做哪块的..加上今天被授予了博客准专家勋章,自己想了一下,还是得梳理 ...

  6. 集成框架 javaweb开发平台ssmy_m(生成代码) java struts2 mybatis spring maven jquery

    网页地址 http://blog.csdn.net/lpy3654321/article/details/31841573 项目设想,在项目开发中,我们的开发者大多数时间都在反复开发 相同的keywo ...

  7. 转:微信开发获取地理位置实例(java,非常详细,附工程源码)

    微信开发获取地理位置实例(java,非常详细,附工程源码)   在本篇博客之前,博主已经写了4篇关于微信相关文章,其中三篇是本文基础: 1.微信开发之入门教程,该文章详细讲解了企业号体验号免费申请与一 ...

  8. (中级篇 NettyNIO编解码开发)第七章-java序列化

    相信大多数Java程序员接触到的第一种序列化或者编解码技术就是.Java的默认序列化,只需要序列化的POJO对象实现java.io.Serializable接口,根据实际情况生成序列ID,这个类就能够 ...

  9. 20个开发人员非常有用的Java功能代码

    本文将为大家介绍20个对开发人员非常有用的Java功能代码.这20段代码,可以成为大家在今后的开发过程中,Java编程手册的重要部分. 1. 把Strings转换成int和把int转换成String ...

随机推荐

  1. AE数据加载

    1. 数据加载问题: 任何系统都离不开数据的加载,下边就AE中几种常用的数据加载做一个列举.以便查阅: 1.加载个人数据库 个人数据库是保存在Access中的数据库.其加载方式有两种:通过名字和通过属 ...

  2. [iOS]iPhone利用<极光推送>实现远程推送

    准备: 1. 一个Xcode工程 2. 开发者账号 3. 真机 (重要,模拟器无法进行远程推送,因为模拟器没有UDID) 第一步:绑定工程的Bundle Identifer 首先当然要登录https: ...

  3. C++仿函数(functor)详解

    C++仿函数(functor)详解 所谓的仿函数(functor),是通过重载()运算符模拟函数形为的类. 因此,这里需要明确两点: 1 仿函数不是函数,它是个类: 2 仿函数重载了()运算符,使得它 ...

  4. Windows 7下配置JDK环境变量,JAVA环境变量配置,Tomcat服务器的使用

    参考来源: http://www.cnblogs.com/pannysp/archive/2012/03/07/2383364.html 1. 常识: 1.1 War包 War包一般是在进行Web开发 ...

  5. Ubuntu下MySQL数据库安装与配置与卸载

    安装: sudo apt-get install mysql-server mysql-client 一旦安装完成,MySQL 服务器应该自动启动.您可以在终端提示符后运行以下命令来检查 MySQL ...

  6. Ext.Net学习笔记01:在ASP.NET WebForm中使用Ext.Net

    Ext.Net是一个对ExtJS进行封装了的.net控件库,可以在ASP.NET WebForm和MVC中使用.从今天开始记录我的学习笔记,这是第一篇,今天学习了如何在WebForm中使用Ext.Ne ...

  7. Android Dialog使用举例

    在Android开发中,我们经常会需要在Android界面上弹出一些对话框,比如询问用户或者让用户选择.这些功能我们叫它Android Dialog对话框,在我们使用Android的过程中,我归纳了一 ...

  8. python - 回溯继承树 - 自己实现

    # -*- coding: utf-8 -*- class test(object): pass class test1(test): pass class test2(test1): pass pr ...

  9. django - 好的 获取 参数值 方法

    第一步: # 参数列表 parameters = ('user_id', 'day_time', 'normal_data', 'hourly_data', 'product_id') # 需要传入的 ...

  10. python - 简述list. extend() 和 append() 区别

    >>> a = 'hello' >>> b = [1, 2, 3] >>> b.append(a) >>> b [1, 2, 3 ...