2
votes

I have a webapp using Spring Social.

I have a button to connect a logged in user to Twitter as per the example in the docs (posting to /connect/twitter) and my user can connect to twitter account and get all the usual account info/token etc.

However, I want to override the default behaviour of Spring-Social after it has connected to the twitter account (in this case, I dont want to have to implement the default views, I want success/failure to direct users back to the normal home page and will provide info etc). So I have overriden ConnectController, and all is good:

@Controller
@RequestMapping("/connect")
public class ConnectController extends org.springframework.social.connect.web.ConnectController {

    @Inject
    public ConnectController(ConnectionFactoryLocator connectionFactoryLocator, ConnectionRepository connectionRepository) {
        super(connectionFactoryLocator, connectionRepository);
    }

    @Override
    protected String connectedView(String providerId) {
        return "redirect:/";
    }

}

I connect to twitter, and my overriden ConnectController takes over and redirects users to home page rather than attempting to find the relevant view.

However, I now also want to provide an interceptor that automatically makes a further API call to grab some more data once connected - and following the example here: http://docs.spring.io/spring-social/docs/1.0.x/reference/htmlsingle/#connect-interceptors I have created an Interceptor:

public class TwitterConnectionInterceptor implements ConnectInterceptor<Twitter> {

    @Autowired TwitterService twitterService;

    @Override
    public void preConnect(ConnectionFactory<Twitter> connectionFactory, MultiValueMap<String, String> parameters, WebRequest request) { }

    @Override
    public void postConnect(Connection<Twitter> connection, WebRequest request) {
        twitterService.importTwiterDetails();
    }
}

Following the docs linked above, I have also updated my config to explicitly add the interceptor to my ConnectController:

@Bean public TwitterConnectionInterceptor twitterConnectionInterceptor(){
    return new TwitterConnectionInterceptor();
}

@Bean public ConnectController connectController() {
    com.tmm.frm.spring.social.ConnectController controller = new com.tmm.frm.spring.social.ConnectController(connectionFactoryLocator(),
        connectionRepository());
    controller.addInterceptor(twitterConnectionInterceptor());
    return controller;
}

However, When I connect to Twitter, the interceptor is not firing (debugging it, the interceptor is not registered on my controller). I thought maybe this was because my ConnectController class has the @Controller annotation and is in one of the packages that I scan at startup, however, I have tried moving that controller out of the scanned packages and just leave it to my explicit bean configuration but then it just isn't registered at all and I don't get my custom redirect.

Can anyone advise how I can override the controller and add an interceptor or what I might be doing wrong?

2

2 Answers

1
votes

Try injecting the interceptor and then adding interceptor in the @PostConstruct phase ?

@Controller
@RequestMapping("/connect")
public class ConnectController extends org.springframework.social.connect.web.ConnectController {

    private TwitterConnectionInterceptor twitterConnInterceptor ;

    @Inject
    public ConnectController(ConnectionFactoryLocator connectionFactoryLocator, ConnectionRepository connectionRepository,TwitterConnectionInterceptor twitterConnInterceptor) {
        super(connectionFactoryLocator, connectionRepository);
        this.twitterConnInterceptor = twitterConnInterceptor; 
    }

    @PostConstruct
    public void addInterceptor(){
       this.addInterceptor(twitterConnInterceptor);
    }

    @Override
    protected String connectedView(String providerId) {
        return "redirect:/";
    }

}

Ok not ideal but should work.

1
votes

I just had the same question when I landed here, but didn't liked the accepted solution. After taking a look at the code, I observed that it's enough to create a bean annotated with @Component and the interceptor will be automatically added.

Therefore, my solution is:

@Component
public class MyFacebookConnectInterceptor implements ConnectInterceptor<Facebook>{

    @Override
    public void preConnect(ConnectionFactory connectionFactory, MultiValueMap multiValueMap, WebRequest webRequest) {

    }

    @Override
    public void postConnect(Connection connection, WebRequest webRequest) {

    }
}

NOTE: This solution didn't worked for me at the first time because when I implemented the ConnectInterceptor interface, I didn't specified the generic type <Facebook>. It will not work without.

Edit: if you want to change more properties than adding an interceptor, you can use Post Bean Processor.