Creare un'applicazione Web Java con Azure Cosmos DB e l'API di DocumentDBBuild a Java web application using Azure Cosmos DB and the DocumentDB API

Questa esercitazione sull'applicazione Web Java illustra come usare il servizio Microsoft Azure Cosmos DB per archiviare i dati e accedervi da un'applicazione Java ospitata in app Web del servizio app di Azure.This Java web application tutorial shows you how to use the Microsoft Azure Cosmos DB service to store and access data from a Java application hosted on Azure App Service Web Apps. In questo argomento, si apprenderà:In this topic, you will learn:

  • Come creare un'applicazione JavaServer Pages (JSP) di base in Eclipse.How to build a basic JavaServer Pages (JSP) application in Eclipse.
  • Come usare il servizio Azure Cosmos DB tramite Azure Cosmos DB Java SDK.How to work with the Azure Cosmos DB service using the Azure Cosmos DB Java SDK.

Questa esercitazione illustra come creare un'applicazione di gestione delle attività basata su Web che consente di creare, recuperare e contrassegnare le attività come completate, come illustrato nella figura seguente.This Java application tutorial shows you how to create a web-based task-management application that enables you to create, retrieve, and mark tasks as complete, as shown in the following image. Tutte le attività nell'elenco attività vengono memorizzate come documenti JSON in Azure Cosmos DB.Each of the tasks in the ToDo list are stored as JSON documents in Azure Cosmos DB.

Applicazione Java My ToDo List

Suggerimento

Questa esercitazione sullo sviluppo dell’applicazione presuppone che l'utente abbia già acquisito familiarità con l'uso di Java.This application development tutorial assumes that you have prior experience using Java. Se non si ha alcuna esperienza riguardo a Java o agli strumenti richiesti come prerequisiti, è consigliabile scaricare il progetto todo completo da GitHub e creare l'applicazione usando le istruzioni alla fine di questo articolo.If you are new to Java or the prerequisite tools, we recommend downloading the complete todo project from GitHub and building it using the instructions at the end of this article. Una volta creata la soluzione, è possibile leggere l'articolo per approfondire il codice nel contesto del progetto.Once you have it built, you can review the article to gain insight on the code in the context of the project.

Prerequisiti per questa esercitazione sull'applicazione Web JavaPrerequisites for this Java web application tutorial

Prima di iniziare questa esercitazione sullo sviluppo dell’applicazione, è necessario disporre di quanto segue:Before you begin this application development tutorial, you must have the following:

Se questi strumenti vengono installati per la prima volta, coreservlets.com fornisce una procedura dettagliata del processo di installazione nella sezione introduttiva dell'articolo relativo all' esercitazione sull'installazione di TomCat7 e il relativo uso con Eclipse .If you're installing these tools for the first time, coreservlets.com provides a walk-through of the installation process in the Quick Start section of their Tutorial: Installing TomCat7 and Using it with Eclipse article.

Passaggio 1: Creare un account di Azure Cosmos DBStep 1: Create an Azure Cosmos DB account

Creare prima di tutto un account Azure Cosmos DB.Let's start by creating an Azure Cosmos DB account. Se si ha già un account o si usa l'emulatore Azure Cosmos DB per questa esercitazione, è possibile proseguire con il Passaggio 2: Creare l'applicazione Java JSP.If you already have an account or if you are using the Azure Cosmos DB Emulator for this tutorial, you can skip to Step 2: Create the Java JSP application.

  1. In una nuova finestra del browser accedere al portale di Azure.In a new browser window, sign in to the Azure portal.
  2. Fare clic su Nuovo > Database > Azure Cosmos DB.Click New > Databases > Azure Cosmos DB.

    Riquadro Database nel portale di Azure

  3. Nella pagina Nuovo account immettere le impostazioni per il nuovo account Azure Cosmos DB.In the New account page, enter the settings for the new Azure Cosmos DB account.

    ImpostazioneSetting Valore consigliatoSuggested value DescrizioneDescription
    IDID Immettere un nome univocoEnter a unique name Immettere un nome univoco per identificare l'account Azure Cosmos DB.Enter a unique name to identify this Azure Cosmos DB account. Poiché alI'ID fornito viene aggiunto documents.azure.com per creare l'URI, usare un ID univoco ma facilmente identificabile.Because documents.azure.com is appended to the ID that you provide to create your URI, use a unique but identifiable ID.

    L'ID può contenere solo lettere minuscole, numeri e il segno meno (-) e deve avere una lunghezza compresa tra 3 e 50 caratteri.The ID can contain only lowercase letters, numbers, and the hyphen (-) character, and it must contain 3 to 50 characters.
    APIAPI SQLSQL L'API determina il tipo di account da creare.The API determines the type of account to create. Azure Cosmos DB offre cinque API per soddisfare le esigenze dell'applicazione, ovvero SQL (database di documenti) Gremlin (grafo), MongoDB, SQL (database di documenti), Tabella di Azure e Cassandra, per ognuna delle quali è attualmente necessario un account separato.Azure Cosmos DB provides five APIs to suits the needs of your application: SQL (document database), Gremlin (graph database), MongoDB (document database), Azure Table, and Cassandra, each which currently require a separate account.

    Selezionare SQL perché in questo avvio rapido si sta creando un database di documenti su cui è possibile eseguire query tramite la sintassi SQL e a cui è possibile accedere tramite l'API DocumentDB.Select SQL because in this quickstart you are creating a document database that is queryable using SQL syntax and accessible with the DocumentDB API.

    Altre informazioni sull'API di DocumentDBLearn more about the DocumentDB API
    SottoscrizioneSubscription Sottoscrizione in usoYour subscription Selezionare la sottoscrizione di Azure da usare per l'account Azure Cosmos DB.Select Azure subscription that you want to use for this Azure Cosmos DB account.
    Gruppo di risorseResource Group Creare un nuovo gruppo di risorseCreate new

    Immettere quindi lo stesso nome univoco specificato sopra in IDThen enter the same unique name as provided above in ID
    Selezionare Crea nuovo, quindi immettere il nome di un nuovo gruppo di risorse per l'account.Select Create New, then enter a new resource-group name for your account. Per semplicità si può usare lo stesso nome usato come ID.For simplicity, you can use the same name as your ID.
    PercorsoLocation Selezionare l'area più vicina agli utentiSelect the region closest to your users Selezionare la posizione geografica in cui ospitare l'account Azure Cosmos DB.Select geographic location in which to host your Azure Cosmos DB account. Usare la località più vicina agli utenti per offrire loro la massima velocità di accesso ai dati.Use the location that's closest to your users to give them the fastest access to the data.
    Abilita ridondanza geograficaEnable geo-redundancy Lasciare vuotoLeave blank Consente di creare una versione replicata del database in una seconda area abbinata.This creates a replicated version of your database in a second (paired) region. Lasciare vuoto.Leave this blank.
    Aggiungi al dashboardPin to dashboard SelezionareSelect Selezionare questa casella per aggiungere il nuovo account di database al dashboard del portale e accedervi più facilmente.Select this box so that your new database account is added to your portal dashboard for easy access.

    Fare quindi clic su Crea.Then click Create.

    Pannello Nuovo account per Azure Cosmos DB

  4. La creazione dell'account richiede alcuni minuti,The account creation takes a few minutes. Durante la creazione dell'account il portale visualizza il riquadro Deploying Azure Cosmos DB (Distribuzione di Azure Cosmos DB) a destra, quindi potrebbe essere necessario scorrere a destra del dashboard per visualizzare il riquadro.During account creation the portal displays the Deploying Azure Cosmos DB tile on the right side, you may need to scroll right on your dashboard to see the tile. È presente anche un indicatore di stato nella parte superiore della schermata.There is also a progress bar displayed near the top of the screen. È possibile esaminare lo stato di avanzamento nelle due aree.You can watch either area for progress.

    Riquadro Notifiche del portale di Azure

    Al termine della creazione dell'account verrà visualizzata la pagina L'account Azure Cosmos DB è stato creato.Once the account is created, the Congratulations! Your Azure Cosmos DB account was created page is displayed.

