Skip to content

Commit c3d2a58

Browse files
committed
Merge pull request #790 from xhh/java-accept-contenttype
Minor improvement to Java API client accept and content-type header
2 parents ddbef8b + d345283 commit c3d2a58

File tree

11 files changed

+442
-93
lines changed

11 files changed

+442
-93
lines changed

modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/JavaClientCodegen.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,10 @@ public void processOpts() {
109109
final String invokerFolder = (sourceFolder + File.separator + invokerPackage).replace(".", File.separator);
110110
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
111111
supportingFiles.add(new SupportingFile("ApiClient.mustache", invokerFolder, "ApiClient.java"));
112-
supportingFiles.add(new SupportingFile("JsonUtil.mustache", invokerFolder, "JsonUtil.java"));
113112
supportingFiles.add(new SupportingFile("apiException.mustache", invokerFolder, "ApiException.java"));
114113
supportingFiles.add(new SupportingFile("Configuration.mustache", invokerFolder, "Configuration.java"));
114+
supportingFiles.add(new SupportingFile("JsonUtil.mustache", invokerFolder, "JsonUtil.java"));
115+
supportingFiles.add(new SupportingFile("StringUtil.mustache", invokerFolder, "StringUtil.java"));
115116

116117
final String authFolder = (sourceFolder + File.separator + invokerPackage + ".auth").replace(".", File.separator);
117118
supportingFiles.add(new SupportingFile("auth/Authentication.mustache", authFolder, "Authentication.java"));

modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,36 @@ public class ApiClient {
238238
}
239239
}
240240

