How to POST array of strings with Java 11 HttpClient? - java

Trying to call an interface which accepts two POST parameters:
param1: string
param2: Array[string]
My attempt to post Array<String> as just a String is obviously naive, but can't find a better way. What would be the right way to post a parameter with the array of strings using Java 11 native HttpClient?
public static HttpResponse<String> postRequest() throws IOException, InterruptedException {
HttpClient httpClient = HttpClientSingleton.getInstance();
Map<Object, Object> data = new HashMap<>();
data.put("param1", "val1");
data.put("param2", "[val21, val22, val23]");
HttpRequest request = HttpRequest.newBuilder()
.POST(ofFormData(data))
.uri(URI.create("http://localhost:19990/test"))
.build();
return httpClient.send(request, HttpResponse.BodyHandlers.ofString());
}
public static HttpRequest.BodyPublisher ofFormData(Map<Object, Object> data) {
var builder = new StringBuilder();
for (Map.Entry<Object, Object> entry : data.entrySet()) {
if (builder.length() > 0) {
builder.append("&");
}
builder.append(URLEncoder.encode(entry.getKey().toString(), StandardCharsets.UTF_8));
builder.append("=");
builder.append(URLEncoder.encode(entry.getValue().toString(), StandardCharsets.UTF_8));
}
return HttpRequest.BodyPublishers.ofString(builder.toString());
}

Easier way could be, encode all the values as json, and parse (decode ) once you receive data in the server side. Cheers!

Related

How to print http request with all the params?

This is a portion of code(somebody else wrote) that I am trying to understand. I want to print the request sent, but couldn't figure out a way to print url with all the params here.
//Obtain Response object returned by POST call to API with parameters passed in as HashMap
public static Response getPOSTResponse(String query, String endpoint, HashMap<String, String> params) {
//Initialize variables - for url and for data to be sent in POST request (need new hashmap for data due to type)
String base_url = getUrl(endpoint);
StringBuffer url = new StringBuffer();
HashMap<String, List<Integer>> postData = new HashMap<String, List<Integer>>();
url.append(base_url + "?");
params.forEach((k, v) -> {
String key = k;
String value = (params.get(k));
if (key.contains("list")) {
postData.put(key, Collections.singletonList(Integer.parseInt(value)));
} else { //should handle case for any [other] POST urls using parameters
url.append(key);
url.append("=");
url.append(value);
url.append("&");
}
});
final RequestSpecification sender = given().headers("Content-Type", ContentType.JSON,
"Accept", ContentType.JSON);
return sender.when().body(postData).post(url.toString()).then().contentType(ContentType.JSON).extract().response();
}

How to pass array of variables to REST URL in android?

I have to make registration using REST URL. REST services are written in Java now i have to pass the set of parameters in that secGameIds parameter is like this [100,102]. Example registration using Insomnia:::
{
"firstName":"parent111",
"lastName":"sadfsdf",
"email":"abc#bbc.com",
"date":"2000-06-09",
"phoneNum":"8765654454",
"gender":"male",
**"secGameIds":[0,0],**
"roleId":102
}
How should i provide secGameIds parameter value is it a ArrayList or Array?
for remaining values i have created JSONObject class object and adding values to that object and 'm appending that object to url
{
JSONObject json = new JSONObject();
json.put("fistName","aaa");
..
..
HttpPost post = new HttpPost(uri);
post.setHeader("Content-type", "application/json");
post.setEntity(new StringEntity(json.toString(), "UTF-8"));
DefaultHttpClient client = new DefaultHttpClient();
httpresponse = client.execute(post);
}
where as for secGameId i have tried like below,
{
int[] secGameId = {100,102};
}
-- gives me an error in back-end like "nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of int[] out of VALUE_NUMBER_INT token"
I even tried by using
{
ArrayList<Integer> secGameId = new ArrayList<String>();
secGameId.add(100);
secGameId.add(102);
}
and passing to value...
{
json.put("secGameIds":secGameId)
}
again at server side i kicked with the same error.
Can anyone help me?
public static String httpPost(HashMap<String, String> map, String url,String token) {
Log.e("call ", "running");
HttpRequest request;
if(token!=null){
request = HttpRequest.post(url).accept("application/json")
.header("Authorization", "Token " + AppInfo.token).form(map);
}
else
request = HttpRequest.post(url).accept("application/json").form(map);
int responseCode = request.code();
String text = request.body();
Log.e("response", " "+responseCode+ " "+ text);
if(responseCode==400){
return "invalid_tocken";
}
else if(responseCode<200 || responseCode>=300) {
return "error";
}
return text;
}
Hope you can convert the JSONArray to HashMap. If you instead need to post it as a JSONArray itself, then OkHttp library will help you.

