Passing json data to a WebApi with special characters results to null - json

I have a json string that is being passed to a webapi, now the problem is, when I try adding special characters, the recieving object becomes null.
Here's I do it.
string json = JsonConvert.SerializeObject(ojectParams);
WebClient client = new WebClient();
client.Headers.Add("content-type", "application/json; charset=utf-8");
client.Headers.Add("AppKey", WebUser.AppKey);
client.Headers.Add("AppSecret", WebUser.AppSecret);
client.Headers.Add("AccountId", WebUser.AccountId.ToString());
if (!string.IsNullOrEmpty(WebUser.StoreId))
{
client.Headers.Add("StoreId", WebUser.StoreId);
}
var returnedStringObject = client.UploadString(string.Format("{0}/{1}", ConfigurationManager.AppSettings["Api"], endpoint), method, json);
Here's the json string:
"{\"Firstname\":\"kyv®\",\"Lastname\":\"sab®\"}"
I have added this one on the header hoping that it will fix the issue. But no luck with that.
charset=utf-8
On the recieving endpoint, the obj becomes null. But when I removed the special characters, the value is being passed.
[HttpPost]
public responseObj Endpoint(requestObj request)
Any ideas? Thanks!

You need to set the Encoding of the WebClient
client.Encoding = Encoding.UTF8;

Please see the code below.
Note: I did not use JsonConvert.SerializeObject and used HttpClient instead of WebClient
public static HttpRequestMessage CreateRequest(string requestUrl, HttpMethod method, String obj)
{
var request = new HttpRequestMessage
{
RequestUri = new Uri(requestUrl),
Method = method,
Content = new StringContent(obj, Encoding.UTF8, "application/json")
};
return request;
}
public static void DoAPI()
{
var client = new HttpClient();
var obj = "{\"Firstname\":\"kyv®\",\"Lastname\":\"sab®\"}";
var httpRequest = CreateRequest("mywebapiURL", HttpMethod.Post, obj);
var response = client.SendAsync(httpRequest).Result;
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
}

Related

Indexing in Elasticsearch

