I am trying to send Json message from my [java application server] to [GCM]:
the java server app located on IIS server (Windows server 2008 R2).
here is my function:
public static String post(String apiKey, String json){
try{
URL url = new URL("https://android.googleapis.com/gcm/send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type:", "application/json");
conn.setRequestProperty("Authorization:", "key="+apiKey); // apiKey is valid browser apiKey.
conn.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
wr.writeUTF(json);
wr.flush();
wr.close();
/*I've deleted the respond check from the question*/
}
but I fail to send!, and does not get any message or exception.
I think that the server itself doesnt let me send http requests!
is this true? how to solve?
I recommend using the Sender and Message objects instead. The sample GCM server code uses those. Sample server code can be seen here.
If you really insist on handling the connection yourself, you can look at the underlying HttpURLConnection implementation of the Sender object here.
It does appear that there are certain differences between the Sender code and your request properties. Hope this helps.
Related
Currently I'm trying to address a webserver using HTTPS and POST method and send a JSON file to this server. I have already tried several tutorials but unfortunately I can only find examples for HTTP and Post and not HTTPS. Did I forget to implement something?
I would like to provide the code of the server, but I only received the address and the format of the JSON files.
Has anyone had the problem before or can help me?
Thank you
public static void main(String[] args) throws IOException {
URL url = new URL(" https://webservice.com:1234");
HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json; utf-8");
con.setRequestProperty("Accept", "application/json");
//con.setDoInput(true);
con.setDoOutput(true);
String jsonInputString = "\"ID\": \"12\"";
System.out.println(jsonInputString);
try(OutputStream os = con.getOutputStream()) {
byte[] input = jsonInputString.getBytes("utf-8");
os.write(input, 0, input.length);
os.flush();
}
System.out.println(con.getResponseCode());
Unfortunately I always get this error message:
Exception in thread "main" javax.net.ssl.SSLException: Unsupported or
unrecognized SSL message at
java.base/sun.security.ssl.SSLSocketInputRecord.handleUnknownRecord(SSLSocketInputRecord.java:439)
at
java.base/sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:184)
at
java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:108)
at
java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1180)
at
java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1091)
at
java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:402)
at
java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
at
java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:187)
at
java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1362)
at
java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1337)
at
java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:247)
at test.main(test.java:40)
Process finished with exit code 1
Sometimes the https returns SSL errors if the service is not secure. This happens a lot in localhost or some servers with only http. Maybe try removing the 's'
Many thanks for all your help, in a discussion with the developer of the web service I was able realize that the server does not support HTTPS. That means the link to the server was wrong - http//: instead of https//:
So with the HttpURLConnection con = (HttpURLConnection)url.openConnection(); it works just fine.
So, I saw this question using Jersey. But still didn't figure out how to send a simple push notification from my server to topic subscribed users.
I don't understand what's wrong in my request as I am trying to build based on their examples.
public class OverSLANotifier {
public static void main(String[] args) throws Exception, FirebaseException {
String rawData = "{\"to\": \"/topics/sla\",\"data\": {\"message\": \"This is test push notification!\",}}";
String encodedData = URLEncoder.encode(rawData, "UTF-8");
URL u = new URL("https://fcm.googleapis.com/fcm/send");
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization", "key=AI<redacted>VGB6YwPWrinoz1YFBgdKv4Pgm8s");
conn.setRequestProperty("Content-Type", "application/json");
OutputStream os = conn.getOutputStream();
os.write(encodedData.getBytes());
System.out.println(""+ conn.getResponseCode() + "-->>"+conn.getResponseMessage());
}
My client is properly set and can receive if I send from console.
The response is always:
401-->>Unauthorized
you're json seems invalid:
{\"to\": \"/topics/sla\",\"data\": {\"message\": \"This is test push notification!\",}}
vs
{\"to\": \"/topics/sla\",\"data\": {\"message\": \"This is test push notification!\"}}
Also check the documentation:
The sender account used to send a message couldn't be authenticated.
Possible causes are:
Authorization header missing or with invalid syntax in HTTP request.
Invalid project number sent as key.
Key valid but with FCM service disabled.
Request originated from a server not whitelisted
in the Server key IPs.
Source
PS: its also invalid in the documentation youll find here ;)
What I need to do is send POST request to specific URL with two parameters and when the request is sent, I need to redirect user to that link so that he would be able to access functionality.
So far, what I have managed to do from various examples is this:
private void postRemoteAdvisoryLink() throws IOException {
URL obj = new URL(KdrmApplicationContext.getRemoteAdvisoryUrlPath());
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setConnectTimeout(60000);
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "Mozilla/5.0");
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
// For post only - start
con.setDoOutput(true);
OutputStream os = con.getOutputStream();
os.write(("?auth=ssor&TransportKey=" + ssorTransportKey).getBytes());
os.flush();
os.close();
int responseCode = con.getResponseCode();
}
The problem is that now I get connection time out when trying to execute OutputStream os = con.getOutputStream(); line. Also, I still have no idea how to redirect user when request is completed.
Any ideas?
Using the basic Java URL classes would require you to manually handle the details of HTTP protocol - it's better to use libraries like Apache Http Components, as they deal with the underlying protocols for you. Some examples including POST requests can be found on their website.
Given the original question, the Timeout is likely related to host not responding or your Java application being unable to connect to given URL (due to no proxy configuration for example).
If you want to redirect a request based on the answer, you need to check the response headers and http status - if the status is 302, then there should be a header called Location, which will contain the URL you should make another request to.
Before getting an OutputStream, also make sure to set the Content-Length header (and ideally the Content-Type header as well).
I used Jodd Http library to connect with the proxy:
ProxyInfo proxyInfoObj = new ProxyInfo(ProxyType.HTTP, "10.30.56.70", 8080, "", "");
SocketHttpConnectionProvider provider = new SocketHttpConnectionProvider();
provider.useProxy(proxyInfoObj);
HttpRequest request = HttpRequest.get(url);
request.method("GET");
request.charset("UTF-8");
HttpResponse response = request.open(provider).send();
result = response.bodyText();
But i got this error:
jodd.http.HttpException: HTTP: Invalid code
at jodd.http.net.HTTPProxySocketFactory.createHttpProxySocket(HTTPProxySocketFactory.java:113)
at jodd.http.net.HTTPProxySocketFactory.createSocket(HTTPProxySocketFactory.java:32)
If I use SOCKS4 type, the program hang and don't return anything. Can anyone help me?
But I can connect via proxy using following code:
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("10.30.56.70", 8080));
HttpURLConnection connection =(HttpURLConnection)new URL("http://tvl.csmtalk.vn/api/sms/receive").openConnection(proxy);
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestProperty("Content-type", "text/xml");
connection.setRequestProperty("Accept", "text/xml, application/xml");
connection.setRequestMethod("GET");
connection.connect();
For me both codes hangs. When I try Jodd, it hangs because it can not open proxy socket to 10.30.56.70:8080. When I try to
telnet 10.30.56.70 8080
from command line it hangs as well. It looks like proxy is not responding. (You can contact Jodd support if you need more details, or if you want to send some private data regarding the connectivity.)
btw, you don't need to:
request.method("GET");
request.charset("UTF-8");
as method is already set to GET by method get() and charset is not used for requests, but response (to set one if not set by server).
I made an app. for Android which uses the C2DM service from Google. I
made a server simulator from some tutorials and it works fine. My
problem is, I tried to build a Java Servlet. From the Android device
it receives fine the message and saves the Registration ID, but when I
try to send a https POST request to the Google C2DM Server it always
gets a SocketTimeoutException : Timeout while fetching:
https://android.clients.google.com/c2dm/send.
I don't get why this is happening when the same works on the Android
device. Here is the code:
//The AuthToken from Google Client Login
String auth_key = TOKEN;
StringBuilder postDataBuilder = new StringBuilder();
//some parameters to pass, I've checked and it's correct, it's working
//with Fiddler
postDataBuilder.append(PARAM_REGISTRATION_ID).append("=").append(REGISTRATION_ID);
postDataBuilder.append("&").append(PARAM_COLLAPSE_KEY).append("=").append("0");
postDataBuilder.append("&").append("data.payload").append("=").append(URLEncoder.encode(message, UTF8));
byte[] postData = postDataBuilder.toString().getBytes(UTF8);
URL url = new URL("https://android.clients.google.com/c2dm/send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
conn.setRequestProperty("Content-Length",Integer.toString(postData.length));
conn.setRequestProperty("Authorization", "GoogleLogin auth="+auth_key);
OutputStream out = conn.getOutputStream();
out.write(postData);
out.close();
int responseCode = conn.getResponseCode();
//here comes the error processing, but I can't reach it, because of
//the exception.
if (responseCode == 401 || responseCode == 403) {
//....
}
Thanks for your help :).
The first obvious thing to check is - if you have thought of this I apologise - are you behind a proxy server e.g. a company firewall? If so a timeout is exactly the symptom I'd expect with the above code. (This catches me out all the time!)
With the latter half of your code (from the HttpURLConnection declaration on), unmodified, I see a timeout; on my system (behind a company firewall), with two changes I get a 200 OK back:
addition of a proxy object passed to the HttpUrlConnection factory as follows:
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("...", 8080));
HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy);
accepting the C2DM server's certificate that wasn't trusted by my JVM. For test purposes I overrode the default hostname verifier and TrustManager as described in Trusting all certificates using HttpClient over HTTPS . For production you should look at a more secure solution.
Another thing I spotted; it doesn't seem to matter but http://code.google.com/android/c2dm/index.html#push says to post to https://android.apis.google.com/c2dm/send, not android.clients.google.com - just something to be aware of that might break in future.
I faced same problem and
I had tried :
URL url = new URL("http://android.apis.google.com/c2dm/send");
instead of :
URL url = new URL("https://android.apis.google.com/c2dm/send");
it worked for me.