You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot调用Strava API空指针问题及认证实现方案咨询

问题根源分析

本次NPE问题和Strava认证逻辑无关,完全是Spring依赖注入使用错误导致,具体原因如下:

  • @Autowired无法注入静态成员变量。Spring依赖注入的核心是给容器管理的实例对象的成员变量赋值,而static修饰的变量属于类层面的属性,在类加载阶段就完成初始化,早于Spring Bean的初始化流程,因此注入失效,导致activitiesApi始终为null。
  • Adapter类未被纳入Spring容器管理。你没有给Adapter类加@Component、@Service等容器注解,Spring不会扫描处理该类的@Autowired注解,就算去掉static修饰也无法完成注入。
  • 你在main方法中直接调用静态方法Adapter.getActivities,此时就算Adapter的实例被注入了属性,静态方法访问的也是类层面的静态变量,依然拿不到Bean实例。
注入问题修复方案

1. 修正Adapter类,交给Spring管理,移除static修饰

@Component
public class Adapter {
    @Autowired
    private ActivitiesApi activitiesApi;
    
    public void getActivities(Integer before, Integer after, Integer page, Integer perPage) {
        final List<SummaryActivity> loggedInAthleteActivities = activitiesApi.getLoggedInAthleteActivities(before, after, page, perPage);
        System.out.println("总活动数:"+ loggedInAthleteActivities.size());
    }
}

2. 修正启动类调用逻辑,从Spring容器中取Adapter实例

@SpringBootApplication
@Import(StravaIntegrationConfiguration.class)
public class App {

    public static void main(String[] args) throws SQLException {
        ConfigurableApplicationContext context = SpringApplication.run(App.class);
        // 从容器中获取Adapter实例
        Adapter adapter = context.getBean(Adapter.class);
        adapter.getActivities(1636130496, 1635529296, 1,  30);
    }
}

完成以上修改即可解决NPE问题,接下来即可对接Strava的认证逻辑。

Strava OAuth2认证实现示例

Strava使用OAuth2授权码流程认证,你需要先在Strava应用设置中配置回调地址,下面是完整的认证配置:

1. 在application.yml中配置Strava参数

strava:
  client-id: 你注册应用拿到的client_id
  client-secret: 你注册应用拿到的client_secret
  redirect-uri: 你在Strava后台配置的回调地址,比如http://localhost:8080/strava/callback
  token-url: https://www.strava.com/oauth/token
  scope: activity:read_all

2. 改造Strava配置类,添加认证逻辑

@Configuration
@ConfigurationProperties(prefix = "strava")
public class StravaIntegrationConfiguration {
    private String clientId;
    private String clientSecret;
    private String redirectUri;
    private String tokenUrl;
    // 省略各属性的getter、setter方法

    @Bean
    public ActivitiesApi stravaApi(ApiClient apiClient){
        return new ActivitiesApi(apiClient);
    }

    @Bean
    public ApiClient apiClient(OAuth2AccessToken accessToken){
        ApiClient apiClient = new ApiClient();
        // 给ApiClient设置认证请求头
        apiClient.setAccessToken(accessToken.getValue());
        return apiClient;
    }

    // 自动刷新token的Bean,首次使用需要先拿到refresh token
    @Bean
    public OAuth2AccessToken stravaToken() {
        // 首次授权可手动拼接授权地址在浏览器打开,授权后拿到code,用code兑换首次的refresh token
        String refreshToken = "你首次授权拿到的长效refresh_token";
        RestTemplate restTemplate = new RestTemplate();
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("client_id", clientId);
        params.add("client_secret", clientSecret);
        params.add("grant_type", "refresh_token");
        params.add("refresh_token", refreshToken);
        
        ResponseEntity<Map> response = restTemplate.postForEntity(tokenUrl, params, Map.class);
        Map<String, Object> tokenInfo = response.getBody();
        return new DefaultOAuth2AccessToken((String) tokenInfo.get("access_token"));
    }
}

首次获取refresh token方式

拼接如下地址在浏览器打开,登录你的Strava账号授权后,回调地址的参数中会返回授权code:
https://www.strava.com/oauth/authorize?client_id=你的client_id&response_type=code&redirect_uri=你的回调地址&scope=activity:read_all
拿到code之后,POST请求https://www.strava.com/oauth/token,携带参数client_id、client_secret、code、grant_type=authorization_code,即可拿到首次的access token和长效refresh token。

内容的提问来源于stack exchange,提问作者Anna Bar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 05:54:02