Sending JSON to Rails - java

My issue is that the escape character is invalidating my JSON. I am sending my JSON to a Rails sever but when it arrives it gains some escape characters.
Is there something I can do to Solve this on my restfull class or is it something to be corrected on the server side?
Here is the JSON I'm sending,
[session={"password":"********","email":"********#omobile.com.br"}]
And here is the JSON thats appearing on the servers log:
{"session"=>"{\"password\":\"********\",\"email\":\"********#omobile.com.br\"}"}
I've tried these different ways to send my JSON and the result is the same:
JSONObject object = new JSONObject();
object.accumulate("email", username);
object.accumulate("password", password);
String jsonString = object.toString();
Session session = new Session();
session.setEmail(username);
session.setPassword(password);
Gson gson = new Gson();
String jsonString = gson.toJson(session, Session.class);

What happens is a mess, because neither of the strings you posted is actually JSON. The first one actually I don't know what it is, while the second one likely means that on the Ruby side you have this Ruby hash, in which the key "session" refers to a JSON-encoded hash.
We can't tell what's going on the wire because you didn't post the code, so we can't tell if your server expects a form-encoded request body, a multipart one, or directly a JSON-encoded object.
I want you to consider that the only JSON I see is the portion:
{"password": "********","email":"********#omobile.com.br"}
As I said, this can be passed as-is, or as a part in a mulipart envelope, or even url-encoded. The format is really estabilished on the server. For example I made a quick test using Apache HttpClient:
public class GsonSendToSinatra {
private static class Session {
#SuppressWarnings("unused")
String username, password;
}
public static void main(String[] args) throws Exception {
Session session = new Session();
session.username = "foo#example.com";
session.password = "qwerty1234";
Gson gson = new Gson();
String responseText = Request.Post("http://localhost:4567/echo")
.bodyString(gson.toJson(session), ContentType.APPLICATION_JSON)
.execute()
.returnContent()
.asString();
System.out.println(responseText);
}
}
and Sinatra on the server:
require 'sinatra'
require 'json'
post '/echo' do
content_type "text/plain"
layout false
session = JSON.parse request.body.read
session.map {|k,v| "#{k}: #{v}\n"}
end
I hope this example helps you to figure out what are the moving parts in a HTTP dialogue and how you can combine them.

Related

Handling POST Request in Java 11

I'm facing an issue with handling POST request using Java 11 embedded library java.net.
Client side:
I have two methods in my QueryGenerator class:
public String postTeachers(String newTeachersList) {
this.customRequest = HttpRequest.newBuilder()
.uri(URI.create("http://" + serverIPport + "/" + postTeachers))
.POST(HttpRequest.BodyPublishers.ofString(newTeachersList))
.build();
return getResponseResults();
}
It is used to create a post request.
And also I have a getResponseResults() method
private String getResponseResults() {
String result = null;
try {
CompletableFuture<HttpResponse<String>> response = CustomHttpClientSingleton.getInstance().sendAsync(customRequest, HttpResponse.BodyHandlers.ofString());
result = response.thenApply(HttpResponse::body).join();
} catch(RuntimeException e) {
System.out.println("Seems like the server may not be working properly! Restart it");
}
return result;
}
Server side:
I have a method handlePostRequest
private void handlePostRequest(HttpExchange httpExchange) throws IOException {
Headers headers = httpExchange.getResponseHeaders();
httpExchange.sendResponseHeaders(200, 0);
InputStream is = httpExchange.getRequestBody();
System.out.println(is.toString());
is.close();
}
I get the POST Request in my HttpServer, but when I try to display the contents of a request body, I don't get any information. I'm expecting to receive JSON representation of my ArrayList collection, but the only output I get is:
sun.net.httpserver.FixedLengthInputStream
Is there any way to get request body sent by http client inside POST request and use it on the server side by means of Java 11 java.net embedded library.
Thanks to everyone!
You must read Inputstream content, not just apply toString().
See https://www.baeldung.com/convert-input-stream-to-string
It looks like you are not reading input stream properly. Try to read input stream instead of calling toString() on it. Please check How to get an HTTP POST request body as a Java String at the server side?
for more information.

