0

私は JSF 2.0、Spring Social Facebook、Google App Engine を使用しています。コードを実行するとエラーが発生します。

web.xml:

    <welcome-file-list>
        <welcome-file>login.jsf</welcome-file>
   </welcome-file-list>

login.jsf:

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:prime="http://primefaces.org/ui">


     <h:outputText value="#{user.text}" />

</html>

UserSessionMbean:

@ManagedBean(name = "user")
@SessionScoped
public final class UserSessionMBean implements Serializable {

OAuth2Operations oauthOperations = null;
FacebookConnectionFactory connectionFactory = null;
private Facebook fbUserSession = null;

private String text = "Loging...";

public UserSessionMBean() {
    connectionFactory = new FacebookConnectionFactory("MY_KEY",
            "MY_SECRET");
    oauthOperations = connectionFactory.getOAuthOperations();
}


public void facebookLogin() {

    try {

        ExternalContext ec = FacesContext.getCurrentInstance()
                .getExternalContext();

        HttpServletRequest httpServletRequest = null;
        Object request = ec.getRequest();

        if (request instanceof HttpServletRequest) {
            httpServletRequest = (HttpServletRequest) request;
        }

        String code = httpServletRequest.getParameter("code");

        if (StringUtil.isNotBlankStr(code)) {

            // upon receiving the callback from the provider:
            AccessGrant accessGrant = oauthOperations.exchangeForAccess(
                    code, "http://localhost:8888/", null);

            Connection<Facebook> connection = connectionFactory
                    .createConnection(accessGrant);

            setFbUserSession(connection != null ? connection.getApi()
                    : new FacebookTemplate());

            ec.getSessionMap().put("fbUserSession", fbUserSession);

            ec.redirect("init.jsf");

        } else {

            OAuth2Parameters params = new OAuth2Parameters();
            params.setRedirectUri("http://localhost:8888/");

            params.setScope("publish_stream");
            params.setScope("email");
            params.setScope("offline_access");

            String authorizeUrl = oauthOperations.buildAuthorizeUrl(
                    GrantType.AUTHORIZATION_CODE, params);
            ec.redirect(authorizeUrl);
            return;
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}


public String getText() {
    facebookLogin();
    return text;
}

エラーが発生する場所:

ec.getSessionMap().put("fbUserSession", fbUserSession);

エラー:

23/08/2013 21:36:36 com.google.apphosting.utils.jetty.JettyLogger warn
AVISO: /
java.lang.RuntimeException: java.io.NotSerializableException:     org.springframework.social.facebook.connect.FacebookConnectionFactory
       at com.google.appengine.tools.development.SerializableObjectsOnlyHashSessionManager$SerializableObjectsOnlyHttpSession.checkCanSerialize(SerializableObjectsOnlyHashSessionManager.java:66)
      at com.google.appengine.tools.development.SerializableObjectsOnlyHashSessionManager$SerializableObjectsOnlyHttpSession.setAttribute(SerializableObjectsOnlyHashSessionManager.java:43)
      at com.sun.faces.context.SessionMap.put(SessionMap.java:141)
      at com.sun.faces.context.SessionMap.put(SessionMap.java:61)
      at com.sun.faces.mgbean.BeanManager$ScopeManager$SessionScopeHandler.handle(BeanManager.java:576)
      at com.sun.faces.mgbean.BeanManager$ScopeManager.pushToScope(BeanManager.java:458)
      at com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:410)
      at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:269)
      at com.sun.faces.el.ManagedBeanELResolver.resolveBean(ManagedBeanELResolver.java:244)
      at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:116)
      at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
      at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
      at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:68)
      at org.apache.el.parser.AstValue.getValue(AstValue.java:112)
      at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
      at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
      at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
      at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
      at javax.faces.component.UIOutput.getValue(UIOutput.java:169)
      at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
      at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:355)
      at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164)
      at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
      at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1786)
      at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782)
      at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:424)
      at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:124)
      at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
      at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
      at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
      at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
      at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
      at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
      at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectRequest(DevAppServerModulesFilter.java:368)
      at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectModuleRequest(DevAppServerModulesFilter.java:351)
      at com.google.appengine.tools.development.DevAppServerModulesFilter.doFilter(DevAppServerModulesFilter.java:116)
      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.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:97)
      at org.mortbay.jetty.servlet.Dispatcher.forward(Dispatcher.java:327)
      at org.mortbay.jetty.servlet.Dispatcher.forward(Dispatcher.java:126)
      at com.google.appengine.tools.development.StaticFileUtils.serveWelcomeFileAsForward(StaticFileUtils.java:82)
      at com.google.appengine.tools.development.LocalResourceFileServlet.maybeServeWelcomeFile(LocalResourceFileServlet.java:247)
      at com.google.appengine.tools.development.LocalResourceFileServlet.doGet(LocalResourceFileServlet.java:120)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
      at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
      at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
      at br.com.caronagem.config.HttpIfModifiedSinceFix.doFilter(HttpIfModifiedSinceFix.java:54)
      at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
      at com.googlecode.objectify.cache.AsyncCacheFilter.doFilter(AsyncCacheFilter.java:59)
      at com.googlecode.objectify.ObjectifyFilter.doFilter(ObjectifyFilter.java:49)
      at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
      at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74)
      at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
      at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:123)
      at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
      at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
      at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
      at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:63)
      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 com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125)
      at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
      at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectRequest(DevAppServerModulesFilter.java:368)
      at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectModuleRequest(DevAppServerModulesFilter.java:351)
      at com.google.appengine.tools.development.DevAppServerModulesFilter.doFilter(DevAppServerModulesFilter.java:116)
      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.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:97)
      at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
      at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:485)
      at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
      at org.mortbay.jetty.Server.handle(Server.java:326)
      at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
      at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
      at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:547)
      at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
      at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
      at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
      at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Caused by: java.io.NotSerializableException: org.springframework.social.facebook.connect.FacebookConnectionFactory
      at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
      at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
      at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
      at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
      at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
      at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
      at com.google.appengine.tools.development.SerializableObjectsOnlyHashSessionManager$SerializableObjectsOnlyHttpSession.checkCanSerialize(SerializableObjectsOnlyHashSessionManager.java:64)
