在gae平台上開發jsp網站

來源:互聯網
上載者:User

準備工作:

下載apache-ant, googleappengine-sdk, jdk等工具

寫一個簡單的環境設定指令碼

setenv.bat

@echo offcd %~dp0 && echo CWD=%cd%set GAE_HOME=""for /d %%i in (appengine*) do (set GAE_HOME=%CD%\%%i)echo GAE_HOME=%GAE_HOME%set JAVA_HOME=""for /d %%i in (jdk*) do (set JAVA_HOME=%CD%\%%i)echo JAVA_HOME=%JAVA_HOME%set ANT_HOME=""for /d %%i in (apache-ant-*) do (set ANT_HOME=%CD%\%%i)echo ANT_HOME=%ANT_HOME%SET PATH=%JAVA_HOME%\BIN;%GAE_HOME%\BIN;%ANT_HOME%\BIN;%PATH%;@echo on%comspec%

關於jsp編譯失敗的問題,可以參考這個,

http://stackoverflow.com/questions/5622726/unable-to-update-app-failed-to-compile-jsp-files

所以要修改上面的指令碼,保證JAVA_HOME的bin路徑是在本地PATH路徑之前,因為path裡面很可能包含了jre的java.exe的路徑.

1, 複製庫檔案到APPID目錄下的src子目錄

cp -rf $GAE_SDK_HOME/{shared, user} src

按照sdk目錄的lib字母下的readme檔案的說明,shared和user是和使用者app的執行與編譯相關的。

2, 掃描所有的jar包

在你的app項目的src目錄下執行

for /r %i in (*.jar) do @echo %i 

得到:

D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\orm\jdo2-api-2.3-eb.jar D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\shared\appengine-local-runtime-shared.jar D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\shared\el-api.jar D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\shared\jsp-api.jar D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\shared\servlet-api.jar D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\shared\jsp\repackaged-appengine-ant-1.7.1.jar D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\shared\jsp\repackaged-appengine-ant-launcher-1.7.1.jar D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\shared\jsp\repackaged-appengine-jasper-6.0.29.jar D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\shared\jsp\repackaged-appengine-jasper-el-6.0.29.jar D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\shared\jsp\repackaged-appengine-tomcat-juli-6.0.29.jar D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\appengine-api-1.0-sdk-1.7.7.jar D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\appengine-api-labs-1.7.7.jar D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\appengine-jsr107cache-1.7.7.jar D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\jsr107cache-1.1.jar D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\orm\datanucleus-appengine-1.0.10.final.jar D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\orm\datanucleus-core-1.1.5.jar D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\orm\datanucleus-jpa-1.1.5.jar D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\orm\geronimo-jpa_3.0_spec-1.1.1.jar D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\orm\geronimo-jta_1.1_spec-1.1.1.jar D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\orm\jdo2-api-2.3-eb.jar 

編寫2個簡單的java類

Res.java

package bagebit;import com.google.appengine.api.datastore.DatastoreService;import com.google.appengine.api.datastore.DatastoreServiceFactory;import com.google.appengine.api.datastore.Entity;import com.google.appengine.api.datastore.Key;import com.google.appengine.api.datastore.KeyFactory;import java.io.IOException;import java.util.logging.Logger;import javax.servlet.http.*;public class Res extends HttpServlet {    private static final Logger log = Logger.getLogger(Res.class.getName());    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {log.info("Res::doGet called at: " + (new java.util.Date()).toString());            resp.setContentType("text/html;charset=UTF-8");            resp.getWriter().println("<b>Hello, " + req.getRequestURI() +"</b>");    }}

User.java

package bagebit;import com.google.appengine.api.datastore.DatastoreService;import com.google.appengine.api.datastore.DatastoreServiceFactory;import com.google.appengine.api.datastore.Entity;import com.google.appengine.api.datastore.Key;import com.google.appengine.api.datastore.KeyFactory;import java.io.IOException;import java.util.logging.Logger;import javax.servlet.http.*;public class User extends HttpServlet {    private static final Logger log = Logger.getLogger(User.class.getName());    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {log.info("User::doGet called at: " + (new java.util.Date()).toString());            resp.setContentType("text/html;charset=UTF-8");            resp.getWriter().println("<b>Hello, " + req.getRequestURI() +"</b>");    }}

在app目錄下,執行batbuild.bat指令碼編譯java檔案:

