!=和notin哪个快_快起来吧!

!=和notin哪个快

一个想法就像痒:您需要抓挠它,当您这样做时会感觉更好。 作为软件开发人员,我们花费大量时间思考各种应用程序的想法。 很好玩吧? 面临的挑战是弄清楚如何使软件产品实现。 想像一下然后创建它就很令人满意。 另一种选择(痒痒)只是令人沮丧。

许多应用程序从未落地的原因之一就是对基础架构的需求。 维护良好的基础结构通常需要系统管理员,DBA和网络工程师组成的团队,这些团队直到最近才是主要针对富人的企业。 即使是向第三方付费以托管您的应用程序也不是万无一失的:如果该应用程序的受欢迎程度飞速上升,并突然受到欢迎,会发生什么? 所谓的Slashdot效应可以说是一个好主意,仅仅是因为很难预测负载峰值。

但是,众所周知,这正在改变。 Web服务的前提已经发生了变化,如今,它通过云计算及其强大的表亲,平台即服务/ PAAS为我们带来了更轻松地构建,部署和分发应用程序的方式。 现在,当您编写下一个Twitter并将其部署在云平台上时,它将可以扩展,扩展,扩展。 哇,真好!

在这一由三部分组成的文章中,您将亲身体验为什么云计算/ PAAS是软件开发如此重要的进化转变,同时还为Java开发提供了令人兴奋的新平台:Google App Engine for Java,当前在预览版中可用。 我将首先概述App Engine for Java,包括它提供的应用程序服务的类型。 之后,您将直接使用Java的App Engine Google Eclipse插件直接进入一个应用程序示例(两个示例之一)。 第一个应用程序示例将利用App Engine for Java对Java Servlet API的支持,第二个示例将利用其对GWT的支持。 在第2部分中 ,您将使用App Engine for Java对servlet和GWT的支持分别创建一个小的联系人管理应用程序。 在第3部分中,您将使用自定义构建的应用程序来探索App Engine for Java的基于Java的持久性支持,该支持基于Java数据对象(JDO)和Java持久性API(JPA)。

好吧,足够多的谈话:让我们快转!

关于Java版Google App Engine

Google(我相信也是某种搜索引擎的制造商)于2008年4月首次发布了Google App Engine。令许多Java开发人员感到沮丧的是,最初的发布纯粹是Python程序员的领域-人们认为空白应该是用于块! (我写了一本关于Python的书,所以我应该知道。)Google于2009年4月发布了针对Java的Google App Engine,以此回应了大众的需求。

Google App Engine for Java提供了用于企业Java开发的端到端解决方案:基于浏览器的Ajax GUI(易于使用),Eclipse工具支持和后端的Google App Engine。 与其他云计算解决方案相比,易用性和工具优势是Google App Engine for Java的优势。

App Engine for Java中的应用程序开发意味着使用Google的资源来存储和检索Java对象。 数据存储基于BigTable ,但具有JDO和JPA接口,使您可以编写不直接与BigTable绑定的代码。 实际上,Google为许多API提供了基于标准的支持,因此您可以编写与Java平台的App Engine无关的代码。

App Engine for Java依赖以下标准Java API:

  • java.net.URL以获取服务(通过使用HTTP和HTTPS协议与其他主机进行通信)
  • JavaMail发送邮件
  • 与Memcache的JCache(JSR 107)接口可为缓存查询和计算提供快速,临时的分布式存储

此外,适用于Java的App Engine还为以下应用程序服务提供支持:

  • 用户认证和授权
  • 克朗
  • 数据导入/导出
  • 访问防火墙数据

数据导入/导出对于将数据从其他来源转移到App Engine for Java应用程序中非常重要。 这是您不受App Engine for Java束缚的另一种方式。 Google的CRON支持基于内部URL在特定时间表上受到攻击,这使其成为一项不错的服务,并且与App Engine for Java没有太多的关联。 用户认证和授权机制是具体到App Engine for Java中,但你可以写一个ServletFilter ,以尽量减少紧耦合,方面或Spring Security的插件。

