NULL JSON Model passed to webservice when specific number of special characters - java

This is driving me mad - I have an object model in android that is turned into a JSON string using GsonBuilder:
WorkItemModel model = new WorkItemModel();
model.Jobs = jobList;
model.Items = itemList;
model.Images = imageList;
model.Questions = questionList;
String gsonJson = new GsonBuilder().create().toJson(model);
The string is passed to a c# webservice using this method :
private String callWebService(String JSONModel, URL url, int appId) throws Exception {
int connTimeout = 5000;
System.setProperty("http.keepAlive", "false");
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) url.openConnection();
//Populate Header
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
conn.setChunkedStreamingMode(0);
conn.setConnectTimeout(connTimeout);
conn.setReadTimeout(connTimeout);
if (JSONModel != null) {
conn.setRequestProperty("Content-Length", String.valueOf(JSONModel.length()));
conn.setDoInput(true);
OutputStream stream = new BufferedOutputStream(conn.getOutputStream());
stream.write(JSONModel.getBytes());
stream.flush();
stream.close();
} else {
conn.setDoOutput(true);
conn.setChunkedStreamingMode(0);
conn.setRequestProperty("Content-Length", "0");
}
conn.connect();
BufferedReader inputStreamReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder returnStringBuilder = new StringBuilder();
String streamString;
while ((streamString = inputStreamReader.readLine()) != null) {
returnStringBuilder.append(streamString);
}
inputStreamReader.close();
return returnStringBuilder.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
throw e;
} catch (SocketTimeoutException e) {
throw e;
} catch (SSLHandshakeException e) {
throw e;
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw e;
} finally {
conn.disconnect();
}
return null;
}
The webservice should receive this model and then go away and do some back-end DB stuff - and for the most part, we don't have a problem, but we've had a few bug reports which I can replicate but can't seem to fix.
In the "Jobs" list in our model, we have a string property called completeNotes. When completeNotes is filled in with 4 "£" symbols, everything still works, but when there are 5 "£" symbols, the webservice Model it receives is NULL and I can see an exception has been thrown on the webservice :
Exception thrown: 'Newtonsoft.Json.JsonReaderException' in Newtonsoft.Json.dll
Additional information: Invalid character after parsing property name. Expected ':' but got: . Path 'Jobs', line 1, position 1585.
Just as a side note, this also happens with € symbols, except it only allows 2 € symbols.. on the third one it does the same thing - passes a NULL model through - the symbols don't have to be contiguous either
I won't show the whole JSON as its quite lengthy.. but the property I speak of is set like this in it :
"completeNotes":"£££££"
Has anyone got any ideas as to why this is happening - I've tried messing around with the encoding (setting it to UTF-8) but this doesn't seem to make a difference.

Have you tried adding "Charset=UTF-8' to the content type header?
conn.setRequestProperty("Content-Type", "application/json; Charset=UTF-8");

Related

403 Response Code - Inputs correct?

