HttpURLConnection.getInputStream() throws SocketTimeoutException - java

I am using HttpURLConnection to upload an image and get its response.
It works on emulator and my XiaoMi device.
However, it always get a SocketTimeoutException on my Sony device on the line connection.getInputStream().
I've tried to set timeouts to large value like 1 minute but not work.
public String uploadFile(File file, String requestURL) {
if (file != null) {
long fileSize = file.length();
HttpURLConnection.setFollowRedirects(false);
HttpURLConnection connection = null;
try {
//config of connection
connection = (HttpURLConnection) new URL(requestURL).openConnection();
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
connection.setRequestMethod("PUT");
connection.setRequestProperty("Content-Type", "image/jpeg");
connection.setDoOutput(true);
connection.setRequestProperty("Content-length", "" + fileSize);
connection.connect();
//upload file
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
int bytesRead;
byte buf[] = new byte[1024];
BufferedInputStream bufInput = new BufferedInputStream(new FileInputStream(file));
while ((bytesRead = bufInput.read(buf)) != -1) {
out.write(buf, 0, bytesRead);
out.flush();
}
out.flush();
out.close();
//get response message, but SocketTimeoutException occurs here
BufferedReader br = new BufferedReader(new InputStreamReader((connection.getInputStream())));
StringBuilder sb = new StringBuilder();
String output;
while ((output = br.readLine()) != null) {
sb.append(output);
}
//return response message
return output;
} catch (Exception e) {
// Exception
e.printStackTrace();
} finally {
if (connection != null) connection.disconnect();
}
}
return null;
}
What causes this problem happen?And how to fix it?
Additional Info:
I tested on devices under same wifi connection. And sure network and file server worked properly. The file size of tested images is about 100~200kbyte.

Because you set a read timeout of ten seconds and no response was received within ten seconds.
Is this a trick question?
NB You don't need to set the content-length header. Java will do that for you.

Just remove connection.setReadTimeout() statement because by default it will set readTiomeout value to 0 i.e it will wait for data until data is available.so,you might not get SocketTimeOut Exception.

Related

Getting unicode results in MailChimp oauth2 token creation

