获取 JIRA 中问题的自定义/默认字段的 Java 程序

Posted

技术标签:

【中文标题】获取 JIRA 中问题的自定义/默认字段的 Java 程序【英文标题】:Java Program to fetch custom/default fields of issues in JIRA 【发布时间】:2018-07-15 02:08:12 【问题描述】:

我开发了一个简单的 java 程序来获取问题/用户故事的数据。 我想获取特定问题的“描述”字段。我已使用 GET 方法获得响应,但在连接到 JIRA 时出现错误。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class JiraIssueDescription 

public static void main(String[] args) 

  try 

    URL url = new URL("https://****.atlassian.net/rest/agile/1.0/issue/41459");
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("GET");
    conn.setRequestProperty("Accept", "application/json");
    conn.setRequestProperty("username", "***@abc.com");
    conn.setRequestProperty("password", "****");

    if (conn.getResponseCode() != 200) 
        throw new RuntimeException("Failed : HTTP error code : "
                + conn.getResponseCode());
    

    BufferedReader br = new BufferedReader(new InputStreamReader(
        (conn.getInputStream())));

    String output;
    System.out.println("Output from Server .... \n");
    while ((output = br.readLine()) != null) 
        System.out.println(output);
    

    conn.disconnect();

   catch (MalformedURLException e) 

    e.printStackTrace();

   catch (IOException e) 

    e.printStackTrace();

  




运行项目时出现以下错误

