HTTP POST запрос к JIRA с использованием Java выдает 400 ошибок неправильного запроса, curl работает нормально

#java #http #post #jira #jira-rest-api

#java #http #Публикация #jira #jira-rest-api

Вопрос:

Итак, я пытаюсь получить информацию о проблемах с Jira через REST API с использованием Java, однако я продолжаю получать ошибку 400. Я чувствую, что есть что-то действительно глупое, чего мне не хватает, кто-нибудь может помочь мне выяснить, что с этим не так? РЕДАКТИРОВАТЬ: я понял, что я не отправляю имя пользователя / пароль в Jira в программе Java, но я на самом деле не уверен, как это сделать… Помощь здесь была бы отличной! Вот код, который у меня есть (название компании отредактировано):

 import java.io.*;
import java.net.*;
import java.util.*;

public class JiraConnector 
{
    public static void main(String[] args)
    {
        try {
            //store necessary query information
            URL jiraURL = new URL("http://jira.somecompany.com/rest/api/2/search");
            String data = "'{"jql":"project = PROJ"}'";

            //establish connection and request properties
            HttpURLConnection connection = (HttpURLConnection)jiraURL.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Accept", "*/*");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setDoOutput(true);
            connection.setDoInput(true);

            connection.connect();

            OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream());
            wr.write(data.toString());
            wr.flush();
            wr.close();

            Reader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            for (int c; (c = in.read()) >= 0; System.out.print((char)c));

        } catch (MalformedURLException e) {
            System.err.println("MalformedURLException: "   e.getMessage());
        } catch (java.net.UnknownServiceException e) {
            System.err.println("UnknownServiceException: "   e.getMessage());
        } catch (IOException e) {
            System.err.println("IOException: "   e.getMessage());
        }        
    }
}
  

Для записи, использование этой команды curl работает:

 curl -D- -u- user:password -X POST -H "Content-Type: application/json" --data '{"jql:"project=PROF"}' "http://jira.somecompany.com/rest/api/2/search"
  

Ответ №1:

Похоже, у вас есть дополнительные одинарные кавычки в данных post.

Вместо этого:

 String data = "'{"jql":"project = PROJ"}'";
  

попробуйте это:

 String data = "{"jql":"project = PROJ"}";
  

Кстати, даже если вы получаете 400 Bad Request, JIRA по-прежнему предоставляет полезную информацию, которая помогает локализовать ошибку. Вы можете просмотреть его, используя метод getErrorStream соединения. Если мы быстро добавим это в ваш код:

 import java.io.*;
import java.net.*;
import java.util.*;

public class JiraConnector 
{
    public static void main(String[] args)
    {
        HttpURLConnection connection = null;
        try {
            //store necessary query information
            URL jiraURL = new URL("http://127.0.0.1:8082/rest/api/2/search");
            String data = "{"jql":"project = PROJ"}";

            //establish connection and request properties
            connection = (HttpURLConnection)jiraURL.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Accept", "*/*");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setDoOutput(true);
            connection.setDoInput(true);

            connection.connect();

            OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream());
            wr.write(data.toString());
            wr.flush();
            wr.close();

            Reader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            for (int c; (c = in.read()) >= 0; System.out.print((char)c));

        } catch (MalformedURLException e) {
            System.err.println("MalformedURLException: "   e.getMessage());
        } catch (java.net.UnknownServiceException e) {
            System.err.println("UnknownServiceException: "   e.getMessage());
        } catch (IOException e) {
            System.err.println("IOException: "   e.getMessage());
            if (connection != null) {
                try {
                    System.out.println(connection.getResponseMessage());

                    InputStream errorStream = connection.getErrorStream();
                    if (errorStream != null) {
                        Reader in = new BufferedReader(new InputStreamReader(errorStream));
                        for (int c; (c = in.read()) >= 0; System.out.print((char)c));
                    }
                }
                catch (IOException e2) {
                }
            }
        }        
    }
}
  

Если вы собираетесь выполнять какую-либо серьезную работу с REST API, я бы рекомендовал использовать Jersey вместо того, чтобы пытаться использовать свой собственный.

Ответ №2:

Сначала общий совет: используйте, например, FireFox с надстройкой TamperData, которая позволяет отслеживать отправку обычной формы и проверять все. В вашем случае прокси-монитор может быть более полезным. Также:

 curl --trace-ascii ...
  

TamperData покажет, где что-то пошло не так.

Без параметра encoding используется текущая кодировка платформы; непереносимая.

 OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream(),
        StandardCharsets.UTF_8);
Reader in = new BufferedReader(new InputStreamReader(
        connection.getInputStream(),
        StandardCharsets.UTF_8));
  

Ответ №3:

Внимание, проблема заключалась в авторизации (на случай, если у кого-то тоже есть эта проблема). Полностью сбит с толку и забыл отправить имя пользователя / пароль.

Ответ №4:

Добавить базовый заголовок авторизации достаточно просто:

 HttpURLConnection connection = (HttpURLConnection)jiraURL.openConnection();
String userCredentials = "username:password";
String basicAuth = "Basic "   new String(new Base64().encode(userCredentials.getBytes()));
connection.setRequestProperty ("Authorization", basicAuth);