Passare ora al pannello dell'account Cosmos DB e fare clic su Chiavi, perché questi valori verranno usati nell'applicazione Web che verrà creata successivamente.Now navigate to the Cosmos DB account blade, and click Keys, as we use these values in the web application we create next.

Screenshot del portale di Azure, che mostra un account Cosmos DB, con il pulsante Chiavi evidenziato nel pannello dell'account Cosmos DB e i valori di URI, CHIAVE PRIMARIA e CHIAVE SECONDARIA evidenziati nel pannello Chiavi

Passaggio 2: Creare l'applicazione Java JSPStep 2: Create the Java JSP application

Per creare l'applicazione JSP:To create the JSP application:

  1. Iniziare innanzitutto con la creazione di un progetto Java.First, we’ll start off by creating a Java project. Avviare Eclipse, quindi fare clic su File, New (Nuovo) e quindi su Dynamic Web Project (Progetto Web dinamico).Start Eclipse, then click File, click New, and then click Dynamic Web Project. Se Dynamic Web Project (Progetto Web dinamico) non è presente nell'elenco dei progetti disponibili, seguire questa procedura: fare clic su File, su New (Nuovo) e su Project (Progetto), espandere Web, fare clic su Dynamic Web Project (Progetto Web dinamico), quindi selezionare Next (Avanti).If you don’t see Dynamic Web Project listed as an available project, do the following: click File, click New, click Project…, expand Web, click Dynamic Web Project, and click Next.

    Sviluppo di applicazioni Java JSP

  2. Immettere un nome di progetto nella casella Project name (Nome progetto) e dal menu a discesa Target Runtime (Runtime di destinazione) selezionare facoltativamente un valore, ad esempio Apache Tomcat v7.0, e quindi fare clic su Finish (Fine).Enter a project name in the Project name box, and in the Target Runtime drop-down menu, optionally select a value (e.g. Apache Tomcat v7.0), and then click Finish. Se si seleziona un runtime di destinazione, sarà possibile eseguire il progetto in locale tramite Eclipse.Selecting a target runtime enables you to run your project locally through Eclipse.
  3. Nella vista Project Explorer di Eclipse espandere il progetto.In Eclipse, in the Project Explorer view, expand your project. Fare clic con il pulsante destro del mouse su WebContent, scegliere New e quindi fare clic su JSP File.Right-click WebContent, click New, and then click JSP File.
  4. Nella finestra di dialogo New JSP File (Nuovo file JSP) assegnare al file il nome index.jsp.In the New JSP File dialog box, name the file index.jsp. Mantenere il nome WebContent per la cartella padre, come illustrato di seguito, e quindi fare clic su Next (Avanti).Keep the parent folder as WebContent, as shown in the following illustration, and then click Next.

    Esercitazione sull’applicazione web Java - Creare un nuovo File JSP

  5. Per le finalità di questa esercitazione, nella finestra di dialogo Select JSP Template (Seleziona modello JSP) selezionare New JSP File (html) (Nuovo file JSP - html), quindi fare clic su Finish (Fine).In the Select JSP Template dialog box, for the purpose of this tutorial select New JSP File (html), and then click Finish.
  6. Quando in Eclipse viene aperto il file index.jsp, aggiungere il testo in modo da visualizzare Hello World!When the index.jsp file opens in Eclipse, add text to display Hello World! all'interno dell'elemento esistente.within the existing element. Il contenuto aggiornato dovrebbe avere un aspetto analogo al seguente:Your updated content should look like the following code:

     <body>
         <% out.println("Hello World!"); %>
     </body>
    
  7. Salvare il file index.jsp.Save the index.jsp file.
  8. Se nel passaggio 2 è stato impostato un runtime di destinazione, è possibile fare clic su Project (Progetto), quindi su Run (Esegui) per eseguire l'applicazione JSP in locale:If you set a target runtime in step 2, you can click Project and then Run to run your JSP application locally:

    Esercitazione sull’applicazione Java - Hello World