I am having problems indexing in elasticsearch. I have a function which creates an index and another one that creates a type mapping for a json I will be indexing. Both of these work fine but when I try calling the function to index something, it gives me a WebException saying that the remote server returned an error: (503) Server Unavailable. Any help will be greatly appreciated! Thanks!
This is my code:
public static void Main(string[] args)
{
string endpoint = "http://localhost:9200";
string index = "logs";
string type = "activity-log";
createIndex(endpoint, index);
createMapping(endpoint, index, type);
indexEvent(endpoint, index, type);
}
public static void createIndex(string endpoint, string index)
{
//Build request url
WebRequest request = WebRequest.Create(string.Format("{0}/{1}/", endpoint, index));
request.ContentType = "application/json"; //set content type of json
request.Method = "PUT"; //use POST method when creating an index
string json = "{\"settings\":{\"number_of_shards\":3,\"number_of_replicas\":2}}";
byte[] byteData = Encoding.GetEncoding("UTF-8").GetBytes(json);
string result = System.Convert.ToBase64String(byteData);
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteData, 0, byteData.Length);
dataStream.Close();
//create a web response
WebResponse response = request.GetResponse();
StreamReader sr = new System.IO.StreamReader(response.GetResponseStream());
Console.WriteLine(sr.ReadToEnd().Trim());
Console.ReadKey();
response.Close();
}
public static void createMapping(string endpoint, string index, string type)
{
//Build request url
WebRequest request = WebRequest.Create(string.Format("{0}/{1}/{2}/_mapping", endpoint, index, type));
request.ContentType = "application/json"; //set content type of json
request.Method = "PUT"; //use POST method when creating an index
string json = "{\"activitylogevent\":{\"properties\":{\"id\":{\"type\":\"string\",\"index\":\"not_analyzed\"},\"parentId\":{\"type\":\"string\",\"index\":\"not_analyzed\"},\"event\":{\"type\":\"string\",\"index\":\"not_analyzed\"}}}}";
byte[] byteData = Encoding.GetEncoding("UTF-8").GetBytes(json);
string result = System.Convert.ToBase64String(byteData);
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteData, 0, byteData.Length);
dataStream.Close();
//create a web response
WebResponse response = request.GetResponse();
StreamReader sr = new System.IO.StreamReader(response.GetResponseStream());
Console.WriteLine(sr.ReadToEnd().Trim());
Console.ReadKey();
response.Close();
}
public static void indexEvent(string endpoint, string index, string type)
{
//build the request URL
WebRequest request = WebRequest.Create(string.Format("{0}/{1}/{2}/", endpoint, index, type);
request.ContentType = "application/json"; //set content type of json
request.Method = "POST"; //use POST method when indexing a record without specifying id, and PUT when you specify an id
string jsonEvent = "{\"id\":\"123546789\",\"parentId\":\"abc123\",\"event\":\"CloseAccount\"}";
byte[] byteData = Encoding.GetEncoding("UTF-8").GetBytes(json);
string result = System.Convert.ToBase64String(byteData);
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteData, 0, byteData.Length);
dataStream.Close();
//create a web response
WebResponse response = request.GetResponse();
Console.WriteLine("after get response");
Console.ReadLine();
StreamReader sr = new System.IO.StreamReader(response.GetResponseStream());
Console.WriteLine(sr.ReadToEnd().Trim());
Console.ReadKey();
response.Close();
}
I was doing something wrong in my createIndex function but here is my working function incase anyone finds it helpful:
public static void createIndex(string endpoint, string index)
{
//Build request url
WebRequest request = WebRequest.Create(string.Format("{0}/{1}/", endpoint, index));
request.ContentType = "application/json"; //set content type of json
request.Method = "PUT"; //use PUT method when creating an index
string json = "{\"settings\":{\"activity-log-events\":{\"number_of_shards\":3,\"number_of_replicas\":2}}}";
byte[] byteData = Encoding.GetEncoding("UTF-8").GetBytes(json);
string result = System.Convert.ToBase64String(byteData);
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteData, 0, byteData.Length);
dataStream.Close();
//create a web response
WebResponse response = request.GetResponse();
StreamReader sr = new System.IO.StreamReader(response.GetResponseStream());
Console.WriteLine(sr.ReadToEnd().Trim());
Console.ReadKey();
response.Close();
}
You have at least one error in your indexEvent() function. You are setting the string jsonEvent but then using an undefined string json when setting up byteData:
string jsonEvent = "{\"id\":\"123546789\",\"parentId\":\"abc123\",\"event\":\"CloseAccount\"}";
byte[] byteData = Encoding.GetEncoding("UTF-8").GetBytes(json);
You'll note that you are doing this correctly in the other two functions, using the string json in both places. From createIndex:
string json = "{\"settings\":{\"number_of_shards\":3,\"number_of_replicas\":2}}";
byte[] byteData = Encoding.GetEncoding("UTF-8").GetBytes(json);
and from createMapping:
string json = "{\"activitylogevent\":{\"properties\":{\"id\":{\"type\":\"string\",\"index\":\"not_analyzed\"},\"parentId\":{\"type\":\"string\",\"index\":\"not_analyzed\"},\"event\":{\"type\":\"string\",\"index\":\"not_analyzed\"}}}}";
byte[] byteData = Encoding.GetEncoding("UTF-8").GetBytes(json);
There may be other things wrong in the code but that's definitely not going to work.
I made a some changes to my createIndex function and it worked. I posted the changes above.

Returning async task from Web API Controller via ajax request as JSON

In my MVC Controller, I had the following:
public async Task<ActionResult> Get()
{
WebClient client = new WebClient();
var result = new ContentResult
{
Content = await client.DownloadStringTaskAsync(url),
ContentType = "application/json"
};
return result;
}
But now that I am using an MVC Web API, how do I change this to return a string and not a ActionResult via an Ajax request?
I tried the following and it works, but I get a string instead of a json object.
public async Task<HttpResponseMessage> Get()
{
WebClient client = new WebClient();
String result = await client.DownloadStringTaskAsync(url);
var resp = new HttpResponseMessage(HttpStatusCode.OK);
resp.Content = new ObjectContent<object>(result, new JsonMediaTypeFormatter());
resp.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
return resp;
}
Any ideas?
Check the below solution to return the string content in response
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(// Your Object
System.Text.Encoding.UTF8, "application/json") };

Read JSON with Jersey 2.0 (JAX-RS 2.0)

