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

使用Microsoft Graph API发送带附件邮件时遇NoSuchMethodError求助

使用Microsoft Graph API发送带附件邮件时遇到NoSuchMethodError错误排查

我在基于Microsoft官方文档开发使用Graph API发送带附件的邮件时遇到错误,该错误仅在为Message添加Attachment列表时触发。

错误详情

错误发生在com.microsoft.graph.serializer.CollectionPageSerializer类的序列化方法中,错误日志如下:

[2022-09-22T09:41:04.345Z] System.Private.CoreLib: Exception while executing function: Functions.QueueTriggerMails. System.Private.CoreLib: Result: Failure
Exception: NoSuchMethodError: com.google.gson.JsonParser.parseString(Ljava/lang/String;)Lcom/google/gson/JsonElement;
Stack: java.lang.reflect.InvocationTargetException
.
.
.
[2022-09-22T09:41:04.356Z] Caused by: java.lang.NoSuchMethodError: com.google.gson.JsonParser.parseString(Ljava/lang/String;)Lcom/google/gson/JsonElement;
[2022-09-22T09:41:04.356Z] at com.microsoft.graph.serializer.CollectionPageSerializer.serialize(CollectionPageSerializer.java:78)
.
.
.

触发错误的序列化方法代码:

/**
 * Serializes an CollectionPage
 *
 * @param src the CollectionPage variable for serialization
 * @param logger the logger
 * @param <T1> the entity type for the collection
 * @param <T2> the collection request builder interface type
 * @return       JsonElement of CollectionPage
 */
@Nullable
public static <T1, T2 extends BaseRequestBuilder<T1>> JsonElement serialize(@Nonnull final BaseCollectionPage<T1, T2> src, @Nonnull final ILogger logger) {
    if(src == null) {
        return null;
    }
    Objects.requireNonNull(logger, "parameter logger cannot be null");
    JsonArray jsonArray = new JsonArray();
    List<T1> items = src.getCurrentPage();
    serializer = new DefaultSerializer(logger);
    for(T1 item : items) {
        final String json = serializer.serializeObject(item);
        final JsonElement element = JsonParser.parseString(json);
        if(element != null && element.isJsonObject()) {
            final JsonObject jsonObject = element.getAsJsonObject();
            jsonArray.add(jsonObject);
        }
    }
    return jsonArray;
}

相关业务代码

发送邮件核心方法

public void sendEmail(Mail mailProperties, ExecutionContext context) {

    final TokenCredentialAuthProvider tokenCredentialAuthProvider = new TokenCredentialAuthProvider(scopes, clientSecretCredential);

    GraphServiceClient<Request> graphClient = GraphServiceClient
            .builder()
            .authenticationProvider(tokenCredentialAuthProvider)
            .buildClient();

    try {
        graphClient.users(noReplyUserId)
                .sendMail(UserSendMailParameterSet
                    .newBuilder()
                    .withMessage(createMessage(mailProperties, context))
                    .withSaveToSentItems(null)
                    .build())
                .buildRequest()
                .post();
    } catch (ClientException | IllegalArgumentException e) {
        context.getLogger().warning("Couldn't send the email due to errors while reading the input message");
        context.getLogger().warning(e.getMessage());
    }

}

创建带附件的邮件方法

private Message createMessage(Mail mailProperties, ExecutionContext context) throws IllegalArgumentException {
    Message message = new Message();
    ItemBody body = new ItemBody();
    body.contentType = BodyType.HTML;
    
    String bodyContent = new String(Base64.getDecoder().decode(mailProperties.getBody()), StandardCharsets.UTF_8);
    body.content = bodyContent;

    List<Recipient> recipientsList = new ArrayList<>();
    for (String item : mailProperties.getDestinatario().split(",")) {
        EmailAddress emailAddress = new EmailAddress();
        emailAddress.address = item.trim();
        
        Recipient recipient = new Recipient();
        recipient.emailAddress = emailAddress;
        recipientsList.add(recipient);
    }

    message.subject = mailProperties.getSubject();
    message.body = body;
    message.toRecipients = recipientsList;
    
    FileAttachment attachment = new FileAttachment();
    attachment.name = "attachment.txt";
    attachment.contentType = "text/plain";
    attachment.contentBytes = Base64.getDecoder().decode("SGVsbG8gV29ybGQh");

    List<Attachment> attachmentsList = new ArrayList<Attachment>();
    attachmentsList.add(attachment);

    AttachmentCollectionResponse attachmentCollectionResponse = new AttachmentCollectionResponse();
    attachmentCollectionResponse.value = attachmentsList;
    AttachmentCollectionPage attachmentCollectionPage = new AttachmentCollectionPage(attachmentCollectionResponse, null);
    
    message.attachments = attachmentCollectionPage;

    return message;
}

依赖配置

使用的Graph API版本为5.31.0,Maven依赖声明如下:

<dependency>
    <groupId>com.microsoft.graph</groupId>
    <artifactId>microsoft-graph</artifactId>
    <version>5.31.0</version>
</dependency>

问题分析与解决步骤

核心原因

NoSuchMethodError表示运行时无法找到JsonParser.parseString()方法,该方法是Gson 2.8.0及以上版本才新增的API。问题根源是项目依赖的Gson版本低于要求,或存在多版本Gson依赖冲突,导致Graph SDK运行时加载了旧版本Gson。

解决措施

  1. 升级Gson依赖版本
    在Maven中明确指定Gson版本为2.8.0或更高(建议使用与Graph SDK 5.31.0兼容的版本,可通过mvn dependency:tree命令查看当前依赖树):

    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.10.1</version>
    </dependency>
    
  2. 排除冲突的旧版本Gson
    如果其他依赖引入了旧版本Gson,在Graph SDK依赖中排除该冲突依赖:

    <dependency>
        <groupId>com.microsoft.graph</groupId>
        <artifactId>microsoft-graph</artifactId>
        <version>5.31.0</version>
        <exclusions>
            <exclusion>
                <groupId>com.google.code.gson</groupId>
                <artifactId>gson</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
  3. 简化附件赋值逻辑
    无需手动创建AttachmentCollectionPage,Graph SDK支持直接将List<Attachment>赋值给message.attachments,可避免手动构建集合页带来的序列化问题:
    修改createMessage方法中的附件部分代码:

    // 替换原AttachmentCollection相关代码
    List<Attachment> attachmentsList = new ArrayList<Attachment>();
    attachmentsList.add(attachment);
    message.attachments = attachmentsList; // 直接赋值List即可
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 12:46:58