创建您的第一个Java应用程序App Engine

如果您已经阅读了本文,那么您就可以开始构建第一个App Engine for Java应用程序了。 第一步是安装Google Eclipse for App Engine for Java插件 ; 完成后,您就可以开始了。

打开你的Eclipse IDE中,你会看到三个在Eclipse IDE旁边的打印机按钮新的按钮:A G在一个蓝色的球,在一个红色的工具箱中的G和一个App Engine的Java迷你喷气式飞机,如图图1:

图1. Eclipse IDE中的闪亮新按钮
!=和notin哪个快_快起来吧!_第1张图片

这些按钮的作用如下:

  • 蓝色的球使您可以访问App Engine for Java项目创建向导。
  • 红色的工具箱可让您编译GWT项目。
  • 小型喷气式飞机是部署App Engine项目的关键。

您将使用项目创建向导创建两个新项目:一个基于servlet,另一个使用GWT构建。 您将使用工具箱功能来编译GWT项目。 准备部署App Engine项目时,您将启动微型喷气机,从而使它生效。

现在开始创建一个Java Java App Engine项目。 首先,单击蓝色球以访问项目创建向导。 然后使用名为gaej.example的包创建一个名为SimpleServletApp的应用程序,如图2所示:

图2.开始一个新项目
!=和notin哪个快_快起来吧!_第2张图片

请注意,对于第一个简单示例,如何取消选择GWT支持。 完成此步骤后,项目创建向导将创建一个具有Hello World类型的servlet的基于servlet的简单应用程序。 图3显示了该项目的屏幕截图:

图3. SimpleServletApp项目
!=和notin哪个快_快起来吧!_第3张图片

请注意,此新的基于Servlet的项目自动包含了JAR文件:

  • datanucleus-*。jar :用于使用标准JDO或低级BigTable API访问App Engine for Java数据存储区
  • appengine-api-sdk.1.2.0.jar :用于将非标准App Engine用于Java应用程序服务,例如App Engine for Java Security
  • geronimo-*。jar :用于使用标准Java API,例如Java事务管理API(JTA)和JPA
  • jdo2-api-2.3-SNAPSHOT.jar :用于使用JDO API

从本文的第2部分开始,您将学习如何使用App Engine for Java和一些App Engine for Java的应用程序服务中的持久性API。

还要注意用于配置Google App Engine运行时容器的文件,名为appengine.xml。 在此示例中,将使用appengine.xml来配置logging.properties文件,以使用App Engine for Java进行日志记录。

首先看一下Java Servlet应用程序的App Engine

在项目创建向导中配置完所有内容后,适用于Java的App Engine将向您展示Hello World风格的servlet应用程序的基础知识。 查看代码,然后查看如何使用App Engine for Java Eclipse工具运行应用程序。 该应用程序的主要入口是SimpleServletAppServlet ,如清单1所示:

清单1. SimpleServletAppServlet
package gaej.example;

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

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

该servlet被映射到web.xml中的URI /simpleservletapp下,如清单2所示:

清单2. web.xml




    
        simpleservletapp
        gaej.example.SimpleServletAppServlet
    
    
        simpleservletapp
        /simpleservletapp
    
    
        index.html
    

项目创建向导还提供了一个index.html文件,该文件具有指向新servlet的链接,如清单3所示:

清单3.由项目创建向导生成的index.html









  
    
    
    
    
    
    Hello App Engine
  

  
  
  
  
  
  
    

Hello App Engine!

Available Servlets:
SimpleServletAppServlet

现在,您仅使用一些Java API构建了一个简单的servlet应用程序。 这就是重点:适用于Java的App Engine使用标准Java API封装了App Engine功能,从而使App Engine可以支持Java平台可用的大量框架。

部署应用程序

要使用App Engine for Java Eclipse工具运行基于servlet的应用程序,首先右键单击该项目并选择Run As菜单,然后选择旁边带有蓝色球的“ Web Application”,如图4所示:

图4.运行App Engine for Java开发服务器
!=和notin哪个快_快起来吧!_第4张图片

现在,您应该能够在浏览器中导航到http:// localhost:8080 / simpleservletapp,并看到带有Hello World消息的应用程序。

为Java / GWT应用程序创建App Engine

您已经了解了简单的Java Servlet应用程序App Engine的工作原理,因此接下来让我们探索GWT应用程序的Java Eclipse App Engine工具。 首先单击Eclipse IDE工具栏中的蓝色球,以激活Google项目创建向导。 这次,选择对GWT的支持,如图5所示:

图5.使用App Engine for Java项目创建向导创建一个简单的GWT应用程序
!=和notin哪个快_快起来吧!_第5张图片

如您在图6中看到的,App Engine for Java为GWT应用程序提供了比基于servlet的简单代码工件更多的代码工件。 示例应用程序是在GWT中完成的GUI,可与问候服务应用程序对话。

图6.为GWT应用程序提供的代码工件
!=和notin哪个快_快起来吧!_第6张图片

GWT应用程序还有一个额外的JAR,而基于servlet的应用程序则不需要,即gwt-servlet.jar。

其他工件如下:

  • src / gaej / example:SimpleGWTApp.gwt.xml:GWT模块描述符
  • src / gaej.example.server:GreetingServiceImpl.java:Greeting服务的实现
  • src / gaej.example.client:GreetingService.java:问候服务的同步API
  • src / gaej.example.client:GreetingServiceAsync.java:问候服务的异步API
  • src / gaej.example.client:SimpleGWTApp.java:还构建启动程序GUI的主入口点
  • war / WEB-INF:web.xml:用于配置GreetingServiceImpl部署描述符
  • 战争:SimpleGWTApp.html:显示GWT GUIHTML页面
  • 战争:SimpleGWTApp.css:GWT GUI的样式表

在深入研究应用程序的体系结构和源代码之前,请查看运行该应用程序时会发生什么。 要运行该应用程序,请单击工具栏上的红色工具箱,然后单击“ 编译”按钮。 现在,右键单击该项目,然后像以前一样选择“ 运行方式-> Web应用程序”菜单项。 这次,因为您正在使用GWT应用程序,所以将显示GWT托管模式控制台和浏览器。 继续并使用Web应用程序输入您的姓名并查看响应。 我收到了如图7所示的响应:

图7.运行示例GWT应用程序
!=和notin哪个快_快起来吧!_第7张图片

在下一节中,我将引导您完成示例GWT应用程序。 如果您想了解更多有关GWT的信息(或参加GWT教程),请参阅参考资料 。

在GWT应用程序内部

基于提供的配置,Eclipse的GWT工具创建了一个具有HTML前端( 清单10所示的SimpleGWTApp.html)的启动程序应用程序,该应用程序加载了simplegwtapp.js和simplegwtapp.nocache.js。 这是GWT从您的Java代码生成JavaScript代码; 即,这是在gaej.example.client包下src目录代码(参见清单6 , 7 ,和8 )。

创建GUI的主要入口是gaej.example.client.SimpleGWTApp ,如清单8所示。 此类创建GWT GUI元素,并将它们与SimpleGWTApp.html上HTML DOM元素关联(请参见清单10 )。 SimpleGWTApp.html定义了两个名为nameFieldContainersendButtonContainer (表中的列)的DOM元素。 SimpleGWTApp类使用RootPanel.get("nameFieldContainer")访问与那些DOM元素关联的面板,并将其替换为GUI元素。 然后, SimpleGWTApp类定义一个文本框和按钮,您可以使用它们输入某人的名字并向他们发送问候(见清单10 )。

GWT知道SimpleGWTApp类是应用程序的主要入口点,因为SimpleGWTApp.gwt.xml使用入口点元素指定了它。

SimpleGWTApp连接名为sendButton的按钮,以便单击该按钮时, SimpleGWTApp将在GreetingService上调用greetServer方法。 GreetingService接口在src / gaej.example.client.GreetingService.java中定义( 清单6 )。