I have generated the access code by using https://login.mailchimp.com/oauth2/authorize API. But when I try to create the token using https://login.mailchimp.com/oauth2/token, I'm getting unicode result like this.
(?M?? ?0F?UJ?N?NQ? %`??'
"?????nb??f=?&9????i'f??]?~j*$??W??Reg??_T1-???;?oc)
qryStr = {"client_secret":"**********","grant_type":"authorization_code","redirect_uri":"https%3A%2F%2Flocalhost%3A9443%2Fverifymailchimp.sas","client_id":"********","code":"*************"}
HttpURLConnection connection = null;
try
{
URL reqURL = new URL("https://login.mailchimp.com/oauth2/token");
connection = (HttpURLConnection) reqURL.openConnection();
connection.setConnectTimeout(3000); // 3 seconds
connection.setReadTimeout(5000); // 5 seconds
connection.setUseCaches(false);
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setRequestProperty("Accept", "application/json");
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); //No I18N
connection.setRequestProperty("Content-Length", "" + Integer.toString(qryStr.getBytes().length)); //No I18N
connection.setDoOutput(true);
OutputStream os = null;
try
{
os = connection.getOutputStream();
os.write(qryStr.getBytes(CHARSET));
}
finally
{
try{os.close();}catch(Exception e){}
}
int resCode = connection.getResponseCode();
boolean success = (resCode >= 200 && resCode < 300);
InputStream is = success ? connection.getInputStream() : connection.getErrorStream();
if (is == null)
{
return null;
}
String contentStr = null;
try
{
InputStreamReader reader = new InputStreamReader(is, CHARSET);
StringBuilder buffer = new StringBuilder();
char[] bytes = new char[1024];
int bytesRead;
while ((bytesRead = reader.read(bytes, 0, bytes.length)) > 0)
{
buffer.append(bytes, 0, bytesRead);
}
contentStr = buffer.toString();//?M?? ?0F?UJ?N?NQ? %`??' "?????nb??f=?&9????i'f??]?~j*$??W??Reg??_T1-???;?oc
}
finally
{
try{is.close();}catch(Exception e){}
}
}
Can anyone please tell the cause?
I found the cause of this case. An access code is valid for 30 seconds. Need to generate the token before the expiry. If they conveyed the proper error message, we can able to sort out the problem without any confusion :(

saving file as .pdf as recieved in http response error

For my project i need to download a pdf file from google drive using java
I get my httpresponse code 200 and by using following method i store it in abc.pdf file
String url = "https://docs.google.com/uc?id="+fileid+"&export=download";
URL obj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
// optional default is GET
conn.setRequestMethod("GET");
//add request header
conn.setRequestProperty("User-Agent", USER_AGENT);
int responseCode = conn.getResponseCode();
System.out.println("\nSending 'GET' request to URL : " + url);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String inputLine;
OutputStream f0 = new FileOutputStream("C:\\Users\\Darshil\\Desktop\\abc.pdf",true);
while ((inputLine = in.readLine()) != null) {
//System.out.println(inputLine);
byte b[]=inputLine.getBytes();
//System.out.println(b);
f0.write(b);
}
in.close();
f0.close();
But when i try to open abc.pdf in my adobe reader x i get following error:
There was an error opening this document.The file is damaged and could not be repaired
You seem to be directly accessing the Google drive using Raw HTTP requests.
You may be better of using the Google Drive SDK. This link contains good examples to address the use cases you state in your question.
However if you do want to stick to your technique then you should not be using a BufferedReader.readLine(). This is because the PDF file is a binary finally that would depend upon the correct byte sequences to be preserved in order to be read correctly by the PDF reader software. Hopefully the below technique should help you:
//read in chunks of 2KB
byte[] buffer = new byte[2048];
int bytesRead = 0;
try(InputStream is = conn.getInputStream())
{
try(DataOutputStream os = new DataOutputStream(new FileOutputStream("file.pdf"))
{
while((bytesRead = is.read(buffer)) != -1)
{
os.write(buffer, 0, bytesRead);
}
}
}
catch(Exception ex)
{
//handle exception
}
Note that I am using the try-with-resources statement in Java 7
Hope this helps.

Sending request to GCM results in a JSON_PARSIN_ERROR

I need to write a server which sends push notifications to iOS and Android devices.
I can successfully send notifications to iOS. Luckily it was painless to implement that part.
I'm facing a problem with the easiest part of the task: Android.
I configured GCM and the Android device successfully registers against the server.
When I try to send a push to the device, I get the following error:
STATUS: 400
JSON_PARSING_ERROR: Unexpected token END OF FILE at position 0.
Here the code that sends the request.
AndroidPush push = new AndroidPush();
push.getRegids().add(token);
push.getData().setMessage(message);
push.getData().setMsgcnt(String.format("%d", (badge + 1)));
URL u = new URL(androidEndpoint);
HttpsURLConnection conn = null;
OutputStream os = null;
OutputStreamWriter osw = null;
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
try{
conn = (HttpsURLConnection)u.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", androidContentType);
conn.setRequestProperty("Authorization", androidAuthorization);
conn.connect();
os = conn.getOutputStream();
osw = new OutputStreamWriter(os);
System.out.println(push.toJSON());
osw.write(push.toJSON());
int status = conn.getResponseCode();
System.err.println("STATUS: "+status);
if(status == 200){
is = conn.getInputStream();
} else {
is = conn.getErrorStream();
}
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
String read = null;
do {
read = br.readLine();
if(read != null)
sb.append(read);
} while (read != null);
if(status != 200){
System.err.println(sb.toString());
} else {
System.out.println(sb.toString());
}
} catch(IOException ex) {
ex.printStackTrace();
throw ex;
} finally {
if(isr != null)
isr.close();
if(is != null)
is.close();
if(osw != null)
osw.close();
if(os != null)
os.close();
if(conn != null)
conn.disconnect();
}
Where:
androidEndpoint = "https://android.googleapis.com/gcm/send";
androidContentType = "application/json";
androidAuthorization = "key=<mykey>";
and the output of the push.toJSON() method is the following String:
{
"registration_ids" : ["APA91bEmD8T9NxQj07uhbTAsD1GTWvT7L_no1SXP70YWaQGPX6VO73pdAOa53PN-hyAyy-3erItWxLDb8W1aQ2nh3np0NttJ5g66w2-142d4bXTCsmrF34-J7rWw4IUObutQznaml59XdfweiEGKzv1Otp3quffUEA"],
"data" : {
"message":"Push di prova",
"msgcnt":"13"
}
}
I cannot see anything wrong... What am I missing?
Thank you for your help,
Developing a solution with php, I recieved always the same error WHEN the message had Umlauts (e.g. äöü) in it.
Without the message went through and arrived the reciever.
The solution was finally to utf8_encode( 'your text here äöä' ) your outgoing strings (message, title, etc. whatever).
Cost my at least several hours to detect what was 'wrong'.
Is it the case that you are missing ',' as shown below in bold
{
"registration_ids" : ["APA91bEmD8T9NxQj07uhbTAsD1GTWvT7L_no1SXP70YWaQGPX6VO73pdAOa53PN-hyAyy-3erItWxLDb8W1aQ2nh3np0NttJ5g66w2-142d4bXTCsmrF34-J7rWw4IUObutQznaml59XdfweiEGKzv1Otp3quffUEA"],
"data" : {
"message":"Push di prova",
"msgcnt":"13"**,**
}**,**
}
Refer message given in this link: http://developer.android.com/google/gcm/adv.html#payload

Streaming Google Speech api

currently I can recognize speech to text using google's speech api. Now that I have this, I was just wondering if there is a way I can stream the response of transcribed text and give it more text to transcribe at the same time. In other words I want to speak into the microphone, and as I speak I want a response from the google servers. The code I am using currently:
System.out.println("openning connection");
HttpsURLConnection httpConn = null;
ByteBuffer buff = ByteBuffer.wrap(data);
byte[] destdata = new byte[2048];
int resCode = -1;
OutputStream out = null;
try {
URL url = new URL(urlStr);
URLConnection urlConn = url.openConnection();
if (!(urlConn instanceof HttpsURLConnection)) {
throw new IOException ("URL must be HTTPS");
}
httpConn = (HttpsURLConnection)urlConn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("POST");
httpConn.setRequestProperty("User-Agent", USER_AGENT);
httpConn.setDoOutput(true);
httpConn.setRequestProperty("AcceptEncoding", "gzip,deflate,sdch");
httpConn.setChunkedStreamingMode(0); //TransferType: chunked
httpConn.setRequestProperty("Content-Type", "audio/l16; rate=" + sampleRate);
// this opens a connection, then sends POST & headers.
out = httpConn.getOutputStream();
//beyond 15 sec duration just simply writing the file
// does not seem to work. So buffer it and delay to simulate
// bufferd microphone delivering stream of speech
// re: net.http.ChunkedOutputStream.java
while(buff.remaining() >= destdata.length){
buff.get(destdata);
out.write(destdata);
};
byte[] lastr = new byte[buff.remaining()];
buff.get(lastr, 0, lastr.length);
out.write(lastr);
out.close();
resCode = httpConn.getResponseCode();
if(resCode >= HttpURLConnection.HTTP_UNAUTHORIZED){//Stops here if Google doesn't like us/
System.out.println("unauthorized");
throw new HTTPException(HttpURLConnection.HTTP_UNAUTHORIZED);//Throws
}
String line;//Each line that is read back from Google.
BufferedReader br = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
while ((line = br.readLine( )) != null) {
System.out.println(line);
if(line.length()>19 && resCode > 100 && resCode < HttpURLConnection.HTTP_UNAUTHORIZED){
GoogleResponse gr = new GoogleResponse();
parseResponse(line, gr);
fireResponseEvent(gr);
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally {httpConn.disconnect();}
Thanks for any help.

How to transfer a file from REST php server to a Java client

I've been surfing over this site looking for an example or "light at the end of the tunnel" about how to write a code that let me download a file from a REST server in PHP to a client in JAVA.
The client will make a GET request with an ID of the file, and then the PHP REST code should response with the file, and JAVA receive that file and store it in the Hard Drive.
Any idea...?
I tried to do the PHP Rest server like this...:
$file = 'path_to_file/file.mp3';
$content = readfile($file);
And this $content var, is sent as the response...
The client... I wrote is:
try {
URL url = new URL("url/to/rest/server");
HttpURLConnection conn (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "Content-Disposition: filename\"music.mp3\"");
if(conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code: " + conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
try {
String output;
File newFile = newFile("/some/path/file.mp3");
fileWriter fw = new FileWriter(newFile);
while ((output = br.readLine()) != null) {
fw.write(output);
}
fw.close();
} catch (IOException iox) {
//do
}
} catch (MalformedURLException e) {
//do
}
The problem with my examples is that when I receive the file on the client is kind of corrupted or something!... in my example with an mp3 file, any music player on the client says that file is corrupted or it doesn't work.
Thanks for any help.
When dealing with binary data (MP3 files) you should use InputStream and OutputStream and not Readers/Writers. Additionally, the BufferedReader.readLine() strips any 'newlines' from the output too.
Because you are using Readers/Writers, the binary data is being converted to Strings, and I am sure there's a lot of corruption happening.
Try the following:
InputStream is = conn.getInputStream();
byte[] buffer = new byte[10240]; // 10K is a 'reasonable' amount
try {
File newFile = newFile("/some/path/file.mp3");
FileOutputStream fos = new FileOutputStream(newFile);
int len = 0;
while ((len = is.read(buffer)) >= 0) {
fos.write(buffer, 0, len);
}
fos.close();
} catch (IOException iox) {
//do
}

Categories

Resources