... 89 more
4

1 に答える 1

1

解決策は簡単です。シリアル化できないインスタンスをシリアル化可能なクラスのプロパティとして宣言しないことです。セッション スコープ Bean は、ハードディスク (低メモリ プロファイルのサーバーなど) に保存したり、ネットワーク経由で (サーバー クラスターなど) 転送したりできるため、シリアル化する必要があります。ただし、「接続」を表すオブジェクトは、単純にパッシベーションできないため、明らかにシリアル化できません。

セッション スコープ Bean を書き直して、メソッド ローカル スコープ内、つまり完全にメソッド ブロック内で作成および破棄されるようにする必要があります。少なくとも public スコープに入ってはなりません (private static ヘルパー メソッドは問題ありません)。

したがって、との 3 つの宣言をメソッド内に移動するだけでoauthOperations、外部に渡さないでください。connectionFactoryfbUserSessionfacebookLogin()

public void facebookLogin() {
    OAuth2Operations oauthOperations = connectionFactory.getOAuthOperations();
    FacebookConnectionFactory connectionFactory = new FacebookConnectionFactory("MY_KEY", "MY_SECRET");
    Facebook fbUserSession = null;
    // ...

もう 1 つの原因は、fbUserSession不明な理由で HTTP セッションに手動で配置したことです。あなたはそれをすべきではありません。は、コードが FB とやり取りできるfbUserSessionセッションを表します。ただし、メソッドが終了した後、これを開いたままにすることはできません。新しい HTTP 要求で閉じてから再度開く必要があります。HTTP セッションまたはそれを表すものではありません。代わりに、FB セッションから必要な情報を抽出し、その情報を代わりにセッションに保存する必要があります (通常、必要に応じて別の Bean にラップされた 、 などのフレーバー) StringIntegerまたは、それを現在のセッション スコープ Bean のプロパティとして割り当てるだけです。

于 2013-08-24T01:35:00.650 に答える