I'm using Springs rest template to post some data in JSON to an API. Unfortunately the values of my HashMap contain both doubles and Strings.
I've attempted to use a HashMap with the following datatype: HashMap, however I've found that the resulting JSON looks something like the following instead:
{
"VARIABLE_1":"0.0000",
"VARIABLE_2":"True",
"VARIABLE_3":"String"
}
Unfortunately the API I'm posting to isn't processing these doubles correctly as they are being sent as Strings. Is there someway I can be agnostic about the datatypes still but have HttpEntity format doubles correctly.
Here is an example of the code I'm actually using:
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.CommonsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
...
public void postMethod(HashMap<String,Object> input) {
CommonsClientHttpRequestFactory requestFactory = new CommonsClientHttpRequestFactory();
restTemplate.setRequestFactory(requestFactory);
HttpEntity<HashMap<String,Object>> requestEntity = new HttpEntity<>(input, headers);
ResponseEntity<Result> result = restTemplate.postForEntity(uri, requestEntity, Result.class);
Result result = result.getBody();
}
You can create a custom JSON body by directly accessing the Jackson library that Spring uses:
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
...
public void postMethod(HashMap<String,Object> input) {
ObjectNode jsonBody = JsonNodeFactory.instance.objectNode();
for (Map.Entry<String, Object> entry : input.entrySet())
{
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof Double)
jsonBody.put(key, (Double)value);
else if (value instanceof Boolean)
jsonBody.put(key, (Boolean)value);
else
jsonBody.put(key, value);
}
// ... make headers ...
HttpEntity<String> requestEntity = new HttpEntity<>(jsonBody.toString(), headers);
// ... make the post request ...
}
The only dumb part is that you have to cast your value
before you call put()
because otherwise Java calls the put(String, Object)
method override.