Spring, Obiekt Scope nie jest wstrzykiwany

0

Witam, mam następującą sytuację:

Używam Twitter4J do OAutha Twitterowego i pobrania AccessTokena użytkownika gdy wyrazy zgodę na działanie aplikacji.

Jako, że URL do autoryzacji ustalam w jednym kontrolerze, a autoryzację przeprowadzam w innym to zadeklarowałem mój obiekt w sesji za pomocą scope = session. Możliwym jest też, że ja źle rozumiem pojęcie "sesji" i gdy Tweeter mnie przekierowuje z powrotem to jest już inna sesja? Jeśli tak to proszę o radę jak to rozwiązać.

Wszystko poniżej:

Obiekt który ma być utrzymywany w sesji:

package org.server.model.socialmedia.apikeys.view;

import java.io.Serializable;

public class AuthInfo implements Serializable {

    private String token;

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    private String tokenSecret;
    
    public String getTokenSecret() {
        return tokenSecret;
    }

    public void setTokenSecret(String tokenSecret) {
        this.tokenSecret = tokenSecret;
    }
    
    private String authURL;

    public String getAuthURL() {
        return authURL;
    }

    public void setAuthURL(String authURL) {
        this.authURL = authURL;
    }
} 

Definicja beanu:

<bean id="scopedAuthInfo" class="org.server.model.socialmedia.apikeys.view.AuthInfo" scope="session">
        <aop:scoped-proxy/>
    </bean> 

Użycie w kontrolerze, który generuje URL i zapisuje tokeny który muszą być potem wykorzystane w drugim kontrolerze:

 @Autowired
    AuthInfo scopedAuthInfo;
@RequestMapping(value = "/ProfileSocialMedia", method = RequestMethod.GET)
    public String ProfileSocialMedia(HttpSession session, Model model)
    {
        try {
            AuthInfo tempInfo = authService.getAuthInfo();
            scopedAuthInfo.setToken(tempInfo.getToken());
            scopedAuthInfo.setTokenSecret(tempInfo.getTokenSecret());
            model.addAttribute("twitterAuthUrl", tempInfo.getAuthURL());
        } catch (AuthorizationLinkGenerationException ex) {
            Logger.getLogger(UserProfileSocialMediaController.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return "UserProfileSocialMedia";
    }

Drugi kontroler:

@Autowired
    AuthInfo scopedAuthInfo;
    
    @RequestMapping(value = "/TwitterSuccessAuth")
    public String TwitterFinishAuthorize(HttpServletRequest request)
    {
        String verifier = request.getParameter("oauth_verifier");
        
        try {
            List<ApiKeyView> tokens = authService.getAuthorizedApiKeys(scopedAuthInfo.getToken(), scopedAuthInfo.getTokenSecret(), verifier);
            
            for (ApiKeyView singleApiKey : tokens)
                System.out.println(singleApiKey.getKeyName() + " : " + singleApiKey.getValueKey());
        } catch (AuthorizationFailedException ex) {
            return "Twitter/TwitterFailedAuth";
        }
        
        return "Twitter/TwitterSuccessfulAuth";
    } 

Niestety w drugim kontrolerze za każdym razem dostaję null w :
scopedAuthInfo.getToken(), scopedAuthInfo.getTokenSecret()

Pewnie to jakiś głupi błąd, ale nie potrafię sobie poradzić.
Za wszelką pomoc podziękowania

0

Próbujesz wstrzykiwać sesyjny bean do beana singletonowego. To nie będzie działać bo niby jak? Masz JEDEN obiekt kontrolera a chcesz nagle żeby jakoś auto-magicznie miał pole które jest sesyjne. Żeby to zadziałało to musiałbyś temu kontrolerowi dać scope request.

edit: nie doczytałem tego twojego xmla (kto jeszcz tak definiuje beany? ;])

0

Coś robisz źle, weź tego beana może spróbuj na chama wsadzić do tego settera przez XML'a

0

Oczywiście miałeś rację, była to moja głupota.

Ogromne podziękowania.

0

Ups, przeprasza za double post ale w chwili pisania odpowiedzi nie widziałem Waszych komentarzy.

Ustawienia scope'a controllerów na Request podziałało, z Waszych najnowszych komentarzy wnioskuję że wcześniejszy kod i tak powinien działać?

1

Widzę jeszcze jeden potencjalny problem. Wstrzykujesz przez klasę a nie przez interfejs a to rodzi problemy z dynamicznym proxy aop. Możesz wymusić użycie class proxy z cgliba albo zrobić interfejs dla tego twojego beana którego wstrzykujesz i wstrzykiwać interfejs.

0

Myślę, że zastosowałem się do Waszych komentarzy i wykonałem to w taki sposób (nigdy nie chciałem XML'a - było tylko dla testu). Jednak dalej jest ta sytuacja z nullem.

Dodany interfejs:

package org.server.model.socialmedia.apikeys.view.interfaces;

public interface IAuthInfo {

    String getAuthURL();
    void setAuthURL(String url);
    String getAccessToken();
    void setAccessToken(String accessToken);
    String getAccessTokenSecret();
    void setAccessTokenSecret(String accessTokenSecret);
}
 

Implementacja:

package org.server.model.socialmedia.apikeys.view.implementations;

import java.io.Serializable;
import org.server.model.socialmedia.apikeys.view.interfaces.IAuthInfo;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;

@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES)
public class AuthInfo implements IAuthInfo, Serializable {

    private String accessToken;
    
    @Override
    public String getAccessToken() {
        return accessToken;
    }
    
    @Override
    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }

    private String accessTokenSecret;

    @Override
    public String getAccessTokenSecret() {
        return accessTokenSecret;
    }

    @Override
    public void setAccessTokenSecret(String accessTokenSecret) {
        this.accessTokenSecret = accessTokenSecret;
    }
       
    private String authURL;

    @Override
    public String getAuthURL() {
        return authURL;
    }

    @Override
    public void setAuthURL(String authURL) {
        this.authURL = authURL;
    }
}
 