Extract string from http response in java client

I want to extract the string returned from java web service in java client. The string returned from java web service is as follows:
{"Name":"Raj Johri","Email":"mailraj#server.com","status":true}
Which is a Json string format. I have written client code to extract this string as follows:
public static void main(String[] args) throws Exception{
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost post = new HttpPost("http://localhost:8080/JsonWebService/services/JsonWebService/getData");
post.setHeader("Content-Type", "application/xml");
HttpResponse httpres = httpClient.execute(post);
HttpEntity entity = httpres.getEntity();
String json = EntityUtils.toString(entity).toString();
System.out.println("json:" + json);
}
I am getting following print on the console for json as:
json:<ns:getDataResponse xmlns:ns="http://ws.jsonweb.com"><ns:return>{"Name":"Raj Johri","Email":"mailraj#server.com","status":true}</ns:return></ns:getDataResponse>
Please tell me how to extract the string
{"Name":"Raj Johri","Email":"mailraj#server.com","status":true}
which is the actual message. Thanks in advance...
Well, The respons is as type of xml, and your json is in the <ns:return> node , so i suggest you to enter in depth of the xml result and simply get your json from the <ns:return> node.
Note:
I suggest you to try to specifying that you need the response as JSON type:
post.setHeader("Content-type", "application/json");
post.setHeader("Accept", "application/json");
There is a dirty way to do this (beside the xml parsing way)
if you are getting the same XML every time,
you can use split()
String parts[] = json.split("<ns:return>");
parts = parts[1].split("</ns:return>");
String jsonPart = parts[0];
now jsonPart should contain only {"Name":"Raj Johri","Email":"mailraj#server.com","status":true}

GSON not sending in UTF-8

The following method sends a JSON reply. However on the receiving end I keep getting invalid characters, and UTF-8 isn't decoding the data. What am I doing wrong?
Response to client = data output stream
//Get the client request
clientRequest = new BufferedReader(new InputStreamReader(connectedClient.getInputStream())); //connectedclient = socket
//Start response object
responseToClient = new DataOutputStream(connectedClient.getOutputStream());
/**
* Sends a JSON response for an object
* #param objectToEncode
* #throws Exception
*/
private void sendJSONResponse(Object objectToEncode) throws Exception{
//Encode object into JSON
String jsonString = new Gson().toJson(objectToEncode);
// HTTP Header... Status code, last modified
responseToClient.writeBytes(HTTP_OK_STATUS_CODE);
responseToClient.writeBytes(CONTENT_TYPE_JSON);
responseToClient.writeBytes("Last-modified: "+ HelperMethods.now() +" \r\n");
responseToClient.writeBytes("\r\n");
// The HTTP content starts here
responseToClient.writeBytes(jsonString);
}
I have no idea why you would write your own HTTP protocol code. It's a lot like writing your own XML parser: No matter how good a programmer you are, you are bound to get it wrong.
Anyway, as the DataOutputStream documentation states, doing writeBytes on a String will just discard its high eight bits. So what you get is... something, but not UTF8. What you should do is:
String jsonString = new Gson().toJson(objectToEncode);
byte[] utf8JsonString = jsonString.getBytes("UTF8");
responseToClient.write(utf8JsonString, 0, utf8JsonString.Length);
The first solution didn't work for me, I did this:
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
String json = gson.toJson(objectToEncode);
Use the following code to encode
response.setCharacterEncoding("UTF8"); // this line solves the problem
response.setContentType("application/json");

Servlet that sends back JSON: Confusion on reception

