

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 部署 Java 應用程式
<a name="layers-java-deploy"></a>

**重要**  
 AWS OpsWorks Stacks 此服務已於 2024 年 5 月 26 日終止，並已針對新客戶和現有客戶停用。我們強烈建議客戶盡快將其工作負載遷移至其他解決方案。如果您對遷移有任何疑問，請透過 [AWS re：Post](https://repost.aws/) 或透過 [AWS Premium Support](https://aws.amazon.com/support) 聯絡 AWS 支援 團隊。

下列主題說明如何將應用程式部署到 Java App Server layer 的執行個體。這些範例是針對 JSP 應用程式，但您可以使用基本上相同的程序，來安裝其他類型的 Java 應用程式。

您可以從任何支援的儲存庫部署 JSP 頁面。如果您想要部署 WAR 檔案，請注意 Stacks OpsWorks 會自動從 Amazon S3 或 HTTP 封存檔擷取部署的 WAR 檔案，但不會從 Git 或 Subversion 儲存庫擷取。如果您想要將 Git 或 Subversion 用於 WAR 檔案，則可以執行下列其中一項：
+ 將擷取的封存檔存放至儲存庫。
+ 將 WAR 檔案存放至儲存庫，並使用 Chef 部署勾點來擷取封存檔，如下列範例所述。

您可以使用 Chef 部署勾點，在四個部署階段中的任何一階段，於執行個體上執行使用者提供的 Ruby 應用程式。應用程式名稱可決定階段。下列範例是名為 `before_migrate.rb` 的 Ruby 應用程式，可擷取已從 Git 或 Subversion 儲存庫所部署的 WAR 檔案。該名稱會建立應用程式與 Checkout 部署勾點的關聯，以在部署操作開始時、檢查程式碼之後但在遷移之前執行。如需如何使用此範例的詳細資訊，請參閱[使用 Chef 部署勾點](workingcookbook-extend-hooks.md)。

```
::Dir.glob(::File.join(release_path, '*.war')) do |archive_file|
  execute "unzip_#{archive_file}" do
    command "unzip #{archive_file}"
    cwd release_path
  end
end
```

**注意**  
在您將更新部署至 JSP 應用程式時，Tomcat 可能會無法識別更新，而繼續執行現有的應用程式版本。舉例來說，這可能會在您將應用程式做為僅包含 JSP 頁面的 .zip 檔案部署時發生。若要確保 Tomcat 執行的是最近部署的版本，專案的根目錄應包括內含 `web.xml` 檔案的 WEB-INF 目錄。`web.xml` 檔案可包含各種內容，但以下內容便足以確保 Tomcat 識別更新及執行目前部署的應用程式版本。您不需要為每次更新變更版本。若版本沒有變更，Tomcat 將會識別更新。  

```
<context-param>
  <param-name>appVersion</param-name>
  <param-value>0.1</param-value>
</context-param>
```

**Topics**
+ [部署 JSP 應用程式](#layers-java-deploy-jsp)
+ [使用後端資料庫部署 JSP 應用程式](#layers-java-deploy-jsp-db)

## 部署 JSP 應用程式
<a name="layers-java-deploy-jsp"></a>

若要部署 JSP 應用程式，請指定名稱和儲存庫資訊。您也可以選擇指定網域和 SSL 設定。如需如何建立應用程式的詳細資訊，請參閱[新增應用程式](workingapps-creating.md)。下列程序說明如何從公有 Amazon S3 封存建立和部署簡單的 JSP 頁面。如需如何使用其他儲存庫類型的資訊，包括私有 Amazon S3 封存，請參閱 [應用程式來源](workingapps-creating.md#workingapps-creating-source)。

下列範例所顯示的 JSP 頁面只會顯示一些系統資訊。

```
<%@ page import="java.net.InetAddress" %>
<html>
<body>
<%
    java.util.Date date = new java.util.Date();
    InetAddress inetAddress = InetAddress.getLocalHost();
%>
The time is 
<%
    out.println( date );
    out.println("<br>Your server's hostname is "+inetAddress.getHostName());
%>
<br>
</body>
</html>
```

**注意**  
下列程序假設您已熟悉建立堆疊、將執行個體新增至 layer 等等的基本知識。如果您是初次使用 OpsWorks Stacks，您應該會先看到 [Chef 11 Linux 堆疊入門](gettingstarted.md)。

**從 Amazon S3 封存檔部署 JSP 頁面**

1. 使用 Java App Server layer [建立堆疊](workingstacks-creating.md)，將[全年無休執行個體新增至](workinginstances-add.md) layer，然後[啟動它](workinginstances-starting.md)。

1. 將程式碼複製至名為 `simplejsp.jsp` 的檔案，並將檔案放入名為 `simplejsp` 的資料夾中，然後建立資料夾的 `.zip` 封存檔。名稱可以是任意名稱；您可以使用您想要的任何檔案或資料夾名稱。您也可以使用其他類型的封存檔，包括 gzip、bzip2、tarball 或 Java WAR 檔案。請注意， OpsWorks Stacks 不支援未壓縮的 tarball。若要部署多個 JSP 頁面，請將它們包括在相同的封存檔中。

1. 將封存上傳到 Amazon S3 儲存貯體並將檔案設為公有。複製檔案的 URL，供日後使用。如需如何建立儲存貯體以及上傳檔案的詳細資訊，請參閱[開始使用 Amazon Simple Storage Service](https://docs.aws.amazon.com/AmazonS3/latest/gsg/GetStartedWithS3.html)。

1. [新增應用程式](workingapps-creating.md#workingapps-creating-general)至堆疊，然後指定下列設定：
   + **名稱** – `SimpleJSP`
   + **App type (應用程式類型)** – `Java`
   + **Repository type (儲存庫類型)** – `Http Archive`
   + **儲存庫 URL** – 封存檔案的 Amazon S3 URL。

   針對剩餘設定使用預設值，然後按一下 **Add App (新增應用程式)** 以建立應用程式。

1. [將應用程式部署](workingapps-deploying.md)到 Java App Server 執行個體。

您現在可以前往應用程式的 URL，以及檢視應用程式。如果您尚未指定網域，則可以使用執行個體的公有 IP 地址或其公有 DNS 名稱來建構 URL。若要取得執行個體的公有 IP 地址或公有 DNS 名稱，請前往 OpsWorks Stacks 主控台，然後按一下執行個體頁面上**的執行個體**名稱以開啟其詳細資訊頁面。

其餘 URL 取決於應用程式的簡短名稱，這是 OpsWorks Stacks 從您在建立應用程式時指定的應用程式名稱產生的小寫名稱。例如，SimpleJSP 的簡短名稱是 simplejsp。您可以從其詳細資訊頁面中取得應用程式的簡短名稱。
+ 如果簡短名稱是 `root`，則您可以使用 `http://public_DNS/appname.jsp` 或 `http://public_IP/appname.jsp`。
+ 否則，您可以使用 `http://public_DNS/app_shortname/appname.jsp` 或 `http://public_IP/app_shortname/appname.jsp`。

如果您已指定應用程式的網域，則 URL 為 `http://domain/appname.jsp`。

此範例的 URL 會類似 `http://192.0.2.0/simplejsp/simplejsp.jsp`。

如果您想要將多個應用程式部署至相同的執行個體，則不應該使用 `root` 做為簡短名稱。這可能會導致 URL 衝突，進而防止應用程式正常運作。相反地，請將不同的網域名稱指派給每個應用程式。

## 使用後端資料庫部署 JSP 應用程式
<a name="layers-java-deploy-jsp-db"></a>

JSP 頁面可以使用 JDBC `DataSource` 物件以連線至後端資料庫。您可以使用上節中的程序來建立和部署這類應用程式，而且只要再一個額外的步驟就可以設定連線。

下列 JSP 頁面顯示如何連線至 `DataSource` 物件。

```
<html>
  <head>
    <title>DB Access</title>
  </head>
  <body>
    <%@ page language="java" import="java.sql.*,javax.naming.*,javax.sql.*" %>
    <%
      StringBuffer output = new StringBuffer();
      DataSource ds = null;
      Connection con = null;
      Statement stmt = null;
      ResultSet rs = null;
      try {
        Context initCtx = new InitialContext();
        ds = (DataSource) initCtx.lookup("java:comp/env/jdbc/mydb");
        con = ds.getConnection();
        output.append("Databases found:<br>");
        stmt = con.createStatement();
        rs = stmt.executeQuery("show databases");
        while (rs.next()) {
          output.append(rs.getString(1));
          output.append("<br>");
        }
      }
      catch (Exception e) {
        output.append("Exception: ");
        output.append(e.getMessage());
        output.append("<br>");
      }
      finally {
        try {
          if (rs != null) {
            rs.close();
          }
          if (stmt != null) {
            stmt.close();
          }
          if (con != null) {
            con.close();
          }
        }
        catch (Exception e) {
          output.append("Exception (during close of connection): ");
          output.append(e.getMessage());
          output.append("<br>");
        }
      }
    %>
    <%= output.toString() %>
  </body>
</html>
```

OpsWorks Stacks 會建立和初始化`DataSource`物件、將其繫結至邏輯名稱，並使用 Java 命名和目錄界面 (JNDI) 命名服務註冊名稱。完整的邏輯名稱為 `java:comp/env/user-assigned-name`。您必須指定名稱中由使用者指派的部分，方法是將自訂 JSON 屬性新增至堆疊組態和部署屬性來定義 `['opsworks_java']['datasources']` 屬性，如下所述。

**部署連線至 MySQL 資料庫的 JSP 頁面**

1. 使用 Java App Server layer [建立堆疊](workingstacks-creating.md)，將[全年無休的執行個體新增至](workinginstances-add.md)每個 layer，然後[啟動它](workinginstances-starting.md)。

1. 將資料庫 layer 新增至堆疊。詳細資訊取決於您使用的資料庫。

   若要使用 MySQL 執行個體做為範例，請將 [ MySQL layer 新增至](workinglayers-db-mysql.md)堆疊，將[全年無休的執行個體新增至](workinginstances-add.md) layer，然後[啟動它](workinginstances-starting.md#workinginstances-starting-start)。

   若要使用 Amazon RDS (MySQL) 執行個體做為範例：
   + 指定執行個體的 MySQL 資料庫引擎。
   + 將 **AWS-OpsWorks-DB-Master-Server (*security\$1group\$1id*)** 和 **AWS-OpsWorks-Java-App-Server (*security\$1group\$1id*)** 安全群組指派給執行個體。當您在區域中建立第一個堆疊時， OpsWorks Stacks 會為您建立這些安全群組。
   + 建立名為 `simplejspdb` 的資料庫。
   + 確定主要使用者名稱和密碼未包含可能會導致 Tomcat 錯誤的 `&` 或其他字元。

     具體而言，在啟動期間，Tomcat 必須剖析 Web 應用程式內容檔案，而此檔案是一種 XML 檔案，其中包括主要密碼和使用者名稱。如果任一字串包括 `&` 字元，則 XML 剖析器會將它視為格式異常的 XML 實體，並拋出剖析例外狀況，以防止啟動 Tomcat。如需 Web 應用程式內容檔案的詳細資訊，請參閱[tomcat::context](create-custom-configure.md#create-custom-configure-context)。
   + 將[ MySQL 驅動程式](workingapps-connectdb.md)新增至 Java App Server layer。
   + 向堆疊[註冊 RDS 執行個體](workinglayers-db-rds.md#workinglayers-db-rds-register)。

   如需如何搭配 Stacks 使用 Amazon RDS OpsWorks 執行個體的詳細資訊，請參閱 [Amazon RDS 服務層](workinglayers-db-rds.md)。

1. 將範例程式碼複製至名為 `simplejspdb.jsp` 的檔案，並將檔案放入名為 `simplejspdb` 的資料夾中，然後建立資料夾的 `.zip` 封存檔。名稱可以是任意名稱；您可以使用您想要的任何檔案或資料夾名稱。您也可以使用其他類型的封存檔，包括 gzip、bzip2 或 tarball。若要部署多個 JSP 頁面，請將它們包括在相同的封存檔中。如需如何從其他儲存庫類型部署應用程式的資訊，請參閱[應用程式來源](workingapps-creating.md#workingapps-creating-source)。

1. 將封存上傳到 Amazon S3 儲存貯體並將檔案設為公有。複製檔案的 URL，供日後使用。如需如何建立儲存貯體以及上傳檔案的詳細資訊，請參閱[開始使用 Amazon Simple Storage Service](https://docs.aws.amazon.com/AmazonS3/latest/gsg/GetStartedWithS3.html)。

1. [新增應用程式](workingapps-creating.md#workingapps-creating-general)至堆疊，然後指定下列設定：
   + **名稱** – `SimpleJSPDB`
   + **App type (應用程式類型)** – `Java`
   + **資料來源類型** – **OpsWorks** （適用於 MySQL 執行個體） 或 **RDS** （適用於 Amazon RDS 執行個體）。
   + **資料庫執行個體** – 您先前建立的 MySQL 執行個體，通常名為 **db-master1(mysql)**，或名為 ***DB\$1instance\$1name* (mysql)** 的 Amazon RDS 執行個體。
   + **Database name (資料庫名稱)** – `simplejspdb`。
   + **Repository type (儲存庫類型)** – `Http Archive`
   + **儲存庫 URL** – 封存檔案的 Amazon S3 URL。

   針對剩餘設定使用預設值，然後按一下 **Add App (新增應用程式)** 以建立應用程式。

1. 將下列自訂 JSON 屬性新增至堆疊組態屬性，其中 simplejspdb 是應用程式的簡短名稱。

   ```
   {
     "opsworks_java": {
       "datasources": {
         "simplejspdb": "jdbc/mydb" 
       }
     }
   }
   ```

   OpsWorks Stacks 使用此映射來產生具有必要資料庫資訊的內容檔案。

   如需如何將自訂 JSON 屬性新增至堆疊組態屬性的詳細資訊，請參閱[使用自訂 JSON](workingstacks-json.md)。

1. [將應用程式部署](workingapps-deploying.md)至 Java App Server 執行個體。

您現在可以使用應用程式的 URL 來檢視應用程式。如需如何建構 URL 的描述，請參閱[部署 JSP 應用程式](#layers-java-deploy-jsp)。

此範例的 URL 會類似 `http://192.0.2.0/simplejspdb/simplejspdb.jsp`。

**注意**  
`datasources` 屬性可以包含多個屬性。每個屬性的名稱都會有應用程式簡短名稱，並設定為邏輯名稱中由使用者指派的適當部分。如果您有多個應用程式，則可以使用不同的邏輯名稱，這需要與下面類似的自訂 JSON。  

```
{
  "opsworks_java": {
    "datasources": {
      "myjavaapp": "jdbc/myappdb",
      "simplejsp": "jdbc/myjspdb",
      ...
    }
  }
}
```