Proper Form of API request to Blogger using Java/App Engine -error 401

与世无争的帅哥 提交于 2019-12-23 02:28:59

问题


I am running into issue in forming the correct api statement for JAVA in calling the Blogger API.

I have tested my statement via the Google Cloud Console and it works but does not work in my code. I am using Google App Engine and have been authorized to use Blogger. The authorization is also tied to the account running Google App Engine.

Any ideas would be helpfull.. have tried many things over the weekend.

Thanks

Request
GET https://www.googleapis.com/blogger/v3/blogs/7676001971884966148/posts?key=   {YOUR_API_KEY}

Authorization:  Bearer ya29.1.AADtN_Vd7lKj8Xy3KbZ1veJjjjv712Nc1erLY2dmAK3gorNilVd0652vnqrrovfuLfSKkQ
X-JavaScript-User-Agent:  Google APIs Explorer


Response
200 OK

- Show headers -

{
"kind": "blogger#postList",
"nextPageToken": "CgkIChjim-ftqygQhIKb6_zjqMNq",
"items": [
{
etc.....

My Code

public class BloggerHandler
{

  public static final Logger log = Logger.getLogger(BloggerHandler.class.getName());

public void testCreds() throws Exception  {
   try{
   ArrayList<String> scopes = new ArrayList<String>();
    scopes.add("https://www.googleapis.com/auth/blogger");
    scopes.add("https://www.googleapis.com/auth/blogger.readonly");


    AppIdentityService appIdentity = AppIdentityServiceFactory.getAppIdentityService();
    AppIdentityService.GetAccessTokenResult accessToken = appIdentity.getAccessToken(scopes);
    // The token asserts the identity reported by appIdentity.getServiceAccountName()
    JSONObject request = new JSONObject();
   //request.put("maxPosts", "1");

   //request.put("view", "AUTHOR");

    log.info("request!!!" + request);

     URL url = new URL("https://www.googleapis.com/blogger/v3/blogs/7676001971884966148/posts?");
     log.info("URL:" + url);
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setDoOutput(true);
    connection.setRequestMethod("GET");
    connection.addRequestProperty("Content-Type", "application/json");
    connection.addRequestProperty("Authorization", "OAuth" + accessToken.getAccessToken());

    log.info("Con!!" + connection);


    OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
    request.write(writer);
    writer.close();
     log.info("connection:" + connection.getResponseCode());
     if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
        // Note: Should check the content-encoding.
        JSONTokener response_tokens = new JSONTokener(connection.getInputStream());
        JSONObject response = new JSONObject(response_tokens);

        log.info("resp:" + response.get("title")); 




     } // end if 

     else {
        throw new Exception();
     }// end else

     } // end try

     catch (Exception e) {
    // Error handling elided.
    log.info("ex:" + e);


    }
// end catch



}// end void


}// end class

回答1:


After a few long nights I was able to figure out how to access the Google Blogger API from a GAE project.

There are a couple of key things that I did that may help aid you.

  • In your Google Appe Engine project make sure that it is linked to the Google API Console. IN the GAE Admin project screen you should see a Google APIs Console Project Number:XX
  • In the Google API Cloud console make sure you are authorized for Blogger (or whatever cloud API you want to use). Create a project (website.. etc) and copy down the API string that it gives you.

Once you have that API string the code below should get you started with base connection.

The code below should return a "200" connection with the stats of the current blog you are trying to reach. From here you can expand upon the API.

// On a side note I know there is a way to read the API from Google Cloud so it does not have to be part of the code. Still working on that workflow.

import java.util.logging.Logger;
import java.util.Arrays;
import com.google.api.client.googleapis.extensions.appengine.auth.oauth2.AppIdentityCredential;
import com.google.api.services.blogger.Blogger;
import com.google.api.services.blogger.Blogger.Blogs.GetByUrl;
import com.google.api.services.blogger.Blogger.Posts.List;
import com.google.api.services.blogger.BloggerScopes;
import com.google.api.services.blogger.model.Blog;
import com.google.api.services.blogger.model.Post;
import com.google.api.services.blogger.model.PostList;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.extensions.appengine.http.UrlFetchTransport;
import java.io.IOException;

public class BlogHandler
{
  public Blogger blogger = null;
  public Blog blog;
  public java.util.List<Post> posts;
  public static final Logger log = Logger.getLogger(EngineParseFeed.class.getName());
  static final String API_KEY = "{Your GOOGLE CLOUD API}";

  public BlogHandler() {}

  public void setupService () throws IOException {

    AppIdentityCredential credential = null;
    credential  = new AppIdentityCredential(Arrays.asList(BloggerScopes.BLOGGER)); // Add your scopes here
    this.blogger = new Blogger.Builder(new UrlFetchTransport(), new JacksonFactory(), credential).setApplicationName("trivalAPPName").build();
   }

   public void executeGetBlogByUrl (String url) throws IOException {
     GetByUrl request = blogger.blogs().getByUrl( url );
     this.blog = request.setKey(API_KEY).execute();
     log.info ("Blog" + this.blog);
   }



回答2:


I managed to get the Blogger API working properly on Google App Engine by using two servlets and modelling them after the examples on this page: https://developers.google.com/google-apps/tasks/oauth-authorization-callback-handler. The example code is out of date and uses some kind of deprecated draft10 library.

Here's the working version for the servlet that posts to Blogger:

public class BloggerServlet
   {
   private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
  private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();   
  public static GoogleAuthorizationCodeFlow flow;

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
     {        
  DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();   
  Entity OAuthTokenEntity;
  OAuthProperties oauthProperties = new OAuthProperties();
   String OAuthAccessToken, OAuthRefreshToken;
  try
     { 
     OAuthTokenEntity = datastore.get(KeyFactory.createKey("OAuthTokenEntity","OA"));
     OAuthAccessToken = OAuthTokenEntity.getProperty("OAuthAccessToken").toString();
     OAuthRefreshToken = OAuthTokenEntity.getProperty("OAuthRefreshToken").toString();
     }
  catch(EntityNotFoundException e)
     {
     Collection<String> scopes = Arrays.asList(BloggerScopes.BLOGGER);
     flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY,
           CLIENT_ID, CLIENT_SECRET, scopes)
           .setAccessType("offline")
           .setApprovalPrompt("auto").build();
     String url = flow.newAuthorizationUrl()
            .setRedirectUri(OAuthCodeCallbackHandlerServlet.getOAuthCodeCallbackHandlerUrl(request))
            .build();
     response.sendRedirect("http://OAuthCodeCallbackHandlerServlet");
     return;
     }

  GoogleCredential credential = new GoogleCredential.Builder()
            .setTransport(HTTP_TRANSPORT)
            .setJsonFactory(JSON_FACTORY)
            .setClientSecrets(CLIENT_ID, CLIENT_SECRET)
            .build();

  credential.setAccessToken(OAuthAccessToken);
  credential.setRefreshToken(OAuthRefreshToken);

  Blogger blog = new Blogger.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
     .setApplicationName("APP_NAME").setHttpRequestInitializer(credential).build();
  }
  }

And here is the working version of the Servlet that handles the callback:

public class OAuthCodeCallbackHandlerServlet
  {
   public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
   {
   String[] code = request.getParameterValues("code");

   GoogleTokenResponse tokenResponse = BloggerServlet.flow.newTokenRequest(code[0]).setRedirectUri(getOAuthCodeCallbackHandlerUrl(request)).execute();

   DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();    
   Entity OAuthTokenEntity = new Entity("OAuthTokenEntity","OA");
   OAuthTokenEntity.setProperty("OAuthAccessToken", tokenResponse.getAccessToken());
   OAuthTokenEntity.setProperty("OAuthRefreshToken",tokenResponse.getRefreshToken());
   datastore.put(OAuthTokenEntity);

   response.sendRedirect("http://BloggerServlet");
   }

public static String getOAuthCodeCallbackHandlerUrl(HttpServletRequest request) 
   {
   StringBuilder oauthURL = new StringBuilder();
   oauthURL.append(request.getScheme() + "://");
   oauthURL.append(request.getServerName());
   oauthURL.append(request.getServerPort() == 80 ? "" : ":" + request.getServerPort());
   oauthURL.append(request.getContextPath());
   oauthURL.append(URL_MAPPING);
   oauthURL.append(request.getPathInfo() == null ? "" : request.getPathInfo());  
   return oauthURL.toString(); 
   }
}



回答3:


I have been working on this and my conclusion is:

  1. To make a request for a blog or post, as long as they are public, you don't have to authenticate, i.e. you don't need OAuth for this kind of requests.Still, you have to identify your application and you do that with the APP_KEY. As stated here, not any application can use the Blogger API, it has to be authorized and for this reason is this key needed.
  2. Based on 1., you dont need to create an AppIdentityCredential. I just set the third parameter of Builder to null. I tried using your code but it didn't work.

I still have a question and probably is the same iamkhova has. I think an app can authenticate itself with OAuth using the AppIdentityCredential for GAE apps. But how can you tell google that my application is owner of the blog I am trying to access? I think this is the reason of getting this 401.



来源:https://stackoverflow.com/questions/20462705/proper-form-of-api-request-to-blogger-using-java-app-engine-error-401

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!