使用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的旧版方法,导致运行时找不到对应方法。
具体解决步骤:
- 弃用Spring Social Twitter:该项目已停止维护多年,不支持Spring Boot 3.x,也无法适配现代Twitter API(API v2)。
- 切换到官方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>
- 在pom.xml中添加依赖:
- 调整私信发送代码:官方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(); } } } - 权限配置:需要在Twitter开发者平台为应用申请
dm.write权限,否则无法发送私信。
如果坚持使用Spring生态,也可以用spring-boot-starter-oauth2-client配合RestTemplate手动调用Twitter API,但官方SDK的封装更完善,维护成本更低。
内容的提问来源于stack exchange,提问作者Clayn
相关产品推荐
相关产品推荐