Unsure how many of you are familiar with Bukkit / Mojang API, however, this is what I'm working with today. Though I don't believe this will suit any relevance to the problem as it seems to be a native issue.
I connect to the authentication service following Mojang's authentication wiki:
http://wiki.vg/Authentication#Authenticate
In my code, the 'MinecraftAccount' is just an object representing the payload in the above link, which I serialize with GSON.
I then want to grab the input response sent back, with properties you can also find in the link above. I use another object to hold the json values and deserialize it with Json (AuthResponse).
It seems I am doing everything right, but I get a 403 Error. I'm unsure why because after several attempts of getting this right, it worked, and then spontaneously began spitting out the 403 again. Hopefully you guys can see the issue here.
public String getAuthToken(MinecraftAccount minecraftAccount) {
try {
HttpURLConnection httpURLConnection = Webs.getConnection("https://authserver.mojang.com/authenticate");
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
httpURLConnection.setInstanceFollowRedirects(false);
httpURLConnection.setRequestProperty("Accept-Charset", "UTF-8");
httpURLConnection.setRequestProperty("Content-Type", "application/json");
httpURLConnection.setUseCaches(false);
httpURLConnection.addRequestProperty("User-Agent", "Mozilla/4.0");
IOUtils.write(GsonProvider.standard().toJson(minecraftAccount), httpURLConnection.getOutputStream(), StandardCharsets.UTF_8);
return GsonProvider.standard().fromJson(IOUtils.toString(httpURLConnection.getInputStream(), StandardCharsets.UTF_8), AuthResponse.class).getAccessToken();
} catch (IOException exception) {
exception.printStackTrace();
}
return null;
}
public void uploadSkin(UUID uuid, String url, boolean normal) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(ImageIO.read(new URL(url)), "png", baos);
String authenticityToken = this.getAuthToken(this.minecraftAccount);
try {
System.out.println("Token: " + authenticityToken);
if (authenticityToken == null) {
return;
}
HttpURLConnection httpURLConnection = Webs.getConnection(String.format(UPLOAD_SKIN_URL, UUIDTypeAdapter.fromUUID(uuid)));
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.addRequestProperty("Authorization", "Bearer " + authenticityToken);
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(httpURLConnection.getOutputStream(), StandardCharsets.UTF_8))) {
writer.write("model=");
if (!normal) {
writer.write("slim");
}
writer.write("&url=" + UrlEscapers.urlPathSegmentEscaper().escape(url));
System.out.println("status: " + httpURLConnection.getResponseMessage() + "(" + httpURLConnection.getResponseCode() + ")");
} catch (Exception exception) {
exception.printStackTrace();
}
} catch (Exception exception) {
exception.printStackTrace();
}
} catch (IOException exception) {
exception.printStackTrace();
}
}
The Webs#getConnection is simply this (Using Proxy.NO_PROXY):
public static HttpURLConnection getConnection(String url, Proxy proxy) throws IOException {
HttpURLConnection httpConnection = (HttpURLConnection) new URL(url).openConnection(proxy);
httpConnection.setConnectTimeout(TIMEOUT);
httpConnection.setReadTimeout(2 * TIMEOUT);
httpConnection.setRequestProperty(HttpHeaders.CONTENT_TYPE, "application/json");
httpConnection.setRequestProperty(HttpHeaders.USER_AGENT, "Mozilla/5.0");
return httpConnection;
}
PS: Yes, I have looked at several other 403 threads, however, their solutions (such as setting the user agent as a fix), doesn't work.
Ultimately, there's no error when calling #uploadSkin, it just returns a 403 and doesn't actually upload the file to the site or anything. The method just outputs this:
Output

Call httpconnection with encoding not working