Passaggio 3: Installazione di DocumentDB Java SDKStep 3: Install the DocumentDB Java SDK

Il modo più semplice per inserire DocumentDB Java SDK e le relative dipendenze è tramite Apache Maven.The easiest way to pull in the DocumentDB Java SDK and its dependencies is through Apache Maven.

A tale scopo, sarà necessario convertire il progetto in un progetto Maven completando i passaggi seguenti:To do this, you will need to convert your project to a maven project by completing the following steps:

  1. Fare clic con il pulsante destro del mouse sul progetto in Project Explorer (Esplora progetti), scegliere Configure (Configura) e quindi fare clic su Convert to Maven Project (Converti in progetto Maven).Right-click your project in the Project Explorer, click Configure, click Convert to Maven Project.
  2. Nella finestra Create new POM (Crea nuovo POM) accettare le impostazioni predefinite e fare clic su Finish (Fine).In the Create new POM window, accept the defaults and click Finish.
  3. In Project Explorer, aprire il file pom.xml.In Project Explorer, open the pom.xml file.
  4. Nel riquadro Dependencies (Dipendenze) della scheda Dependencies (Dipendenze), fare clic su Add (Aggiungi).On the Dependencies tab, in the Dependencies pane, click Add.
  5. Nella finestra Select Dependency (Seleziona dipendenza) eseguire le operazioni seguenti:In the Select Dependency window, do the following:

    • Nella casella Group Id immettere com.microsoft.azure.In the Group Id box, enter com.microsoft.azure.
    • Nella casella Artifact Id immettere azure-documentdb.In the Artifact Id box, enter azure-documentdb.
    • Nella casella Version immettere 1.5.1.In the Version box, enter 1.5.1.

    Installare l'SDK dell’applicazione Java di DocumentDB

    • Oppure aggiungere l'XML della dipendenza per Group Id e Artifact Id direttamente nel file pom.xml mediante un editor di testo:Or add the dependency XML for Group Id and Artifact Id directly to the pom.xml via a text editor:

      com.microsoft.azure azure-documentdb 1.9.1 com.microsoft.azure azure-documentdb 1.9.1

  6. Fare clic su OK e Maven installerà DocumentDB Java SDK.Click OK and Maven will install the DocumentDB Java SDK.
  7. Salvare il file pom.xml.Save the pom.xml file.

