diff --git a/lib/codegen/codegen.dart b/lib/codegen/codegen.dart index 07e141d1..f3f606ae 100644 --- a/lib/codegen/codegen.dart +++ b/lib/codegen/codegen.dart @@ -58,8 +58,7 @@ class Codegen { case CodegenLanguage.nodejsFetch: return FetchCodeGen(isNodeJs: true).getCode(rM); case CodegenLanguage.javaAsyncHttpClient: - return JavaAsyncHttpClientGen() - .getCode(rM, boundary: boundary ?? getNewUuid()); + return JavaAsyncHttpClientGen().getCode(rM); case CodegenLanguage.javaHttpClient: return JavaHttpClientCodeGen().getCode(rM); case CodegenLanguage.javaOkHttp: diff --git a/lib/codegen/java/async_http_client.dart b/lib/codegen/java/async_http_client.dart index 9542b180..a32b6e49 100644 --- a/lib/codegen/java/async_http_client.dart +++ b/lib/codegen/java/async_http_client.dart @@ -1,12 +1,11 @@ -import 'dart:convert'; -import 'package:apidash/utils/har_utils.dart'; -import 'package:apidash/utils/http_utils.dart'; import 'package:jinja/jinja.dart' as jj; +import 'package:apidash/utils/utils.dart' + show getValidRequestUri, stripUriParams; import 'package:apidash/models/models.dart' show RequestModel; import 'package:apidash/consts.dart'; class JavaAsyncHttpClientGen { - final String kTemplateStart = ''' + final String kStringStart = ''' import org.asynchttpclient.*; import java.io.*; @@ -20,17 +19,18 @@ import java.util.stream.Collectors; final String kTemplateMultipartImport = ''' import java.util.Map; import java.util.HashMap; -import org.asynchttpclient.request.body.multipart.FilePart; import org.asynchttpclient.request.body.multipart.StringPart; +{% if hasFileInFormData %}import org.asynchttpclient.request.body.multipart.FilePart; +{% endif %} '''; - final String kTemplateMainClassMainMethodStart = ''' + final String kStringMainClassMainMethodStart = ''' public class Main { public static void main(String[] args) { '''; - final String kTemplateAsyncHttpClientTryBlockStart = ''' + final String kStringAsyncHttpClientTryBlockStart = ''' try (AsyncHttpClient asyncHttpClient = Dsl.asyncHttpClient()) { '''; @@ -51,10 +51,6 @@ public class Main { requestBuilder{% for name, value in headers %} .addHeader("{{ name }}", "{{ value }}"){% endfor %};\n '''; - final String kTemplateSimpleTextFormData = ''' - requestBuilder{% for param in params if param.type == "text" %} - .addFormParam("{{ param.name }}", "{{ param.value }}"){% endfor %};\n -'''; final String kTemplateMultipartTextFormData = ''' @@ -95,13 +91,14 @@ public class Main { '''; String kTemplateRequestBodyContent = ''' - String bodyContent = "{{body}}";\n + String bodyContent = """ +{{body}}""";\n '''; - String kTemplateRequestBodySetup = ''' - requestBuilder.setBody(bodyContent);\n + String kStringRequestBodySetup = ''' + requestBuilder.setBody(bodyContent); '''; - final String kTemplateRequestEnd = ''' + final String kStringRequestEnd = ''' Future whenResponse = requestBuilder.execute(); Response response = whenResponse.get(); InputStream is = response.getResponseBodyAsStream(); @@ -113,13 +110,12 @@ public class Main { } } -}\n +} '''; String? getCode( - RequestModel requestModel, { - String? boundary, - }) { + RequestModel requestModel, + ) { try { String result = ''; bool hasBody = false; @@ -134,46 +130,33 @@ public class Main { return ""; } - result += kTemplateStart; - if (requestModel.hasBody && requestModel.hasFileInFormData) { - result += kTemplateMultipartImport; + result += kStringStart; + if (requestModel.hasFormData) { + var templateMultipartImport = jj.Template(kTemplateMultipartImport); + result += templateMultipartImport + .render({"hasFileInFormData": requestModel.hasFileInFormData}); + ; } - result += kTemplateMainClassMainMethodStart; - result += kTemplateAsyncHttpClientTryBlockStart; + result += kStringMainClassMainMethodStart; + result += kStringAsyncHttpClientTryBlockStart; var url = stripUriParams(uri); // contains the HTTP method associated with the request var method = requestModel.method; - // contains the entire request body as a string if body is present - var requestBody = requestModel.requestBody; - // generating the URL to which the request has to be submitted var templateUrl = jj.Template(kTemplateUrl); result += templateUrl.render({"url": url}); - // creating request body if available - var rM = requestModel.copyWith(url: url); - var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); - // if request type is not form data, the request method can include // a body, and the body of the request is not null, in that case // we need to parse the body as it is, and write it to the body - if (!requestModel.hasFormData && - kMethodsWithBody.contains(method) && - requestBody != null) { - var contentLength = utf8.encode(requestBody).length; - if (contentLength > 0) { - var templateBodyContent = jj.Template(kTemplateRequestBodyContent); - hasBody = true; - if (harJson["postData"]?["text"] != null) { - result += templateBodyContent.render({ - "body": kEncoder.convert(harJson["postData"]["text"]).substring( - 1, kEncoder.convert(harJson["postData"]["text"]).length - 1) - }); - } - } + if (requestModel.hasTextData || requestModel.hasJsonData) { + var templateBodyContent = jj.Template(kTemplateRequestBodyContent); + result += + templateBodyContent.render({"body": requestModel.requestBody}); + hasBody = true; } var templateRequestCreation = jj.Template(kTemplateRequestCreation); @@ -186,44 +169,16 @@ public class Main { result += templateUrlQueryParam.render({"queryParams": params}); } - var headers = {}; - for (var i in harJson["headers"]) { - headers[i["name"]] = i["value"]; - } - - // especially sets up Content-Type header if the request has a body - // and Content-Type is not explicitely set by the developer - if (requestModel.hasBody && !headers.containsKey("Content-Type")) { - headers["Content-Type"] = requestModel.requestBodyContentType.header; - } - - if (requestModel.hasBody && - requestModel.hasFormData && - !requestModel.hasFileInFormData) { - headers["Content-Type"] = "application/x-www-form-urlencoded"; - } - - // we will use this request boundary to set boundary if multipart formdata is used - // String requestBoundary = ""; - String multipartTypePrefix = "multipart/form-data; boundary="; - if (headers.containsKey("Content-Type") && - headers["Content-Type"]!.startsWith(RegExp(multipartTypePrefix))) { - // String tmp = headers["Content-Type"]!; - // requestBoundary = tmp.substring(multipartTypePrefix.length); - - // if a boundary is provided, we will use that as the default boundary - if (boundary != null) { - // requestBoundary = boundary; - headers["Content-Type"] = multipartTypePrefix + boundary; - } + var headers = requestModel.enabledHeadersMap; + if (hasBody && !requestModel.hasContentTypeHeader) { + headers[kHeaderContentType] = + requestModel.requestBodyContentType.header; } // setting up rest of the request headers if (headers.isNotEmpty) { var templateRequestHeader = jj.Template(kTemplateRequestHeader); - result += templateRequestHeader.render({ - "headers": headers // - }); + result += templateRequestHeader.render({"headers": headers}); } // handling form data @@ -240,13 +195,11 @@ public class Main { } if (textCount > 0) { - var templateRequestFormData = jj.Template( - (requestModel.hasFileInFormData) - ? kTemplateMultipartTextFormData - : kTemplateSimpleTextFormData); + var templateRequestFormData = + jj.Template(kTemplateMultipartTextFormData); result += templateRequestFormData.render({ - "params": formDataList, // + "params": formDataList, }); } @@ -259,15 +212,11 @@ public class Main { } } - var templateRequestBodySetup = jj.Template(kTemplateRequestBodySetup); - if (kMethodsWithBody.contains(method) && - hasBody && - !requestModel.hasFormData) { - result += templateRequestBodySetup.render(); + if (hasBody) { + result += kStringRequestBodySetup; } - var templateRequestBodyEnd = jj.Template(kTemplateRequestEnd); - result += templateRequestBodyEnd.render(); + result += kStringRequestEnd; return result; } catch (e) { diff --git a/test/codegen/java_async_http_client_codegen.dart b/test/codegen/java_async_http_client_codegen.dart index 5575e65a..857ec4cf 100644 --- a/test/codegen/java_async_http_client_codegen.dart +++ b/test/codegen/java_async_http_client_codegen.dart @@ -516,7 +516,10 @@ public class Main { public static void main(String[] args) { try (AsyncHttpClient asyncHttpClient = Dsl.asyncHttpClient()) { String url = "https://api.apidash.dev/case/lower"; - String bodyContent = "{\n\"text\": \"I LOVE Flutter\"\n}"; + String bodyContent = """ +{ +"text": "I LOVE Flutter" +}"""; BoundRequestBuilder requestBuilder = asyncHttpClient.prepare("POST", url); requestBuilder .addHeader("Content-Type", "text/plain"); @@ -553,7 +556,15 @@ public class Main { public static void main(String[] args) { try (AsyncHttpClient asyncHttpClient = Dsl.asyncHttpClient()) { String url = "https://api.apidash.dev/case/lower"; - String bodyContent = "{\n\"text\": \"I LOVE Flutter\",\n\"flag\": null,\n\"male\": true,\n\"female\": false,\n\"no\": 1.2,\n\"arr\": [\"null\", \"true\", \"false\", null]\n}"; + String bodyContent = """ +{ +"text": "I LOVE Flutter", +"flag": null, +"male": true, +"female": false, +"no": 1.2, +"arr": ["null", "true", "false", null] +}"""; BoundRequestBuilder requestBuilder = asyncHttpClient.prepare("POST", url); requestBuilder .addHeader("Content-Type", "application/json"); @@ -590,11 +601,14 @@ public class Main { public static void main(String[] args) { try (AsyncHttpClient asyncHttpClient = Dsl.asyncHttpClient()) { String url = "https://api.apidash.dev/case/lower"; - String bodyContent = "{\n\"text\": \"I LOVE Flutter\"\n}"; + String bodyContent = """ +{ +"text": "I LOVE Flutter" +}"""; BoundRequestBuilder requestBuilder = asyncHttpClient.prepare("POST", url); requestBuilder - .addHeader("Content-Type", "application/json") - .addHeader("User-Agent", "Test Agent"); + .addHeader("User-Agent", "Test Agent") + .addHeader("Content-Type", "application/json"); requestBuilder.setBody(bodyContent); Future whenResponse = requestBuilder.execute(); Response response = whenResponse.get(); @@ -624,17 +638,30 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.stream.Collectors; +import java.util.Map; +import java.util.HashMap; +import org.asynchttpclient.request.body.multipart.StringPart; + public class Main { public static void main(String[] args) { try (AsyncHttpClient asyncHttpClient = Dsl.asyncHttpClient()) { String url = "https://api.apidash.dev/io/form"; BoundRequestBuilder requestBuilder = asyncHttpClient.prepare("POST", url); - requestBuilder - .addHeader("Content-Type", "application/x-www-form-urlencoded"); - requestBuilder - .addFormParam("text", "API") - .addFormParam("sep", "|") - .addFormParam("times", "3"); + + Map params = new HashMap<>() { + { + put("text", "API"); + put("sep", "|"); + put("times", "3"); + } + }; + + for (String paramName : params.keySet()) { + requestBuilder.addBodyPart(new StringPart( + paramName, params.get(paramName) + )); + } + Future whenResponse = requestBuilder.execute(); Response response = whenResponse.get(); InputStream is = response.getResponseBodyAsStream(); @@ -663,18 +690,32 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.stream.Collectors; +import java.util.Map; +import java.util.HashMap; +import org.asynchttpclient.request.body.multipart.StringPart; + public class Main { public static void main(String[] args) { try (AsyncHttpClient asyncHttpClient = Dsl.asyncHttpClient()) { String url = "https://api.apidash.dev/io/form"; BoundRequestBuilder requestBuilder = asyncHttpClient.prepare("POST", url); requestBuilder - .addHeader("Content-Type", "application/x-www-form-urlencoded") .addHeader("User-Agent", "Test Agent"); - requestBuilder - .addFormParam("text", "API") - .addFormParam("sep", "|") - .addFormParam("times", "3"); + + Map params = new HashMap<>() { + { + put("text", "API"); + put("sep", "|"); + put("times", "3"); + } + }; + + for (String paramName : params.keySet()) { + requestBuilder.addBodyPart(new StringPart( + paramName, params.get(paramName) + )); + } + Future whenResponse = requestBuilder.execute(); Response response = whenResponse.get(); InputStream is = response.getResponseBodyAsStream(); @@ -705,16 +746,14 @@ import java.util.stream.Collectors; import java.util.Map; import java.util.HashMap; -import org.asynchttpclient.request.body.multipart.FilePart; import org.asynchttpclient.request.body.multipart.StringPart; +import org.asynchttpclient.request.body.multipart.FilePart; public class Main { public static void main(String[] args) { try (AsyncHttpClient asyncHttpClient = Dsl.asyncHttpClient()) { String url = "https://api.apidash.dev/io/img"; BoundRequestBuilder requestBuilder = asyncHttpClient.prepare("POST", url); - requestBuilder - .addHeader("Content-Type", "multipart/form-data; boundary=12b3ea10-3711-1f2f-ae52-0d40a793d870"); Map params = new HashMap<>() { { @@ -760,8 +799,7 @@ public class Main { '''; expect( codeGen.getCode( - CodegenLanguage.javaAsyncHttpClient, requestModelPost6, "https", - boundary: "12b3ea10-3711-1f2f-ae52-0d40a793d870"), + CodegenLanguage.javaAsyncHttpClient, requestModelPost6, "https"), expectedCode); }); @@ -776,16 +814,14 @@ import java.util.stream.Collectors; import java.util.Map; import java.util.HashMap; -import org.asynchttpclient.request.body.multipart.FilePart; import org.asynchttpclient.request.body.multipart.StringPart; +import org.asynchttpclient.request.body.multipart.FilePart; public class Main { public static void main(String[] args) { try (AsyncHttpClient asyncHttpClient = Dsl.asyncHttpClient()) { String url = "https://api.apidash.dev/io/img"; BoundRequestBuilder requestBuilder = asyncHttpClient.prepare("POST", url); - requestBuilder - .addHeader("Content-Type", "multipart/form-data; boundary=12b3ea10-3711-1f2f-ae52-0d40a793d870"); Map params = new HashMap<>() { { @@ -831,8 +867,7 @@ public class Main { '''; expect( codeGen.getCode( - CodegenLanguage.javaAsyncHttpClient, requestModelPost7, "https", - boundary: "12b3ea10-3711-1f2f-ae52-0d40a793d870"), + CodegenLanguage.javaAsyncHttpClient, requestModelPost7, "https"), expectedCode); }); @@ -845,6 +880,10 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.stream.Collectors; +import java.util.Map; +import java.util.HashMap; +import org.asynchttpclient.request.body.multipart.StringPart; + public class Main { public static void main(String[] args) { try (AsyncHttpClient asyncHttpClient = Dsl.asyncHttpClient()) { @@ -853,12 +892,21 @@ public class Main { requestBuilder .addQueryParam("size", "2") .addQueryParam("len", "3"); - requestBuilder - .addHeader("Content-Type", "application/x-www-form-urlencoded"); - requestBuilder - .addFormParam("text", "API") - .addFormParam("sep", "|") - .addFormParam("times", "3"); + + Map params = new HashMap<>() { + { + put("text", "API"); + put("sep", "|"); + put("times", "3"); + } + }; + + for (String paramName : params.keySet()) { + requestBuilder.addBodyPart(new StringPart( + paramName, params.get(paramName) + )); + } + Future whenResponse = requestBuilder.execute(); Response response = whenResponse.get(); InputStream is = response.getResponseBodyAsStream(); @@ -889,8 +937,8 @@ import java.util.stream.Collectors; import java.util.Map; import java.util.HashMap; -import org.asynchttpclient.request.body.multipart.FilePart; import org.asynchttpclient.request.body.multipart.StringPart; +import org.asynchttpclient.request.body.multipart.FilePart; public class Main { public static void main(String[] args) { @@ -901,7 +949,6 @@ public class Main { .addQueryParam("size", "2") .addQueryParam("len", "3"); requestBuilder - .addHeader("Content-Type", "multipart/form-data; boundary=1556b1e0-1406-1f2f-ae52-0d40a793d870") .addHeader("User-Agent", "Test Agent") .addHeader("Keep-Alive", "true"); @@ -949,8 +996,7 @@ public class Main { '''; expect( codeGen.getCode( - CodegenLanguage.javaAsyncHttpClient, requestModelPost9, "https", - boundary: "1556b1e0-1406-1f2f-ae52-0d40a793d870"), + CodegenLanguage.javaAsyncHttpClient, requestModelPost9, "https"), expectedCode); }); }); @@ -969,7 +1015,11 @@ public class Main { public static void main(String[] args) { try (AsyncHttpClient asyncHttpClient = Dsl.asyncHttpClient()) { String url = "https://reqres.in/api/users/2"; - String bodyContent = "{\n\"name\": \"morpheus\",\n\"job\": \"zion resident\"\n}"; + String bodyContent = """ +{ +"name": "morpheus", +"job": "zion resident" +}"""; BoundRequestBuilder requestBuilder = asyncHttpClient.prepare("PUT", url); requestBuilder .addHeader("Content-Type", "application/json"); @@ -1008,7 +1058,11 @@ public class Main { public static void main(String[] args) { try (AsyncHttpClient asyncHttpClient = Dsl.asyncHttpClient()) { String url = "https://reqres.in/api/users/2"; - String bodyContent = "{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}"; + String bodyContent = """ +{ +"name": "marfeus", +"job": "accountant" +}"""; BoundRequestBuilder requestBuilder = asyncHttpClient.prepare("PATCH", url); requestBuilder .addHeader("Content-Type", "application/json"); @@ -1080,7 +1134,11 @@ public class Main { public static void main(String[] args) { try (AsyncHttpClient asyncHttpClient = Dsl.asyncHttpClient()) { String url = "https://reqres.in/api/users/2"; - String bodyContent = "{\n\"name\": \"marfeus\",\n\"job\": \"accountant\"\n}"; + String bodyContent = """ +{ +"name": "marfeus", +"job": "accountant" +}"""; BoundRequestBuilder requestBuilder = asyncHttpClient.prepare("DELETE", url); requestBuilder .addHeader("Content-Type", "application/json");