241+
/**
242+
* Select the Accept header's value from the given accepts array:
243+
* if JSON exists in the given array, use it;
244+
* otherwise use all of them (joining into a string)
245+
*
246+
* @param accepts The accepts array to select from
247+
* @return The Accept header to use. If the given array is empty,
248+
* null will be returned (not to set the Accept header explicitly).
249+
*/
250+
public String selectHeaderAccept(String[] accepts) {
251+
if (accepts.length == 0) return null;
252+
if (StringUtil.containsIgnoreCase(accepts, "application/json")) return "application/json";
253+
return StringUtil.join(accepts, ",");
254+
}
255+
256+
/**
257+
* Select the Content-Type header's value from the given array:
258+
* if JSON exists in the given array, use it;
259+
* otherwise use the first one of the array.
260+
*
261+
* @param contentTypes The Content-Type array to select from
262+
* @return The Content-Type header to use. If the given array is empty,
263+
* JSON will be used.
264+
*/
265+
public String selectHeaderContentType(String[] contentTypes) {
266+
if (contentTypes.length == 0) return "application/json";
267+
if (StringUtil.containsIgnoreCase(contentTypes, "application/json")) return "application/json";
268+
return contentTypes[0];
269+
}
270+
241271
/**
242272
* Escape the given string to be used as URL query value.
243273
*/
@@ -306,11 +336,12 @@ public class ApiClient {
306336
* @param body The request body object
307337
* @param headerParams The header parameters
308338
* @param formParams The form parameters
309-
* @param contentType The request Content-Type
339+
* @param accept The request's Accept header
340+
* @param contentType The request's Content-Type header
310341
* @param authNames The authentications to apply
311342
* @return The response body in type of string
312343
*/
313-
public String invokeAPI(String path, String method, Map<String, String> queryParams, Object body, Map<String, String> headerParams, Map<String, String> formParams, String contentType, String[] authNames) throws ApiException {
344+
public String invokeAPI(String path, String method, Map<String, String> queryParams, Object body, Map<String, String> headerParams, Map<String, String> formParams, String accept, String contentType, String[] authNames) throws ApiException {
314345
updateParamsForAuth(authNames, queryParams, headerParams);
315346
316347
Client client = getClient();
@@ -328,16 +359,21 @@ public class ApiClient {
328359
}
329360
String querystring = b.toString();
330361

331-
Builder builder = client.resource(basePath + path + querystring).accept("application/json");
362+
Builder builder;
363+
if (accept == null)
364+
builder = client.resource(basePath + path + querystring).getRequestBuilder();
365+
else
366+
builder = client.resource(basePath + path + querystring).accept(accept);
367+
332368
for(String key : headerParams.keySet()) {
333369
builder = builder.header(key, headerParams.get(key));
334370
}
335-
336371
for(String key : defaultHeaderMap.keySet()) {
337372
if(!headerParams.containsKey(key)) {
338373
builder = builder.header(key, defaultHeaderMap.get(key));
339374
}
340375
}
376+
341377
ClientResponse response = null;
342378

343379
if("GET".equals(method)) {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package {{invokerPackage}};
2+
3+
public class StringUtil {
4+
/**
5+
* Check if the given array contains the given value (with case-insensitive comparison).
6+
*
7+
* @param array The array
8+
* @param value The value to search
9+
* @return true if the array contains the value
10+
*/
11+
public static boolean containsIgnoreCase(String[] array, String value) {
12+
for (String str : array) {
13+
if (value == null && str == null) return true;
14+
if (value != null && value.equalsIgnoreCase(str)) return true;
15+
}
16+
return false;
17+
}
18+
19+
/**
20+
* Join an array of strings with the given separator.
21+
* <p>
22+
* Note: This might be replaced by utility method from commons-lang or guava someday
23+
* if one of those libraries is added as dependency.
24+
* </p>
25+
*
26+
* @param array The array of strings
27+
* @param separator The separator
28+
* @return the resulting string
29+
*/
30+
public static String join(String[] array, String separator) {
31+
int len = array.length;
32+
if (len == 0) return "";
33+
34+
StringBuilder out = new StringBuilder();
35+
out.append(array[0]);
36+
for (int i = 1; i < len; i++) {
37+
out.append(separator).append(array[i]);
38+
}
39+
return out.toString();
40+
}
41+
}

modules/swagger-codegen/src/main/resources/Java/api.mustache

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,20 @@ public class {{classname}} {
6868
{{#queryParams}}if ({{paramName}} != null)
6969
queryParams.put("{{baseName}}", apiClient.parameterToString({{paramName}}));
7070
{{/queryParams}}
71+
7172
{{#headerParams}}if ({{paramName}} != null)
7273
headerParams.put("{{baseName}}", apiClient.parameterToString({{paramName}}));
7374
{{/headerParams}}
74-
String[] contentTypes = {
75-
{{#consumes}}"{{mediaType}}"{{#hasMore}},{{/hasMore}}{{/consumes}}
75+
76+
final String[] accepts = {
77+
{{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}}
7678
};
79+
final String accept = apiClient.selectHeaderAccept(accepts);
7780

78-
String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
81+
final String[] contentTypes = {
82+
{{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}
83+
};
84+
final String contentType = apiClient.selectHeaderContentType(contentTypes);
7985

8086
if(contentType.startsWith("multipart/form-data")) {
8187
boolean hasFields = false;
@@ -103,7 +109,7 @@ public class {{classname}} {
103109

104110
try {
105111
String[] authNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
106-
String response = apiClient.invokeAPI(path, "{{httpMethod}}", queryParams, postBody, headerParams, formParams, contentType, authNames);
112+
String response = apiClient.invokeAPI(path, "{{httpMethod}}", queryParams, postBody, headerParams, formParams, accept, contentType, authNames);
107113
if(response != null){
108114
return {{#returnType}}({{{returnType}}}) apiClient.deserialize(response, "{{returnContainer}}", {{returnBaseType}}.class){{/returnType}};
109115
}

samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,36 @@ public String parameterToString(Object param) {
237237
}
238238
}
239239

240+
/**
241+
* Select the Accept header's value from the given accepts array:
242+
* if JSON exists in the given array, use it;
243+
* otherwise use all of them (joining into a string)
244+
*
245+
* @param accepts The accepts array to select from
246+
* @return The Accept header to use. If the given array is empty,
247+
* null will be returned (not to set the Accept header explicitly).
248+
*/
249+
public String selectHeaderAccept(String[] accepts) {
250+
if (accepts.length == 0) return null;
251+
if (StringUtil.containsIgnoreCase(accepts, "application/json")) return "application/json";
252+
return StringUtil.join(accepts, ",");
253+
}
254+
255+
/**
256+
* Select the Content-Type header's value from the given array:
257+
* if JSON exists in the given array, use it;
258+
* otherwise use the first one of the array.
259+
*
260+
* @param contentTypes The Content-Type array to select from
261+
* @return The Content-Type header to use. If the given array is empty,
262+
* JSON will be used.
263+
*/
264+
public String selectHeaderContentType(String[] contentTypes) {
265+
if (contentTypes.length == 0) return "application/json";
266+
if (StringUtil.containsIgnoreCase(contentTypes, "application/json")) return "application/json";
267+
return contentTypes[0];
268+
}
269+
240270
/**
241271
* Escape the given string to be used as URL query value.
242272
*/
@@ -305,11 +335,12 @@ public String serialize(Object obj) throws ApiException {
305335
* @param body The request body object
306336
* @param headerParams The header parameters
307337
* @param formParams The form parameters
308-
* @param contentType The request Content-Type
338+
* @param accept The request's Accept header
339+
* @param contentType The request's Content-Type header
309340
* @param authNames The authentications to apply
310341
* @return The response body in type of string
311342
*/
312-
public String invokeAPI(String path, String method, Map<String, String> queryParams, Object body, Map<String, String> headerParams, Map<String, String> formParams, String contentType, String[] authNames) throws ApiException {
343+
public String invokeAPI(String path, String method, Map<String, String> queryParams, Object body, Map<String, String> headerParams, Map<String, String> formParams, String accept, String contentType, String[] authNames) throws ApiException {
313344
updateParamsForAuth(authNames, queryParams, headerParams);
314345

315346
Client client = getClient();
@@ -327,16 +358,21 @@ public String invokeAPI(String path, String method, Map<String, String> queryPar
327358
}
328359
String querystring = b.toString();
329360

330-
Builder builder = client.resource(basePath + path + querystring).accept("application/json");
361+
Builder builder;
362+
if (accept == null)
363+
builder = client.resource(basePath + path + querystring).getRequestBuilder();
364+
else
365+
builder = client.resource(basePath + path + querystring).accept(accept);
366+
331367
for(String key : headerParams.keySet()) {
332368
builder = builder.header(key, headerParams.get(key));
333369
}
334-
335370
for(String key : defaultHeaderMap.keySet()) {
336371
if(!headerParams.containsKey(key)) {
337372
builder = builder.header(key, defaultHeaderMap.get(key));
338373
}
339374
}
375+
340376
ClientResponse response = null;
341377

342378
if("GET".equals(method)) {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package io.swagger.client;
2+
3+
public class StringUtil {
4+
/**
5+
* Check if the given array contains the given value (with case-insensitive comparison).
6+
*
7+
* @param array The array
8+
* @param value The value to search
9+
* @return true if the array contains the value
10+
*/
11+
public static boolean containsIgnoreCase(String[] array, String value) {
12+
for (String str : array) {
13+
if (value == null && str == null) return true;
14+
if (value != null && value.equalsIgnoreCase(str)) return true;
15+
}
16+
return false;
17+
}
18+
19+
/**
20+
* Join an array of strings with the given separator.
21+
* <p>
22+
* Note: This might be replaced by utility method from commons-lang or guava someday
23+
* if one of those libraries is added as dependency.
24+
* </p>
25+
*
26+
* @param array The array of strings
27+
* @param separator The separator
28+
* @return the resulting string
29+
*/
30+
public static String join(String[] array, String separator) {
31+
int len = array.length;
32+
if (len == 0) return "";
33+
34+
StringBuilder out = new StringBuilder();
35+
out.append(array[0]);
36+
for (int i = 1; i < len; i++) {
37+
out.append(separator).append(array[i]);
38+
}
39+
return out.toString();
40+
}
41+
}

0 commit comments

Comments
 (0)