2010-08-30 13 views
0

J'ai essayé de suivre l'exemple facebook-java-api filter mais j'ai obtenu cette attente quand j'ai essayé d'enregistrer à l'objet client à la session. Le code est hébergé sur la plate-forme google appengine.FacebookXmlRestClient NotSerializableException sur Google AppEngine

java.lang.RuntimeException: java.io.NotSerializableException: com.google.code.facebookapi.FacebookXmlRestClient 
    at com.google.apphosting.runtime.jetty.SessionManager.serialize(SessionManager.java:387) 
    at com.google.apphosting.runtime.jetty.SessionManager.createEntityForSession(SessionManager.java:364) 
    at com.google.apphosting.runtime.jetty.SessionManager$AppEngineSession.save(SessionManager.java:164) 
    at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:41) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388) 
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) 
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) 
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765) 
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418) 
    ..... 
    at com.google.net.async.Connection.handleReadEvent(Connection.java:474) 
    at com.google.net.async.EventDispatcher.processNetworkEvents(EventDispatcher.java:831) 
    at com.google.net.async.EventDispatcher.internalLoop(EventDispatcher.java:207) 
    at com.google.net.async.EventDispatcher.loop(EventDispatcher.java:103) 
    at com.google.net.rpc.RpcService.runUntilServerShutdown(RpcService.java:251) 
    at com.google.apphosting.runtime.JavaRuntime$RpcRunnable.run(JavaRuntime.java:418) 
    at java.lang.Thread.run(Thread.java:636) 
Caused by: java.io.NotSerializableException: com.google.code.facebookapi.FacebookXmlRestClient 
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1173) 
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:343) 
    at java.util.HashMap.writeObject(HashMap.java:1018) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 

I mis à jour le code de filtre à utiliser une carte pour enregistrer la session et de l'objet client associé, mais je peux encore obtenir un login valide. Est-ce que quelqu'un peut repérer le problème avec ce code, ou expliquer comment le com.google.code.facebookapi.ExtensibleClient peut être utilisé correctement?

import com.google.code.facebookapi.FacebookException; 
import com.google.code.facebookapi.FacebookWebappHelper; 
import com.google.code.facebookapi.FacebookXmlRestClient; 
import com.google.code.facebookapi.IFacebookRestClient; 

import java.util.HashMap; 
import java.util.Map; 
import java.util.logging.Logger; 

import org.w3c.dom.Document; 

public class FacebookFilter implements Filter { 

     private static final Logger logger = Logger.getLogger(FacebookFilter.class.getName()); 

     private String api_key; 
     private String secret; 
     private static Map map = new HashMap(); 

     public void init(FilterConfig filterConfig) throws ServletException { 
       api_key = filterConfig.getInitParameter("facebook_api_key"); 
       secret = filterConfig.getInitParameter("facebook_secret_key"); 
       if(api_key == null || secret == null) { 
         throw new ServletException("Cannot initialise Facebook User Filter because the " + 
                  "facebook_api_key or facebook_secret context init " + 
                  "params have not been set. Check that they're there " + 
                  "in your servlet context descriptor."); 
       } else { 
         logger.info("Using facebook API key: " + api_key); 
       } 
     } 

     public void destroy() { 
     } 

     public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 
       try { 
         HttpServletRequest request = (HttpServletRequest)req; 
         HttpServletResponse response = (HttpServletResponse)res; 

         HttpSession session = request.getSession(true); 
         IFacebookRestClient<Document> userClient = getUserClient(session); 
         if(userClient == null) { 
          logger.info("User session doesn't have a Facebook API client setup yet. Creating one and storing it in the user's session."); 
          userClient = new FacebookXmlRestClient(api_key, secret); 
          logger.info("add new session to map "+map.size()+" "+session.getId()+" "+userClient.toString()); 
          map.put(session,userClient); 
         } 

         logger.fine("Creating a FacebookWebappHelper, which copies fb_ request param data into the userClient"); 
         FacebookWebappHelper<Document> facebook = new FacebookWebappHelper<Document>(request, response, api_key, secret, userClient); 
         String nextPage = request.getRequestURI(); 
         nextPage = nextPage.substring(nextPage.indexOf("/", 1) + 1); //cut out the first /, the context path and the 2nd/
         logger.fine(nextPage); 
         boolean redirectOccurred = facebook.requireLogin(nextPage); 
         if(redirectOccurred) { 
           return; 
         } 
         redirectOccurred = facebook.requireFrame(nextPage); 
         if(redirectOccurred) { 
           return; 
         } 

         long facebookUserID; 
         try { 
          facebookUserID = userClient.users_getLoggedInUser(); 
          logger.info("facebookUserID "+facebookUserID+" "+session.getId()); 

         } catch(FacebookException ex) { 
          response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error while fetching user's facebook ID"); 
          logger.warning("Error while getting cached (supplied by request params) value " + 
              "of the user's facebook ID or while fetching it from the Facebook service " + 
              "if the cached value was not present for some reason. Cached value = {} "+ userClient.getCacheUserId()); 
          return; 
         } 
         chain.doFilter(request, response); 
       } 
     } 

    public static FacebookXmlRestClient getUserClient(HttpSession session) { 
      if(map.containsKey(session)) 
      { 
       logger.info("return match "+session.getId()); 
       return (FacebookXmlRestClient) map.get(session); 
      }  
      else 
      { 
       logger.warning("getUserClient() null "+session.getId()); 
       return null; 
      } 

    } 
} 

Répondre

0

Tous les objets que vous avez dans un HttpSession devront être marqués comme Serializable. (GAE utilise le datastore pour stocker les données de session)

Vous vous demandez simplement, au lieu d'utiliser la HttpSession comme clé dans la carte, essayez d'utiliser l'ID de session? .: par exemple

map.put(session.getId(),userClient); 

+0

Je ne suis pas la mise en userClient comme attribut ou paramètre de la session http ou objet de requête (pour éviter la question sérialisable) il est ajouté à une carte simple. – emeraldjava

+0

Vient-il le même message d'erreur lorsque vous essayez de le mettre dans la carte? Avez-vous essayé ma suggestion (en utilisant l'identifiant de session)? –