swagger-js-codegen api 发送了错误的请求 header content-type
swagger-js-codegen api is sending the wrong request header content-type
所以我刚从 1.x 升级到 Swagger 2,但遇到了一个奇怪的问题。我的一个 API 将不正确的 content-type 注入到 header 中,我不知道从哪里来的,您可以在下面的 SwaggerJSON 中看到,DELETE 函数甚至说它消耗了 application/json,但它的 CURL(从检查面板复制)发送 'Content-Type: text/plain;charset=UTF-8'。我提供了 CREATE 函数作为一个粗略的示例,以表明类似的 api 可以正常工作。我认为这是 swagger-js-codegen 的一个问题,因为如果我将相同的请求放入 api-docs 它工作正常,或者当然是我的 Java,或者不知何故我的 content-type header 正在设置,但我不知道如何设置或在哪里设置。我错过了什么吗? API 行为相同,无论我的 JAVA 是否声称 'consume = "application/json"'。
Swagger JSON
{
"/api/entities/{id}/labels": {
"delete": {
"consumes": [
"application/json"
],
"operationId": "deleteEntityLabel",
"parameters": [
{
"default": "16_appiniteDev",
"description": "The id of the entity to be edited",
"in": "path",
"name": "id",
"required": true,
"type": "string"
},
{
"description": "The label/labels to be deleted",
"in": "body",
"name": "labels",
"required": true,
"schema": {
"items": {
"type": "string"
},
"type": "array"
}
}
],
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/ResponseEntity"
}
},
"204": {
"description": "No Content"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
}
},
"summary": "Deletes Labels for Entities",
"tags": [
"entity-resource"
]
},
"post": {
"consumes": [
"application/json"
],
"operationId": "createEntityLabel",
"parameters": [
{
"default": "16_appiniteDev",
"description": "The id of the entity to be edited",
"in": "path",
"name": "id",
"required": true,
"type": "string"
},
{
"description": "The array of labels to be set",
"in": "body",
"name": "labels",
"required": true,
"schema": {
"items": {
"type": "string"
},
"type": "array"
}
}
],
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/ResponseEntity"
}
},
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not Found"
}
},
"summary": "Creates Labels for Entities",
"tags": [
"entity-resource"
]
}
}
}
DELETE
JAVA/SPRING
/**
* DELETE /entities/{id}/labels -> delete labels for an entity
*
* @param id
* @param labels
* @throws ServiceException
*/
@RequestMapping(value = "/entities/{id}/labels", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
@ApiOperation(value = "Deletes Labels for Entities", nickname = "deleteEntityLabel", consumes = "application/json")
public ResponseEntity deleteLabels(
@ApiParam(value = "The id of the entity to be edited", required = true, defaultValue = "16_appiniteDev") @PathVariable final String id,
@ApiParam(value = "The label/labels to be deleted", required = true, defaultValue = "[\"label1\",\"label2\",\"label3\"]") @NotNull final @RequestBody String[] labels
) throws ServiceException {
boolean isAppEntity = false;
User user = userService.getUserWithAuthorities();
String[] type = id.split("_");
if (StringUtils.isNumeric(type[0]) && !type[1].startsWith(type[0])) {
isAppEntity = true;
}
entityService.deleteTags(id, labels, user, isAppEntity);
Map<String, String> response = new LinkedHashMap<>();
response.put(Constants.RESPONSE_ENTITY_HEADER_MESSAGE,
"Labels deleted successfully");
return new ResponseEntity(response, HttpStatus.OK);
}
CURL FROM APP
curl 'http://localhost:8080//api/entities/52_QA42/labels?cacheBuster=1472070679337' -X DELETE -H 'Pragma: no-cache' -H 'Origin: http://localhost:8080' -H 'Accept-Encoding: gzip, deflate, sdch' -H 'Accept-Language: en-US,en;q=0.8' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36' -H 'Content-Type: text/plain;charset=UTF-8' -H 'Accept: application/json, text/plain, */*' -H 'Cache-Control: no-cache' -H 'x-auth-token: admin:1472097365429:8e6524e252e2aebb786b7738c44fe385' -H 'Referer: http://localhost:8080/' -H 'Cookie: NG_TRANSLATE_LANG_KEY=%22en%22' -H 'Connection: keep-alive' -H 'DNT: 1' --data-binary '["Bug13124"]' --compressed
CREATE
JAVA/SPRING
/**
* POST /entities/{id}/labels -> add labels for a non hadoop entity
*
* @param id
* @param labels
* @throws ServiceException
*/
@RequestMapping(value = "/entities/{id}/labels", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
@ApiOperation(value = "Creates Labels for Entities", nickname = "createEntityLabel")
public ResponseEntity addLabels(
@ApiParam(value = "The id of the entity to be edited", required = true, defaultValue = "16_appiniteDev") @PathVariable final String id,
@ApiParam(value = "The array of labels to be set", required = true, defaultValue = "[\"label1\",\"label2\",\"label3\"]") @NotNull final @RequestBody String[] labels)
throws ServiceException {
boolean isAppEntity = false;
User user = userService.getUserWithAuthorities();
String[] type = id.split("_");
if (StringUtils.isNumeric(type[0]) && !type[1].startsWith(type[0])) {
isAppEntity = true;
}
entityService.addTags(id, labels, user, isAppEntity);
Map<String, String> response = new LinkedHashMap<>();
response.put(Constants.RESPONSE_ENTITY_HEADER_MESSAGE,
"Labels added successfully");
return new ResponseEntity(response, HttpStatus.OK);
}
CURL FROM APP
curl 'http://localhost:8080//api/entities/52_QA42/labels?cacheBuster=1472071851544' -H 'Pragma: no-cache' -H 'Origin: http://localhost:8080' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: en-US,en;q=0.8' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36' -H 'Content-Type: application/json;charset=UTF-8' -H 'Accept: application/json, text/plain, */*' -H 'Cache-Control: no-cache' -H 'x-auth-token: admin:1472097365429:8e6524e252e2aebb786b7738c44fe385' -H 'Referer: http://localhost:8080/' -H 'Cookie: NG_TRANSLATE_LANG_KEY=%22en%22' -H 'Connection: keep-alive' -H 'DNT: 1' --data-binary '["test"]' --compressed
有什么想法吗?
我无法确定 Content-Type 的设置方式或设置位置,所以我用蛮力解决了这个问题:创建了一个拦截器来更改 header content-type 强制:
.factory('contentInterceptor', function ($rootScope, $q, $location, localStorageService, $cookies) {
return {
// Add authorization token to headers
request: function (config) {
config.headers = config.headers || {};
config.headers['Content-Type'] = 'application/json';
return config;
}
};
})
.config(function ($httpProvider) {
$httpProvider.interceptors.push('contentInterceptor');
});
工作起来很有魅力,幸运的是不会影响我的任何其他 API,因为它们都需要 Application/JSON 除了多部分形式的,但是那些明确地设置并且是' 受此拦截器影响。
**** 更新 *****
我是个笨蛋,没有意识到我可以将以下内容放入我的小胡子模板中。这是正确答案。它采用适当的 'consumes' 和 'produces' 属性并确保发送正确的 header。
{{#headers}}
options.headers['{{&name}}'] = {{&value}};
{{/headers}}
所以我刚从 1.x 升级到 Swagger 2,但遇到了一个奇怪的问题。我的一个 API 将不正确的 content-type 注入到 header 中,我不知道从哪里来的,您可以在下面的 SwaggerJSON 中看到,DELETE 函数甚至说它消耗了 application/json,但它的 CURL(从检查面板复制)发送 'Content-Type: text/plain;charset=UTF-8'。我提供了 CREATE 函数作为一个粗略的示例,以表明类似的 api 可以正常工作。我认为这是 swagger-js-codegen 的一个问题,因为如果我将相同的请求放入 api-docs 它工作正常,或者当然是我的 Java,或者不知何故我的 content-type header 正在设置,但我不知道如何设置或在哪里设置。我错过了什么吗? API 行为相同,无论我的 JAVA 是否声称 'consume = "application/json"'。
Swagger JSON
{
"/api/entities/{id}/labels": {
"delete": {
"consumes": [
"application/json"
],
"operationId": "deleteEntityLabel",
"parameters": [
{
"default": "16_appiniteDev",
"description": "The id of the entity to be edited",
"in": "path",
"name": "id",
"required": true,
"type": "string"
},
{
"description": "The label/labels to be deleted",
"in": "body",
"name": "labels",
"required": true,
"schema": {
"items": {
"type": "string"
},
"type": "array"
}
}
],
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/ResponseEntity"
}
},
"204": {
"description": "No Content"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
}
},
"summary": "Deletes Labels for Entities",
"tags": [
"entity-resource"
]
},
"post": {
"consumes": [
"application/json"
],
"operationId": "createEntityLabel",
"parameters": [
{
"default": "16_appiniteDev",
"description": "The id of the entity to be edited",
"in": "path",
"name": "id",
"required": true,
"type": "string"
},
{
"description": "The array of labels to be set",
"in": "body",
"name": "labels",
"required": true,
"schema": {
"items": {
"type": "string"
},
"type": "array"
}
}
],
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/ResponseEntity"
}
},
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not Found"
}
},
"summary": "Creates Labels for Entities",
"tags": [
"entity-resource"
]
}
}
}
DELETE
JAVA/SPRING
/**
* DELETE /entities/{id}/labels -> delete labels for an entity
*
* @param id
* @param labels
* @throws ServiceException
*/
@RequestMapping(value = "/entities/{id}/labels", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
@ApiOperation(value = "Deletes Labels for Entities", nickname = "deleteEntityLabel", consumes = "application/json")
public ResponseEntity deleteLabels(
@ApiParam(value = "The id of the entity to be edited", required = true, defaultValue = "16_appiniteDev") @PathVariable final String id,
@ApiParam(value = "The label/labels to be deleted", required = true, defaultValue = "[\"label1\",\"label2\",\"label3\"]") @NotNull final @RequestBody String[] labels
) throws ServiceException {
boolean isAppEntity = false;
User user = userService.getUserWithAuthorities();
String[] type = id.split("_");
if (StringUtils.isNumeric(type[0]) && !type[1].startsWith(type[0])) {
isAppEntity = true;
}
entityService.deleteTags(id, labels, user, isAppEntity);
Map<String, String> response = new LinkedHashMap<>();
response.put(Constants.RESPONSE_ENTITY_HEADER_MESSAGE,
"Labels deleted successfully");
return new ResponseEntity(response, HttpStatus.OK);
}
CURL FROM APP
curl 'http://localhost:8080//api/entities/52_QA42/labels?cacheBuster=1472070679337' -X DELETE -H 'Pragma: no-cache' -H 'Origin: http://localhost:8080' -H 'Accept-Encoding: gzip, deflate, sdch' -H 'Accept-Language: en-US,en;q=0.8' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36' -H 'Content-Type: text/plain;charset=UTF-8' -H 'Accept: application/json, text/plain, */*' -H 'Cache-Control: no-cache' -H 'x-auth-token: admin:1472097365429:8e6524e252e2aebb786b7738c44fe385' -H 'Referer: http://localhost:8080/' -H 'Cookie: NG_TRANSLATE_LANG_KEY=%22en%22' -H 'Connection: keep-alive' -H 'DNT: 1' --data-binary '["Bug13124"]' --compressed
CREATE
JAVA/SPRING
/**
* POST /entities/{id}/labels -> add labels for a non hadoop entity
*
* @param id
* @param labels
* @throws ServiceException
*/
@RequestMapping(value = "/entities/{id}/labels", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
@ApiOperation(value = "Creates Labels for Entities", nickname = "createEntityLabel")
public ResponseEntity addLabels(
@ApiParam(value = "The id of the entity to be edited", required = true, defaultValue = "16_appiniteDev") @PathVariable final String id,
@ApiParam(value = "The array of labels to be set", required = true, defaultValue = "[\"label1\",\"label2\",\"label3\"]") @NotNull final @RequestBody String[] labels)
throws ServiceException {
boolean isAppEntity = false;
User user = userService.getUserWithAuthorities();
String[] type = id.split("_");
if (StringUtils.isNumeric(type[0]) && !type[1].startsWith(type[0])) {
isAppEntity = true;
}
entityService.addTags(id, labels, user, isAppEntity);
Map<String, String> response = new LinkedHashMap<>();
response.put(Constants.RESPONSE_ENTITY_HEADER_MESSAGE,
"Labels added successfully");
return new ResponseEntity(response, HttpStatus.OK);
}
CURL FROM APP
curl 'http://localhost:8080//api/entities/52_QA42/labels?cacheBuster=1472071851544' -H 'Pragma: no-cache' -H 'Origin: http://localhost:8080' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: en-US,en;q=0.8' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36' -H 'Content-Type: application/json;charset=UTF-8' -H 'Accept: application/json, text/plain, */*' -H 'Cache-Control: no-cache' -H 'x-auth-token: admin:1472097365429:8e6524e252e2aebb786b7738c44fe385' -H 'Referer: http://localhost:8080/' -H 'Cookie: NG_TRANSLATE_LANG_KEY=%22en%22' -H 'Connection: keep-alive' -H 'DNT: 1' --data-binary '["test"]' --compressed
有什么想法吗?
我无法确定 Content-Type 的设置方式或设置位置,所以我用蛮力解决了这个问题:创建了一个拦截器来更改 header content-type 强制:
.factory('contentInterceptor', function ($rootScope, $q, $location, localStorageService, $cookies) {
return {
// Add authorization token to headers
request: function (config) {
config.headers = config.headers || {};
config.headers['Content-Type'] = 'application/json';
return config;
}
};
})
.config(function ($httpProvider) {
$httpProvider.interceptors.push('contentInterceptor');
});
工作起来很有魅力,幸运的是不会影响我的任何其他 API,因为它们都需要 Application/JSON 除了多部分形式的,但是那些明确地设置并且是' 受此拦截器影响。
**** 更新 *****
我是个笨蛋,没有意识到我可以将以下内容放入我的小胡子模板中。这是正确答案。它采用适当的 'consumes' 和 'produces' 属性并确保发送正确的 header。
{{#headers}}
options.headers['{{&name}}'] = {{&value}};
{{/headers}}