Passaggio 4: Uso del servizio Azure Cosmos DB in un'applicazione JavaStep 4: Using the Azure Cosmos DB service in a Java application

  1. Definire innanzitutto l'oggetto TodoItem in TodoItem.java:First, let's define the TodoItem object in TodoItem.java:

     @Data
     @Builder
     public class TodoItem {
         private String category;
         private boolean complete;
         private String id;
         private String name;
     }
    

    In questo progetto viene usato Project Lombok per generare il costruttore, getter, setter e un generatore.In this project, we are using Project Lombok to generate the constructor, getters, setters, and a builder. In alternativa, è possibile scrivere il codice manualmente o farlo generare da IDE.Alternatively, you can write this code manually or have the IDE generate it.

  2. Per richiamare il servizio Azure Cosmos DB, è necessario creare un'istanza di un nuovo client DocumentClient.To invoke the Azure Cosmos DB service, you must instantiate a new DocumentClient. È in genere preferibile riutilizzare il client DocumentClient anziché creare un nuovo client per ogni richiesta successiva.In general, it is best to reuse the DocumentClient - rather than construct a new client for each subsequent request. È possibile riutilizzare il client eseguendo il wrapping del client in una factory DocumentClientFactory.We can reuse the client by wrapping the client in a DocumentClientFactory. In DocumentClientFactory.java è necessario incollare i valori URI e CHIAVE PRIMARIA salvati negli Appunti al passaggio 1.In DocumentClientFactory.java, you need to paste the URI and PRIMARY KEY value you saved to your clipboard in step 1. Sostituire [YOUR_ENDPOINT_HERE] con l'URI e sostituire [YOUR_KEY_HERE] con la CHIAVE PRIMARIA.Replace [YOUR_ENDPOINT_HERE] with your URI and replace [YOUR_KEY_HERE] with your PRIMARY KEY.

     private static final String HOST = "[YOUR_ENDPOINT_HERE]";
     private static final String MASTER_KEY = "[YOUR_KEY_HERE]";
    
     private static DocumentClient documentClient = new DocumentClient(HOST, MASTER_KEY,
                     ConnectionPolicy.GetDefault(), ConsistencyLevel.Session);
    
     public static DocumentClient getDocumentClient() {
         return documentClient;
     }
    
  3. Creare a questo punto un oggetto DAO (Data Access Object) per astrarre in modo permanente gli elementi ToDo in Azure Cosmos DB.Now let's create a Data Access Object (DAO) to abstract persisting our ToDo items to Azure Cosmos DB.

    Per salvare gli elementi ToDo in una raccolta, il client deve conoscere i database e le raccolte da rendere permanenti (in base al riferimento dei collegamenti automatici).In order to save ToDo items to a collection, the client needs to know which database and collection to persist to (as referenced by self-links). È in genere preferibile memorizzare nella cache database e raccolte appena possibile, in modo da evitare episodi di round trip del database.In general, it is best to cache the database and collection when possible to avoid additional round-trips to the database.

    Il codice seguente illustra come recuperare il database e la raccolta, se esistenti, o crearne di nuovi se non esistenti:The following code illustrates how to retrieve our database and collection, if it exists, or create a new one if it doesn't exist:

     public class DocDbDao implements TodoDao {
         // The name of our database.
         private static final String DATABASE_ID = "TodoDB";
    
         // The name of our collection.
         private static final String COLLECTION_ID = "TodoCollection";
    
         // The Azure Cosmos DB Client
         private static DocumentClient documentClient = DocumentClientFactory
                 .getDocumentClient();
    
         // Cache for the database object, so we don't have to query for it to
         // retrieve self links.
         private static Database databaseCache;
    
         // Cache for the collection object, so we don't have to query for it to
         // retrieve self links.
         private static DocumentCollection collectionCache;
    
         private Database getTodoDatabase() {
             if (databaseCache == null) {
                 // Get the database if it exists
                 List<Database> databaseList = documentClient
                         .queryDatabases(
                                 "SELECT * FROM root r WHERE r.id='" + DATABASE_ID
                                         + "'", null).getQueryIterable().toList();
    
                 if (databaseList.size() > 0) {
                     // Cache the database object so we won't have to query for it
                     // later to retrieve the selfLink.
                     databaseCache = databaseList.get(0);
                 } else {
                     // Create the database if it doesn't exist.
                     try {
                         Database databaseDefinition = new Database();
                         databaseDefinition.setId(DATABASE_ID);
    
                         databaseCache = documentClient.createDatabase(
                                 databaseDefinition, null).getResource();
                     } catch (DocumentClientException e) {
                         // TODO: Something has gone terribly wrong - the app wasn't
                         // able to query or create the collection.
                         // Verify your connection, endpoint, and key.
                         e.printStackTrace();
                     }
                 }
             }
    
             return databaseCache;
         }
    
         private DocumentCollection getTodoCollection() {
             if (collectionCache == null) {
                 // Get the collection if it exists.
                 List<DocumentCollection> collectionList = documentClient
                         .queryCollections(
                                 getTodoDatabase().getSelfLink(),
                                 "SELECT * FROM root r WHERE r.id='" + COLLECTION_ID
                                         + "'", null).getQueryIterable().toList();
    
                 if (collectionList.size() > 0) {
                     // Cache the collection object so we won't have to query for it
                     // later to retrieve the selfLink.
                     collectionCache = collectionList.get(0);
                 } else {
                     // Create the collection if it doesn't exist.
                     try {
                         DocumentCollection collectionDefinition = new DocumentCollection();
                         collectionDefinition.setId(COLLECTION_ID);
    
                         collectionCache = documentClient.createCollection(
                                 getTodoDatabase().getSelfLink(),
                                 collectionDefinition, null).getResource();
                     } catch (DocumentClientException e) {
                         // TODO: Something has gone terribly wrong - the app wasn't
                         // able to query or create the collection.
                         // Verify your connection, endpoint, and key.
                         e.printStackTrace();
                     }
                 }
             }
    
             return collectionCache;
         }
     }
    
  4. Il passaggio successivo consiste nella scrittura di codice per rendere permanenti gli elementi TodoItems nella raccolta.The next step is to write some code to persist the TodoItems in to the collection. In questo esempio verrà usato Gson per serializzare e deserializzare gli oggetti POJO (Plain Old Java Object) dell'elemento TodoItem nei documenti JSON.In this example, we will use Gson to serialize and de-serialize TodoItem Plain Old Java Objects (POJOs) to JSON documents.

     // We'll use Gson for POJO <=> JSON serialization for this example.
     private static Gson gson = new Gson();
    
     @Override
     public TodoItem createTodoItem(TodoItem todoItem) {
         // Serialize the TodoItem as a JSON Document.
         Document todoItemDocument = new Document(gson.toJson(todoItem));
    
         // Annotate the document as a TodoItem for retrieval (so that we can
         // store multiple entity types in the collection).
         todoItemDocument.set("entityType", "todoItem");
    
         try {
             // Persist the document using the DocumentClient.
             todoItemDocument = documentClient.createDocument(
                     getTodoCollection().getSelfLink(), todoItemDocument, null,
                     false).getResource();
         } catch (DocumentClientException e) {
             e.printStackTrace();
             return null;
         }
    
         return gson.fromJson(todoItemDocument.toString(), TodoItem.class);
     }
    
  5. Come nel caso dei database e delle raccolte di Azure Cosmos DB, anche per fare riferimento ai documenti vengono usati collegamenti automatici.Like Azure Cosmos DB databases and collections, documents are also referenced by self-links. La funzione di supporto seguente consente di recuperare documenti da un altro attributo, ad esempio "ID", piuttosto che da un collegamento automatico:The following helper function lets us retrieve documents by another attribute (e.g. "id") rather than self-link:

     private Document getDocumentById(String id) {
         // Retrieve the document using the DocumentClient.
         List<Document> documentList = documentClient
                 .queryDocuments(getTodoCollection().getSelfLink(),
                         "SELECT * FROM root r WHERE r.id='" + id + "'", null)
                 .getQueryIterable().toList();
    
         if (documentList.size() > 0) {
             return documentList.get(0);
         } else {
             return null;
         }
     }
    
  6. Il metodo di supporto al passaggio 5 consente di recuperare un documento JSON dell'elemento TodoItem in base all'ID e di deserializzarlo in un oggetto POJO:We can use the helper method in step 5 to retrieve a TodoItem JSON document by id and then deserialize it to a POJO:

     @Override
     public TodoItem readTodoItem(String id) {
         // Retrieve the document by id using our helper method.
         Document todoItemDocument = getDocumentById(id);
    
         if (todoItemDocument != null) {
             // De-serialize the document in to a TodoItem.
             return gson.fromJson(todoItemDocument.toString(), TodoItem.class);
         } else {
             return null;
         }
     }
    
  7. È inoltre possibile usare il client DocumentClient per ottenere una raccolta o un elenco di elementi TodoItems mediante DocumentDB SQL:We can also use the DocumentClient to get a collection or list of TodoItems using DocumentDB SQL:

     @Override
     public List<TodoItem> readTodoItems() {
         List<TodoItem> todoItems = new ArrayList<TodoItem>();
    
         // Retrieve the TodoItem documents
         List<Document> documentList = documentClient
                 .queryDocuments(getTodoCollection().getSelfLink(),
                         "SELECT * FROM root r WHERE r.entityType = 'todoItem'",
                         null).getQueryIterable().toList();
    
         // De-serialize the documents in to TodoItems.
         for (Document todoItemDocument : documentList) {
             todoItems.add(gson.fromJson(todoItemDocument.toString(),
                     TodoItem.class));
         }
    
         return todoItems;
     }
    
  8. Sono disponibili diversi metodi per aggiornare un documento con il client DocumentClient.There are many ways to update a document with the DocumentClient. Nell'applicazione dell'elenco Todo, può essere utile disporre di un'opzione da attivare o disattivare in caso di completamento di un elemento TodoItem.In our Todo list application, we want to be able to toggle whether a TodoItem is complete. A tale scopo, è necessario aggiornare l'attributo "complete" nel documento:This can be achieved by updating the "complete" attribute within the document:

     @Override
     public TodoItem updateTodoItem(String id, boolean isComplete) {
         // Retrieve the document from the database
         Document todoItemDocument = getDocumentById(id);
    
         // You can update the document as a JSON document directly.
         // For more complex operations - you could de-serialize the document in
         // to a POJO, update the POJO, and then re-serialize the POJO back in to
         // a document.
         todoItemDocument.set("complete", isComplete);
    
         try {
             // Persist/replace the updated document.
             todoItemDocument = documentClient.replaceDocument(todoItemDocument,
                     null).getResource();
         } catch (DocumentClientException e) {
             e.printStackTrace();
             return null;
         }
    
         return gson.fromJson(todoItemDocument.toString(), TodoItem.class);
     }
    
  9. Infine, può essere utile disporre di un'opzione che consenta di eliminare un elemento TodoItem dall'elenco.Finally, we want the ability to delete a TodoItem from our list. A tale scopo, è possibile usare il metodo di supporto scritto in precedenza per recuperare il collegamento automatico e quindi indicare al client di eliminarlo:To do this, we can use the helper method we wrote earlier to retrieve the self-link and then tell the client to delete it:

     @Override
     public boolean deleteTodoItem(String id) {
         // Azure Cosmos DB refers to documents by self link rather than id.
    
         // Query for the document to retrieve the self link.
         Document todoItemDocument = getDocumentById(id);
    
         try {
             // Delete the document by self link.
             documentClient.deleteDocument(todoItemDocument.getSelfLink(), null);
         } catch (DocumentClientException e) {
             e.printStackTrace();
             return false;
         }
    
         return true;
     }
    

