I am testing a https post on android , I have 2 android devices, this code perfectly worked on my 2.3 device but will be blocked in my 4.1 device at "retcode=urlCon.getResponseCode();", also I have checked the packet in sniffer the post request has been sent and the server did reply the https response,but it still be blocked until timeout.
private String GetHttpPage(HttpsURLConnection urlsCon,String host,String url,String reference,boolean type,String curcookie,String postparam){
String query = postparam;
byte[] entitydata = query.getBytes();
String line="";
HttpURLConnection urlCon=urlsCon;
try{
String domain="";
String fullurl=host+url;
if(urlCon==null){
if(host.indexOf("https")!=-1){
urlCon =GetHttpsConnect(fullurl);
domain=host.substring(8);
}
else{
urlCon =GetHttpConnect(fullurl);
domain=host.substring(7);
}
}
urlCon.setConnectTimeout(30000);
urlCon.setReadTimeout(30000);
if(reference!=null)
urlCon.setRequestProperty("Referer", reference);
urlCon.setRequestProperty("Cache-Control", "no-cache");
urlCon.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)");
urlCon.setRequestProperty("Accept-Encoding", "identity");
urlCon.setRequestProperty("Accept", "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*");
urlCon.setRequestProperty("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
urlCon.setRequestProperty("connection", "Keep-Alive");
urlCon.setRequestProperty("Host", domain);
//
if(curcookie.length()>0)
urlCon.setRequestProperty("Cookie", curcookie);
if(type){
urlCon.setDoOutput(true);
urlCon.setDoInput(true);
urlCon.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
urlCon.setRequestProperty("Content-Length",String.valueOf(entitydata.length));
urlCon.setRequestMethod("POST");
}
else{
urlCon.setDoOutput(false);
urlCon.setDoInput(true);
urlCon.setRequestMethod("GET");
}
urlCon.connect();
if(type){
OutputStream outStream = urlCon.getOutputStream();
outStream.write(entitydata, 0, entitydata.length);
// outStream.write(entitydata);
outStream.flush();
outStream.close();
}
retcode=urlCon.getResponseCode();
if(urlCon.getHeaderField("Location")!=null)
redirect=urlCon.getHeaderField("Location");
Map m=urlCon.getHeaderFields();
Set set=m.entrySet();
Iterator it=set.iterator();
while(it.hasNext())
{
Map.Entry me=(Map.Entry)it.next();
String skey=me.getKey()!=null?me.getKey().toString():"";
String svalue=me.getValue()!=null?me.getValue().toString():"";
if(skey.compareToIgnoreCase("Set-Cookie")==0){
String tempcookie=svalue;
tempcookie=tempcookie.substring(1, tempcookie.length()-1);
cookie+=ProcessCookie(tempcookie);
//cookie=cookie.substring(0, cookie.length()-2);
}
}
// if(urlCon.getHeaderField("Set-Cookie")!=null)
// cookie=urlCon.getHeaderField("Set-Cookie");
BufferedReader in = new BufferedReader(new InputStreamReader(urlCon.getInputStream()));
String subline="";
while ((subline = in.readLine()) != null) {
line+=subline;
}
in.close();
}
catch(IOException e){
String aaa=e.toString();
Log.e("xx", aaa);
}
catch(Exception e){
String aaa=e.toString();
Log.e("xx", aaa);
}
if(urlCon!=null)
urlCon.disconnect();
return line;
}
I suppose you have the Internet permission inside the manifest?I think that the problem is in the "User-Agent" inside one of the setRequestProperty or maybe in another one, but not in the rest of the code.
Try putting
System.setProperty("http.keepAlive", "false");
somewhere in your code.
Related
I have been running into a very strange problem. I am trying to implement log in service in my app. When I pass right email and password service returns response as expected(means no error comes) but when I delibrately pass wrong email or password geInputStream() method throws FileNotFoundException. I don't know what is the reason behind this.Further more, before calling getInputStream() method i checked status code as well(this is the case when I am passing wrong email and password intentionally).The status code was 500. I checked for 500 and that was internal server error. My question is why is that so? I mean when intentionally passing wrong email or password why internal server occurred? One more thing I would like to mention that I have checked the same service on post man it is working fine as expected. If i pass wrong email or password postman returns the expected error. Below is the code I am using
private String invokeWebservice() {
String data = null;
HttpURLConnection conn = null;
BufferedReader in = null;
try {
String webservice = Constants.BASE_URL + serviceName;
LogUtility.debugLog("webservice just called "+ webservice);
URL url = new URL(webservice);
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setUseCaches(false);
if (isPost) {
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
Writer writer = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), "UTF-8"));
if (jsonObject != null)
writer.write(jsonObject.toString());
writer.close();
}
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuffer sb = new StringBuffer("");
String l = "";
String nl = System.getProperty("line.separator");
while ((l = in.readLine()) != null)
sb.append(l + nl);
in.close();
data = sb.toString();
return data;
} catch (Exception e) {
LogUtility.errorLog("exception while calling web service");
} finally {
try {
if (conn != null)
conn.disconnect();
if (in != null)
in.close();
} catch (Exception ex) {
// LogUtility.errorLogWithException(ex, ex.getMessage());
}
}
return data;
}
Any help?
After spending some time now I was able to solve my problem.Posting my answer for others. Passing wrong email and password to the service was right and server was consuming those parameters as well and because there was an error(because email and password) that is why it was returning 500 code. So, I checked for status code if it was 200 then I used getInputStream() method and else i called getErrorStream() method. By this way i got the stream that has property for error(this property contains error detail). Below is the code i used
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
in = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
} else {
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
}
Hope it helps other as well.
I have 2 phones:
lg g3 that i bought from China
and lg g3 that i bought from Israel
i build an android app that gets a response from web according to a keysearch(key search can be in any language:russian,hebrew, arabic, english etc.)
In english, both phones work great.
But when i use non-english langauge(all above, didn't try chinese) the Israel phone still works great but the China phone not.
When i debug the program in the China phone i saw that the keysearch (in non english langaage) when i get the reponse is in question marks. but in the Isreal phone it's works great, so i tried all kinds of encoding, but nothing seems to work.
here's the piece of the code that have the problem:
HttpURLConnection connection = null;
try {
//Create connection
URL url = new URL("https://www.example.com/results?search_query="+keyword);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setRequestProperty("content-type", "application/x-www-form-urlencoded; charset=utf-8");
BufferedReader in = new BufferedReader(
new InputStreamReader(connection.getInputStream(),"UTF-8"));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
response.append('\r');
}
m_htmlDoc = response.toString();
} catch (Exception e) {
e.printStackTrace();
m_htmlDoc = null;
} finally {
if(connection != null) {
connection.disconnect();
}
}
the question is: do i need to change something in the code so the China phone will accept other langauges (not just english)? if so, it would be great if someone can direct me to the answer. if not, so maybe i need to change settings on the phone? both phones has the same OS langauge (hebrew)
Thank you all.
so the utf-8 was correct and i didn't need tochange any local langauge on the phone all i needed is to encode the keysearch (URLEncoder.encode(keyword, "UTF-8")).
this is the complete answer:
HttpURLConnection connection = null;
try {
//Create connection
URL url = new URL("https://www.example.com/results?search_query=" + URLEncoder.encode(keyword, "UTF-8"));
connection = (HttpURLConnection)url.openConnection();
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setRequestProperty("content-type", "application/x-www-form-urlencoded; charset=utf-8");
BufferedReader in = new BufferedReader(
new InputStreamReader(connection.getInputStream(),"UTF-8"));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
response.append('\r');
}
m_htmlDoc = response.toString();
} catch (Exception e) {
e.printStackTrace();
m_htmlDoc = null;
} finally {
if(connection != null) {
connection.disconnect();
}
}
Thank you all for the help.
Today I'm making my first attempt of sending a POST request with a JSON to save some data, and I'm not being able to do so.
My app works by signing in, and then save, modify and delete data. It's already done in iOS, but since I'm new to Android, I'm not sure how to do it.
Here's my POST function:
public String POST(String targetURL, String urlParameters, String user, String pwd) {
URL url;
String u = targetURL;
HttpURLConnection connection = null;
try {
// Create connection
// u=URLEncoder.encode(u, "UTF-8");
url = new URL(u);
connection = (HttpURLConnection) url.openConnection();
// cambiarlo luego al usuario q esta logeado
String login = user + ":" + pwd;
String encoding = new String(org.apache.commons.codec.binary.Base64.encodeBase64(org.apache.commons.codec.binary.StringUtils.getBytesUtf8(login)));
connection.setRequestMethod("POST");
connection.setRequestProperty("Authorization", "Basic " + encoding);
connection.setRequestProperty("Content-Type", "plain/text");// hace q sirva con el string de json
connection.setRequestProperty("Content-Length", "" + Integer.toString(urlParameters.getBytes().length));
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setReadTimeout(120000);
// Send request
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
// Get Response
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
this.setResponseCode(connection.getResponseCode());
while ((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
return response.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
The method above is executed with Asynctask, and even if I use it to Login using Spring security, it works, and even I can save for internal usage the username, password, and secret token.
I dunno if I need to put the token in a header or something, because I already did that, with no positive results.
I'm supposing that the only permission I need to execute this is the internet one, so in my manifest file I specified that permission.
I'm going crazy with this issue, please help!
Thanks in advance.
EDIT:
Sorry guys, I'm kinda new to this way of asking, and also, not an English native speaker :P
The output I receive after sending the request, is the HTML of the page that handles logging in into the web app... I need like a json response or something like that to make sure the request was saved correctly
Try handling your cookies
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
This should be a singleton.
Im currently working on an Android app with heavy server side communication. Yesterday I got a bug report saying that the users aren't able to send (simple) special characters such as ëäï.
I searched but didn't find anything helpful
Possible duplicate ( without answer ):
https://stackoverflow.com/questions/12388974/android-httpurlconnection-post-special-charactes-to-rest-clint-in-android
My relevant code:
public void execute(String method) {
HttpsURLConnection urlConnection = null;
try {
URL url = new URL(this.url);
urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setRequestMethod(method);
urlConnection.setReadTimeout(30 * 1000);
urlConnection.setDoInput(true);
if (secure)
urlConnection.setRequestProperty("Authorization", "Basic " + getCredentials());
if (body != null) {
urlConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
urlConnection.setFixedLengthStreamingMode(body.length());
urlConnection.setDoOutput(true);
DataOutputStream dos = new DataOutputStream(urlConnection.getOutputStream());
dos.writeBytes(body);
dos.flush();
dos.close();
}
responseCode = urlConnection.getResponseCode();
message = urlConnection.getResponseMessage();
InputStream in = null;
try {
in = new BufferedInputStream(urlConnection.getInputStream(), 2048);
} catch (Exception e) {
in = new BufferedInputStream(urlConnection.getErrorStream(), 2048);
}
if (in != null)
response = convertStreamToString(in);
} catch (UnknownHostException no_con) {
responseCode = 101;
}catch (ConnectException no_con_2){
responseCode = 101;
}catch(IOException io_ex){
if(io_ex.getMessage().contains("No authentication challenges found")){
responseCode = 401;
}else
responseCode = 101;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (urlConnection != null)
urlConnection.disconnect();
}
}
body is a String ;-)
Hope we can solve this together
UPDATE:
Tried:
writeUTF()
need a server capable of understanding the modified UTF-8
byte[] buf = body.getBytes("UTF-8");
dos.write(buf, 0, buf.length);
strings work but no special chars
update: Got it working with StringEntity(* string, "UTF-8") then parse the result to a byte[] and write it with dos.write(byte[])!
--
Setting the encoding of the StringEntity did the trick for me:
StringEntity entity = new StringEntity(body, "UTF-8");
seen here: https://stackoverflow.com/a/5819465/570168
i am not totally sure buy try this utility for your case
URLEncoder.encode(string, "UTF-8")
I faced this problem in android while passing a json with special char (ñ).
In my WebApi method, [FromBody] param is giving null, it seems it can't parse the json.
I got it working by getting bytes as UTF-8 then writing it in DataOutputStream (Client-side fix).
byte[] b = jsonString.getBytes("UTF-8");
os.write(b, 0, b.length);
I am trying to post a JSON message to a site and to retrieve a JSON message back.
java.net.ProtocolException: method does not support a request body: POST
Does anyone know what is wrong? Thanks in advance
HttpURLConnection conn=null;
try{
URL url=new URL(urlString);
String userPassword = userName +":" + passWord;
byte[] bytes=Base64.encode(userPassword.getBytes(),Base64.DEFAULT);
String stringEncoding = new String(bytes, "UTF-8");
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty ("Authorization", "Basic " + stringEncoding);
conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
Log.i("Net", "length="+conn.getContentLength());
Log.i("Net", "contentType="+conn.getContentType());
Log.i("Net", "content="+conn.getContent());
conn.connect();
}catch(Exception e){
Log.d("Url Formation Connection", e.toString());
}
//output{
try{
String requestString="{“ ";
wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(requestString.toString());
wr.flush();
//input{
BufferedReader rd = null;
String response=" ";
is = conn.getInputStream();
rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer responseBuff = new StringBuffer();
while ((line = rd.readLine()) != null) {
// Process line...
responseBuff.append(line);
}
response = responseBuff.toString();
Log.d("response", response);
}catch(Exception e){
Log.d("buffer error", e.toString());
}finally {
if (is != null) {
try {
wr.close();
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
It could be that the server you're connecting to doesn't allow POST operations. I would try a GET request first, to see if you have permissions for that web service method.
Also, you could try your luck with a simpler HttpClient, although I haven't tested this solution myself: http://www.geekmind.net/2009/11/android-simple-httpclient-to.html
Just a guess but can you try setting:
conn.setDoOutput(false);
The documentation says: "Optionally upload a request body. Instances must be configured with setDoOutput(true) if they include a request body." HttpURLConnection
Since you do not have anything in your body, might as well set it to false.
The documentation Android has for setRequestMethod is minimal, however your error states that POST is not a valid method. Try using PUT instead:
conn.setRequestMethod("PUT");
Also see this post for any tweaks you may need to make.