set APPID=bagebit
set CLASSPATH="D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\orm\jdo2-api-2.3-eb.jar;D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\shared\appengine-local-runtime-shared.jar;D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\shared\el-api.jar;D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\shared\jsp-api.jar;D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\shared\servlet-api.jar;D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\shared\jsp\repackaged-appengine-ant-1.7.1.jar;D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\shared\jsp\repackaged-appengine-ant-launcher-1.7.1.jar;D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\shared\jsp\repackaged-appengine-jasper-6.0.29.jar;D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\shared\jsp\repackaged-appengine-jasper-el-6.0.29.jar;D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\shared\jsp\repackaged-appengine-tomcat-juli-6.0.29.jar;D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\appengine-api-1.0-sdk-1.7.7.jar;D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\appengine-api-labs-1.7.7.jar;D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\appengine-jsr107cache-1.7.7.jar;D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\jsr107cache-1.1.jar;D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\orm\datanucleus-appengine-1.0.10.final.jar;D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\orm\datanucleus-core-1.1.5.jar;D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\orm\datanucleus-jpa-1.1.5.jar;D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\orm\geronimo-jpa_3.0_spec-1.1.1.jar;D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\src\user\orm\geronimo-jta_1.1_spec-1.1.1.jar"
javac -encoding UTF-8 src\%APPID%\*.java -d war\WEB-INF\classes

這個時候可以在$APPID\war\WEB-INF\classes\$APP_PACKAGE_NAME裡面就可以看到產生的class檔案了。

User.java -> User.classRes.java -> Res.class

配置servlet映射:

開啟$APPID/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>user</servlet-name>        <servlet-class>bagebit.User</servlet-class>    </servlet>    <servlet-mapping>        <servlet-name>user</servlet-name>        <url-pattern>/user</url-pattern>    </servlet-mapping>        <servlet>        <servlet-name>res</servlet-name>        <servlet-class>bagebit.Res</servlet-class>    </servlet>    <servlet-mapping>        <servlet-name>res</servlet-name>        <url-pattern>/res</url-pattern>    </servlet-mapping>    <welcome-file-list>        <welcome-file>index.jsp</welcome-file>    </welcome-file-list></web-app>

運行測試用的jetty伺服器

D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit>dev_appserver -p 8888 war2013-4-22 17:30:41 com.google.apphosting.utils.config.AppEngineWebXmlReader readAppEngineWebXml資訊: Successfully processed D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\war\WEB-INF/appengine-web.xml2013-04-22 17:30:41.379:INFO::Logging to STDERR via org.mortbay.log.StdErrLog2013-4-22 17:30:41 com.google.apphosting.utils.config.AbstractConfigXmlReader readConfigXml資訊: Successfully processed D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\war\WEB-INF/web.xml2013-4-22 17:30:41 com.google.appengine.tools.development.SystemPropertiesManager setSystemProperties資訊: Overwriting system property key 'java.util.logging.config.file', value 'D:\webdev\gae\appengine-java-sdk-1.7.7\config\sdk\logging.properties' with value 'WEB-INF/logging.properties' from 'D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit\war\WEB-INF\appengine-web.xml'2013-04-22 17:30:41.695:INFO::jetty-6.1.x2013-04-22 17:30:42.671:INFO::Started SelectChannelConnector@127.0.0.1:88882013-4-22 9:30:42 com.google.appengine.tools.development.AbstractServer startup資訊: Server default is running at http://localhost:8888/2013-4-22 9:30:42 com.google.appengine.tools.development.AbstractServer startup資訊: The admin console is running at http://localhost:8888/_ah/admin2013-4-22 9:30:42 com.google.appengine.tools.development.DevAppServerImpl start資訊: Dev App Server is now running

在瀏覽器裡面測試

HTTP ERROR 500Problem accessing /. Reason:    Unable to compile class for JSP: An error occurred at line: 7 in the generated java fileOnly a type can be imported. com.google.appengine.api.users.User resolves to a packageAn error occurred at line: 8 in the generated java fileOnly a type can be imported. com.google.appengine.api.users.UserService resolves to a packageAn error occurred at line: 9 in the generated java fileOnly a type can be imported. com.google.appengine.api.users.UserServiceFactory resolves to a package

出錯了,看來的首頁index.jsp編譯失敗了。

原因是沒有複製相應的jsp支援庫到WEB-INF的lib目錄下。

從剛才複製過去的src目錄下的user子目錄複製,或者從sdk的lib目錄的user子目錄複製,保持檔案夾結構。

