Scopri come utilizzare le code di attività e l'API Image di App Engine per ridimensionare le immagini.
Le code di attività eseguono il codice al di fuori dell'interazione diretta con l'utente, consentendo alle attività di essere eseguite in background. Questa guida utilizza una coda di attività per eseguire attività dopo aver aggiunto un'immagine a Cloud Storage. Le attività da eseguire nella coda delle attività sono:
- Recupera il file immagine appena caricato su Cloud Storage.
- Ridimensiona l'immagine in una miniatura utilizzando l'API Image.
- Archivia la miniatura risultante in Cloud Storage.
Il runtime Java 8 di App Engine supporta anche le classi di manipolazione delle immagini native di Java, come AWT e Java2D.
Prima di iniziare
Configura l'ambiente di sviluppo e crea il progetto App Engine.
Questa guida utilizza la libreria Apache Commons IOUtils. Per includere la libreria IOUtils nel tuo progetto App Engine:
Aggiungi al tuo
pom.xml:<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.5</version> </dependency>
Importazione delle librerie
Il codice campione fornito con questa guida utilizza i seguenti import:
import com.google.appengine.api.images.Image;
import com.google.appengine.api.images.ImagesService;
import com.google.appengine.api.images.ImagesServiceFactory;
import com.google.appengine.api.images.Transform;
import org.apache.commons.io.IOUtils;
Creazione di una coda di attività
Sebbene App Engine fornisca una coda di attività default, puoi creare
code delle attività diverse per diversi tipi di lavoro. Ad esempio, puoi creare
una coda di attività per ridimensionare le immagini e un'altra per aggiornare il database dell'app.
Per aggiungere code, crea il file queue.xml nella directory WEB-INF del progetto App Engine. Una coda di attività deve specificare un nome e una
velocità di esecuzione:
<?xml version="1.0" encoding="UTF-8"?>
<queue-entries>
<queue>
<name>resize-image</name>
<rate>60/h</rate>
</queue>
</queue-entries>
Questa coda di esempio, denominata resize-image, definisce una frequenza di esecuzione
di 60 volte all'ora o una volta al minuto. Per visualizzare l'elenco completo delle opzioni della coda, consulta il riferimento queue.xml.
Una coda di attività è composta da due componenti: il richiedente dell'attività e un gestore delle attività. Il richiedente aggiunge un'attività alla coda e la invia al gestore delle attività.
Aggiungere attività a una coda
Per aggiungere un'attività a una coda:
Crea un oggetto coda di attività utilizzando
QueueFactory.getQueue(), assicurandoti di specificare il nome della coda definito inqueue.xml:Queue imageResizeQueue; // Taskqueue queue @Override public void init() throws ServletException { // Setup Cloud Storage service gcsService = GcsServiceFactory.createGcsService( new RetryParams.Builder() .initialRetryDelayMillis(10) .retryMaxAttempts(10) .totalRetryPeriodMillis(15000) .build()); // Initialize the queue object with the specific queue imageResizeQueue = QueueFactory.getQueue([QUEUE-NAME]); // Cloud SQL connection setup try { final String url = System.getProperty("cloudsql"); // Cloud SQL server URI try { conn = DriverManager.getConnection(url); // Connect to the database Statement createTable; // SQL statement // Batch SQL table creation commands createTable.addBatch(createContentTableSql); createTable.addBatch(createUserTableSql); createTable.addBatch(createImageTableSql); createTable.addBatch(createBlogPostImageTableSql); conn.createTable.executeBatch(); // Execute batch } catch (SQLException e) { throw new ServletException("Unable to connect to Cloud SQL", e); } } finally { // Nothing really to do here. } }Aggiungi attività all'oggetto
Queue. Come mostrato nel esempio di codice,imageResizeQueue.add()aggiunge un'attività all'oggettoimageResizeQueue:try { // Add a queued task to create a thumbnail of the uploaded image imageResizeQueue.add( TaskOptions.Builder.withUrl("/tasks/imageresize").param("filename", filename)); }Specifica l'URI del gestore delle attività utilizzando
TaskOptions.Builder.withUrl(), insieme a tutti i parametri inviati al gestore.In questo esempio, l'URI è
/tasks/imageresizee il parametro è una variabile chiamatafilenameche contiene il nome file dell'immagine da elaborare.
Creazione di un gestore di attività
Una volta aggiunta un'attività alla coda, viene eseguito il gestore attività mappato all'URI
/tasks/imageresize. Un gestore delle attività è una servlet Java che tenta di
eseguire l'attività finché non va a buon fine.
In questo esempio, il gestore delle attività svolge tre attività:
Recupera l'immagine specificata dal chiamante da Cloud Storage.
Trasforma l'immagine utilizzando l'API Image di App Engine, in questo esempio, in un'immagine in miniatura.
Archivia l'immagine trasformata (miniatura) in Cloud Storage.
Per creare il gestore di attività:
Aggiungi un'annotazione che mappa il gestore all'URI
/tasks/imageresize:@WebServlet(name = "imageResize", description = "Task queue handler", urlPatterns = "/tasks/imageresize") public class imageResize extends HttpServlet { // Task handler functionality }Configura una connessione a Cloud Storage come descritto nella guida all'utilizzo di Cloud Storage e recupera l'immagine da Cloud Storage:
public void init() throws ServletException { // initiate GcsService GcsService gcsService = GcsServiceFactory.createGcsService( new RetryParams.Builder() .initialRetryDelayMillis(10) .retryMaxAttempts(10) .totalRetryPeriodMillis(15000) .build()); }Gestisci la richiesta in entrata della coda di attività utilizzando il nome file fornito per recuperare l'immagine da Cloud Storage:
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String filename = req.getParameter("filename"); // Get the filename passed from the task requestor GcsFilename gcsFile = new GcsFilename(bucket, filename); // Create a valid Cloud Storage filename GcsInputChannel readChannel = gcsService.openPrefetchingReadChannel(gcsFile, 0, BUFFER_SIZE); // Read the file from Cloud StorageUtilizza l'oggetto
ImagesServiceper ridimensionare l'immagine:// Get an instance of the ImagesService we can use to transform images. ImagesService imagesService = ImagesServiceFactory.getImagesService(); // Make an image directly from a byte array, and transform it. Image image = ImagesServiceFactory.makeImage(IOUtils.toByteArray(Channels.newInputStream(readChannel))); Transform resize = ImagesServiceFactory.makeResize(100, 50); // resize image to 100x50 Image resizedImage = imagesService.applyTransform(resize, image); // Write the transformed image back to a Cloud Storage object. gcsService.createOrReplace( new GcsFilename(bucket, "thumbnail_" + filename), new GcsFileOptions.Builder().acl("public-read").build(), ByteBuffer.wrap(resizedImage.getImageData()));Lo snippet precedente utilizza il metodo
makeResize()dell'API Image per ridimensionare l'immagine in una miniatura. A questo scopo, legge l'immagine da Cloud Storage in unInputChannele la converte in un ByteArray utilizzandoIOUtils.toByteArray().Dopo aver applicato la trasformazione, la nuova immagine ha la stringa
thumbnail_aggiunta al nome file, l'autorizzazione impostata per essere leggibile pubblicamente e viene scritta in Cloud Storage.
Protezione degli URL dei gestori di attività
Devi proteggere le attività che eseguono operazioni sensibili, come la modifica dei dati, in modo che gli utenti esterni non possano chiamarle direttamente. Puoi farlo limitando l'accesso alle attività agli amministratori di App Engine, il che impedisce agli utenti di accedere agli URL delle attività . Tieni presente che questa limitazione non si applica alle richieste di attività provenienti dalla tua app App Engine.
Nell'esempio attuale, i gestori delle attività hanno URL nella cartella /tasks/.
Per limitare l'accesso alla cartella /tasks/ agli amministratori di App Engine, aggiungi
quanto segue al file web.xml del progetto.
<security-constraint>
<web-resource-collection>
<web-resource-name>tasks</web-resource-name>
<url-pattern>/tasks/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
Rimozione di una singola attività da una coda
Per rimuovere una singola attività da una coda, utilizza deleteTask():
private void removeTask(Queue queue, String taskName) {
queue.deleteTask(taskName); // remove a task from a queue
}
Rimozione di tutte le attività da una coda
Per rimuovere tutte le attività da una coda, utilizza purge(). L'eliminazione definitiva può richiedere fino a un minuto per rimuovere tutte le attività in coda.
private void purgeQueue(Queue queue) {
queue.purge(); // remove all tasks from a queue
}
La rimozione di tutte le attività da una coda può richiedere un minuto, quindi devi attendere qualche secondo prima di aggiungere nuove attività alla coda.
Eliminazione di una coda di attività
Per eliminare una coda di attività, rimuovi la voce dal file queue.xml del progetto e
esegui nuovamente il deployment.
Deployment in App Engine
Puoi eseguire il deployment della tua app in App Engine utilizzando Maven.
Vai alla directory principale del progetto e digita:
mvn package appengine:deploy -Dapp.deploy.projectId=PROJECT_ID
Sostituisci PROJECT_ID con l'ID del tuo progetto Google Cloud . Se il
tuo file pom.xml
specifica già
l'ID progetto, non devi includere la proprietà -Dapp.deploy.projectId nel
comando che esegui.
Dopo che Maven esegue il deployment dell'app, si apre automaticamente una scheda del browser web nella nuova app digitando:
gcloud app browse
Passaggi successivi
Questa guida mostra come utilizzare una coda di attività per creare una miniatura dell'immagine e archiviarla in Cloud Storage. Può essere utilizzato con altri servizi di archiviazione come Cloud Datastore o Cloud SQL.