I was using Jersey 1.16 to consume a JSON, but now I'm with difficulties to consume a JSON using Jersey 2.0 (that implements JAX-RS 2.0).
I have a JSON response like this:
{
"id": 105430,
"version": 0,
"cpf": "55443946447",
"email": "maria#teste.br",
"name": "Maria",
}
and the method that consumes it:
public static JSONObject get() {
String url = "http://127.0.0.1:8080/core/api/person";
URI uri = URI.create(url);
final Client client = ClientBuilder.newClient();
WebTarget webTarget = client.target(uri);
Response response = webTarget.request(MediaType.APPLICATION_JSON).get();
if (response.getStatus() == 200) {
return response.readEntity(JSONObject.class);
}
}
I also tried:
return webTarget.request(MediaType.APPLICATION_JSON).get(JSONObject.class);
But the jSONObject return is null. I don't understand my error because the response is OK!
This is how to use the Response type correctly:
private void getRequest() {
Client client = ClientBuilder.newClient();
String url = "http://localhost:8080/api/masterdataattributes";
WebTarget target = client.target(url);
Response res = target
.request(MediaType.APPLICATION_JSON)
.get();
int status = res.getStatus();
String json = res.readEntity(String.class);
System.out.println(String.format("Status: %d, JSON Payload: %s", status, json));
}
If you're just interested in the payload, you could also just issue a get(String.class). But usually you will also want to check the response status, so working with the Response is usually the way to go.
If you want a typed (generic) JSON response, you could also have readEntity return a Map, or a list of Map if the response is an array of objects as in this example:
List<Map<String, Object>> json = res.readEntity(new GenericType<List<Map<String, Object>>>() {});
String id = (String) json.get(0).get("id");
System.out.println(id);
I have found the solution. Maybe it is not the best of, but it works.
public static JsonObject get() {
String url = "http://127.0.0.1:8080/core/api/person";
URI uri = URI.create(url);
final Client client = ClientBuilder.newClient();
WebTarget webTarget = client.target(uri);
Response response = webTarget.request(MediaType.APPLICATION_JSON).get();
//Se Response.Status.OK;
if (response.getStatus() == 200) {
StringReader stringReader = new StringReader(webTarget.request(MediaType.APPLICATION_JSON).get(String.class));
try (JsonReader jsonReader = Json.createReader(stringReader)) {
return jsonReader.readObject();
}
}
return null;
}
I switched the class JSONObject (package import org.codehaus.jettison) by JsonObject (package javax.json) and I used the methods to manipulate the content as String.
S.
mmey answer is the correct and optimal one, instead of invoking the service twice it does it one time.

how to send a json string in a POST request to web server in Java? [duplicate]