Kontrolery są obecnie bez Scope na Request.

 @Autowired
    IAuthInfo scopedAuthInfo;
    
    @RequestMapping(value = "/ProfileSocialMedia", method = RequestMethod.GET)
    public String ProfileSocialMedia(HttpSession session, Model model)
    {
        try {
            IAuthInfo tempInfo = authService.getAuthInfo();
            scopedAuthInfo.setAccessToken(tempInfo.getAccessToken());
            scopedAuthInfo.setAccessTokenSecret(tempInfo.getAccessTokenSecret());
            model.addAttribute("twitterAuthUrl", tempInfo.getAuthURL());
        } catch (AuthorizationLinkGenerationException ex) {
            Logger.getLogger(UserProfileSocialMediaController.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return "UserProfileSocialMedia";
    }
 @Autowired
    IAuthInfo scopedAuthInfo;
    
    @RequestMapping(value = "/TwitterSuccessAuth")
    public String TwitterFinishAuthorize(HttpServletRequest request)
    {
        String verifier = request.getParameter("oauth_verifier");
        
        try {
            List<ApiKeyView> tokens = authService.getAuthorizedApiKeys(scopedAuthInfo.getAccessToken(), scopedAuthInfo.getAccessTokenSecret(), verifier);
            
            for (ApiKeyView singleApiKey : tokens)
                System.out.println(singleApiKey.getKeyName() + " : " + singleApiKey.getValueKey());
        } catch (AuthorizationFailedException ex) {
            return "Twitter/TwitterFailedAuth";
        }
        
        return "Twitter/TwitterSuccessfulAuth";
    }
0

A jesteś pewien że spring wykrywa te beany? Nie leży to w jakimś pakiecie którego nie skanujesz automatycznie? Masz właczone annotation config i dobrą ścieżke w context component scan w kontekście?

0

Konfiguracja w XMLu (applicationContext.xml):

 <context:annotation-config/>
    <context:component-scan base-package="org.server" />
    <mvc:resources mapping="/resources/**" location="/resources/" cache-period="31556926"/>
    <mvc:annotation-driven />
0

Ktokolwiek? Dalej z tym walczę, jeśli potrzeba więcej kodu /więcej konfiguracji z XML'a to napiszcie.

0

Zrób z tego minimalny projekt który pokazuje twój problem i wrzuć na githuba jakiegoś. Przez minimalny rozumiem że będą tam tylko 2 klasy -> ten bean i kontroller i w ogóle projekt nie będzie robił nic oprócz demonstrowania twojego problemu.

0

Minimalny projekt oczywiście działa jak powinien dlatego zacząłem dłubać dalej i znalazłem na pewno ciekawy trop ale nie potrafię go wyjaśnić co pewnie wynika z mojego braku wiedzy.

Pod adresem:

/ProfileSocialMedia wartości są nadawane bez problemu
/TwitterSuccessAuth mają zostać odczytane

I teraz fakt: Gdy sam ręcznie przejdę na /TwitterSuccessAuth po wejściu na /ProfileSocialMedia wszystko jest okej. Natomiast gdy TWITTER mnie przekierowuje z powrotem na TwitterSuccessAuth?oauth=string_blblbl to dostaję NULLa. Czy przekierowanie z Twittera jest traktowane jako osobna sesja ponieważ przyszło z zewnętrznego serwera? Jeśli tak to jak temu zaradzić?

0

Okej mój debilizm, ustawiałem przekierowanie Twitter na 127.0.0.1 a GlassFish odpalany jest u mnie pod localhostem co według mnie powodowało że ciasteczka były pod inne nazwy i przez co traciłem sesję. Po zmianie adresu Twitter na localhost:8080 bla bla bla wszystko działa.

1 użytkowników online, w tym zalogowanych: 0, gości: 1