Java-HTTP Post Jira API-错误请求
我有这段代码来做一个Java-HTTP Post Jira API-错误请求,java,http,post,jira,http-status-code-400,Java,Http,Post,Jira,Http Status Code 400,我有这段代码来做一个httppost到JiraURL(https://xxxxxxx.atlassian.net/rest/api/2/issue/): 如果我使用不带JSON消息的HTTP Get,它可以正常工作,但如果我使用发送JSON消息的POST,它会返回以下错误: java.io.IOException:服务器返回了URL: 我使用邮递员应用程序检查标题(内容类型和授权)和正文,并使用该应用程序在Jira中创建问题 添加: 如果我检查连接,它的参数是方法,比如GET,而不是POST
httppost
到JiraURL(https://xxxxxxx.atlassian.net/rest/api/2/issue/
):
如果我使用不带JSON消息的HTTP Get,它可以正常工作,但如果我使用发送JSON消息的POST,它会返回以下错误:
java.io.IOException:服务器返回了URL:
我使用邮递员应用程序检查标题(内容类型
和授权
)和正文,并使用该应用程序在Jira中创建问题
添加:
如果我检查连接,它的参数是方法
,比如GET
,而不是POST
我做错了什么?您能显示400响应的详细信息吗 我尝试了一些关键代码并成功地提出了POST请求。JIRA服务器将返回非常详细的消息以获得400响应,如
{
"errorMessages": [
"Field 'priority' is required"
],
"errors": {}
}
这个答案对于如何提出post请求可能很有用。
我请求将Jira集成到公司应用程序中。请求是使用OAuth,并且能够使用JIRAAPI,强调使用“createissue”调用。 稍后我将提供源代码,只是为了强调在使用POST调用时,我遇到了json问题,为了正确创建问题,我必须使用
com.google.api.client.util.GenericData
代码摘录:
@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 );
}
}
}
@PropertySource(“classpath:/JiraApiCalls/calls.properties”)
@服务
公共类JiraService{
//
@自动连线
JiraClient JiraClient;
//
@值(${GET\u ISSUE\u BY\u KEY\u URL}”)
细绳顶端;
@值(${SITE\u ID\u AND\u PORTFOLIO\u SEARCH\u JQL\u WITH\u OR}”)
字符串apiCallSiteIdAndPortfolioSearchJQLWithOr;
@值(${OR_SITE_ID}”)
字符串apicallorsteid;
@值(${SEARCH\u ISSUES\u URL}”)
字符串searchIssuesKey;
@值(“${DASHBOARDS}”)
字符串apicalldashboard;
@值(“${PROJECTS}”)
项目串;
@值(“${PROJECT}”)
字符串apiCallProjectById;
@值(“${ISSUETYPES}”)
字符串类型;
@值(“${ISSUETYPE}”)
字符串apiCallApiIssueType;
@值(${ISSUE\u CREATE}”)
弦顶端密生;
//
//
静态最终列表问题\字段=Arrays.asList(
“状态”、“创建者”、“报告者”、“受让人”、“描述”,
“摘要”、“自定义字段_11110”、“自定义字段_11126”、“组件”
);
公共jirasingleresultissuedtoGetIssuebyKey(字符串键){
字符串ISSUEAPMETHODCALLURL=MessageFormat.format(apiCallIssueByKey,key);
JiraSingleResultIssueDto=jiraClient.executeGet(JiraSingleResultIssueDto.class,IssueApmethodCallUrl);
返回dto;
}
public AllDashboards访问getAllDashboards(){
返回jiraClient.executeGet(AllDashboardsTo.class,ApicAllDashboard);
}
公共列表getAllProjects(){
List projects=jiraClient.executegetexginglist(apicallprojects);
返回项目;
}
公共项目到getProjectByKey(对象键){
ProjectDto project=jiraClient.executeGet(ProjectDto.class,MessageFormat.format(apiCallProjectById,String.valueOf(key));
返回项目;
}
公共列表getAllissueType(){
List issueTypes=jiraClient.executegeTexGingGlist(apiCallAllIssueTypes);
返回issueTypes;
}
公共JiraissueTypedToGetIssueType(对象键){
JiraIssueTypeDto issueType=jiraClient.executeGet(JiraIssueTypeDto.class,MessageFormat.format(apiCallApiIssueType,String.valueOf(key));
返回issueType;
}
public IssueCreatedResponseDto createIssue(IssueDto IssueDto)引发异常{
GenericData issueData=新的GenericData();
试一试{
//检查现有项目,如果存在则继续。。。
ProjectDto ProjectDto=getProjectByKey(发布到.getFields().getProject().getId());
GenericData projectData=新的GenericData();
projectData.put(“key”,projectDto.getKey());
//检查现有的问题类型,并在没有错误的情况下继续。。
Long issueId=issueDto.getFields().getIssuetype().getId();
getIssueType(issueId);
GenericData issueTypeData=新的GenericData();
issueTypeData.put(“id”,issueId);
GenericData字段数据=新的GenericData();
fieldsData.set(“摘要”,发布到.getFields().getSummary());
fieldsData.set(“description”,issueDto.getFields().getDescription());
字段数据集(“issuetype”,issueTypeData);
fieldsData.set(“项目”,项目数据);
发布数据。发布(“字段”,字段数据);
IssueCreatedResponseDto issueResponse=jiraClient.executePost(IssueCreatedResponseDto.class,apiCallIssueCreate,issueData);
返回发行人响应;
}捕获(例外e){
抛出新异常(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>
}
@组件
公共类JiraClient{
私有静态记录器Logger=Logger.getLogger(JiraClient.class.getName());
//
@值(${jira_home})
字符串JIRA_HOME_URL;
@值(${jira\u base\u url}”)
字符串JIRA_ENDPOINT_URL;
@值(${jira\u access\u token}”)
字符串JIRA_访问_令牌;
@值(${jira_secret}”)
字符串JIRA_SECRET_密钥;
@值(${jira\u consumer\u key})
字符串JIRA_消费者_键;
@值(${jira\u private\u key})
字符串JIRA_私钥;
//
@值(${datetimeformat}”)
私有字符串日期时间格式;
JSONUtils JSONUtils;
JiraOAuthClient JiraOAuthClient;
@施工后
void jiraoauthclientint(){
if(jiraOAuthClient==null){
试一试{
jiraOAuthClient=新的jiraOAuthClient(JIRA_HOME_URL);
}捕获(例外e){
String errMsg=“Jira OAuth客户端错误。”;
LOGGER.log(级别W
@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>
}