Passaggio 5: Collegare il resto del progetto di sviluppo dell'applicazione JavaStep 5: Wiring the rest of the of Java application development project together

Dopo aver completato questi passaggi, è necessario creare un'interfaccia utente intuitiva e collegarla all'oggetto DAO.Now that we've finished the fun bits - all that's left is to build a quick user interface and wire it up to our DAO.

  1. Creare innanzitutto un controller per la chiamata dell'oggetto DAO:First, let's start with building a controller to call our DAO:

     public class TodoItemController {
         public static TodoItemController getInstance() {
             if (todoItemController == null) {
                 todoItemController = new TodoItemController(TodoDaoFactory.getDao());
             }
             return todoItemController;
         }
    
         private static TodoItemController todoItemController;
    
         private final TodoDao todoDao;
    
         TodoItemController(TodoDao todoDao) {
             this.todoDao = todoDao;
         }
    
         public TodoItem createTodoItem(@NonNull String name,
                 @NonNull String category, boolean isComplete) {
             TodoItem todoItem = TodoItem.builder().name(name).category(category)
                     .complete(isComplete).build();
             return todoDao.createTodoItem(todoItem);
         }
    
         public boolean deleteTodoItem(@NonNull String id) {
             return todoDao.deleteTodoItem(id);
         }
    
         public TodoItem getTodoItemById(@NonNull String id) {
             return todoDao.readTodoItem(id);
         }
    
         public List<TodoItem> getTodoItems() {
             return todoDao.readTodoItems();
         }
    
         public TodoItem updateTodoItem(@NonNull String id, boolean isComplete) {
             return todoDao.updateTodoItem(id, isComplete);
         }
     }
    

    In un'applicazione più complessa il controller può ospitare una logica di business articolata nell'oggetto DAO.In a more complex application, the controller may house complicated business logic on top of the DAO.

  2. Creare in seguito un oggetto servlet per l'indirizzamento delle richieste HTTP al controller:Next, we'll create a servlet to route HTTP requests to the controller:

     public class TodoServlet extends HttpServlet {
         // API Keys
         public static final String API_METHOD = "method";
    
         // API Methods
         public static final String CREATE_TODO_ITEM = "createTodoItem";
         public static final String GET_TODO_ITEMS = "getTodoItems";
         public static final String UPDATE_TODO_ITEM = "updateTodoItem";
    
         // API Parameters
         public static final String TODO_ITEM_ID = "todoItemId";
         public static final String TODO_ITEM_NAME = "todoItemName";
         public static final String TODO_ITEM_CATEGORY = "todoItemCategory";
         public static final String TODO_ITEM_COMPLETE = "todoItemComplete";
    
         public static final String MESSAGE_ERROR_INVALID_METHOD = "{'error': 'Invalid method'}";
    
         private static final long serialVersionUID = 1L;
         private static final Gson gson = new Gson();
    
         @Override
         protected void doGet(HttpServletRequest request,
                 HttpServletResponse response) throws ServletException, IOException {
    
             String apiResponse = MESSAGE_ERROR_INVALID_METHOD;
    
             TodoItemController todoItemController = TodoItemController
                     .getInstance();
    
             String id = request.getParameter(TODO_ITEM_ID);
             String name = request.getParameter(TODO_ITEM_NAME);
             String category = request.getParameter(TODO_ITEM_CATEGORY);
             boolean isComplete = StringUtils.equalsIgnoreCase("true",
                     request.getParameter(TODO_ITEM_COMPLETE)) ? true : false;
    
             switch (request.getParameter(API_METHOD)) {
             case CREATE_TODO_ITEM:
                 apiResponse = gson.toJson(todoItemController.createTodoItem(name,
                         category, isComplete));
                 break;
             case GET_TODO_ITEMS:
                 apiResponse = gson.toJson(todoItemController.getTodoItems());
                 break;
             case UPDATE_TODO_ITEM:
                 apiResponse = gson.toJson(todoItemController.updateTodoItem(id,
                         isComplete));
                 break;
             default:
                 break;
             }
    
             response.getWriter().println(apiResponse);
         }
    
         @Override
         protected void doPost(HttpServletRequest request,
                 HttpServletResponse response) throws ServletException, IOException {
             doGet(request, response);
         }
     }
    
  3. Sarà necessaria un'interfaccia utente Web per la visualizzazione dell'utente.We'll need a web user interface to display to the user. A tale scopo, riscrivere il file index.jsp creato in precedenza:Let's re-write the index.jsp we created earlier:

        <html>
        <head>
          <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
          <meta http-equiv="X-UA-Compatible" content="IE=edge;" />
          <title>Azure Cosmos DB Java Sample</title>
    
          <!-- Bootstrap -->
          <link href="//ajax.aspnetcdn.com/ajax/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
    
          <style>
            /* Add padding to body for fixed nav bar */
            body {
              padding-top: 50px;
            }
          </style>
        </head>
        <body>
          <!-- Nav Bar -->
          <div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
            <div class="container">
              <div class="navbar-header">
                <a class="navbar-brand" href="#">My Tasks</a>
              </div>
            </div>
          </div>
    
          <!-- Body -->
          <div class="container">
            <h1>My ToDo List</h1>
    
            <hr/>
    
            <!-- The ToDo List -->
            <div class = "todoList">
              <table class="table table-bordered table-striped" id="todoItems">
                <thead>
                  <tr>
                    <th>Name</th>
                    <th>Category</th>
                    <th>Complete</th>
                  </tr>
                </thead>
                <tbody>
                </tbody>
              </table>
    
              <!-- Update Button -->
              <div class="todoUpdatePanel">
                <form class="form-horizontal" role="form">
                  <button type="button" class="btn btn-primary">Update Tasks</button>
                </form>
              </div>
    
            </div>
    
            <hr/>
    
            <!-- Item Input Form -->
            <div class="todoForm">
              <form class="form-horizontal" role="form">
                <div class="form-group">
                  <label for="inputItemName" class="col-sm-2">Task Name</label>
                  <div class="col-sm-10">
                    <input type="text" class="form-control" id="inputItemName" placeholder="Enter name">
                  </div>
                </div>
    
                <div class="form-group">
                  <label for="inputItemCategory" class="col-sm-2">Task Category</label>
                  <div class="col-sm-10">
                    <input type="text" class="form-control" id="inputItemCategory" placeholder="Enter category">
                  </div>
                </div>
    
                <button type="button" class="btn btn-primary">Add Task</button>
              </form>
            </div>
    
          </div>
    
          <!-- Placed at the end of the document so the pages load faster -->
          <script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.1.min.js"></script>
          <script src="//ajax.aspnetcdn.com/ajax/bootstrap/3.2.0/bootstrap.min.js"></script>
          <script src="assets/todo.js"></script>
        </body>
        </html>
    
  4. Scrivere infine codice JavaScript sul lato client per il collegamento dell'interfaccia utente Web e dell'oggetto servlet:And finally, write some client-side JavaScript to tie the web user interface and the servlet together:

     var todoApp = {
       /*
        * API methods to call Java backend.
        */
       apiEndpoint: "api",
    
       createTodoItem: function(name, category, isComplete) {
         $.post(todoApp.apiEndpoint, {
             "method": "createTodoItem",
             "todoItemName": name,
             "todoItemCategory": category,
             "todoItemComplete": isComplete
           },
           function(data) {
             var todoItem = data;
             todoApp.addTodoItemToTable(todoItem.id, todoItem.name, todoItem.category, todoItem.complete);
           },
           "json");
       },
    
       getTodoItems: function() {
         $.post(todoApp.apiEndpoint, {
             "method": "getTodoItems"
           },
           function(data) {
             var todoItemArr = data;
             $.each(todoItemArr, function(index, value) {
               todoApp.addTodoItemToTable(value.id, value.name, value.category, value.complete);
             });
           },
           "json");
       },
    
       updateTodoItem: function(id, isComplete) {
         $.post(todoApp.apiEndpoint, {
             "method": "updateTodoItem",
             "todoItemId": id,
             "todoItemComplete": isComplete
           },
           function(data) {},
           "json");
       },
    
       /*
        * UI Methods
        */
       addTodoItemToTable: function(id, name, category, isComplete) {
         var rowColor = isComplete ? "active" : "warning";
    
         todoApp.ui_table().append($("<tr>")
           .append($("<td>").text(name))
           .append($("<td>").text(category))
           .append($("<td>")
             .append($("<input>")
               .attr("type", "checkbox")
               .attr("id", id)
               .attr("checked", isComplete)
               .attr("class", "isComplete")
             ))
           .addClass(rowColor)
         );
       },
    
       /*
        * UI Bindings
        */
       bindCreateButton: function() {
         todoApp.ui_createButton().click(function() {
           todoApp.createTodoItem(todoApp.ui_createNameInput().val(), todoApp.ui_createCategoryInput().val(), false);
           todoApp.ui_createNameInput().val("");
           todoApp.ui_createCategoryInput().val("");
         });
       },
    
       bindUpdateButton: function() {
         todoApp.ui_updateButton().click(function() {
           // Disable button temporarily.
           var myButton = $(this);
           var originalText = myButton.text();
           $(this).text("Updating...");
           $(this).prop("disabled", true);
    
           // Call api to update todo items.
           $.each(todoApp.ui_updateId(), function(index, value) {
             todoApp.updateTodoItem(value.name, value.value);
             $(value).remove();
           });
    
           // Re-enable button.
           setTimeout(function() {
             myButton.prop("disabled", false);
             myButton.text(originalText);
           }, 500);
         });
       },
    
       bindUpdateCheckboxes: function() {
         todoApp.ui_table().on("click", ".isComplete", function(event) {
           var checkboxElement = $(event.currentTarget);
           var rowElement = $(event.currentTarget).parents('tr');
           var id = checkboxElement.attr('id');
           var isComplete = checkboxElement.is(':checked');
    
           // Toggle table row color
           if (isComplete) {
             rowElement.addClass("active");
             rowElement.removeClass("warning");
           } else {
             rowElement.removeClass("active");
             rowElement.addClass("warning");
           }
    
           // Update hidden inputs for update panel.
           todoApp.ui_updateForm().children("input[name='" + id + "']").remove();
    
           todoApp.ui_updateForm().append($("<input>")
             .attr("type", "hidden")
             .attr("class", "updateComplete")
             .attr("name", id)
             .attr("value", isComplete));
    
         });
       },
    
       /*
        * UI Elements
        */
       ui_createNameInput: function() {
         return $(".todoForm #inputItemName");
       },
    
       ui_createCategoryInput: function() {
         return $(".todoForm #inputItemCategory");
       },
    
       ui_createButton: function() {
         return $(".todoForm button");
       },
    
       ui_table: function() {
         return $(".todoList table tbody");
       },
    
       ui_updateButton: function() {
         return $(".todoUpdatePanel button");
       },
    
       ui_updateForm: function() {
         return $(".todoUpdatePanel form");
       },
    
       ui_updateId: function() {
         return $(".todoUpdatePanel .updateComplete");
       },
    
       /*
        * Install the TodoApp
        */
       install: function() {
         todoApp.bindCreateButton();
         todoApp.bindUpdateButton();
         todoApp.bindUpdateCheckboxes();
    
         todoApp.getTodoItems();
       }
     };
    
     $(document).ready(function() {
       todoApp.install();
     });
    
  5. A questo punto,Awesome! è necessario testare l'applicazione.Now all that's left is to test the application. Eseguire l'applicazione in locale e aggiungere alcuni elementi Todo specificando i valori relativi al nome e alla categoria dell'elemento e selezionando Add Task (Aggiungi attività).Run the application locally, and add some Todo items by filling in the item name and category and clicking Add Task.
  6. Quando l'elemento viene visualizzato, è possibile aggiornarne lo stato attivando o disattivando la relativa casella di controllo e facendo clic su Update Tasks.Once the item appears, you can update whether it's complete by toggling the checkbox and clicking Update Tasks.

