Java-HTTP Post Jira API-错误的请求 [英] Java - HTTP Post Jira API - Bad Request

查看:134
本文介绍了Java-HTTP Post Jira API-错误的请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码对 Jira URL(https://xxxxxxx.atlassian.net/rest/api/2/issue/)进行HTTP Post:

I have this code to do a HTTP Post to a Jira URL (https://xxxxxxx.atlassian.net/rest/api/2/issue/):

    Object jsonMessage = arg0.getMessage().getPayload();

    URL url = new URL(jiraUrl + jiraIssuePath);

    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();

    BASE64Encoder enc = new sun.misc.BASE64Encoder();
    String userpassword = jiraUsername + ":" + jiraPassword;
    String encodedAuthorization = enc.encode(userpassword.getBytes());
    conn.setDoOutput(true);
    conn.setDoInput(true);
    conn.setRequestProperty("Authorization", "Basic " + encodedAuthorization);
    conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");

    conn.setRequestMethod("POST");

    OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
    wr.write(jsonMessage.toString());
    wr.flush();

    StringBuilder sb = new StringBuilder();
    int HttpResult = conn.getResponseCode();
    if (HttpResult == HttpsURLConnection.HTTP_OK) {
        BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
        String line = null;
        while ((line = br.readLine()) != null) {
            sb.append(line + "\n");
        }
        br.close();
        System.out.println("" + sb.toString());
    } else {
        System.out.println(conn.getResponseMessage());
    }

如果我使用不带JSON消息的HTTP Get可以正常工作,但是如果我使用POST发送JSON消息,则会返回此错误:

If I use a HTTP Get without JSON message it works fine, but if I use a POST sending a JSON message it return me this error:

java.io.IOException:服务器为URL返回HTTP响应代码:400: https://xxxxxxx.atlassian.net/rest/api/2/issue/

java.io.IOException: Server returned HTTP response code: 400 for URL: https://xxxxxxx.atlassian.net/rest/api/2/issue/

我使用 Postman应用程序检查标头(Content-TypeAuthorization)和正文,并使用该应用程序在Jira中创建问题.

I use Postman App to check headers(Content-Type and Authorization) and body and with that App it create the issue in Jira.

已添加: 如果我检查连接,它的参数为Method,例如GET而不是POST.

Added: If I inspect the connection it has the parameter Method like GET instead of POST.

我该怎么办?

推荐答案

我有一个将Jira集成到公司应用程序中的请求.请求是使用OAuth,并能够使用Jira API,并带有重音以使用创建问题"调用. 稍后我将提供源代码,以强调使用POST调用时遇到了json问题,并且必须使用com.google.api.client.util.GenericData才能正确创建问题.

I had a request to integrate Jira into company application. The request is to use OAuth, and to be able to use Jira API, with accent to use "create issue" call. I'll provide source later, just to emphasize that for use a POST call I've encountered problems with json, and I had to use com.google.api.client.util.GenericData in order to make proper creation of issue.

代码摘录:

@PropertySource("classpath:/JiraApiCalls/calls.properties")
@Service
public class JiraService {

    //<editor-fold desc="infra">
    @Autowired
    JiraClient jiraClient;

    //<editor-fold desc="Api Business Calls">
    @Value("${GET_ISSUE_BY_KEY_URL}")
    String apiCallIssueByKey;

    @Value("${SITE_ID_AND_PORTFOLIO_SEARCH_JQL_WITH_OR}")
    String apiCallSiteIdAndPortfolioSearchJQLWithOr;

    @Value("${OR_SITE_ID}")
    String apiCallOrSiteId;

    @Value("${SEARCH_ISSUES_URL}")
    String searchIssuesKey;

    @Value("${DASHBOARDS}")
    String apiCallAllDashboard;

    @Value("${PROJECTS}")
    String apiCallAllProjects;

    @Value("${PROJECT}")
    String apiCallProjectById;

    @Value("${ISSUETYPES}")
    String apiCallAllIssueTypes;

    @Value("${ISSUETYPE}")
    String apiCallApiIssueType;

    @Value("${ISSUE_CREATE}")
    String apiCallIssueCreate;
    //</editor-fold>

    //<editor-fold desc="Definitions : Jira concrete usage">
    static final List<String> ISSUE_FIELDS = Arrays.asList(
            "status", "creator", "reporter", "assignee", "description",
            "summary", "customfield_11110", "customfield_11126", "components"
    );

public JiraSingleResultIssueDto getIssueByKey(String key) {
        String issueApiMethodCallUrl = MessageFormat.format( apiCallIssueByKey, key );
        JiraSingleResultIssueDto dto = jiraClient.executeGet( JiraSingleResultIssueDto.class, issueApiMethodCallUrl );
        return dto;
    }

    public AllDashboardsDto getAllDashboards() {
        return jiraClient.executeGet( AllDashboardsDto.class, apiCallAllDashboard );
    }

    public List<ProjectDto> getAllProjects() {
        List<ProjectDto> projects = jiraClient.executeGetExpectingList( apiCallAllProjects );
        return projects;
    }

    public ProjectDto getProjectByKey(Object key) {
        ProjectDto project = jiraClient.executeGet( ProjectDto.class, MessageFormat.format( apiCallProjectById, String.valueOf( key ) ) );
        return project;
    }

    public List<JiraIssueTypeDto> getAllIssueTypes() {
        List<JiraIssueTypeDto> issueTypes = jiraClient.executeGetExpectingList( apiCallAllIssueTypes );
        return issueTypes;
    }

    public JiraIssueTypeDto getIssueType(Object key) {
        JiraIssueTypeDto issueType = jiraClient.executeGet( JiraIssueTypeDto.class, MessageFormat.format( apiCallApiIssueType, String.valueOf( key ) ) );
        return issueType;
    }

    public IssueCreatedResponseDto createIssue(IssueDto issueDto) throws Exception {
        GenericData issueData = new GenericData();

        try {
            // check for existing Project, and carry on if it exists...
            ProjectDto projectDto = getProjectByKey( issueDto.getFields().getProject().getId() );
            GenericData projectData = new GenericData();
            projectData.put( "key", projectDto.getKey() );

            // check for existing issue type, and carry on with no errors..
            Long issueId = issueDto.getFields().getIssuetype().getId();
            getIssueType( issueId );
            GenericData issueTypeData = new GenericData();
            issueTypeData.put( "id", issueId );

            GenericData fieldsData = new GenericData();
            fieldsData.set( "summary", issueDto.getFields().getSummary() );
            fieldsData.set( "description", issueDto.getFields().getDescription() );

            fieldsData.set( "issuetype", issueTypeData );
            fieldsData.set( "project", projectData );

            issueData.put( "fields", fieldsData );

            IssueCreatedResponseDto issueResponse = jiraClient.executePost( IssueCreatedResponseDto.class, apiCallIssueCreate, issueData );
            return issueResponse;
        } catch (Exception e) {
            throw new Exception( e );
        }
    }
}

Jira客户:

@Component
public class JiraClient {

    private static Logger LOGGER = Logger.getLogger( JiraClient.class.getName() );

    //<editor-fold desc="oauth 1.0 credentials">
    @Value("${jira_home}")
    String JIRA_HOME_URL;

    @Value("${jira_base_url}")
    String JIRA_ENDPOINT_URL;

    @Value("${jira_access_token}")
    String JIRA_ACCESS_TOKEN;

    @Value("${jira_secret}")
    String JIRA_SECRET_KEY;

    @Value("${jira_consumer_key}")
    String JIRA_CONSUMER_KEY;

    @Value("${jira_private_key}")
    String JIRA_PRIVATE_KEY;
    //</editor-fold>

    @Value("${datetimeformat}")
    private String dateTimeFormat;

    JSONUtils jsonUtils;

    JiraOAuthClient jiraOAuthClient;

    @PostConstruct
    void jiraOAuthClientInit() {
        if (jiraOAuthClient == null) {
            try {
                jiraOAuthClient = new JiraOAuthClient( JIRA_HOME_URL );
            } catch (Exception e) {
                String errMsg = "Jira OAuth Client Error.";
                LOGGER.log( Level.WARNING, errMsg, e );
                throw new RuntimeException( errMsg + e );
            }
        }

        jsonUtils = new JSONUtils( dateTimeFormat );
    }

    //<editor-fold desc="Infra : Basic Get/Post Request support methods">
    public HttpResponse handleGetRequest(String apiMethodCallUrl) {
        try {
            OAuthParameters parameters = jiraOAuthClient.getParameters( JIRA_ACCESS_TOKEN, JIRA_SECRET_KEY, JIRA_CONSUMER_KEY, JIRA_PRIVATE_KEY );
            HttpResponse response = getResponseFromUrl( parameters, new GenericUrl( apiMethodCallUrl ) );
            return response;
        } catch (Exception e) {
            String errMsg = "Handle GetRequest Error.";
            LOGGER.log( Level.WARNING, errMsg, e );
            return null;
        }
    }

    public HttpResponse handlePostRequest(String apiMethodCallUrl, HttpContent requestContent) {
        try {
            OAuthParameters parameters = jiraOAuthClient.getParameters( JIRA_ACCESS_TOKEN, JIRA_SECRET_KEY, JIRA_CONSUMER_KEY, JIRA_PRIVATE_KEY );
            HttpResponse response = postResponseFromUrl( parameters, new GenericUrl( apiMethodCallUrl ), requestContent );
            return response;
        } catch (Exception e) {
            String errMsg = "Handle PostRequest Error.";
            LOGGER.log( Level.WARNING, errMsg, e );
            return null;
        }
    }

    private HttpResponse getResponseFromUrl(OAuthParameters parameters, GenericUrl jiraUrl) throws IOException {
        HttpRequestFactory requestFactory = new NetHttpTransport().createRequestFactory( parameters );
        HttpRequest request = requestFactory.buildGetRequest( jiraUrl );
        return request.execute();
    }

    private HttpResponse postResponseFromUrl(OAuthParameters parameters, GenericUrl jiraUrl, HttpContent requestContent) throws IOException {
        HttpRequestFactory requestFactory = new NetHttpTransport().createRequestFactory( parameters );
        HttpRequest request = requestFactory.buildPostRequest( jiraUrl, requestContent );
        return request.execute();
    }
    //</editor-fold>

    //<editor-fold desc="Advanced Get/Post methods">
    //<editor-fold desc="Generic universal call/response">
    private HttpResponse executeGetAndReturnHttpResponse(@NonNull String apiMethodCallUrl) {
        return handleGetRequest( JIRA_ENDPOINT_URL + apiMethodCallUrl );
    }
    //</editor-fold>

    /**
     * Custom GET call, expecting result of a type T<br>
     *
     * @param apiMethodCallUrl Url defined by the user.<br>
     *                         Usage example :<br>
     *                         Api call, and two parameters defined at {0} and {1} positions:<br>
     *                         SITE_ID_AND_PORTFOLIO_SEARCH_JQL_WITH_OR=Portfolio = {0} AND ("Site ID" ~ "0"{1})<br>
     *                         For proper usage, MessageFormat.format( apiCall_Name, apiCall_Parameters) may be used.<br>
     */
    public <T> T executeGet(Class<T> clazz, String apiMethodCallUrl) {
        try {
            HttpResponse jsonResponse = executeGetAndReturnHttpResponse( apiMethodCallUrl );
            if (jsonResponse == null) {
                return null;
            }

            return jsonUtils.parseResponse( jsonResponse, clazz );
        } catch (Exception e) {
            String errMsg = "Executing Get Request Error.";
            LOGGER.log( Level.SEVERE, errMsg, e );
            throw new RuntimeException( errMsg, e );
        }
    }

    //<editor-fold desc="Default GET call with path variables injected into call, for returning Lists of objects">

    /**
     * Custom GET call, expecting list result.<br>
     *
     * @param apiMethodCallUrl Url defined by user.<br>
     *                         Usage example :<br>
     *                         Api call, with no parameters defined in api call "apiCallAllProjects",<br>
     *                         so there is no need for formating rest method call with parameters.<br>
     *                         If there was a need, look at {@link JiraClient#executeGet)
     */
    public <T> List<T> executeGetExpectingList(@NonNull String apiMethodCallUrl) {
        try {
            HttpResponse jsonResponse = executeGetAndReturnHttpResponse( apiMethodCallUrl );
            if (jsonResponse == null) {
                return null;
            }

            return jsonUtils.parseResponseAsList( jsonResponse );
        } catch (Exception e) {
            String errMsg = "Executing Get Request Error.";
            LOGGER.log( Level.SEVERE, errMsg, e );
            throw new RuntimeException( errMsg, e );
        }
    }
    //</editor-fold>

    //<editor-fold desc="POST">
    public HttpResponse executePostRequest(@NonNull String postOperationName, @NonNull GenericData contentGenericData) {
        String apiCallUrlPath = JIRA_ENDPOINT_URL + postOperationName;

        try {
            OAuthParameters parameters = jiraOAuthClient.getParameters( JIRA_ACCESS_TOKEN, JIRA_SECRET_KEY, JIRA_CONSUMER_KEY, JIRA_PRIVATE_KEY );
            HttpContent content = new JsonHttpContent( new JacksonFactory(), contentGenericData );
            HttpResponse response = postResponseFromUrl( parameters, new GenericUrl( apiCallUrlPath ), content );

            return response;
        } catch (HttpResponseException hre) {
            String errMsg = "Executing Post Request Error. " + hre;
            LOGGER.log( Level.SEVERE, errMsg, hre );
            throw new RuntimeException( errMsg, hre );
        } catch (Exception e) {
            String errMsg = "Executing Get Request, no result.";
            LOGGER.log( Level.INFO, errMsg, e );
            throw new RuntimeException( errMsg, e );
        }
    }

    public <T> T executePost(Class<T> clazz, @NonNull String postOperationName, @NonNull GenericData contentGenericData) {
        try {
            HttpResponse jsonResponse = executePostRequest( postOperationName, contentGenericData );
            if (jsonResponse == null) {
                return null;
            }

            return jsonUtils.parseResponse( jsonResponse, clazz );
        } catch (Exception e) {
            String errMsg = "Executing Post Request Error.";
            LOGGER.log( Level.WARNING, errMsg, e );
            throw new RuntimeException( errMsg, e );
        }
    }
    //</editor-fold>
    //</editor-fold>
}

这篇关于Java-HTTP Post Jira API-错误的请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