在 Java 中使用 Microsoft 自适应卡
Posted
技术标签:
【中文标题】在 Java 中使用 Microsoft 自适应卡【英文标题】:Using Microsoft adaptive cards in Java 【发布时间】:2022-01-01 16:04:49 【问题描述】:我正在尝试使用自适应卡片在 Java 中实现一个聊天机器人,就像 C# 示例 here。
我可以让机器人在 Teams 中显示卡片,但我无法处理任何响应,因为我总是遇到此异常:
2021-11-23T05:32:35.715171392Z: [INFO]
java.util.concurrent.CompletionException: com.microsoft.bot.builder.ActivityHandler$InvokeResponseException
2021-11-23T05:32:35.715176693Z: [INFO] at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(Unknown Source) ~[na:na]
2021-11-23T05:32:35.715182093Z: [INFO] at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(Unknown Source) ~[na:na]
2021-11-23T05:32:35.715186993Z: [INFO] at java.base/java.util.concurrent.CompletableFuture.thenCompose(Unknown Source) ~[na:na]
2021-11-23T05:32:35.715191793Z: [INFO] at com.microsoft.bot.builder.ActivityHandler.onTurn(ActivityHandler.java:105) ~[bot-builder-4.14.0.jar!/:4.14.0]
2021-11-23T05:32:35.715196594Z: [INFO] at com.microsoft.bot.builder.MiddlewareSet.receiveActivityInternal(MiddlewareSet.java:99) ~[bot-builder-4.14.0.jar!/:4.14.0]
2021-11-23T05:32:35.715201494Z: [INFO] at com.microsoft.bot.builder.MiddlewareSet.lambda$receiveActivityInternal$1(MiddlewareSet.java:110) ~[bot-builder-4.14.0.jar!/:4.14.0]
2021-11-23T05:32:35.715206394Z: [INFO] at com.microsoft.bot.builder.BotFrameworkAdapter$TenantIdWorkaroundForTeamsMiddleware.onTurn(BotFrameworkAdapter.java:1430) ~[bot-builder-4.14.0.jar!/:4.14.0]
2021-11-23T05:32:35.715211294Z: [INFO] at com.microsoft.bot.builder.MiddlewareSet.receiveActivityInternal(MiddlewareSet.java:109) ~[bot-builder-4.14.0.jar!/:4.14.0]
2021-11-23T05:32:35.715216095Z: [INFO] at com.microsoft.bot.builder.MiddlewareSet.receiveActivityInternal(MiddlewareSet.java:74) ~[bot-builder-4.14.0.jar!/:4.14.0]
2021-11-23T05:32:35.715220795Z: [INFO] at com.microsoft.bot.builder.MiddlewareSet.receiveActivityWithStatus(MiddlewareSet.java:67) ~[bot-builder-4.14.0.jar!/:4.14.0]
2021-11-23T05:32:35.715225395Z: [INFO] at com.microsoft.bot.builder.BotAdapter.runPipeline(BotAdapter.java:206) ~[bot-builder-4.14.0.jar!/:4.14.0]
2021-11-23T05:32:35.715243796Z: [INFO] at com.microsoft.bot.builder.BotFrameworkAdapter.lambda$processActivity$2(BotFrameworkAdapter.java:478) ~[bot-builder-4.14.0.jar!/:4.14.0]
2021-11-23T05:32:35.715248396Z: [INFO] at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(Unknown Source) ~[na:na]
2021-11-23T05:32:35.715252696Z: [INFO] at java.base/java.util.concurrent.CompletableFuture.thenCompose(Unknown Source) ~[na:na]
2021-11-23T05:32:35.715256997Z: [INFO] at com.microsoft.bot.builder.BotFrameworkAdapter.processActivity(BotFrameworkAdapter.java:476) ~[bot-builder-4.14.0.jar!/:4.14.0]
2021-11-23T05:32:35.715261997Z: [INFO] at com.microsoft.bot.builder.BotFrameworkAdapter.lambda$processActivity$1(BotFrameworkAdapter.java:433) ~[bot-builder-4.14.0.jar!/:4.14.0]
2021-11-23T05:32:35.715266297Z: [INFO] at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(Unknown Source) ~[na:na]
2021-11-23T05:32:35.715270397Z: [INFO] at java.base/java.util.concurrent.CompletableFuture.thenCompose(Unknown Source) ~[na:na]
2021-11-23T05:32:35.715274597Z: [INFO] at com.microsoft.bot.builder.BotFrameworkAdapter.processActivity(BotFrameworkAdapter.java:433) ~[bot-builder-4.14.0.jar!/:4.14.0]
2021-11-23T05:32:35.715278798Z: [INFO] at com.microsoft.bot.integration.BotFrameworkHttpAdapter.processIncomingActivity(BotFrameworkHttpAdapter.java:102) ~[bot-integration-core-4.14.0.jar!/:4.14.0]
2021-11-23T05:32:35.715283098Z: [INFO] at com.microsoft.bot.integration.spring.BotController.incoming(BotController.java:84) ~[bot-integration-spring-4.14.0.jar!/:4.14.0]
2021-11-23T05:32:35.715287298Z: [INFO] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
2021-11-23T05:32:35.715291498Z: [INFO] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:na]
2021-11-23T05:32:35.715295699Z: [INFO] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:na]
2021-11-23T05:32:35.715299799Z: [INFO] at java.base/java.lang.reflect.Method.invoke(Unknown Source) ~[na:na]
2021-11-23T05:32:35.715303799Z: [INFO] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197) ~[spring-web-5.3.1.jar!/:5.3.1]
2021-11-23T05:32:35.715308199Z: [INFO] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141) ~[spring-web-5.3.1.jar!/:5.3.1]
2021-11-23T05:32:35.715312499Z: [INFO] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.3.1.jar!/:5.3.1]
2021-11-23T05:32:35.715317000Z: [INFO] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:893) ~[spring-webmvc-5.3.1.jar!/:5.3.1]
2021-11-23T05:32:35.715321400Z: [INFO] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:807) ~[spring-webmvc-5.3.1.jar!/:5.3.1]
2021-11-23T05:32:35.715325800Z: [INFO] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.1.jar!/:5.3.1]
2021-11-23T05:32:35.715330300Z: [INFO] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1061) ~[spring-webmvc-5.3.1.jar!/:5.3.1]
2021-11-23T05:32:35.715338401Z: [INFO] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:961) ~[spring-webmvc-5.3.1.jar!/:5.3.1]
2021-11-23T05:32:35.715342801Z: [INFO] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.1.jar!/:5.3.1]
2021-11-23T05:32:35.715347001Z: [INFO] at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.1.jar!/:5.3.1]
2021-11-23T05:32:35.715351101Z: [INFO] at javax.servlet.http.HttpServlet.service(HttpServlet.java:652) ~[tomcat-embed-core-9.0.39.jar!/:4.0.FR]
2021-11-23T05:32:35.715355202Z: [INFO] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.1.jar!/:5.3.1]
2021-11-23T05:32:35.715359702Z: [INFO] at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.39.jar!/:4.0.FR]
2021-11-23T05:32:35.715364102Z: [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.715368302Z: [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.715372902Z: [INFO] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719456008Z: [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719463708Z: [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719468709Z: [INFO] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.1.jar!/:5.3.1]
2021-11-23T05:32:35.719473209Z: [INFO] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.1.jar!/:5.3.1]
2021-11-23T05:32:35.719477709Z: [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719482209Z: [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719497610Z: [INFO] at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.1.jar!/:5.3.1]
2021-11-23T05:32:35.719502910Z: [INFO] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.1.jar!/:5.3.1]
2021-11-23T05:32:35.719507111Z: [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719511411Z: [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719515611Z: [INFO] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.1.jar!/:5.3.1]
2021-11-23T05:32:35.719529412Z: [INFO] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.1.jar!/:5.3.1]
2021-11-23T05:32:35.719533812Z: [INFO] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719538012Z: [INFO] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719542212Z: [INFO] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719546413Z: [INFO] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719550513Z: [INFO] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719554813Z: [INFO] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719559013Z: [INFO] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719563113Z: [INFO] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719567314Z: [INFO] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719572214Z: [INFO] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719576414Z: [INFO] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719580514Z: [INFO] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719584714Z: [INFO] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719588815Z: [INFO] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719593015Z: [INFO] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[na:na]
2021-11-23T05:32:35.719597015Z: [INFO] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) ~[na:na]
2021-11-23T05:32:35.719601115Z: [INFO] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.39.jar!/:9.0.39]
2021-11-23T05:32:35.719605216Z: [INFO] at java.base/java.lang.Thread.run(Unknown Source) ~[na:na]
2021-11-23T05:32:35.719609216Z: [INFO] Caused by: com.microsoft.bot.builder.ActivityHandler$InvokeResponseException: null
2021-11-23T05:32:35.719613216Z: [INFO] at com.microsoft.bot.builder.ActivityHandler.getAdaptiveCardInvokeValue(ActivityHandler.java:712) ~[bot-builder-4.14.0.jar!/:4.14.0]
2021-11-23T05:32:35.719621116Z: [INFO] at com.microsoft.bot.builder.ActivityHandler.onInvokeActivity(ActivityHandler.java:408) ~[bot-builder-4.14.0.jar!/:4.14.0]
2021-11-23T05:32:35.719625517Z: [INFO] ... 68 common frames omitted
2021-11-23T05:32:35.719629517Z: [INFO]
我已将问题缩小到 com.microsoft.bot.builder.ActivityHandler
类中的这段代码:
Object obj = activity.getValue();
JsonNode node = null;
if (obj instanceof JsonNode)
node = (JsonNode) obj;
else
AdaptiveCardInvokeResponse response = createAdaptiveCardInvokeErrorResponse(
HttpURLConnection.HTTP_BAD_REQUEST, "BadRequest", "Value property instanceof not properly formed");
throw new InvokeResponseException(HttpURLConnection.HTTP_BAD_REQUEST, response);
从这段代码中我可以看到,如果activity.getValue()
对象不是JsonNode
的实例,则会抛出InvokeResponseException
。
我什至将这段代码提取到我自己的类中并注销了返回的实际对象类型:
Object obj = activity.getValue();
JsonNode node = null;
LOGGER.error("obj type: " + obj.getClass().getName());
if (obj instanceof JsonNode)
node = (JsonNode) obj;
else
AdaptiveCardInvokeResponse response = createAdaptiveCardInvokeErrorResponse(
HttpURLConnection.HTTP_BAD_REQUEST, "BadRequest", "Value property instanceof not properly formed");
throw new InvokeResponseException(HttpURLConnection.HTTP_BAD_REQUEST, response);
实际的对象类型是java.util.LinkedHashMap
。
那么这里的解决方案是什么?是否有一个配置选项可以更改标准聊天机器人项目对活动响应的反序列化方式?我的代码基于使用 Yeoman yo botbuilder-java -T "echo"
描述的 here 创建的示例项目。
【问题讨论】:
【参考方案1】:这似乎是 Java Bot Framework SDK 的一个错误,但与此同时,我已经解决了一个接受来自 activity.getValue()
的 Map 的中间类的问题(参见 invokeValue = objectMapper.convertValue(obj, AdaptiveCardInvokeValue.class);
行):
package com.matthewcasperson;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.microsoft.bot.builder.ActivityHandler;
import com.microsoft.bot.builder.InvokeResponse;
import com.microsoft.bot.builder.TurnContext;
import com.microsoft.bot.connector.Async;
import com.microsoft.bot.schema.Activity;
import com.microsoft.bot.schema.AdaptiveCardInvokeResponse;
import com.microsoft.bot.schema.AdaptiveCardInvokeValue;
import com.microsoft.bot.schema.Serialization;
import com.microsoft.bot.schema.SignInConstants;
import java.net.HttpURLConnection;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FixedActivityHandler extends ActivityHandler
private static final Logger LOGGER = LoggerFactory.getLogger(CateringBot.class);
@Override
protected CompletableFuture<InvokeResponse> onInvokeActivity(TurnContext turnContext)
if (StringUtils.equals(turnContext.getActivity().getName(), "adaptiveCard/action"))
AdaptiveCardInvokeValue invokeValue = null;
try
invokeValue = getAdaptiveCardInvokeValue(turnContext.getActivity());
catch (InvokeResponseException e)
return Async.completeExceptionally(e);
return onAdaptiveCardInvoke(turnContext, invokeValue).thenApply(result -> createInvokeResponse(result));
if (
StringUtils.equals(
turnContext.getActivity().getName(), SignInConstants.VERIFY_STATE_OPERATION_NAME
) || StringUtils.equals(
turnContext.getActivity().getName(), SignInConstants.TOKEN_EXCHANGE_OPERATION_NAME
)
)
return onSignInInvoke(turnContext).thenApply(aVoid -> createInvokeResponse(null))
.exceptionally(ex ->
if (
ex instanceof CompletionException
&& ex.getCause() instanceof InvokeResponseException
)
InvokeResponseException ire = (InvokeResponseException) ex.getCause();
return new InvokeResponse(500, "");
else if (ex instanceof InvokeResponseException)
InvokeResponseException ire = (InvokeResponseException) ex;
return new InvokeResponse(500, "");
return new InvokeResponse(HttpURLConnection.HTTP_INTERNAL_ERROR, null);
);
CompletableFuture<InvokeResponse> result = new CompletableFuture<>();
result.complete(new InvokeResponse(HttpURLConnection.HTTP_NOT_IMPLEMENTED, null));
return result;
private AdaptiveCardInvokeValue getAdaptiveCardInvokeValue(Activity activity) throws InvokeResponseException
if (activity.getValue() == null)
AdaptiveCardInvokeResponse response = createAdaptiveCardInvokeErrorResponse(
HttpURLConnection.HTTP_BAD_REQUEST, "BadRequest", "Missing value property");
throw new InvokeResponseException(HttpURLConnection.HTTP_BAD_REQUEST, response);
/*
The original code required activity.getValue() to be a JsonNode. It is in fact a
LinkedHashMap, so this change allows the response to proceed.
*/
Object obj = activity.getValue();
AdaptiveCardInvokeValue invokeValue = null;
if (obj instanceof JsonNode)
invokeValue = Serialization.treeToValue((JsonNode) obj, AdaptiveCardInvokeValue.class);
else if (obj instanceof Map)
final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
invokeValue = objectMapper.convertValue(obj, AdaptiveCardInvokeValue.class);
else
AdaptiveCardInvokeResponse response = createAdaptiveCardInvokeErrorResponse(
HttpURLConnection.HTTP_BAD_REQUEST, "BadRequest", "Value property instanceof not properly formed");
throw new InvokeResponseException(HttpURLConnection.HTTP_BAD_REQUEST, response);
/*
End of changes
*/
if (invokeValue == null)
AdaptiveCardInvokeResponse response = createAdaptiveCardInvokeErrorResponse(
HttpURLConnection.HTTP_BAD_REQUEST, "BadRequest", "Value property instanceof not properly formed");
throw new InvokeResponseException(HttpURLConnection.HTTP_BAD_REQUEST, response);
if (invokeValue.getAction() == null)
AdaptiveCardInvokeResponse response = createAdaptiveCardInvokeErrorResponse(
HttpURLConnection.HTTP_BAD_REQUEST, "BadRequest", "Missing action property");
throw new InvokeResponseException(HttpURLConnection.HTTP_BAD_REQUEST, response);
if (!invokeValue.getAction().getType().equals("Action.Execute"))
AdaptiveCardInvokeResponse response = createAdaptiveCardInvokeErrorResponse(
HttpURLConnection.HTTP_BAD_REQUEST, "NotSupported",
String.format("The action '%s'is not supported.", invokeValue.getAction().getType()));
throw new InvokeResponseException(HttpURLConnection.HTTP_BAD_REQUEST, response);
return invokeValue;
private AdaptiveCardInvokeResponse createAdaptiveCardInvokeErrorResponse(
Integer statusCode,
String code,
String message
)
AdaptiveCardInvokeResponse adaptiveCardInvokeResponse = new AdaptiveCardInvokeResponse();
adaptiveCardInvokeResponse.setStatusCode(statusCode);
adaptiveCardInvokeResponse.setType("application/vnd.getmicrosoft().error");
com.microsoft.bot.schema.Error error = new com.microsoft.bot.schema.Error();
error.setCode(code);
error.setMessage(message);
adaptiveCardInvokeResponse.setValue(error);
return adaptiveCardInvokeResponse;
【讨论】:
以上是关于在 Java 中使用 Microsoft 自适应卡的主要内容,如果未能解决你的问题,请参考以下文章
如何使用自适应卡操作从自适应卡获取用户响应。使用 Microsoft Bot Framework 从 MS Teams 频道提交操作?