由于Ajax本质上是异步的,因此GWT定义了用于访问远程服务的异步接口。 SimpleGWTApp使用src / gaej.example.client.GreetingServiceAsync.java( 清单7 )中定义的异步接口。 所述GreetingServiceImpl的(SRC / gaej.example.server.GreetingServiceImpl.java)实现greetServer在所定义的方法GreetingService ( 清单5 )。 GreetingServiceImpl.greetServer方法返回问候消息String ,SimpleGWTApp使用该String在其创建的对话框中显示问候消息。

GWT模块描述符声明了GUI应用程序的主要入口点,即gaej.example.client.SimpleGWTApp ,如清单4所示:

清单4. GWT模块描述符(src / gaej / example / SimpleGWTApp.gwt.xml)





  
  

  
  
  
  
  
  

  

  
  

GreetingServiceImplGreetingServiceImpl -service应用程序的实际实现,如清单5所示。它在服务器端运行,客户端代码通过远程过程调用对其进行调用。

清单5.问候服务应用程序的实现(src / gaej.example.server.GreetingServiceImpl.java)
package gaej.example.server;

import gaej.example.client.GreetingService;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class GreetingServiceImpl extends RemoteServiceServlet implements
        GreetingService {

    public String greetServer(String input) {
        String serverInfo = getServletContext().getServerInfo();
        String userAgent = getThreadLocalRequest().getHeader("User-Agent");
        return "Hello, " + input + "!

I am running " + serverInfo + ".

It looks like you are using:
" + userAgent; } }

清单6中所示的GreetingService是客户端代码使用的远程过程调用的接口:

清单6.同步API(src / gaej.example.client.GreetingService.java)
package gaej.example.client;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

/**
 * The client side stub for the RPC service.
 */
@RemoteServiceRelativePath("greet")
public interface GreetingService extends RemoteService {
    String greetServer(String name);
}

GreetingServiceAsync是客户端代码将使用的实际接口,如清单7所示。每个方法都提供一个回调对象,以便在远程过程调用完成后以异步方式通知您。 在后台,GWT使用Ajax。 在客户端上使用Ajax时,最好不要阻塞客户端,从而避免异步调用。 阻塞会破坏使用Ajax的目的。

清单7.异步API(src / gaej.example.client.GreetingServiceAsync.java)
package gaej.example.client;

import com.google.gwt.user.client.rpc.AsyncCallback;

/**
 * The async counterpart of GreetingService.
 */
public interface GreetingServiceAsync {
    void greetServer(String input, AsyncCallback callback);
}

SimpleGWTApp是执行大多数操作的地方。 它注册GUI事件,然后将Ajax请求发送到GreetingService

清单8.该应用程序的主要入口点还构建了启动程序GUI(src / gaej.example.client.SimpleGWTApp.java)
package gaej.example.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * Entry point classes define onModuleLoad().
 */
public class SimpleGWTApp implements EntryPoint {
    /**
     * The message displayed to the user when the server cannot be reached or
     * returns an error.
     */
    private static final String SERVER_ERROR = "An error occurred while "
            + "attempting to contact the server. Please check your network "
            + "connection and try again.";

    /**
     * Create a remote service proxy to talk to the server-side Greeting service.
     */
    private final GreetingServiceAsync greetingService = GWT
            .create(GreetingService.class);

    /**
     * This is the entry point method.
     */
    public void onModuleLoad() {
        final Button sendButton = new Button("Send");
        final TextBox nameField = new TextBox();
        nameField.setText("GWT User");

        // You can add style names to widgets
        sendButton.addStyleName("sendButton");

        // Add the nameField and sendButton to the RootPanel
        // Use RootPanel.get() to get the entire body element
        RootPanel.get("nameFieldContainer").add(nameField);
        RootPanel.get("sendButtonContainer").add(sendButton);

        // Focus the cursor on the name field when the app loads
        nameField.setFocus(true);
        nameField.selectAll();

        // Create the popup dialog box
        final DialogBox dialogBox = new DialogBox();
        dialogBox.setText("Remote Procedure Call");
        dialogBox.setAnimationEnabled(true);
        final Button closeButton = new Button("Close");
        // You can set the id of a widget by accessing its Element
        closeButton.getElement().setId("closeButton");
        final Label textToServerLabel = new Label();
        final HTML serverResponseLabel = new HTML();
        VerticalPanel dialogVPanel = new VerticalPanel();
        dialogVPanel.addStyleName("dialogVPanel");
        dialogVPanel.add(new HTML("Sending name to the server:"));
        dialogVPanel.add(textToServerLabel);
        dialogVPanel.add(new HTML("
Server replies:")); dialogVPanel.add(serverResponseLabel); dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT); dialogVPanel.add(closeButton); dialogBox.setWidget(dialogVPanel); // Add a handler to close the DialogBox closeButton.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { dialogBox.hide(); sendButton.setEnabled(true); sendButton.setFocus(true); } }); // Create a handler for the sendButton and nameField class MyHandler implements ClickHandler, KeyUpHandler { /** * Fired when the user clicks on the sendButton. */ public void onClick(ClickEvent event) { sendNameToServer(); } /** * Fired when the user types in the nameField. */ public void onKeyUp(KeyUpEvent event) { if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) { sendNameToServer(); } } /** * Send the name from the nameField to the server and wait for a response. */ private void sendNameToServer() { sendButton.setEnabled(false); String textToServer = nameField.getText(); textToServerLabel.setText(textToServer); serverResponseLabel.setText(""); greetingService.greetServer(textToServer, new AsyncCallback() { public void onFailure(Throwable caught) { // Show the RPC error message to the user dialogBox .setText("Remote Procedure Call - Failure"); serverResponseLabel .addStyleName("serverResponseLabelError"); serverResponseLabel.setHTML(SERVER_ERROR); dialogBox.center(); closeButton.setFocus(true); } public void onSuccess(String result) { dialogBox.setText("Remote Procedure Call"); serverResponseLabel .removeStyleName("serverResponseLabelError"); serverResponseLabel.setHTML(result); dialogBox.center(); closeButton.setFocus(true); } }); } } // Add a handler to send the name to the server MyHandler handler = new MyHandler(); sendButton.addClickHandler(handler); nameField.addKeyUpHandler(handler); } }

Web部署描述符(web.xml,如清单9所示)将GreetingService映射为基于servlet的Web资源。 它以/simplegwtapp/greet名称映射GreetingService servlet,以便SimpleGWTApp可以加载它并对其进行调用。 Web部署描述符还表示SimpleGWTApp.html是应用程序的欢迎页面,因此它将始终加载。

清单9.用于配置GreetingServiceImpl的部署描述符(war / WEB-INF / web.xml)





  
  
    SimpleGWTApp.html
  
 
  
  
    greetServlet
    gaej.example.server.GreetingServiceImpl
  
 
  
    greetServlet
    /simplegwtapp/greet
  

HTML前端是SimpleGWTApp.html,如清单10所示。该页面加载了simplegwtapp.js和simplegwtapp.nocache.js,这是GWT从Java代码生成JavaScript代码。 如前面提到的,这个代码生活在src目录的gaej.example.client包下(从信息6 , 7 ,和8 )。

清单10.显示GWT GUIHTML页面(war / SimpleGWTApp.html)









  
    

    
    
    
    

    
    
    
    Web Application Starter Project
    
    
    
    
    
    
    
  

  
  
  
  
  
  

    
    

    

Web Application Starter Project

Please enter your name:

使用GWT,您可以通过CSS控制应用程序的外观,如清单11所示:

清单11. GWT GUI的样式表(war / SimpleGWTApp.css)
/** Add css rules here for your application. */


/** Example rules used by the template application (remove for your app) */
h1 {
  font-size: 2em;
  font-weight: bold;
  color: #777777;
  margin: 40px 0px 70px;
  text-align: center;
}

.sendButton {
  display: block;
  font-size: 16pt;
}

/** Most GWT widgets already have a style name defined */
.gwt-DialogBox {
  width: 400px;
}

.dialogVPanel {
  margin: 5px;
}

.serverResponseLabelError {
  color: red;
}

/** Set ids using widget.getElement().setId("idOfElement") */
#closeButton {
  margin: 15px 6px 6px;
}

部署到Google App Engine

一旦创建了世界上下一个杀手级应用程序(因为我们确实需要一个用户友好的问候语应用程序),您将需要对其进行部署。 使用Google App Engine的全部目的是,您可以在Google的坚实基础架构上部署应用程序,从而更易于扩展。 Google App Engine旨在提供一个平台来构建可扩展的应用程序,“这些应用程序可以从无数用户增长到数百万,而不会遭受基础架构的困扰”(如App Engine主页上所述)。 为了使用此基础架构,您需要一个Google App Engine for Java帐户 。

就像生活中的许多事情一样,第一次是免费的。 App Engine for Java的免费版本为已部署的应用程序提供了足够的CPU,带宽和存储空间,可提供约500万次浏览量。 除此之外,它是随用随付的。 (还要记住,在撰写本文时,可用的是Java平台App Engine的预览版。)

获得该帐户后,您应该在App Engine for Java网站上看到一个空白的应用程序列表。 单击Create New Application按钮,将出现一个如图8所示的表单。 输入唯一的应用程序名称和描述,然后您将看到一条确认消息,其中包含应用程序的标识符。

该标识符也属于您应用程序的app.yaml文件。 注意,标识符不能更改。 如果您对应用程序使用Google身份验证,则在访问应用程序时,“登录页面”中会显示“ GAEj Rick Part 1文章”。 您将使用gaejarticleforrick通过适用于Java的App Engine Eclipse插件将应用程序部署到Google App Engine。

图8.为Java应用程序创建一个新的App Engine
!=和notin哪个快_快起来吧!_第8张图片

设置应用程序ID之后,可以从Eclipse部署应用程序。 首先,点击看起来类似于Google App Engine徽标(带有机翼和尾巴的喷气发动机)的工具栏按钮,如图9所示:

图9. App Engine for Java Eclipse插件
!=和notin哪个快_快起来吧!_第9张图片

在图10所示的对话框中单击Deploy之前,您可能需要确保选择了Java的App Engine项目。将提示您输入Google凭据,即您的电子邮件地址和用户名。

图10.部署项目
!=和notin哪个快_快起来吧!_第10张图片

图10中的对话框具有指向“ App Engine项目设置”的链接。 单击此链接(也可以从项目设置文件访问),然后输入应用程序ID(在本例中为gaejarticleforrick ),如图11所示。填写应用程序ID后,单击OK ,然后单击Deploy

图11. Google App Engine的项目设置
!=和notin哪个快_快起来吧!_第11张图片

部署应用程序后,可以从http://.appspot.com/

结论

到此结束我对Java的Google App Engine简介的第1部分。 到目前为止,您已经获得了有关Java App Engine的所有内容的概述,并通过使用Java App Engine Google Eclipse插件迈出了第一步。 您创建了两个小型启动器应用程序(一个基于servlet,另一个基于GWT),然后将GWT应用程序部署到Google App Engine平台。

到目前为止的示例已经展示了工具和功能,这些工具和功能使创建和部署可扩展的基于Java的应用程序变得更加容易,甚至可能达到YouTube或Facebook的规模。 在第2部分中 ,您将继续探索致力于App Engine for Java的Java开发人员可以使用的机会。 摆脱本文演示的示例应用程序,您将构建一个自定义联系人管理应用程序。 该应用程序还将成为第3部分中练习的重点,深入研究App Engine for Java的数据存储区及其GUI前端。


翻译自: https://www.ibm.com/developerworks/java/library/j-gaej1/index.html

!=和notin哪个快

你可能感兴趣的:(java,web,javascript,python,编程语言)