使用JIRA Rest API在Apex中检索JQL结果遇格式问题求助
解决Apex调用JIRA REST API返回415不支持媒体类型错误
问题重现
在Apex中调用JIRA的/rest/api/3/search接口执行JQL查询时,返回415 HTTP错误,提示请求体格式不被支持。原代码如下:
原JiraRestClient类
public class JiraRestClient { private static final String JIRA_BASE_URL = 'https://sregmi48.atlassian.net'; private static final String JIRA_API_TOKEN = 'my_api_code'; public static HttpResponse getAllIssues(string jqlQuery) { HttpRequest request = new HttpRequest(); request.setEndpoint(JIRA_BASE_URL + '/rest/api/3/search'); request.setMethod('POST'); // Use GET for searching issues by project key request.setHeader('Authorization', 'Basic ' + EncodingUtil.base64Encode(Blob.valueOf('apiToken:' + JIRA_API_TOKEN))); request.setHeader('Accept','application/json'); Map<String, Object> requestBodyMap = new Map<String, Object>{ 'jql' => jqlQuery }; String requestBodyJSON = JSON.serialize(requestBodyMap); // String requestBody = '{"jql":{"project":{"key":"' + projectKey + '"}}}'; request.setBody(requestBodyJSON); System.debug(requestBodyJSON); return new Http().send(request); } }
原测试代码(匿名窗口)
HttpResponse response = JiraRestClient.getAllIssues('project = "JIR"'); if (response.getStatusCode() == 415) { String responseBody = response.getBody(); System.debug('Response Body: ' + responseBody); List<String> responseHeaders = response.getHeaderKeys(); for (String key : responseHeaders) { System.debug('Response Header ' + key ); } } else { String responseBody = response.getBody(); System.debug('Response Body: ' + responseBody); }
错误原因
415错误的核心原因是请求未指定Content-Type头。JIRA的POST接口需要明确知道请求体的格式为JSON,原代码仅设置了Accept头(告知服务器返回JSON),但未告知服务器发送的请求体是JSON格式。
另外注意:JIRA的Basic Auth认证格式应为你的邮箱地址:API Token,而非apiToken:API Token,这可能导致后续权限错误,需一并修正。
修复方案
- 添加
Content-Type: application/json请求头,明确告知服务器请求体格式 - 修正Authorization的认证字符串格式(邮箱+API Token)
- 保留使用
JSON.serialize()自动处理JQL的转义,避免手动拼接JSON的语法错误
修改后的完整代码
修正后的JiraRestClient类
public class JiraRestClient { private static final String JIRA_BASE_URL = 'https://sregmi48.atlassian.net'; private static final String JIRA_EMAIL = 'your-email@example.com'; // 替换为你的JIRA关联邮箱 private static final String JIRA_API_TOKEN = 'my_api_code'; // 替换为你的API Token public static HttpResponse getAllIssues(String jqlQuery) { HttpRequest request = new HttpRequest(); request.setEndpoint(JIRA_BASE_URL + '/rest/api/3/search'); request.setMethod('POST'); // 修正Basic Auth格式:邮箱:API Token request.setHeader('Authorization', 'Basic ' + EncodingUtil.base64Encode(Blob.valueOf(JIRA_EMAIL + ':' + JIRA_API_TOKEN))); request.setHeader('Accept','application/json'); // 添加Content-Type头,指定请求体为JSON request.setHeader('Content-Type','application/json'); Map<String, Object> requestBodyMap = new Map<String, Object>{ 'jql' => jqlQuery }; String requestBodyJSON = JSON.serialize(requestBodyMap); request.setBody(requestBodyJSON); System.debug('Request Body: ' + requestBodyJSON); return new Http().send(request); } }
测试代码(匿名窗口)
HttpResponse response = JiraRestClient.getAllIssues('project = "JIR"'); System.debug('Status Code: ' + response.getStatusCode()); if (response.getStatusCode() == 200) { // 解析返回的JSON结果 Map<String, Object> resultMap = (Map<String, Object>)JSON.deserializeUntyped(response.getBody()); System.debug('Total Issues: ' + resultMap.get('total')); } else { System.debug('Error Response: ' + response.getBody()); }
额外说明
- 如果使用GET请求调用JIRA搜索接口,JQL可以直接作为URL参数传递,此时不需要请求体,也不需要Content-Type头,但GET请求的URL长度有限制,复杂JQL建议用POST
- 确保你的API Token有足够的权限访问目标JIRA项目的搜索接口
内容的提问来源于stack exchange,提问作者BigPy
相关产品推荐
相关产品推荐

