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

使用spring-social-twitter时遭遇java.lang.NoSuchMethodError错误

问题描述

我尝试通过Spring库spring-social-twitter调用Twitter API,调用sendDirectMessage(String toScreenName, String text)方法时抛出如下异常:

java.lang.NoSuchMethodError: 'org.springframework.http.HttpStatus org.springframework.http.client.ClientHttpResponse.getStatusCode()'
    at org.springframework.social.twitter.api.impl.TwitterErrorHandler.handleError(TwitterErrorHandler.java:56) ~[spring-social-twitter-1.1.0.RELEASE.jar:1.1.0.RELEASE]
    at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63) ~[spring-web-6.0.4.jar:6.0.4]
    at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:915) ~[spring-web-6.0.4.jar:6.0.4]
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:864) ~[spring-web-6.0.4.jar:6.0.4]
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:804) ~[spring-web-6.0.4.jar:6.0.4]
    at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:503) ~[spring-web-6.0.4.jar:6.0.4]
    at org.springframework.social.twitter.api.impl.DirectMessageTemplate.sendDirectMessage(DirectMessageTemplate.java:77) ~[spring-social-twitter-1.1.0.RELEASE.jar:1.1.0.RELEASE]
    at com.example.twittertest.TwitterController.send(TwitterController.java:17) ~[classes/:na]
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:731) ~[tomcat-embed-core-10.1.5.jar:6.0]
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:814) ~[tomcat-embed-core-10.1.5.jar:6.0]

TwitterTemplate配置

@Component
public class TwitterTemplateCreator {
    public Twitter getTwitterTemplate() {
        return new TwitterTemplate(
                "<cosumerKey>",
                "<consumerSecret>",
                "<accessToken>",
                "<accessTokenSecret>");
    }
}

TwitterController代码

@RestController
@RequestMapping(("/api"))
public class TwitterController {
    @Autowired
    private TwitterTemplateCreator twitterTemplateCreator;

    @PostMapping(value = "/send")
    public void send(@RequestParam("name") String name, @RequestParam("text") String text) {
        twitterTemplateCreator.getTwitterTemplate().directMessageOperations().sendDirectMessage(name, text);
    }
}

pom.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>twitter-test</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>twitter-test</name>
    <description>twitter-test</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.social</groupId>
            <artifactId>spring-social-twitter</artifactId>
            <version>1.1.0.RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

我猜测是依赖版本不一致,但尝试更换不同Spring Boot版本后仍未解决问题。


解决方案

这个NoSuchMethodError的核心原因是Spring Social Twitter 1.1.0.RELEASE与Spring Boot 3.x版本完全不兼容:

  • Spring Boot 3.x依赖的Spring Web 6.x中,ClientHttpResponse.getStatusCode()方法的返回值已从int改为HttpStatus枚举;
  • 而Spring Social Twitter 1.1.0基于2016年的旧版Spring Framework(4.x)开发,调用的是返回int的旧版方法,导致运行时找不到对应方法。

具体解决步骤:

  1. 弃用Spring Social Twitter:该项目已停止维护多年,不支持Spring Boot 3.x,也无法适配现代Twitter API(API v2)。
  2. 切换到官方Twitter API SDK:使用Twitter官方的twitter-api-java-sdk,它支持Spring Boot 3.x和Java 17,且适配最新的Twitter API v2。
    • 在pom.xml中添加依赖:
      <dependency>
          <groupId>com.twitter</groupId>
          <artifactId>twitter-api-java-sdk</artifactId>
          <version>2.1.4</version> <!-- 可替换为最新稳定版 -->
      </dependency>
      
  3. 调整私信发送代码:官方SDK的调用逻辑与Spring Social不同,示例如下:
    import com.twitter.clientlib.TwitterCredentialsOAuth1;
    import com.twitter.clientlib.api.TwitterApi;
    import com.twitter.clientlib.model.*;
    
    @Component
    public class TwitterClient {
        private final TwitterApi twitterApi;
    
        public TwitterClient() {
            // 使用OAuth 1.0a凭证(对应原Spring Social的密钥配置)
            TwitterCredentialsOAuth1 credentials = new TwitterCredentialsOAuth1(
                    "<consumerKey>",
                    "<consumerSecret>",
                    "<accessToken>",
                    "<accessTokenSecret>"
            );
            twitterApi = new TwitterApi(credentials);
        }
    
        public void sendDirectMessage(String recipientUsername, String text) {
            try {
                // 先通过用户名获取用户ID(Twitter API v2私信需要用户ID而非用户名)
                String recipientId = twitterApi.users().findUserByUsername(recipientUsername)
                        .execute()
                        .getData()
                        .getId();
    
                // 构造私信请求
                MessageCreateText messageText = new MessageCreateText().text(text);
                MessageCreate messageCreate = new MessageCreate().text(messageText);
                DirectMessageEventCreateRequestData data = new DirectMessageEventCreateRequestData()
                        .messageCreate(messageCreate)
                        .target(recipientId);
                DirectMessageEventCreateRequest request = new DirectMessageEventCreateRequest().data(data);
    
                // 发送私信
                twitterApi.directMessages().createDirectMessage(request).execute();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
  4. 权限配置:需要在Twitter开发者平台为应用申请dm.write权限,否则无法发送私信。

如果坚持使用Spring生态,也可以用spring-boot-starter-oauth2-client配合RestTemplate手动调用Twitter API,但官方SDK的封装更完善,维护成本更低。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 03:01:00