java.net.UnknownHostException: ****.atlassian.net
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at sun.security.ssl.SSLSocketImpl.connect(Unknown Source)
at sun.security.ssl.BaseSSLSocketImpl.connect(Unknown Source)
at sun.net.NetworkClient.doConnect(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.<init>(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.New(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at java.net.HttpURLConnection.getResponseCode(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
at com.JiraIntegration.bean.JiraIssueDescription.main(JiraIssueDescription.java:24)

谁能帮我解决错误。我需要实施 OAuth 吗?

【问题讨论】:

问题是什么?你用docs.oracle.com/cd/B14099_19/web.1012/b14020/HTTPClient/…吗?到目前为止,您尝试过什么? 嗨@jschnasse 我已经更新了问题。 【参考方案1】:

UnknownHostException 看起来您的 URL 中有错字或者是 facing some proxy issues 。

    它可以在您的浏览器中使用吗? 它应该给你一些json作为回应。像这样: https://jira.atlassian.com/rest/api/2/issue/JSWCLOUD-11658

    您还可以使用 curl 等其他工具进行测试。它有效吗? curl https://jira.atlassian.com/rest/api/2/issue/JSWCLOUD-11658

    Atlassian REST API 提供two authentication methods、基本身份验证和 Oauth。 Use this approach 创建有效的基本身份验证标头或尝试不带参数的请求。

以下代码演示了它应该如何工作:

package stack48618849;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

import org.junit.Test;

public class HowToReadFromAnURL 
    @Test
    public void readFromUrl() 
        try (InputStream in = getInputStreamFromUrl("https://jira.atlassian.com/rest/api/2/issue/JSWCLOUD-11658")) 
            System.out.println(convertInputStreamToString(in));
         catch (Exception e) 
            throw new RuntimeException(e);
        
    

    @Test(expected = RuntimeException.class)
    public void readFromUrlWithBasicAuth() 
        String user="aUser";
        String passwd="aPasswd";
        try (InputStream in = getInputStreamFromUrl("https://jira.atlassian.com/rest/api/2/issue/JSWCLOUD-11658",user,passwd)) 
            System.out.println(convertInputStreamToString(in));
         catch (Exception e) 
            System.out.println("If basic auth is provided, it should be correct: "+e.getMessage());
            throw new RuntimeException(e);
        
    

    private InputStream getInputStreamFromUrl(String urlString,String user, String passwd) throws IOException 
        URL url = new URL(urlString);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setRequestProperty("Accept", "application/json");
        String encoded = Base64.getEncoder().encodeToString((user+":"+passwd).getBytes(StandardCharsets.UTF_8));  
        conn.setRequestProperty("Authorization", "Basic "+encoded);
        return conn.getInputStream();
    

    private InputStream getInputStreamFromUrl(String urlString) throws IOException 
        URL url = new URL(urlString);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setRequestProperty("Accept", "application/json");
        return conn.getInputStream();
    

    private String convertInputStreamToString(InputStream inputStream) throws IOException 
        ByteArrayOutputStream result = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) != -1) 
            result.write(buffer, 0, length);
        
        return result.toString("UTF-8");
    

打印出来:

"expand":"renderedFields,names,schema,operations,editmeta,changelog,versionedRepresentations","id":"789521","self":"https://jira.atlassian.com/rest/api/2/issue/789521","key":"JSWCLOUD-11658","fields":"customfield_18232":...
If basic auth is provided, it should be correct: Server returned HTTP response code: 401 for URL: https://jira.atlassian.com/rest/api/2/issue/JSWCLOUD-11658

【讨论】:

您好 jschnasse,感谢您的回复。是的,我在 Postman 中尝试了相同的 URL,我得到了 json 作为响应。我是否必须使用任何身份验证? conn.setRequestProperty("username"conn.setRequestProperty("password"的格式是否正确? 代码进入 IOException 捕获块。所以 URL 没有问题。 UnknownHostException is an IOException抛出表示无法确定主机IP地址。 哦。当我使用 Postman 尝试相同的 URL 时,它运行良好。也许它可以工作,因为我已经在 Chrome 上登录了 JIRA,它使用 cookie 进行身份验证。 嗨 jschnasse,在解决代理问题后,代码运行良好。非常感谢!【参考方案2】:

您可以使用SpringRestTemplate 来有效地解决您的问题,而不是HttpURLConnection 的实现方式:

为您提供一段我使用的代码,以及 JIRA REST API:

创建一个您希望与 JIRA REST API 一起使用的 RESTClient,如下所示:

public class JIRASpringRESTClient 

    private static final String username = "fred";
    private static final String password = "fred";
    private static final String jiraBaseURL = "https://jira.xxx.com/rest/api/2/";

    private RestTemplate restTemplate;
    private HttpHeaders httpHeaders;

    public JIRASpringRESTClient() 
        restTemplate = new RestTemplate();
        httpHeaders = createHeadersWithAuthentication();
    

    private HttpHeaders createHeadersWithAuthentication() 
        String plainCredentials = username + ":" + password;
        byte[] base64CredentialsBytes = Base64.getEncoder().encode(plainCredentials.getBytes());
        String base64Credentials = new String(base64CredentialsBytes);

        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Basic " + base64Credentials);
        return headers;
    

    @SuppressWarnings( "unchecked", "rawtypes" )
    public ResponseEntity<String> getJIRATicket(String issueId) 
        String url = jiraBaseURL + "issue/" + issueId;

        HttpEntity<?> requestEntity = new HttpEntity(httpHeaders);
        return restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
    

然后您可以进一步重复使用这些方法,如下所示:

public class JIRATicketGet 
    public static void main(String... args) 
        JIRASpringRESTClient restClient = new JIRASpringRESTClient();
        ResponseEntity<String> response = restClient.getJIRATicket("XXX-12345");
        System.out.println(response.getBody());
    

这将提供来自 JIRA 的 GET 响应,该响应采用 JSON 格式,可以进一步操作以使用 com.fasterxml.jackson.databind.ObjectMapperGET 响应中获取特定字段

使用上面步骤中得到的 JSON,您可以创建一个 POJO 类(例如,Ticket),然后按如下方式使用它:

ObjectMapper mapper = new ObjectMapper();
try 
    Ticket response = mapper.readValue(response.getBody(), Ticket.class);
 catch (IOException e) 
    e.printStackTrace();

希望这会有所帮助!

【讨论】:

以上是关于获取 JIRA 中问题的自定义/默认字段的 Java 程序的主要内容,如果未能解决你的问题,请参考以下文章

使用 jira 中的 REST api 修改自定义字段名称后,CustomFieldManager 未获取自定义字段

jira 创建项目时候如何增加自定义字段?

JIRA上字段的默认值怎么配置

Jira scriptrunner脚本字段:在自定义字段上,计算其他自定义字段的值并显示总计

JIRA 的字段配置

JIRA中设置[描述]字段的默认值