I would like to make a simple HTTP POST using JSON in Java.
Let's say the URL is www.site.com
and it takes in the value {"name":"myname","age":"20"} labeled as 'details' for example.
How would I go about creating the syntax for the POST?
I also can't seem to find a POST method in the JSON Javadocs.
Here is what you need to do:
Get the Apache HttpClient, this would enable you to make the required request
Create an HttpPost request with it and add the header application/x-www-form-urlencoded
Create a StringEntity that you will pass JSON to it
Execute the call
The code roughly looks like (you will still need to debug it and make it work):
// #Deprecated HttpClient httpClient = new DefaultHttpClient();
HttpClient httpClient = HttpClientBuilder.create().build();
try {
HttpPost request = new HttpPost("http://yoururl");
StringEntity params = new StringEntity("details={\"name\":\"xyz\",\"age\":\"20\"} ");
request.addHeader("content-type", "application/x-www-form-urlencoded");
request.setEntity(params);
HttpResponse response = httpClient.execute(request);
} catch (Exception ex) {
} finally {
// #Deprecated httpClient.getConnectionManager().shutdown();
}
You can make use of Gson library to convert your java classes to JSON objects.
Create a pojo class for variables you want to send
as per above Example
{"name":"myname","age":"20"}
becomes
class pojo1
{
String name;
String age;
//generate setter and getters
}
once you set the variables in pojo1 class you can send that using the following code
String postUrl = "www.site.com";// put in your url
Gson gson = new Gson();
HttpClient httpClient = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(postUrl);
StringEntity postingString = new StringEntity(gson.toJson(pojo1));//gson.tojson() converts your pojo to json
post.setEntity(postingString);
post.setHeader("Content-type", "application/json");
HttpResponse response = httpClient.execute(post);
and these are the imports
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
and for GSON
import com.google.gson.Gson;
#momo's answer for Apache HttpClient, version 4.3.1 or later. I'm using JSON-Java to build my JSON object:
JSONObject json = new JSONObject();
json.put("someKey", "someValue");
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
try {
HttpPost request = new HttpPost("http://yoururl");
StringEntity params = new StringEntity(json.toString());
request.addHeader("content-type", "application/json");
request.setEntity(params);
httpClient.execute(request);
// handle response here...
} catch (Exception ex) {
// handle exception here
} finally {
httpClient.close();
}
It's probably easiest to use HttpURLConnection.
http://www.xyzws.com/Javafaq/how-to-use-httpurlconnection-post-data-to-web-server/139
You'll use JSONObject or whatever to construct your JSON, but not to handle the network; you need to serialize it and then pass it to an HttpURLConnection to POST.
protected void sendJson(final String play, final String prop) {
Thread t = new Thread() {
public void run() {
Looper.prepare(); //For Preparing Message Pool for the childThread
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 1000); //Timeout Limit
HttpResponse response;
JSONObject json = new JSONObject();
try {
HttpPost post = new HttpPost("http://192.168.0.44:80");
json.put("play", play);
json.put("Properties", prop);
StringEntity se = new StringEntity(json.toString());
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post.setEntity(se);
response = client.execute(post);
/*Checking response */
if (response != null) {
InputStream in = response.getEntity().getContent(); //Get the data in the entity
}
} catch (Exception e) {
e.printStackTrace();
showMessage("Error", "Cannot Estabilish Connection");
}
Looper.loop(); //Loop in the message queue
}
};
t.start();
}
Try this code:
HttpClient httpClient = new DefaultHttpClient();
try {
HttpPost request = new HttpPost("http://yoururl");
StringEntity params =new StringEntity("details={\"name\":\"myname\",\"age\":\"20\"} ");
request.addHeader("content-type", "application/json");
request.addHeader("Accept","application/json");
request.setEntity(params);
HttpResponse response = httpClient.execute(request);
// handle response here...
}catch (Exception ex) {
// handle exception here
} finally {
httpClient.getConnectionManager().shutdown();
}
I found this question looking for solution about how to send post request from java client to Google Endpoints. Above answers, very likely correct, but not work in case of Google Endpoints.
Solution for Google Endpoints.
Request body must contains only JSON string, not name=value pair.
Content type header must be set to "application/json".
post("http://localhost:8888/_ah/api/langapi/v1/createLanguage",
"{\"language\":\"russian\", \"description\":\"dsfsdfsdfsdfsd\"}");
public static void post(String url, String json ) throws Exception{
String charset = "UTF-8";
URLConnection connection = new URL(url).openConnection();
connection.setDoOutput(true); // Triggers POST.
connection.setRequestProperty("Accept-Charset", charset);
connection.setRequestProperty("Content-Type", "application/json;charset=" + charset);
try (OutputStream output = connection.getOutputStream()) {
output.write(json.getBytes(charset));
}
InputStream response = connection.getInputStream();
}
It sure can be done using HttpClient as well.
You can use the following code with Apache HTTP:
String payload = "{\"name\": \"myname\", \"age\": \"20\"}";
post.setEntity(new StringEntity(payload, ContentType.APPLICATION_JSON));
response = client.execute(request);
Additionally you can create a json object and put in fields into the object like this
HttpPost post = new HttpPost(URL);
JSONObject payload = new JSONObject();
payload.put("name", "myName");
payload.put("age", "20");
post.setEntity(new StringEntity(payload.toString(), ContentType.APPLICATION_JSON));
For Java 11 you can use the new HTTP client:
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://localhost/api"))
.header("Content-Type", "application/json")
.POST(ofInputStream(() -> getClass().getResourceAsStream(
"/some-data.json")))
.build();
client.sendAsync(request, BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
You can use publishers from InputStream, String, File. Converting JSON to a String or IS can be done with Jackson.
Java 11 standardization of HTTP client API that implements HTTP/2 and Web Socket, and can be found at java.net.HTTP.*:
String payload = "{\"name\": \"myname\", \"age\": \"20\"}";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder(URI.create("www.site.com"))
.header("content-type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
Java 8 with apache httpClient 4
CloseableHttpClient client = HttpClientBuilder.create().build();
HttpPost httpPost = new HttpPost("www.site.com");
String json = "details={\"name\":\"myname\",\"age\":\"20\"} ";
try {
StringEntity entity = new StringEntity(json);
httpPost.setEntity(entity);
// set your POST request headers to accept json contents
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
try {
// your closeablehttp response
CloseableHttpResponse response = client.execute(httpPost);
// print your status code from the response
System.out.println(response.getStatusLine().getStatusCode());
// take the response body as a json formatted string
String responseJSON = EntityUtils.toString(response.getEntity());
// convert/parse the json formatted string to a json object
JSONObject jobj = new JSONObject(responseJSON);
//print your response body that formatted into json
System.out.println(jobj);
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
I recomend http-request built on apache http api.
HttpRequest<String> httpRequest = HttpRequestBuilder.createPost(yourUri, String.class)
.responseDeserializer(ResponseDeserializer.ignorableDeserializer()).build();
public void send(){
ResponseHandler<String> responseHandler = httpRequest.execute("details", yourJsonData);
int statusCode = responseHandler.getStatusCode();
String responseContent = responseHandler.orElse(null); // returns Content from response. If content isn't present returns null.
}
If you want send JSON as request body you can:
ResponseHandler<String> responseHandler = httpRequest.executeWithBody(yourJsonData);
I higly recomend read documentation before use.

Restlet implementing post with json receive and response

First, what i wanted to know is what i am doing is the right way to do it.
I have a scenario where i have will receive a json request and i have to update the database with that, once the db is updated i have to respond back with the json acknowledgment.
What i have done so far is create the class extending application as follows:
#Override
public Restlet createRoot() {
// Create a router Restlet that routes each call to a
// new instance of ScanRequestResource.
Router router = new Router(getContext());
// Defines only one route
router.attach("/request", RequestResource.class);
return router;
}
My resource class is extending the ServerResource and i have the following method in my resource class
#Post("json")
public Representation post() throws ResourceException {
try {
Representation entity = getRequestEntity();
JsonRepresentation represent = new JsonRepresentation(entity);
JSONObject jsonobject = represent.toJsonObject();
JSONObject json = jsonobject.getJSONObject("request");
getResponse().setStatus(Status.SUCCESS_ACCEPTED);
StringBuffer sb = new StringBuffer();
ScanRequestAck ack = new ScanRequestAck();
ack.statusURL = "http://localhost:8080/status/2713";
Representation rep = new JsonRepresentation(ack.asJSON());
return rep;
} catch (Exception e) {
getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
}
My first concern is the object i receive in the entity is inputrepresentation so when i fetch the jsonobject from the jsonrepresentation created i always get empty/null object.
I have tried passing the json request with the following code as well as the client attached
function submitjson(){
alert("Alert 1");
$.ajax({
type: "POST",
url: "http://localhost:8080/thoughtclicksWeb/request",
contentType: "application/json; charset=utf-8",
data: "{request{id:1, request-url:http://thoughtclicks.com/status}}",
dataType: "json",
success: function(msg){
//alert("testing alert");
alert(msg);
}
});
};
Client used to call
ClientResource requestResource = new ClientResource("http://localhost:8080/thoughtclicksWeb/request");
Representation rep = new JsonRepresentation(new JSONObject(jsonstring));
rep.setMediaType(MediaType.APPLICATION_JSON);
Representation reply = requestResource.post(rep);
Any help or clues on this is hight appreciated ?
Thanks,
Rahul
Using just 1 JAR jse-x.y.z/lib/org.restlet.jar, you could construct JSON by hand at the client side for simple requests:
ClientResource res = new ClientResource("http://localhost:9191/something/other");
StringRepresentation s = new StringRepresentation("" +
"{\n" +
"\t\"name\" : \"bank1\"\n" +
"}");
res.post(s).write(System.out);
At the server side, using just 2 JARs - gson-x.y.z.jar and jse-x.y.z/lib/org.restlet.jar:
public class BankResource extends ServerResource {
#Get("json")
public String listBanks() {
JsonArray banksArray = new JsonArray();
for (String s : names) {
banksArray.add(new JsonPrimitive(s));
}
JsonObject j = new JsonObject();
j.add("banks", banksArray);
return j.toString();
}
#Post
public Representation createBank(Representation r) throws IOException {
String s = r.getText();
JsonObject j = new JsonParser().parse(s).getAsJsonObject();
JsonElement name = j.get("name");
.. (more) .. ..
//Send list on creation.
return new StringRepresentation(listBanks(), MediaType.TEXT_PLAIN);
}
}
When I use the following JSON as the request, it works:
{"request": {"id": "1", "request-url": "http://thoughtclicks.com/status"}}
Notice the double quotes and additional colon that aren't in your sample.