i need to call a service get using http connection, the response contains arabic characters, but when i call it using the code below
try {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
InputStream in = new BufferedInputStream(conn.getInputStream());
response = IOUtils.toString(in, "UTF-8");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
the reponse is
1|U|����� ������|$2|L|���� �������|$3|S|����
I tried another solution not using Commons-io but also not working
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setConnectTimeout(5000);
connection.setRequestMethod("GET");
connection.connect();
int statusCode = connection.getResponseCode();
//Log.e("statusCode", "" + statusCode);
if (statusCode == 200) {
sb = new StringBuilder();
reader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8"));
char[] tmp = new char[1024];
int l;
while((l = reader.read(tmp)) != -1) {
sb.append(tmp, 0, l);
}
//sb = buffer.toString();
}
connection.disconnect();
if (sb != null)
serverResponse = sb.toString();
Do i need to change anything from web service??? but when i call it from browser all characters show clearly with no problem
any suggestion?
Maybe the server is not using UTF-8, your code is trying to use UTF-8 to decode the data but that will only work if the server is using the same encoding.
The browser works because maybe it is using the HTTP header "Content-Encoding" which should indicate the encoding used for the data.
Please decode your string response
String dateStr = URLDecoder.decode(yourStringResponse, "utf-8");

android Error converting result java.io.FileNotFoundException

I have created an API in post method which is working fine in postman i.e it is giving desired response. But while using that API in Android it is giving error:
Error converting result java.io.FileNotFoundException and Error parsing data org.json.JSONException: End of input at character 0 of
I would appreciate anyone guiding me on how to do this.
Here is the code of makeHttpRequest method of jsonparser:
public JSONObject makeHttpRequest2(String url2 , String method,
String name, String password) throws IOException {
// Making HTTP request
try {
// check for request method
if (method == "POST") {
// request method is POST
url = new URL(url2);
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setUseCaches(false);
conn.setConnectTimeout(10000);
conn.setReadTimeout(10000);
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Host", "android.schoolportal.gr");
conn.connect();
JSONObject jsonParam = new JSONObject();
jsonParam.put("name", name);
//jsonParam.put("email", email);
jsonParam.put("password", password);
Log.d("json",String.valueOf(jsonParam));
OutputStreamWriter out=new OutputStreamWriter(
conn.getOutputStream());
out.write(jsonParam.toString());
out.close();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
try {
InputStream is = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
Log.e("JSON", json);
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
Log.d("json3",String.valueOf(json));
// return JSON String
return jObj;
}
First off you are not checking that the request was successful, before calling the conn.getInputStream(); If the request failed that stream is empty and you need to call
new BufferedReader(new InputStreamReader(connection.getErrorStream()));
What line number is giving you issue? If you print out the JSON to insure that the response is valid JSON.
Add this to your code:
conn.setDoInput(true); //After or before of setDoOutput(true) for organization :)
conn.setChunkedStreamingMode(0);
conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
EDIT :
And this if you need to upload a JSON for the server:
conn.setRequestProperty("Content-Length", "" + Integer.toString(JsonObjectstr.getBytes().length)); // Get the json string length

FileNotFoundException on HttpsURLConnection with POST and unmutable doOutput variable

I'm trying to POST some data to an https url, in my android application, in order to get a json format response.
I'm facing two problems:
is = conn.getInputStream();
throws
java.io.FileNotFoundException
I don't get if i do something wrong with HttpsURLConnection.
The second problem arose when i debug the code (used eclipse); I set a breakpoint after
conn.setDoOutput(true);
and, when inspecting conn values, I see that the variable doOutput remain set to false and type GET.
My method for https POST is the following, where POSTData is a class extending ArrayList<NameValuePair>
private static String httpsPOST(String urlString, POSTData postData, List<HttpCookie> cookies) {
String result = null;
HttpsURLConnection conn = null;
OutputStream os = null;
InputStream is = null;
try {
URL url = new URL(urlString);
conn = (HttpsURLConnection) url.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setUseCaches (false);
conn.setDoInput(true);
conn.setDoOutput(true);
if(cookies != null)
conn.setRequestProperty("Cookie",
TextUtils.join(";", cookies));
os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(postData.getPostData());
writer.flush();
writer.close();
is = conn.getInputStream();
BufferedReader r = new BufferedReader(
new InputStreamReader(is));
StringBuilder total = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
total.append(line);
}
result = total.toString();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
}
}
if (conn != null) {
conn.disconnect();
}
}
return result;
}
A little update: apparently eclipse debug lied to me, running and debugging on netbeans shows a POST connection. Error seems to be related to parameters i'm passing to the url.
FileNotFoundException means that the URL you posted to doesn't exist, or couldn't be mapped to a servlet. It is the result of an HTTP 404 status code.
Don't worry about what you see in the debugger if it doesn't agree with how the program behaves. If doOutput really wasn't enabled, you would get an exception obtaining the output stream.

Java, FileNotfound Exception, While reading conn.getInputStream()

Please tell me some one, How to resolve this problem,
Sometime I am getting Filenotfound Exception and Some time this code working fine.
Below is my code,
public String sendSMS(String data, String url1) {
URL url;
String status = "Somthing wrong ";
try {
url = new URL(url1);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
conn.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
conn.setRequestProperty("Accept","*/*");
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
// Get the response
try {
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String s;
while ((s = rd.readLine()) != null) {
status = s;
}
rd.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
wr.close();
} catch (MalformedURLException e) {
status = "MalformedURLException Exception in sendSMS";
e.printStackTrace();
} catch (IOException e) {
status = "IO Exception in sendSMS";
e.printStackTrace();
}
return status;
}
Rewrite like this and let me know how you go... (note closing of reading and writing streams, also the cleanup of streams if an exception is thrown).
public String sendSMS(String data, String url1) {
URL url;
OutputStreamWriter wr = null;
BufferedReader rd = null;
String status = "Somthing wrong ";
try {
url = new URL(url1);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
conn.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
conn.setRequestProperty("Accept","*/*");
wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
wr.close();
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String s;
while ((s = rd.readLine()) != null) {
status = s;
}
rd.close();
} catch (Exception e) {
if (wr != null) try { wr.close(); } catch (Exception x) {/*cleanup*/}
if (rd != null) try { rd.close(); } catch (Exception x) {/*cleanup*/}
e.printStackTrace();
}
return status;
}
This issue seems to be known, but for different reasons so its not clear why this happend.
Some threads would recommend closing the OutputStreamWriter as flushing it is not enough, therefor i would try to clos it directly after fushing as you are not using it in the code between the flush and close.
Other threads show that using a different connections like HttpURLConnection are avoiding this problem from occuring (Take a look here)
Another article suggests to use the URLEncoder class’ static method encode. This method takes a string and encodes it to a string that is ok to put in a URL.
Some similar questions:
URL is accessable with browser but still FileNotFoundException with URLConnection
URLConnection FileNotFoundException for non-standard HTTP port sources
URLConnection throwing FileNotFoundException
Wish you good luck.
It returns FileNotFoundException when the server response to HTTP request is code 404.
Check your URL.

Categories