Passaggio 6: Distribuire l'applicazione Java in Siti Web di AzureStep 6: Deploy your Java application to Azure Web Sites

Con Siti Web di Azure la procedura di distribuzione di applicazioni Java è molto semplice e consiste nell'esportazione di un'applicazione come file con WAR e nel relativo caricamento tramite controllo del codice sorgente (ad esempio Git) o FTP.Azure Web Sites makes deploying Java applications as simple as exporting your application as a WAR file and either uploading it via source control (e.g. Git) or FTP.

  1. Per esportare l'applicazione come file WAR, fare clic con il pulsante destro del mouse sul progetto in Project Explorer (Esplora progetti), fare clic su Export (Esporta) e quindi su WAR File (File WAR).To export your application as a WAR file, right-click on your project in Project Explorer, click Export, and then click WAR File.
  2. Nella finestra WAR Export eseguire le operazioni seguenti:In the WAR Export window, do the following:

    • Nella casella Web project immettere azure-documentdb-java-sample.In the Web project box, enter azure-documentdb-java-sample.
    • Nella casella Destination scegliere una destinazione in cui salvare il file WAR.In the Destination box, choose a destination to save the WAR file.
    • Fare clic su Finish.Click Finish.
  3. A questo punto è sufficiente caricare il file nella directory webapps di Siti Web di Azure.Now that you have a WAR file in hand, you can simply upload it to your Azure Web Site's webapps directory. Per istruzioni sul caricamento del file, vedere Distribuire l'applicazione di esempio nelle app Web di Servizio app di Azure.For instructions on uploading the file, see Add a Java application to Azure App Service Web Apps.

    Dopo aver caricato il file con estensione war nella directory webapps, l'ambiente di runtime identificherà il file aggiunto e lo caricherà automaticamente.Once the WAR file is uploaded to the webapps directory, the runtime environment will detect that you've added it and will automatically load it.

  4. Per visualizzare il prodotto finito, passare a http://YOUR_SITE_NAME.azurewebsites.net/azure-java-sample/ e iniziare ad aggiungere le attività.To view your finished product, navigate to http://YOUR_SITE_NAME.azurewebsites.net/azure-java-sample/ and start adding your tasks!