I have a Servlet that sends back a JSON Object and I would like to use this servlet in another Java project. I have this method that gets me the results:
public JSONArray getSQL(String aServletURL)
{
JSONArray toReturn = null;
String returnString = "";
try
{
URL myUrl = new URL(aServletURL);
URLConnection conn = myUrl.openConnection();
conn.setDoOutput(true);
BufferedReader in = new BufferedReader( new InputStreamReader( conn.getInputStream() ) );
String s;
while ((s = in.readLine()) != null )
returnString += s;
in.close();
toReturn = new JSONArray(returnString);
}
catch(Exception e)
{
return new JSONArray();
}
return toReturn;
}
This works pretty will, but the problem I am facing is the following:
When I do several simultaneous requests, the results get mixed up and I sometimes get a Response that does not match the request I send.
I suspect the problem to be related to the way I get the response back: The Reader reading a String from the InputStream of the connection.
How can I make sure that I get one reques -> one corresponding reply ?
Is there a better way to retrieve my JSON object from my servlet ?
Cheers,
Tim
When I do several simultaneous requests, the results get mixed up and I sometimes get a Response that does not match the request I send.
Your servlet is not thread safe. I'd bet that you've improperly assigned request scoped data either directly or indirectly as instance or class variables of the servlet. This is a common beginner's mistake.
Carefully read this How do servlets work? Instantiation, sessions, shared variables and multithreading and fix your servlet code accordingly. The problem is not in the URLConnection code shown so far, although it indicates that you're doing exactly the same job in both doGet() and doPost(), which in turn is already a smell as to how the servlet is designed.
Try removing setDoOutput(true), you are using the connection only for input and so you shouldn't use it.
Edit: alternatively try using HttpClient, it's much nicer that using "raw" Java.

Bing Maps REST services returns incorrect characters for French. Is there a way to request them to encode their response or decode it somehow?

In the Android application I have written, there is a portion which allows the user to enter the start and end location of their trip, and a route itinerary is returned. I am using Bing Maps REST services for this. I want the directions returned to be in French.
A sample request: request. This is best seen on a Chrome browser, Safari and Firefox take care of this. You can see that the directions have lots of strange characters where they are not supposed to be. I have tried decoding on the device, by doing:
URLDecoder.decode(obj.optString("text"), HTTP.ISO_8859_1)
which does not work (the response stays the same), which makes sense I think since it has already become the special characters. I cannot use Windows-1252 to decode because Android does not seem to support that.
An example of what I am being sent back: Léger Encombrement. What it should be: Léger Encombrement.
It works perfectly on an iPhone as well, but not on Android. Any suggestions on how I can solve this?
My code in the connection class is:
public static JSONObject getJSONResult(final String url) {
try {
final HttpClient client = new DefaultHttpClient();
final HttpGet get = new HttpGet(url);
final HttpResponse responsePost = client.execute(get);
final HttpEntity resEntity = responsePost.getEntity();
boolean DEBUG = true;
if (DEBUG) {
Log.d("", "[JSON-ENV] url: " + url);
}
final String str = EntityUtils.toString(resEntity);
Log.d("connection", "response str: " + str);
if (resEntity != null) {
final JSONObject obj = new JSONObject(str);
Log.d("connection", "JSON RESPONSE IS " + obj);
return obj;
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Is there something I need to add into my connection class?
UPDATE:
I added the JSON parsing code to format as "ISO_8859_1" as seen at this link: http://p-xr.com/android-tutorial-how-to-parse-read-json-data-into-a-android-listview/ but I still get the same results ...
This is JSON. You don't need to use URLDecoder. The error is before that, probably when you create the String for the JSON Parser. JSON is always in UTF-8 (or 16, rarely)
Can you post the code for reading the server response?
edit
EntityUtils uses ISO_8859_1 as a default Charset if it does not find one in the content. Simply change
final String str = EntityUtils.toString(resEntity);
to
final String str = EntityUtils.toString(resEntity, HTTP.UTF_8);

Categories