sending empty content with HttpClient

I am trying to connect to an API of another company.
from the doc there is ::
even with your GET request, you'll need to include the Java equivalent of
curl_setopt($ch, CURLOPT_POSTFIELDS, $content), and you can set $data equal
to an empty array.
$content in their example is an empty JSON array.
I am using org.apache.commons.httpclient.
i am not sure how to add post fields to a org.apache.commons.httpclient.methods.GetMethod or if it is even possible.
i tried faking with a Content-Length of 2 but the GET times out (probably looking for content that i am not providing. if i remove the content-length i get an invalid response from the api server)
HttpClient client = new HttpClient();
GetMethod method = new GetMethod("https://api.xxx.com/account/");
method.addRequestHeader("Content-Type", "application/json");
method.addRequestHeader("X-Public-Key", APKey);
method.addRequestHeader("X-Signed-Request-Hash", "xxx");
method.addRequestHeader("Content-Length", "2");
int statusCode = client.executeMethod(method);
I don't think GetMethod includes any means of attaching a request body, because a GET request isn't supposed to have a body. (But having a body isn't actually prohibited, either - see: HTTP GET with request body .)
You're trying to use documentation written with a different language and a different client library in mind, so you'll have to use trial and error a bit. It sounds like they expect a request with no body, and you already have that. There's no good reason why they'd require a "Content-Length" with GET, but if that's the case, try setting it to 0.
This is how i resolved this issue
Created this class
public class HttpGetWithEntity extends HttpEntityEnclosingRequestBase {
public HttpGetWithEntity() {
super();
}
public HttpGetWithEntity(URI uri) {
super();
setURI(uri);
}
public HttpGetWithEntity(String uri) {
super();
setURI(URI.create(uri));
}
#Override
public String getMethod() {
return HttpGet.METHOD_NAME;
}
}
Then the calling function looks like
public JSONObject get(JSONObject payload, String URL) throws Exception {
JSONArray jsonArray = new JSONArray();
CloseableHttpClient client = HttpClientBuilder.create().build();
HttpGetWithEntity myGet = new HttpGetWithEntity(WeeblyAPIHost+URL);
myGet.setEntity( new StringEntity("[]") );
myGet.setHeader("Content-Type", "application/json");
myGet.setHeader("X-Public-Key", APIKey);
HttpResponse response = client.execute(myGet);
JSONParser parser = new JSONParser();
Object obj = parser.parse( EntityUtils.toString(response.getEntity(), "UTF-8") ) ;
JSONObject jsonResponse = (JSONObject) obj;
return jsonResponse;
}

How to add query parameters to a HTTP GET request by OkHttp?

I am using the latest okhttp version: okhttp-2.3.0.jar
How to add query parameters to GET request in okhttp in java ?
I found a related question about android, but no answer here!
For okhttp3:
private static final OkHttpClient client = new OkHttpClient().newBuilder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
public static void get(String url, Map<String,String>params, Callback responseCallback) {
HttpUrl.Builder httpBuilder = HttpUrl.parse(url).newBuilder();
if (params != null) {
for(Map.Entry<String, String> param : params.entrySet()) {
httpBuilder.addQueryParameter(param.getKey(),param.getValue());
}
}
Request request = new Request.Builder().url(httpBuilder.build()).build();
client.newCall(request).enqueue(responseCallback);
}
Here's my interceptor
private static class AuthInterceptor implements Interceptor {
private String mApiKey;
public AuthInterceptor(String apiKey) {
mApiKey = apiKey;
}
#Override
public Response intercept(Chain chain) throws IOException {
HttpUrl url = chain.request().url()
.newBuilder()
.addQueryParameter("api_key", mApiKey)
.build();
Request request = chain.request().newBuilder().url(url).build();
return chain.proceed(request);
}
}
I finally did my code, hope the following code can help you guys. I build the URL first using
HttpUrl httpUrl = new HttpUrl.Builder()
Then pass the URL to Request requesthttp hope it helps .
public class NetActions {
OkHttpClient client = new OkHttpClient();
public String getStudentById(String code) throws IOException, NullPointerException {
HttpUrl httpUrl = new HttpUrl.Builder()
.scheme("https")
.host("subdomain.apiweb.com")
.addPathSegment("api")
.addPathSegment("v1")
.addPathSegment("students")
.addPathSegment(code) // <- 8873 code passthru parameter on method
.addQueryParameter("auth_token", "71x23768234hgjwqguygqew")
// Each addPathSegment separated add a / symbol to the final url
// finally my Full URL is:
// https://subdomain.apiweb.com/api/v1/students/8873?auth_token=71x23768234hgjwqguygqew
.build();
System.out.println(httpUrl.toString());
Request requesthttp = new Request.Builder()
.addHeader("accept", "application/json")
.url(httpUrl) // <- Finally put httpUrl in here
.build();
Response response = client.newCall(requesthttp).execute();
return response.body().string();
}
}
As mentioned in the other answer, okhttp v2.4 offers new functionality that does make this possible.
See http://square.github.io/okhttp/2.x/okhttp/com/squareup/okhttp/HttpUrl.Builder.html#addQueryParameter-java.lang.String-java.lang.String-
This is not possible with the current version of okhttp, there is no method provided that will handle this for you.
The next best thing is building an url string or an URL object (found in java.net.URL) with the query included yourself, and pass that to the request builder of okhttp.
As you can see, the Request.Builder can take either a String or an URL.
Examples on how to build an url can be found at What is the idiomatic way to compose a URL or URI in Java?
As of right now (okhttp 2.4), HttpUrl.Builder now has methods addQueryParameter and addEncodedQueryParameter.
You can create a newBuilder from existing HttoUrl and add query parameters there. Sample interceptor code:
Request req = it.request()
return chain.proceed(
req.newBuilder()
.url(
req.url().newBuilder()
.addQueryParameter("v", "5.60")
.build());
.build());
Use HttpUrl class's functions:
//adds the pre-encoded query parameter to this URL's query string
addEncodedQueryParameter(String encodedName, String encodedValue)
//encodes the query parameter using UTF-8 and adds it to this URL's query string
addQueryParameter(String name, String value)
more detailed: https://stackoverflow.com/a/32146909/5247331

aquery post with no hashmap like in Qt

I am porting an app from BB10 to android. For an http request I am using AQuery.
In Qt on BB10, I can simply post data:
QByteArray data = "test";
QNetworkRequest request;
request.setUrl(new QUrl("example.com"));
QNetworkAccessManager manager = new QNetworkAccessManager(this);
manager->post(request,data);
but in AQuery I can only find a POST method with key/value pairs (from the doc):
String url = "http://search.twitter.com/search.json";
Map<String, Object> params = new HashMap<String, Object>();
params.put("q", "androidquery");
aq.ajax(url, params, JSONObject.class, new AjaxCallback<JSONObject>() {
#Override
public void callback(String url, JSONObject json, AjaxStatus status) {
showResult(json);
}
});
Is there a way to POST just data in AQuery?
I have found out how to do this.
In the AQuery source, in the httpEntity method of the AbstractAjaxCallback class:
HttpEntity entity = null;
Object value = params.get(AQuery.POST_ENTITY);
if(value instanceof HttpEntity){
entity = (HttpEntity) value;
} else {
//urlencoded POST data
}
So all I needed to do was this:
HttpEntity entity = new StringEntity(data);
cb.param(AQuery.POST_ENTITY,entity);
where cb is my AjaxCallback object.

Categories

Resources