D:\webdev\gae\appengine-java-sdk-1.7.7\demos\bagebit>xcopy /Y /e /s src\user war\WEB-INF\libsrc\user\appengine-api-1.0-sdk-1.7.7.jarsrc\user\appengine-api-labs-1.7.7.jarsrc\user\appengine-jsr107cache-1.7.7.jarsrc\user\jsr107cache-1.1.jarsrc\user\orm\datanucleus-appengine-1.0.10.final.jarsrc\user\orm\datanucleus-core-1.1.5.jarsrc\user\orm\datanucleus-jpa-1.1.5.jarsrc\user\orm\geronimo-jpa_3.0_spec-1.1.1.jarsrc\user\orm\geronimo-jta_1.1_spec-1.1.1.jarsrc\user\orm\jdo2-api-2.3-eb.jar複製了 10 個檔案

shared目錄就不必了,看lib的readme文檔。

具體複製那些jar包是必要的可以參考guestbook例子裡面的WEB-INF/lib下面的樣子。

注意:在update到伺服器的時候,請記住把你的項目裡面gae內建的的jar包刪掉。

比如,剛才user目錄下複製過來的那些jar包都不要上傳了,自己額外添加的3rd的jar包可以一起上傳上去。因為sdk內建的這些jar包,伺服器已經為你準備好這些了。

否則很多巨大的jar包上傳可能會失敗,出現什麼--enable-jar-splitting的提示。

注意:gae內建的demos裡面的那些例子,也就guestbook添加了輔助的jar包,所以用dev_appserver -p 8888 war可以測試,其他的例子好像都不能運行,起碼我實驗的幾個是不行的。

OK, 頁面出來了。

改個簡單的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="com.google.appengine.api.datastore.DatastoreServiceFactory" %><%@ page import="com.google.appengine.api.datastore.DatastoreService" %><%@ page import="com.google.appengine.api.datastore.Query" %><%@ page import="com.google.appengine.api.datastore.Entity" %><%@ page import="com.google.appengine.api.datastore.FetchOptions" %><%@ page import="com.google.appengine.api.datastore.Key" %><%@ page import="com.google.appengine.api.datastore.KeyFactory" %><%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %><html>  <head>    <link type="text/css" rel="stylesheet" href="/stylesheets/main.css" />  </head>  <body>    <form action="/res?write" method="Post">      <div><input type="text" name="guestbookName" value="${fn:escapeXml(guestbookName)}"/></div>      <div><input type="submit" value="Commit" /></div>    </form>  </body></html>

不需要重啟伺服器,jsp檔案可以立即生效的。

這是jetty的可配置選項。

提交一下到servlet,讓java來處理吧。

報錯了,HTTP405, 

原因是,index.jsp是用post方式請求的,但是res.java沒有實現doPost()方法

更有用的來了,開始吧。。。

後端儲存,即“資料庫操作”, 請先複習google的資料存放區策略,google的大資料本身很厲害,有google做我們的後端,可以放心了。

https://developers.google.com/appengine/docs/java/gettingstarted/usingdatastore

建立一個Broker.java

package bagebit;import com.google.appengine.api.datastore.DatastoreService;import com.google.appengine.api.datastore.DatastoreServiceFactory;import com.google.appengine.api.datastore.Entity;import com.google.appengine.api.datastore.Key;import com.google.appengine.api.datastore.KeyFactory;import java.io.IOException;import java.util.logging.Logger;import javax.servlet.http.*;public class Broker extends HttpServlet {    private static final Logger log = Logger.getLogger(Broker.class.getName());    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {log.info("Broker::doGet called at: " + (new java.util.Date()).toString());            resp.setContentType("text/html;charset=UTF-8");            resp.getWriter().println("<b>Hello, " + req.getRequestURI() +"</b>");    }public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {log.info("Res::doPost called at: " + (new java.util.Date()).toString());            resp.setContentType("text/html;charset=UTF-8");            resp.getWriter().println("<b>Hello, " + req.getRequestURI() +"</b>");    }}

修改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>SERVLET_KEY_do</servlet-name>        <servlet-class>bagebit.Broker</servlet-class>    </servlet>    <servlet-mapping>        <servlet-name>SERVLET_KEY_do</servlet-name>        <url-pattern>/do</url-pattern>    </servlet-mapping>    <welcome-file-list>        <welcome-file>index.jsp</welcome-file>    </welcome-file-list></web-app>

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.