如何使用TFS JAVA SDK 14.0.3运行共享查询及解决URL过期问题
运行TFS共享查询并获取结果(基于Java SDK 14.0.3)
一、核心思路:避开过期的查询URL
你碰到的查询URL每90天过期的问题,根源是这类URL包含短期有效的会话令牌,根本不适合长期依赖。最优方案是用查询的持久化标识(项目内路径或GUID)来定位并执行共享查询——只要查询不被删除或修改核心属性,这些标识就一直有效。
二、新增共享查询执行方法
结合你已经实现的getWorkItem方法,我给你新增两个实用的共享查询执行方法,分别对应不同的场景:
方法1:通过共享查询路径执行
路径格式一般是Shared Queries/你的查询名称,如果有子文件夹,就写成Shared Queries/子文件夹名/目标查询:
import java.util.ArrayList; import java.util.List; import com.microsoft.tfs.core.TFSTeamProjectCollection; import com.microsoft.tfs.core.clients.workitem.Project; import com.microsoft.tfs.core.clients.workitem.WorkItem; import com.microsoft.tfs.core.clients.workitem.WorkItemClient; import com.microsoft.tfs.core.clients.workitem.query.QueryDefinition; public List<WorkItem> getSharedQueryResultsByPath(TFSTeamProjectCollection tpc, Project project, String sharedQueryPath) throws Exception { WorkItemClient workItemClient = project.getWorkItemClient(); // 通过共享查询的项目内路径获取查询定义 QueryDefinition queryDefinition = workItemClient.getQuery(project, sharedQueryPath); // 执行查询,可根据需求调整QueryOption(比如是否包含关联的文件) WorkItemCollection results = workItemClient.query( queryDefinition.getQueryText(), null, // 如果是参数化查询,这里传入参数数组,比如new Object[]{"迭代1"} null, WorkItemClient.QueryOption.INCLUDE_LINKED_FILES ); // 转换为WorkItem列表返回 List<WorkItem> workItems = new ArrayList<>(); for (WorkItem item : results) { workItems.add(item); } return workItems; }
方法2:通过共享查询GUID执行
如果查询可能被重命名或移动路径,用GUID会更稳定。你可以在TFS网页端打开共享查询,从URL的queryId参数里提取GUID:
import java.util.ArrayList; import java.util.List; import java.util.UUID; import com.microsoft.tfs.core.TFSTeamProjectCollection; import com.microsoft.tfs.core.clients.workitem.Project; import com.microsoft.tfs.core.clients.workitem.WorkItem; import com.microsoft.tfs.core.clients.workitem.WorkItemClient; import com.microsoft.tfs.core.clients.workitem.query.QueryDefinition; public List<WorkItem> getSharedQueryResultsByGuid(TFSTeamProjectCollection tpc, Project project, String queryGuid) throws Exception { WorkItemClient workItemClient = project.getWorkItemClient(); // 通过GUID获取查询定义 QueryDefinition queryDefinition = workItemClient.getQueryById(UUID.fromString(queryGuid)); // 执行查询 WorkItemCollection results = workItemClient.query( queryDefinition.getQueryText(), null, null, WorkItemClient.QueryOption.INCLUDE_LINKED_FILES ); List<WorkItem> workItems = new ArrayList<>(); for (WorkItem item : results) { workItems.add(item); } return workItems; }
三、调用示例
// 初始化你的TFS连接和项目实例(和你getWorkItem方法里的逻辑一致) TFSTeamProjectCollection tpc = ...; Project project = ...; // 方式1:通过路径调用 String queryPath = "Shared Queries/团队待办事项"; List<WorkItem> pathResults = getSharedQueryResultsByPath(tpc, project, queryPath); // 方式2:通过GUID调用 String queryGuid = "xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; List<WorkItem> guidResults = getSharedQueryResultsByGuid(tpc, project, queryGuid); // 遍历处理结果 for (WorkItem item : pathResults) { System.out.printf("工作项ID: %d, 标题: %s%n", item.getId(), item.getTitle()); }
四、关键注意事项
- 权限验证:确保当前TFS用户对该共享查询有读取权限,否则会抛出权限异常。
- 参数化查询:如果你的共享查询是参数化的(比如包含
@CurrentIteration或自定义参数),在query方法的第二个参数传入参数数组即可,比如new Object[]{"迭代1"}。 - 性能优化:如果频繁执行同一个查询,可以缓存
QueryDefinition对象,避免重复从TFS服务器获取,提升执行效率。
内容的提问来源于stack exchange,提问作者Ansar Samad
相关产品推荐
相关产品推荐