Ottenere il progetto da GitHubGet the project from GitHub

Tutti gli esempi in questa esercitazione sono inclusi nel progetto todo su GitHub.All the samples in this tutorial are included in the todo project on GitHub. Per importare il progetto todo in Eclipse, assicurarsi di avere il software e le risorse elencate nella sezione Prerequisiti , quindi eseguire le operazioni seguenti:To import the todo project into Eclipse, ensure you have the software and resources listed in the Prerequisites section, then do the following:

  1. Installare Project Lombok.Install Project Lombok. Lombok viene usato per generare costruttori, getter e setter nel progetto.Lombok is used to generate constructors, getters, setters in the project. Dopo aver scaricato il file lombok.jar, fare doppio clic per installarlo o eseguire l'installazione dalla riga di comando.Once you have downloaded the lombok.jar file, double-click it to install it or install it from the command line.
  2. Se Eclipse è aperto, chiuderlo e riavviarlo per caricare Lombok.If Eclipse is open, close it and restart it to load Lombok.
  3. In Eclipse scegliere Import (Importa) dal menu File.In Eclipse, on the File menu, click Import.
  4. Nella finestra Import (Importa) fare clic su Git, su Projects from Git (Progetti da Git) e quindi su Next (Avanti).In the Import window, click Git, click Projects from Git, and then click Next.
  5. Nella schermata Select Repository Source (Seleziona origine repository) fare clic su Clone URI (Clona URI).On the Select Repository Source screen, click Clone URI.
  6. Nella schermata Source Git Repository (Repository Git di origine), nella casella URI, immettere https://github.com/Azure-Samples/java-todo-app.git e quindi scegliere Next (Avanti).On the Source Git Repository screen, in the URI box, enter https://github.com/Azure-Samples/java-todo-app.git, and then click Next.
  7. Nella schermata Branch Selection (Selezione ramo) assicurarsi che sia selezionata l'opzione master e quindi fare clic su Next (Avanti).On the Branch Selection screen, ensure that master is selected, and then click Next.
  8. Nella schermata Local Destination (Destinazione locale) fare clic su Browse (Sfoglia) per selezionare una cartella in cui sia possibile copiare il repository e quindi fare clic su Next (Avanti).On the Local Destination screen, click Browse to select a folder where the repository can be copied, and then click Next.
  9. Nella schermata Select a wizard to use for importing projects (Selezionare una procedura guidata per l'importazione di progetti) assicurarsi che l'opzione Import existing projects (Importa progetti esistenti) sia selezionata e quindi fare clic su Next (Avanti).On the Select a wizard to use for importing projects screen, ensure that Import existing projects is selected, and then click Next.
  10. Nella schermata Import Projects (Importa progetti) deselezionare il progetto DocumentDB e quindi fare clic su Finish (Fine).On the Import Projects screen, unselect the DocumentDB project, and then click Finish. Il progetto DocumentDB contiene Azure Cosmos DB Java SDK, che verrà aggiunto invece come dipendenza.The DocumentDB project contains the Azure Cosmos DB Java SDK, which we will add as a dependency instead.
  11. In Esplora progetti passare ad azure-documentdb-java-sample\src\com.microsoft.azure.documentdb.sample.dao\DocumentClientFactory.java e sostituire i valori HOST e MASTER_KEY con i valori URI e PRIMARY KEY dell'account Azure Cosmos DB, quindi salvare il file.In Project Explorer, navigate to azure-documentdb-java-sample\src\com.microsoft.azure.documentdb.sample.dao\DocumentClientFactory.java and replace the HOST and MASTER_KEY values with the URI and PRIMARY KEY for your Azure Cosmos DB account, and then save the file. Per altre informazioni, vedere Passaggio 1. Creare un account di database Azure Cosmos DB.For more information, see Step 1. Create an Azure Cosmos DB database account.
  12. In Project Explorer (Esplora progetti) fare clic con il pulsante destro del mouse su azure-documentdb-java-sample, fare clic su Build Path (Percorso compilazione) e quindi su Configure Build Path (Configura percorso compilazione).In Project Explorer, right click the azure-documentdb-java-sample, click Build Path, and then click Configure Build Path.
  13. Nella schermata Java Build Path (Percorso compilazione Java), nel riquadro a destra selezionare la scheda Libraries (Librerie) e quindi fare clic su Add External JARs (Aggiungi JAR esterni).On the Java Build Path screen, in the right pane, select the Libraries tab, and then click Add External JARs. Passare al percorso del file lombok.jar e fare clic su Open (Apri) e quindi su OK.Navigate to the location of the lombok.jar file, and click Open, and then click OK.
  14. Vedere il passaggio 12 per aprire nuovamente la finestra Properties (Proprietà) e quindi nel riquadro a sinistra fare clic su Targeted Runtimes (Runtime di destinazione).Use step 12 to open the Properties window again, and then in the left pane click Targeted Runtimes.
  15. Nella schermata Targeted Runtimes (Runtime di destinazione) fare clic su New (Nuovo), selezionare Apache Tomcat v7.0 e quindi fare clic su OK.On the Targeted Runtimes screen, click New, select Apache Tomcat v7.0, and then click OK.
  16. Vedere il passaggio 12 per aprire nuovamente la finestra Properties (Proprietà) e quindi nel riquadro a sinistra fare clic su Project Facets (Facet di progetto).Use step 12 to open the Properties window again, and then in the left pane click Project Facets.
  17. Nella schermata Project Facets (Facet di progetto) selezionare Dynamic Web Module (Modulo Web dinamico) e Java e quindi fare clic su OK.On the Project Facets screen, select Dynamic Web Module and Java, and then click OK.
  18. Nella scheda Servers (Server) nella parte inferiore della schermata fare clic con il pulsante destro del mouse su Tomcat v7.0 Server at localhost (Server Tomcat v7.0 in localhost) e quindi fare clic su Add and Remove (Aggiungi e rimuovi).On the Servers tab at the bottom of the screen, right-click Tomcat v7.0 Server at localhost and then click Add and Remove.
  19. Nella finestra Add and Remove (Aggiungi e rimuovi) spostare azure-documentdb-java-sample nella casella Configured (Configurato) e quindi fare clic su Finish (Fine).On the Add and Remove window, move azure-documentdb-java-sample to the Configured box, and then click Finish.
  20. Nella scheda Server fare clic con il pulsante destro del mouse su Tomcat v7.0 Server at localhost (Server Tomcat v7.0 in localhost) e quindi fare clic su Restart (Riavvia).In the Servers tab, right-click Tomcat v7.0 Server at localhost, and then click Restart.
  21. In un browser, passare a http://localhost:8080/azure-documentdb-java-sample/ e iniziare ad aggiungere all'elenco attività.In a browser, navigate to http://localhost:8080/azure-documentdb-java-sample/ and start adding to your task list. Si noti che se sono stati modificati i valori di porta predefiniti, è necessario modificare la porta 8080 con il valore selezionato.Note that if you changed your default port values, change 8080 to the value you selected.
  22. Per distribuire il progetto in un sito web di Azure, vedere il passaggio 6. Distribuire l'applicazione in Siti Web di Azure.To deploy your project to an Azure web site, see Step 6. Deploy your application to Azure Web Sites.