In diesem Dokument wird erläutert, wie Sie mithilfe einer Beispiel-Webanwendung, die die Aufgaben des Nutzers mithilfe der Google Tasks API anzeigt, mithilfe von Java-Servlets einen Callback-Handler für die OAuth 2.0-Autorisierung implementieren. Die Beispielanwendung fordert zuerst eine Autorisierung für den Zugriff auf den Google Tasks-Zugriff des Nutzers an und zeigt die Aufgaben des Nutzers dann in der Standardaufgabenliste an.
Zielgruppe
Dieses Dokument richtet sich an Personen, die mit der Architektur von Java- und J2EE-Webanwendungen vertraut sind. Es werden grundlegende Kenntnisse des OAuth 2.0-Autorisierungsvorgangs empfohlen.
Inhalt
Um ein solches voll funktionsfähiges Beispiel zu erhalten, sind mehrere Schritte erforderlich, die Sie durchführen müssen:
- Servlet-Zuordnungen in der Datei „web.xml“ deklarieren
- Authentifizieren Sie die Nutzer in Ihrem System und fordern Sie die Autorisierung für den Zugriff auf die Tasks an.
- Auf den Autorisierungscode des Google-Autorisierungsendpunkts warten
- Autorisierungscode gegen Aktualisierungs- und Zugriffstoken austauschen
- Aufgaben des Nutzers lesen und anzeigen
Servlet-Zuordnungen in der Datei web.xml deklarieren
Wir verwenden zwei Servlets in unserer Anwendung:
- PrintTasksTitlesServlet (zugeordnet zu /): Der Einstiegspunkt der Anwendung, die die Nutzerauthentifizierung verarbeitet und die Aufgaben des Nutzers anzeigt
- OAuthCodeCallbackHandlerServlet (zugeordnet zu /oauth2callback): Der OAuth 2.0-Callback, der die Antwort vom OAuth-Autorisierungsendpunkt verarbeitet.
Nachstehend finden Sie die Datei web.xml, in der diese beiden Servlets URLs in unserer Anwendung zugeordnet werden:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>PrintTasksTitles</servlet-name> <servlet-class>com.google.oauthsample.PrintTasksTitlesServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>PrintTasksTitles</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <servlet> <servlet-name>OAuthCodeCallbackHandlerServlet</servlet-name> <servlet-class>com.google.oauthsample.OAuthCodeCallbackHandlerServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>OAuthCodeCallbackHandlerServlet</servlet-name> <url-pattern>/oauth2callback</url-pattern> </servlet-mapping> </web-app>
Authentifizieren Sie die Nutzer in Ihrem System und fordern Sie die Autorisierung für den Zugriff auf die Aufgaben an.
Der Nutzer gelangt über das Stammverzeichnis „/“ in die Anwendung URL, die dem Servlet PrintTaskListsTitlesServlet zugeordnet ist. In diesem Servlet werden die folgenden Aufgaben ausgeführt:
- Prüft, ob der Nutzer im System authentifiziert ist
- Wenn der Nutzer nicht authentifiziert ist, wird er zur Authentifizierungsseite weitergeleitet.
- Wenn der Nutzer authentifiziert ist, prüfen wir, ob sich bereits ein Aktualisierungstoken in unserem Datenspeicher befindet. Dieses wird vom unten stehenden OAuthTokenDao verarbeitet. Wenn für den Nutzer kein Aktualisierungstoken gespeichert ist, bedeutet dies, dass der Nutzer der Anwendung noch keine Berechtigung für den Zugriff auf ihre Aufgaben erteilt hat. In diesem Fall wird der Nutzer zum OAuth 2.0-Autorisierungsendpunkt von Google weitergeleitet.
package com.google.oauthsample; import ... /** * Simple sample Servlet which will display the tasks in the default task list of the user. */ @SuppressWarnings("serial") public class PrintTasksTitlesServlet extends HttpServlet { /** * The OAuth Token DAO implementation, used to persist the OAuth refresh token. * Consider injecting it instead of using a static initialization. Also we are * using a simple memory implementation as a mock. Change the implementation to * using your database system. */ public static OAuthTokenDao oauthTokenDao = new OAuthTokenDaoMemoryImpl(); public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { // Getting the current user // This is using App Engine's User Service but you should replace this to // your own user/login implementation UserService userService = UserServiceFactory.getUserService(); User user = userService.getCurrentUser(); // If the user is not logged-in it is redirected to the login service, then back to this page if (user == null) { resp.sendRedirect(userService.createLoginURL(getFullRequestUrl(req))); return; } // Checking if we already have tokens for this user in store AccessTokenResponse accessTokenResponse = oauthTokenDao.getKeys(user.getEmail()); // If we don't have tokens for this user if (accessTokenResponse == null) { OAuthProperties oauthProperties = new OAuthProperties(); // Redirect to the Google OAuth 2.0 authorization endpoint resp.sendRedirect(new GoogleAuthorizationRequestUrl(oauthProperties.getClientId(), OAuthCodeCallbackHandlerServlet.getOAuthCodeCallbackHandlerUrl(req), oauthProperties .getScopesAsString()).build()); return; } } /** * Construct the request's URL without the parameter part. * * @param req the HttpRequest object * @return The constructed request's URL */ public static String getFullRequestUrl(HttpServletRequest req) { String scheme = req.getScheme() + "://"; String serverName = req.getServerName(); String serverPort = (req.getServerPort() == 80) ? "" : ":" + req.getServerPort(); String contextPath = req.getContextPath(); String servletPath = req.getServletPath(); String pathInfo = (req.getPathInfo() == null) ? "" : req.getPathInfo(); String queryString = (req.getQueryString() == null) ? "" : "?" + req.getQueryString(); return scheme + serverName + serverPort + contextPath + servletPath + pathInfo + queryString; } }
Hinweis: Die obige Implementierung verwendet einige App Engine-Bibliotheken. Diese dienen der Vereinfachung. Wenn Sie für eine andere Plattform entwickeln, können Sie die UserService-Schnittstelle, die die Nutzerauthentifizierung handhabt, gerne erneut implementieren.
Die Anwendung verwendet einen DAO, um die Autorisierungstokens des Nutzers dauerhaft zu speichern und darauf zuzugreifen. Unten sehen Sie die Schnittstelle OAuthTokenDao und OAuthTokenDaoMemoryImpl als Simulation (im Arbeitsspeicher), die in diesem Beispiel verwendet werden:
package com.google.oauthsample; import com.google.api.client.auth.oauth2.draft10.AccessTokenResponse; /** * Allows easy storage and access of authorization tokens. */ public interface OAuthTokenDao { /** * Stores the given AccessTokenResponse using the {@code username}, the OAuth * {@code clientID} and the tokens scopes as keys. * * @param tokens The AccessTokenResponse to store * @param userName The userName associated wit the token */ public void saveKeys(AccessTokenResponse tokens, String userName); /** * Returns the AccessTokenResponse stored for the given username, clientId and * scopes. Returns {@code null} if there is no AccessTokenResponse for this * user and scopes. * * @param userName The username of which to get the stored AccessTokenResponse * @return The AccessTokenResponse of the given username */ public AccessTokenResponse getKeys(String userName); }
package com.google.oauthsample; import com.google.api.client.auth.oauth2.draft10.AccessTokenResponse; ... /** * Quick and Dirty memory implementation of {@link OAuthTokenDao} based on * HashMaps. */ public class OAuthTokenDaoMemoryImpl implements OAuthTokenDao { /** Object where all the Tokens will be stored */ private static MaptokenPersistance = new HashMap (); public void saveKeys(AccessTokenResponse tokens, String userName) { tokenPersistance.put(userName, tokens); } public AccessTokenResponse getKeys(String userName) { return tokenPersistance.get(userName); } }
Außerdem werden die OAuth 2.0-Anmeldedaten für die Anwendung in einer Eigenschaftendatei gespeichert. Alternativ können Sie sie einfach als Konstante in einer Ihrer Java-Klassen einfügen. Hier sehen Sie jedoch die OAuthProperties-Klasse und die oauth.properties-Datei, die im Beispiel verwendet werden:
package com.google.oauthsample; import ... /** * Object representation of an OAuth properties file. */ public class OAuthProperties { public static final String DEFAULT_OAUTH_PROPERTIES_FILE_NAME = "oauth.properties"; /** The OAuth 2.0 Client ID */ private String clientId; /** The OAuth 2.0 Client Secret */ private String clientSecret; /** The Google APIs scopes to access */ private String scopes; /** * Instantiates a new OauthProperties object reading its values from the * {@code OAUTH_PROPERTIES_FILE_NAME} properties file. * * @throws IOException IF there is an issue reading the {@code propertiesFile} * @throws OauthPropertiesFormatException If the given {@code propertiesFile} * is not of the right format (does not contains the keys {@code * clientId}, {@code clientSecret} and {@code scopes}) */ public OAuthProperties() throws IOException { this(OAuthProperties.class.getResourceAsStream(DEFAULT_OAUTH_PROPERTIES_FILE_NAME)); } /** * Instantiates a new OauthProperties object reading its values from the given * properties file. * * @param propertiesFile the InputStream to read an OAuth Properties file. The * file should contain the keys {@code clientId}, {@code * clientSecret} and {@code scopes} * @throws IOException IF there is an issue reading the {@code propertiesFile} * @throws OAuthPropertiesFormatException If the given {@code propertiesFile} * is not of the right format (does not contains the keys {@code * clientId}, {@code clientSecret} and {@code scopes}) */ public OAuthProperties(InputStream propertiesFile) throws IOException { Properties oauthProperties = new Properties(); oauthProperties.load(propertiesFile); clientId = oauthProperties.getProperty("clientId"); clientSecret = oauthProperties.getProperty("clientSecret"); scopes = oauthProperties.getProperty("scopes"); if ((clientId == null) || (clientSecret == null) || (scopes == null)) { throw new OAuthPropertiesFormatException(); } } /** * @return the clientId */ public String getClientId() { return clientId; } /** * @return the clientSecret */ public String getClientSecret() { return clientSecret; } /** * @return the scopes */ public String getScopesAsString() { return scopes; } /** * Thrown when the OAuth properties file was not at the right format, i.e not * having the right properties names. */ @SuppressWarnings("serial") public class OAuthPropertiesFormatException extends RuntimeException { } }
Unten finden Sie die Datei oauth.properties, die die OAuth 2.0-Anmeldedaten Ihrer Anwendung enthält. Sie müssen die Werte unten selbst ändern.
# Client ID and secret. They can be found in the APIs console. clientId=1234567890.apps.googleusercontent.com clientSecret=aBcDeFgHiJkLmNoPqRsTuVwXyZ # API scopes. Space separated. scopes=https://www.googleapis.com/auth/tasks
Die OAuth 2.0-Client-ID und der Clientschlüssel identifizieren Ihre Anwendung und ermöglichen der Tasks API, Filter und Kontingentregeln anzuwenden, die für Ihre Anwendung definiert sind. Die Client-ID und das Secret finden Sie in der Google APIs-Konsole. Gehen Sie in der Konsole so vor:
- Erstellen Sie ein neues Projekt oder wählen Sie ein vorhandenes Projekt aus.
- Aktivieren Sie die Tasks API, indem Sie den Status der Tasks API in der Liste der Dienste auf EIN setzen.
- Erstellen Sie unter API-Zugriff eine OAuth 2.0-Client-ID, falls noch keine vorhanden ist.
- Achten Sie darauf, dass die Callback-Handler-URL des OAuth 2.0-Codes des Projekts in den Weiterleitungs-URIs registriert bzw. auf die weiße Liste gesetzt wurde. In diesem Beispielprojekt müssten Sie beispielsweise https://www.example.com/oauth2callback registrieren, wenn Ihre Webanwendung von der Domain https://www.example.com bereitgestellt wird.
![Weiterleitungs-URI in der APIs-Konsole](https://developers.google.cn/static/tasks/images/Google_APIs_Console_Redirect_URI.png?hl=de)
Auf den Autorisierungscode des Google-Autorisierungsendpunkts warten
Für den Fall, dass der Nutzer die Anwendung noch nicht für den Zugriff auf ihre Aufgaben autorisiert hat und daher zum OAuth 2.0-Autorisierungsendpunkt von Google weitergeleitet wurde, wird dem Nutzer ein Autorisierungsdialogfeld von Google angezeigt, in dem er gebeten wird, Ihrer Anwendung Zugriff auf die Aufgaben zu gewähren:
![Dialogfeld für die Autorisierung von Google](https://developers.google.cn/static/tasks/images/Google_Auth_Dialog.png?hl=de)
Nachdem der Zugriff gewährt oder verweigert wurde, erfolgt eine Weiterleitung zurück zum Callback-Handler für OAuth 2.0-Code, der beim Erstellen der Google-Autorisierungs-URL als Weiterleitung/Callback festgelegt wurde:
new GoogleAuthorizationRequestUrl(oauthProperties.getClientId(), OAuthCodeCallbackHandlerServlet.getOAuthCodeCallbackHandlerUrl(req), oauthProperties .getScopesAsString()).build()
Der OAuth 2.0-Code-Callback-Handler OAuthCodeCallbackHandlerServlet wickelt die Weiterleitung vom Google OAuth 2.0-Endpunkt ab. Es sind zwei Fälle zu bearbeiten:
- Der Nutzer hat Zugriff gewährt: parst die Anfrage, um den OAuth 2.0-Code aus den URL-Parametern abzurufen
- Der Nutzer hat den Zugriff verweigert: Dem Nutzer wird eine Nachricht angezeigt.
package com.google.oauthsample; import ... /** * Servlet handling the OAuth callback from the authentication service. We are * retrieving the OAuth code, then exchanging it for a refresh and an access * token and saving it. */ @SuppressWarnings("serial") public class OAuthCodeCallbackHandlerServlet extends HttpServlet { /** The name of the Oauth code URL parameter */ public static final String CODE_URL_PARAM_NAME = "code"; /** The name of the OAuth error URL parameter */ public static final String ERROR_URL_PARAM_NAME = "error"; /** The URL suffix of the servlet */ public static final String URL_MAPPING = "/oauth2callback"; public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { // Getting the "error" URL parameter String[] error = req.getParameterValues(ERROR_URL_PARAM_NAME); // Checking if there was an error such as the user denied access if (error != null && error.length > 0) { resp.sendError(HttpServletResponse.SC_NOT_ACCEPTABLE, "There was an error: \""+error[0]+"\"."); return; } // Getting the "code" URL parameter String[] code = req.getParameterValues(CODE_URL_PARAM_NAME); // Checking conditions on the "code" URL parameter if (code == null || code.length == 0) { resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "The \"code\" URL parameter is missing"); return; } } /** * Construct the OAuth code callback handler URL. * * @param req the HttpRequest object * @return The constructed request's URL */ public static String getOAuthCodeCallbackHandlerUrl(HttpServletRequest req) { String scheme = req.getScheme() + "://"; String serverName = req.getServerName(); String serverPort = (req.getServerPort() == 80) ? "" : ":" + req.getServerPort(); String contextPath = req.getContextPath(); String servletPath = URL_MAPPING; String pathInfo = (req.getPathInfo() == null) ? "" : req.getPathInfo(); return scheme + serverName + serverPort + contextPath + servletPath + pathInfo; } }
Autorisierungscode gegen Aktualisierungs- und Zugriffstoken austauschen
Anschließend tauscht OAuthCodeCallbackHandlerServlet den Auth 2.0-Code gegen Aktualisierungs- und Zugriffstokens aus, speichert ihn im Datenspeicher und leitet den Nutzer zurück zur URL PrintTaskListsTitlesServlet:
Die Syntax des Codes, der der Datei unten hinzugefügt wurde, ist hervorgehoben. Der bereits vorhandene Code ist ausgegraut.
package com.google.oauthsample; import ... /** * Servlet handling the OAuth callback from the authentication service. We are * retrieving the OAuth code, then exchanging it for a refresh and an access * token and saving it. */ @SuppressWarnings("serial") public class OAuthCodeCallbackHandlerServlet extends HttpServlet { /** The name of the Oauth code URL parameter */ public static final String CODE_URL_PARAM_NAME = "code"; /** The name of the OAuth error URL parameter */ public static final String ERROR_URL_PARAM_NAME = "error"; /** The URL suffix of the servlet */ public static final String URL_MAPPING = "/oauth2callback";/** Die URL, an die der Nutzer nach der Verarbeitung des Callbacks weitergeleitet werden soll. Erwägen Sie * die dies in einem Cookie gespeichert wird, bevor die Nutzer zur Google * Autorisierungs-URL, wenn Sie mehrere mögliche URLs haben, zu denen Nutzer weitergeleitet werden können. */ public static final String REDIRECT_URL = "/"; /** Die OAuth-Token-DAO-Implementierung. Injizieren Sie sie, anstatt sie zu verwenden. * eine statische Initialisierung. Außerdem verwenden wir eine einfache Speicherimplementierung, * als Simulation. Ändern Sie die Implementierung in Ihr Datenbanksystem. */ public static OAuthTokenDao oauthTokenDao = new OAuthTokenDaoMemoryImpl()public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { // Getting the "error" URL parameter String[] error = req.getParameterValues(ERROR_URL_PARAM_NAME); // Checking if there was an error such as the user denied access if (error != null && error.length > 0) { resp.sendError(HttpServletResponse.SC_NOT_ACCEPTABLE, "There was an error: \""+error[0]+"\"."); return; } // Getting the "code" URL parameter String[] code = req.getParameterValues(CODE_URL_PARAM_NAME); // Checking conditions on the "code" URL parameter if (code == null || code.length == 0) { resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "The \"code\" URL parameter is missing"); return; }// URL für eingehende Anfrage erstellen String requestUrl = getOAuthCodeCallbackHandlerUrl(req); // Code gegen OAuth-Tokens austauschen AccessTokenResponse accessTokenResponse = ExchangeCodeForAccessAndRefreshTokens(code[0], requestUrl); // Aktuellen Nutzer abrufen // This is using App Engine's User Service but you should Replace this to // Ihre eigene Nutzer-/Anmeldeimplementierung UserService userService = UserServiceFactory.getUserService() String email = userService.getCurrentUser().getEmail() // Tokens speichern oauthTokenDao.saveKeys(accessTokenResponse, email); resp.sendRedirect(REDIRECT_URL); }/** * Construct the OAuth code callback handler URL. * * @param req the HttpRequest object * @return The constructed request's URL */ public static String getOAuthCodeCallbackHandlerUrl(HttpServletRequest req) { String scheme = req.getScheme() + "://"; String serverName = req.getServerName(); String serverPort = (req.getServerPort() == 80) ? "" : ":" + req.getServerPort(); String contextPath = req.getContextPath(); String servletPath = URL_MAPPING; String pathInfo = (req.getPathInfo() == null) ? "" : req.getPathInfo(); return scheme + serverName + serverPort + contextPath + servletPath + pathInfo; }/** * Taugt den angegebenen Code gegen eine Anzeigenplattform und ein Aktualisierungstoken aus. * * @param code Der Code, der vom Autorisierungsdienst zurückgegeben wurde * @param currentUrl Die URL des Callbacks * @param oauthProperties Das Objekt, das die OAuth-Konfiguration enthält * @return Das Objekt, das sowohl ein Zugriffs- als auch ein Aktualisierungstoken enthält * @wirft IOException */ public AccessTokenResponse ExchangeCodeForAccessAndRefreshTokens(String code, String currentUrl) throws IOException { HttpTransport httpTransport = new NetHttpTransport() JacksonFactory jsonFactory = new JacksonFactory() // Laden der OAuth-Konfigurationsdatei OAuthProperties oauthProperties = new OAuthProperties() Neuen GoogleAuthorizationCodeGrant(httpTransport, jsonFactory, oauthProperties zurückgeben) zurückgeben .getClientId(), oauthProperties.getClientSecret(), code, currentUrl).execute() } }Datei OAuthCodeCallbackHandlerServlet.javaHinweis: Die obige Implementierung verwendet einige App Engine-Bibliotheken. Diese dienen der Vereinfachung. Wenn Sie für eine andere Plattform entwickeln, können Sie die UserService-Schnittstelle, die die Nutzerauthentifizierung handhabt, gerne erneut implementieren.
Aufgaben des Nutzers lesen und anzeigen
Der Nutzer hat der Anwendung Zugriff auf ihre Aufgaben gewährt. Die Anwendung verfügt über ein Aktualisierungstoken, das im Datenspeicher gespeichert wird, auf den über OAuthTokenDao zugegriffen werden kann. Das Servlet PrintTaskListsTitlesServlet kann jetzt diese Tokens verwenden, um auf die Aufgaben des Nutzers zuzugreifen und sie anzuzeigen:
Die Syntax des Codes, der der Datei unten hinzugefügt wurde, ist hervorgehoben. Der bereits vorhandene Code ist ausgegraut.
package com.google.oauthsample; import ... /** * Simple sample Servlet which will display the tasks in the default task list of the user. */ @SuppressWarnings("serial") public class PrintTasksTitlesServlet extends HttpServlet { /** * The OAuth Token DAO implementation, used to persist the OAuth refresh token. * Consider injecting it instead of using a static initialization. Also we are * using a simple memory implementation as a mock. Change the implementation to * using your database system. */ public static OAuthTokenDao oauthTokenDao = new OAuthTokenDaoMemoryImpl(); public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { // Getting the current user // This is using App Engine's User Service but you should replace this to // your own user/login implementation UserService userService = UserServiceFactory.getUserService(); User user = userService.getCurrentUser(); // If the user is not logged-in it is redirected to the login service, then back to this page if (user == null) { resp.sendRedirect(userService.createLoginURL(getFullRequestUrl(req))); return; } // Checking if we already have tokens for this user in store AccessTokenResponse accessTokenResponse = oauthTokenDao.getKeys(user.getEmail()); // If we don't have tokens for this user if (accessTokenResponse == null) { OAuthProperties oauthProperties = new OAuthProperties(); // Redirect to the Google OAuth 2.0 authorization endpoint resp.sendRedirect(new GoogleAuthorizationRequestUrl(oauthProperties.getClientId(), OAuthCodeCallbackHandlerServlet.getOAuthCodeCallbackHandlerUrl(req), oauthProperties .getScopesAsString()).build()); return; }// Die Titel der Aufgabenlisten des Nutzers in der Antwort drucken resp.setContentType("text/plain"); resp.getWriter().append("Aufgabenlistentitel für Nutzer " + user.getEmail() + ":\n\n") printTasksTitles(accessTokenResponse, resp.getWriter());} /** * Construct the request's URL without the parameter part. * * @param req the HttpRequest object * @return The constructed request's URL */ public static String getFullRequestUrl(HttpServletRequest req) { String scheme = req.getScheme() + "://"; String serverName = req.getServerName(); String serverPort = (req.getServerPort() == 80) ? "" : ":" + req.getServerPort(); String contextPath = req.getContextPath(); String servletPath = req.getServletPath(); String pathInfo = (req.getPathInfo() == null) ? "" : req.getPathInfo(); String queryString = (req.getQueryString() == null) ? "" : "?" + req.getQueryString(); return scheme + serverName + serverPort + contextPath + servletPath + pathInfo + queryString; }/** * Verwendet das Google Tasks API zum Abrufen einer Liste der Aufgaben des Nutzers in der Standard- * Aufgabenliste. * * @param accessTokenResponse Das OAuth 2.0 AccessTokenResponse-Objekt * mit dem Zugriffstoken und einem Aktualisierungstoken * @param gibt den Ausgabestream-Writer aus, wo die Titel der Aufgabenlisten aufgeführt werden sollen * @return Eine Liste der Aufgabentitel des Nutzers in der Standardaufgabenliste. * @wirft IOException */ public void printTasksTitles(AccessTokenResponse accessTokenResponse, Writer output) throws IOException { // Initialisieren des Tasks-Dienstes HttpTransport transport = new NetHttpTransport() JsonFactory jsonFactory = new JacksonFactory() OAuthProperties oauthProperties = new OAuthProperties() GoogleAccessProtectedResource accessProtectedResource = neue GoogleAccessProtectedResource( accessTokenResponse.accessToken, transport, jsonFactory, oauthProperties.getClientId(), oauthProperties.getClientSecret(), accessTokenResponse.refreshToken); Tasks-Dienst = new Tasks(transport, accessProtectedResource, jsonFactory); // Verwendung des initialisierten Tasks API-Dienstes zum Abfragen der Aufgabenliste com.google.api.services.tasks.model.Tasks tasks = service.tasks.list("@default").execute(); for (Task task : tasks.items) { Ausgabe.append(task.title + "\n") } } }PrintTasksTitlesServlet.java-DateiDer Nutzer wird mit seinen Aufgaben angezeigt:
Aufgaben des NutzersBeispielanwendung
Den Code für diese Beispielanwendung können Sie hier herunterladen. Probieren Sie es einfach aus.