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 :(
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.
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
EDIT: Now that I've figured out some behavior, I'm wondering, why does it not send the request as soon as I call flush()? or close()? Why does it wait until I call getResponseCode()?
Original question:
I am new to the HttpsURLConnection class in java, and looked on the doc and found it not very enlightening. I have inherited this code on a project I am working on (I did not write it myself) and wondered what it's doing, and how it can be improved. For example, I can't tell if "writeBytes" actually sends the data or "close." I've looked at many javadocs and found them to be ambiguous, and haven't found any good resources for this topic in books or blog posts online. Could someone please enlighten me, or point me to some good resources?
By the way, this code is for an android SDK library I am working on.
Note: I understand the theory of HTTP requests very well. I took a class on it. I know all about URL parameters (using the ?name=value) and cookies and RESTful services and TCP and IP... etc. Just struggling to find good docs so I know how to use the java libraries.
Edit: Changed this to the HttpClient code because it turns out I couldn't use Https and still see the request from the echo server. It has the same idea though.
import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class HttpClient
{
public static final String DEBUG_URL = "http://10.20.1.61:8001/api/ad/v5/";
public static final String MAPPED_KEYWORDS = "get_mapped_keywords/";
private static byte[] buffer = new byte[1024];
static NetworkReturn sendHttpPost(String urlString, String postData)
{
URL url;
HttpURLConnection con = null;
try {
url = new URL(urlString);
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-length", String.valueOf(postData.length()));
con.setRequestProperty("Content-Type", "application/json");
con.setDoOutput(true);
DataOutputStream output = new DataOutputStream(con.getOutputStream());
output.writeBytes(postData);
output.close();
StringBuilder result = new StringBuilder(), error = new StringBuilder();
int responseCode = con.getResponseCode();
if (responseCode >= 200 && responseCode < 300)
{
if (con.getInputStream() != null)
{
InputStream in = new BufferedInputStream(con.getInputStream());
int length;
while ((length = in.read(buffer)) != -1)
{
result.append(new String(buffer, 0, length));
}
}
}
else
{
if (con.getErrorStream() != null)
{
InputStream in = new BufferedInputStream(con.getErrorStream());
int length;
while ((length = in.read(buffer)) != -1)
{
error.append(new String(buffer, 0, length));
}
}
}
return new NetworkReturn(responseCode, result.toString(), error.toString());
}
catch (MalformedURLException e) {
return new NetworkReturn(-1, "", "MalformedURLException: " + e.getLocalizedMessage());
}
catch (IOException e) {
e.printStackTrace();
return new NetworkReturn(-1, "", "IOEXCEPTION: " + e.getLocalizedMessage());
}
finally {
if (con != null)
con.disconnect();
}
}
}
The first method you call that gets input from the server will set the content-length header and write the output. That could be getResponseCode() or getInputStream(), or maybe getErrorStream().
If you're using fixed-length or chunked transfer mode, writing is direct.
For example, I can't tell if "writeBytes" actually sends the data or
"close."
This is purposefully ambiguous to give implementations leeway.
The issue is whether or not fixed length or chunked requests will be used. It appears that fixed length requests are being used by default, though it does not appear that is required by the spec. The behavior can be controlled by methods on the HttpURLConnection. To specify use of chunked, you can call setChunkedStreamingMode. You can also call setFixedLengthStreamingMode to define the fixed length of the request. Even in this case, the implementation /could/ choose to start sending data early, as the total length is known and so can be set in the request header correctly.
Practically speaking, calling writeBytes will (generally) cause data to buffer until some threshold is reached. At that time the buffered data will be actually written and the process will repeat. When you call close, any buffered data will be written as well as the necessary bytes to signify the end of the http request.
Explicit calls to flush will also usually cause any buffered data to be written out.
I finally figured it out. The "getResponseCode()" method is the straw that breaks the camel's back (so to speak). Because when I commented out stuff, it was when I commented that part out it didn't "echo" my response on the echo server I was using (and printing the received requests to the terminal).
Note: I used a nearly-identical HttpClient class because otherwise the echo server would print out encrypted code like this:
����5D��s����l!���RMav*X?�+gJ.�+�/ � �����32E98�/A5� P
localhost�
When I ran this code as a Java application, the server did not print anything to the terminal:
(notice the commented out parts)
static NetworkReturn sendHttpPost(String urlString, String postData)
{
URL url;
HttpURLConnection con = null;
try {
url = new URL(urlString);
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-length", String.valueOf(postData.length()));
con.setRequestProperty("Content-Type", "application/json");
con.setDoOutput(true);
DataOutputStream output = new DataOutputStream(con.getOutputStream());
output.writeBytes(postData);
output.close();
//StringBuilder result = new StringBuilder(), error = new StringBuilder();
//int responseCode = con.getResponseCode();
/*
if (responseCode >= 200 && responseCode < 300)
{
if (con.getInputStream() != null)
{
InputStream in = new BufferedInputStream(con.getInputStream());
int length;
while ((length = in.read(buffer)) != -1)
{
result.append(new String(buffer, 0, length));
}
}
}
else
{
if (con.getErrorStream() != null)
{
InputStream in = new BufferedInputStream(con.getErrorStream());
int length;
while ((length = in.read(buffer)) != -1)
{
error.append(new String(buffer, 0, length));
}
}
}
return new NetworkReturn(responseCode, result.toString(), error.toString());
*/
return new NetworkReturn();
}
catch (MalformedURLException e) {
return new NetworkReturn(-1, "", "MalformedURLException: " + e.getLocalizedMessage());
}
catch (IOException e) {
e.printStackTrace();
return new NetworkReturn(-1, "", "IOEXCEPTION: " + e.getLocalizedMessage());
}
finally {
if (con != null)
con.disconnect();
}
}
However, this code DID make the server print to the terminal:
static NetworkReturn sendHttpPost(String urlString, String postData)
{
URL url;
HttpURLConnection con = null;
try {
url = new URL(urlString);
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-length", String.valueOf(postData.length()));
con.setRequestProperty("Content-Type", "application/json");
con.setDoOutput(true);
DataOutputStream output = new DataOutputStream(con.getOutputStream());
output.writeBytes(postData);
output.close();
//StringBuilder result = new StringBuilder(), error = new StringBuilder();
int responseCode = con.getResponseCode();
/*
if (responseCode >= 200 && responseCode < 300)
{
if (con.getInputStream() != null)
{
InputStream in = new BufferedInputStream(con.getInputStream());
int length;
while ((length = in.read(buffer)) != -1)
{
result.append(new String(buffer, 0, length));
}
}
}
else
{
if (con.getErrorStream() != null)
{
InputStream in = new BufferedInputStream(con.getErrorStream());
int length;
while ((length = in.read(buffer)) != -1)
{
error.append(new String(buffer, 0, length));
}
}
}
return new NetworkReturn(responseCode, result.toString(), error.toString());
*/
return new NetworkReturn();
}
catch (MalformedURLException e) {
return new NetworkReturn(-1, "", "MalformedURLException: " + e.getLocalizedMessage());
}
catch (IOException e) {
e.printStackTrace();
return new NetworkReturn(-1, "", "IOEXCEPTION: " + e.getLocalizedMessage());
}
finally {
if (con != null)
con.disconnect();
}
}
and the terminal output was this (an echo server, so this is what the request must have looked like):
POST / HTTP/1.1
Content-Type: application/json
User-Agent: Java/1.7.0_60
Host: localhost:3000
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-Length: 16
blah blah blah
This was the method call I did:
public class Main
{
public static void main(String[] args)
{
NetworkReturn result = HttpClient.sendHttpPost("http://localhost:3000/", "blah blah blah\n\n");
}
}
Edit:
I tried Brett's suggestion by calling flush to the output stream (getResponseCode() is still commented out, so now I'm seeing if flush will make it work):
...
DataOutputStream output = new DataOutputStream(con.getOutputStream());
output.writeBytes(postData);
output.flush(); //<------------here
output.close();
//StringBuilder result = new StringBuilder(), error = new StringBuilder();
//int responseCode = con.getResponseCode();
/*
if (responseCode >= 200 && responseCode < 300)
{
if
...
But my echo server didn't print anything. It makes sense, now that I think about it, because "output.close();" probably calls "flush()" already. If flush() worked, then my first code snippet (with getResponseCode() commented out) would have probably worked.
Edit: Tried to see if a 512 kilobyte request body would make the difference and cause the request to be sent, but it didn't work when getResponseCode() was commented out. I verified that it worked when I uncommented getResponseCode().
My new main method for testing a large "file", assuming a char is 1 byte so it should be over 512 kilobytes:
public class Main
{
public static void main(String[] args)
{
StringBuilder largeString = new StringBuilder();
for (int i = 0; i < 524288; i++)
{
largeString.append('a');
}
largeString.append("\n\n");
NetworkReturn result = HttpClient.sendHttpPost("http://localhost:3000/", largeString.toString());
}
}
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
}