Greetings,
I am trying to setup a server connection from my BlackBerry Application . I was able to get a response code on the status of the server. Now i have a few values which i have to POST to the server
Its like a registration page values(username, password, age ) have to be sent to the server .
ConnectionFactory connFact = new ConnectionFactory();
ConnectionDescriptor connDesc;
connDesc = connFact.getConnection(url);
if (connDesc != null)
{
HttpConnection httpConn;
httpConn = (HttpConnection)connDesc.getConnection();
try
{
final int iResponseCode = httpConn.getResponseCode();
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("Response code: " + Integer.toString(iResponseCode));
}
});
}
catch (IOException e)
{
System.err.println("Caught IOException: " + e.getMessage());
}
}
Thats the code i used to get the response code.
I would appreciate it if someone could help me how i can make a POST request to the server..
the server url for status was company.com/app/version/stats
when it for register it would be
company.com/app/register
Thank you
What type of a POST do you use? If you are just passing key-value pairs, then it should be a POST of a "application/x-www-form-urlencoded" content-type.
So, what lacks youe code is:
1). Set a proper content-type on your connection:
httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
2). Prepare the content to be sent to the server via the POST:
URLEncodedPostData encPostData = new URLEncodedPostData("UTF-8", false);
encPostData.append("username", username);
encPostData.append("password", password);
encPostData.append("age", age);
byte[] postData = encPostData.toString().getBytes("UTF-8");
3). Set content-length for the connection (this step may be optional - try without this first, probably the BB OS is smart enough to set this automatically):
httpConn.setRequestProperty("Content-Length", String.valueOf(postData.length));
4). Open an OutputStream and write the content to it (the code is simplified):
OutputStream os = httpConn.openOutputStream();
os.write(postData);
os.flush();
...
httpConn = (HttpConnection)connDesc.getConnection();
httpConn.setRequestMethod(HttpConnection.POST);
httpConn.setRequestProperty("username",name);
httpConn.setRequestProperty("password",pass);
....
Related
I try to use HttpURLConnection to send a post request to my local (xampp) server with an url like this http://xxx.xxx.0.3/Company/index.php/booking/c200/p-205/2025-02-09 8:2 , the server php file take param in url and send data to mysql database .
The url works fine on postman agent , and even another get method request works smooth in the android application .
Yet when i try the post method with following code :
public void postOrder() {
TextView tv = findViewById(R.id.tv1);
Thread t = new Thread( new Runnable() {
#Override
public void run() {
HttpURLConnection conn = null;
try {
String link = "http://xxx.xxx.0.3/Company/index.php/booking/c200/p-205/2025-02-09 8:2";
URL url = new URL(link);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setReadTimeout(10000 /*ms*/);
conn.setConnectTimeout(15000 /*ms*/);
conn.connect();
}
catch (IOException e) {
Log.d("HTTP error: ", e.toString());
}
finally {
conn.disconnect();
}
}
} );
t.start();
}
It never sent the url and thus no data is stored to database .
And with 6 hours of trial and error , google and searching , i added this line of code :
InputStream is = conn.getInputStream();
And it finally works .
Please answer me why it only works after adding this line of code , what does it do ? I thought the url is triggered right after conn.connect();
Calling connect() only connects, but it doesn't send anything yet. Call getResponseCode() to force the request to be sent. That method is safer than getInputStream() which will throw an exception if the response is not a 2xx (in which case you'd need getErrorStream()).
I am trying to validate the linkedIn profile of 100K person and wrote a dummy code but its giving "java.io.IOException: Server returned HTTP response code: 403 for URL: https://www.linkedin.com/in/test.user"
I have tried setting different setRequestProperty but not working.
public static void main(final String[] args) {
String output = "";
int TIMEOUT_VALUE = 99999999;
HttpURLConnection conn = null;
BufferedReader br = null;
String urlEndPoint = "";
String authUser = "";
String authPwd = "";
try {
long start = System.nanoTime();
urlEndPoint = "https://www.linkedin.com/in/test.user";
authUser = "linkedin-username";
authPwd = "linkedin-password";
URL url = new URL(urlEndPoint);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("username", authUser);
conn.setRequestProperty("password", authPwd);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Keep-Alive", "header");
conn.setRequestProperty("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
conn.setConnectTimeout(TIMEOUT_VALUE);
conn.setReadTimeout(TIMEOUT_VALUE);
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept-Language", "en-US,en;q=0.9,mt;q=0.8");
conn.setRequestProperty("Accept-Encoding", "gzip,deflate,br");
conn.setRequestProperty("Host", "www.linkedin.com");
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36");
conn.setRequestProperty("http.agent", "Chrome/71.0.3578.80 (Windows NT 10.0; Win64; x64)");
conn.setDoOutput(true);
String userPassword = authUser + ":" + authPwd;
String encoding = Base64Encoder.encode(userPassword);
conn.setRequestProperty("Authorization", "Basic " + encoding);
OutputStream os = conn.getOutputStream();
os.flush();
conn.connect();
br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
while ((output = br.readLine()) != null) {
System.out.println(output);
}
if (br != null) {
br.close();
}
if (os != null) {
os.close();
}
long elapsed = System.nanoTime() - start;
} catch (MalformedURLException e) {
//this.logger.error("Error occurred during processPartyTerrRelationship ", e);
e.printStackTrace();
} catch (IOException e) {
//this.logger.error("Error occurred during processPartyTerrRelationship ", e);
e.printStackTrace();
} catch (Exception e) {
//this.logger.error("Error occurred during processPartyTerrRelationship ", e);
e.printStackTrace();
} finally {
try {
if (conn != null) {
conn.disconnect();
}
} catch (Exception e) {
//this.logger.error("Error occurred during processPartyTerrRelationship ", e);
e.printStackTrace();
}
}
//logger.info("processPartyTerrRelationship called ends");
}
The outcode of above code is :
java.io.IOException: Server returned HTTP response code: 403 for URL: https://www.linkedin.com/in/test.user
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1894)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:263)
at ValidateLinkedInProfiles.main(ValidateLinkedInProfiles.java:57)
The HTTP error code 403 is an error related to the authorization to the requested resource:
HTTP 403 provides a distinct error case from HTTP 401; while HTTP 401 is returned when the client has not authenticated, and implies that a successful response may be returned following valid authentication, HTTP 403 is returned when the client is not permitted access to the resource for some reason besides authentication
It's hard to understand how you're working. The LinkedIn link requires login. But you indeed need to debug it somehow and need a raw real output to the server with the correct one otherwise you will not complete it. If you have Java example program, see if they or you have a typo, but again without screenshot or text from LinkedIn I cannot debug it. Maybe try to add the examples and I will try to help you (just make me login with my public profile to other places). Also make sure there is your real password and your user account in the correct fields of course (authUsr,authPwd shall not be copy paste unlike everything else).
HTTP 403 is a legitimate response from a server. So the behavior is valid. However, I would recommend to use some HTTP client utility rather then writing your own code to make Http request. This will reduce the chance of a problem caused by your own code. As some Http clients I would suggest Apache Http Client or OK Http client or MgntUtils Http Client (see MgntUtils HttpClient javadoc here, Full MgntUtils library on github is here and Maven repository is here). Disclaimer: MgntUtils library is written by me
HTTP 403 is a standard HTTP status code communicated to clients by an HTTP server to indicate that the server understood the request, but will not fulfill it. There are a number of sub-status error codes that provide a more specific reason for responding with the 403 status code.
You either do not have access to the site(try logging in from a browser and try to run the script from the same browser, if your access is shared across different tabs of the same browser that is also fine, but make sure you're authorized) or the request to the link contains sensitive information which the site doesn't want to share.
I am having trouble sending through a java application the data to a page in php. Basically, I have a page in php that receives the data through the POST method and created a class in java that sends this data via post. The problem is that in java I do not insert the identifier that is requested in the php page. As you can see, I get the value on the page in php by the filter_input (INPUT_POST, "user") code snippet, but in the java application I do not enter this "user" identifier in the information I want to send. So, there's no way the php page "picks up" the value that the java application is sending. Anyone have any ideas how to solve this problem? Thank you very much in advance!
Page PHP:
<?php
require_once './vendor/autoload.php';
$controller = new App\CWS\Controller();
if($_SERVER['REQUEST_METHOD'] == "POST"){
$controller->registerUser(filter_input(INPUT_POST, "user"));
}
?>
Class responsible for connecting and sending data in the Java application:
public class WebClient {
public String post(String json) {
try {
URL url = new URL("http://localhost//CWS//cadastrar_usuario.php");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-type", "application/json");
connection.setRequestProperty("Accept", "application/json");
connection.setDoOutput(true);
PrintStream output = new PrintStream(connection.getOutputStream());
output.println(json);
connection.connect();
Scanner scanner = new Scanner(connection.getInputStream());
String resposta = scanner.next();
return resposta;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
PrintStream output = new PrintStream(connection.getOutputStream());
output.println(json);
With this you are sending the data as JSON encoded text to the server.
Whatever is in the JSON string at this point will be sent.
If you have not put the data for "user" in the JSON, you have to put it before sending it.
We (Panos and Rainer - see the comments down) have a server and several Android devices.
We want to send push notifications from our server via GCM to the Android devices.
Now we make a post request to the GCM server. The GCM server response is that all is fine (success==1 and even the message-id)!
BUT the push notification(s) are never delivered to the devices.
If we use the same data and the Chrome addon Postman - the notifications are delivered immediately.
We tried all lot of different solutions. We get always the feedback of the GCM server that all is ok - but the push notifications aren't send.
We also tried this one:
https://github.com/googlesamples/google-services/blob/master/android/gcm/gcmsender/src/main/java/gcm/play/android/samples/com/gcmsender/GcmSender.java
You might also post the URL you use. There is a new GCM enpoint which looks like the following:
https://gcm-http.googleapis.com/gcm/send
I am not yet sure what's causing the issues on your side. But the following is tested and working:
public class Main {
public static void main(String[] args) {
// write your code here
try {
String url = "https://gcm-http.googleapis.com/gcm/send";
URL obj = new URL(url);
HttpsURLConnectionImpl conn = (HttpsURLConnectionImpl) obj.openConnection();
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty ("Authorization", "key=***");
String title = "Short title";
String body = "A body :D";
String token = "****";
String data = "{ \"notification\": { \"title\": \"" + title +"\", \"body\": \"" + body + "\" }, \"to\" : \"" + token + "\", \"priority\" : \"high\" }";
OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
out.write(data);
out.close();
String text = getText(new InputStreamReader(conn.getInputStream()));
System.out.println(text);
} catch (Exception e) {
e.printStackTrace();
}
}
public static String getText(InputStreamReader in) throws IOException {
StringBuilder sb=new StringBuilder();
BufferedReader br = new BufferedReader(in);
String read;
while((read=br.readLine()) != null) {
sb.append(read);
}
br.close();
return sb.toString();
}
}
This is the data used for the Postman request which is working without any problem.
Rainer already mentioned that we tried several implementations on the Java side and it seems that we are always able to communicate with the service and receive a response which seems to look correct so far:
{
"multicast_id":7456542468425129822,
"success":1,
"failure":0,
"canonical_ids":0,
"results":
[{
"message_id":"0:1457548597263237%39c590d7f9fd7ecd"
}]
}
Not sure if I'm on the right track but do you mean downstream HTTP messages (plain text)?
Tried to send the following JSON to the service (from Postman) which results again in a positive response but this time the notification did not reach the device (just to make that clear, at the moment there is no app on the device listening actively for incoming notifications -> first of all we just want to ensure that they generally arrive on the device):
{
"data":
{
"score": "5x1",
"time": "15:10"
},
"to" : "SECRET-DEVICE-TOKEN"
}
Thanks to all of you trying to help here but to be honest, this issue is really frustrating. Communicating with an interface\service which seems not to be able to return a useful response in case the request contains maybe evil stuff which will finally prevent GCM from sending the push notification to the device, feels like a pain in the ass. If Postman would also fail I would say ok, you can not be so stupid :-)
Here are some quick'n dirty implementations we have already used.
Example
try
{
URL url = new URL(apiUrl);
HttpsURLConnection conn = (HttpsURLConnection);//also tried HttpURLConnection
url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Authorization", "key="+apiKey);
conn.setDoOutput(true);
String json = "{\"priority\":\"high\",\"notification\":{\"title\":\"Some title\",\"text\":\"Some text\"},\"to\":\""+deviceToken+"\"}";
OutputStream os = conn.getOutputStream();
os.write(json.getBytes());
os.flush();
}
catch(Exception exc)
{
System.out.println("Error while trying to send push notification: "+exc);
}
Example
HttpClient httpClient = HttpClientBuilder.create().build();
try
{
HttpPost request = new HttpPost(apiUrl);
StringEntity params =new StringEntity("{\"priority\":\"high\",\"notification\":{\title\":\"Some title\",\"text\":\"Some text\"},\"to\":\""+deviceToken+"\"}");
request.addHeader("Content-Type", "application/json");
request.addHeader("Authorization", "key="+apiKey);
request.setEntity(params);
HttpResponse response = httpClient.execute(request);
// check response
System.out.println(response.getStatusLine().toString());
}catch (Exception exc) {
System.out.println("Error while trying to send push notification: "+exc);
} finally {
httpClient.getConnectionManager().shutdown(); //Deprecated
}
Example
try
{
String charset = "UTF-8";
URLConnection connection = new URL(apiUrl).openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Accept-Charset", charset);
connection.setRequestProperty("Content-Type", "application/json;charset=" + charset);
connection.setRequestProperty("Authorization", "key="+apiKey);
String param = "{\"priority\":\"high\",\"notification\":{\"title\":\"Some title\",\"text\":\"Some text\"},\"to\":\""+deviceToken+"\"}";
try (OutputStream output = connection.getOutputStream())
{
output.write(param.getBytes(charset));
}
InputStream response = connection.getInputStream();
}
catch(Exception exc)
{
System.out.println("Error while trying to send push notification: "+exc);
}
Example
try
{
// prepare JSON
JSONObject jGcmData = new JSONObject();
JSONObject jData = new JSONObject();
jData.put("message", "{ \"data\": {\"score\": \"5x1\",\"time\": \"15:10\"},\"to\" : \""+deviceToken+"\"}");
jGcmData.put("to", deviceToken);
jGcmData.put("data", jData);
// Create connection to send GCM Message request.
URL url = new URL("https://android.googleapis.com/gcm/send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", "key=" + apiKey);
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestMethod("POST");
conn.setDoOutput(true);
// Send GCM message content.
OutputStream outputStream = conn.getOutputStream();
outputStream.write(jGcmData.toString().getBytes());
// Read GCM response.
InputStream inputStream = conn.getInputStream();
String resp = IOUtils.toString(inputStream);
System.out.println(resp);
} catch (IOException e) {
System.out.println("Unable to send GCM message. "+e);
}
Mike, with your example it's working also on our side. After comparing your implementation with the on eon our side, the only real difference I found is the used URL!!
Somehow the URL used in our Java implementation was https://android.googleapis.com/gcm/send
Seems that https://gcm-http.googleapis.com/gcm/send is the right one which by the way was also used for our Postman tests.
But why on hell is the URL from our failed tests still somehowe valid and returns a response!?
Setting the priority to high in the json resolved the issue for me.
'registration_ids' => $id,
'priority' => 'high',
'data' => $load
For our case, the clients Android devices had intermittent internet connection issue, that is, network dropouts thus causing notification delivery failed. We resolved the reliability issue with the following JAVA GCM code:
gcmPayload.setTime_to_live(messageExpiryTime); //in seconds. Set notification message expiry to give user time to receive it in case they have intermittent internet connection, or phone was off
gcmPayload.setPriority("high");
and APNS code:
ApnsService apnsService = APNS.newService().withCert(certificateStream, configurations.getApnPassword()).withProductionDestination().build();
PayloadBuilder payloadBuilder = APNS.newPayload();
...
payloadBuilder.instantDeliveryOrSilentNotification(); //same as content-available=true
String payload = payloadBuilder.build();
Integer now = (int)(new Date().getTime()/1000);
//use EnhancedApnsNotification to set message expiry time
for(String deviceToken : deviceTokens) {
EnhancedApnsNotification notification = new EnhancedApnsNotification(EnhancedApnsNotification.INCREMENT_ID() /* Next ID */,
now + messageExpiryTime /* Expiry time in seconds */,
deviceToken /* Device Token */,
payload);
apnsService.push(notification);
}
Also, remember to consider time zone if your backend server time is different to the client mobile app time.
I'm trying to establish a Connection via HTTPS. I also set the "Authorization" property in the Request Header to Basic and provide an encoded auth string accordingly.
I checked with the Firefox Plugin HttpRequester and everythign works fine, which means I entered the url, choose "GET" as request method, add the Authorization to the header and after pressing submit I get back some xml which only a properly authorized user should get.
Unfortunately I can neither provide you with the actual auth info nor the real url in the SSCCE. However, I can tell you, that the Auth seems to work, since I get a 200 response. I also changed the Auth to a wrong value and get a "401 Authorization Required" response then.
It actually seems like the "?myparam=xyz" is somehow cut off, because when I remove this parameter from the url and test with Firefox HttpRequester again I get the same response as in Java.
Unfortunately I have no access to "theirdomain.com", so I don't know what's happending on the server side. But since it works with the Firefox HttpRequester, it should also work with Java.
What could be the reason? Thanks for your help!
EDIT:
I changed the url to "https://www.google.com/search?q=foo" and commented this line:
//con.setRequestProperty("Authorization", auth);
I can see from the returned string, that google received the "foo". So apparently the combination of Authorization and get parameter seems to be the problem, since both separately work fine.
SSCCE:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
public class HttpRequest
{
/**
* #param args
*/
public static void main(final String[] args)
{
System.out.println("start request");
final String urlString = "https://theirdomain.com/foo/bar/bob?myparam=xyz";
final String auth = "Basic XyzxYzxYZxYzxyzXYzxY==";
HttpsURLConnection con;
try
{
final URL url = new URL(urlString);
con = (HttpsURLConnection) url.openConnection();
con.setRequestProperty("Authorization", auth);
con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0");
con.setRequestMethod("GET");
// con.setDoOutput(true);
con.connect();
final int responseCode = con.getResponseCode();
if (responseCode != 200)
System.out.println("Server responded with code " + responseCode + " " + con.getResponseMessage());
else
{
System.out.println("Starting to read...");
final InputStream inStream = con.getInputStream();
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
int c;
while (inStream != null && (c = inStream.read()) != -1)
{
baos.write(c);
}
System.out.println(new String(baos.toByteArray()));
}
}
catch (final IOException e)
{
System.out.println("could not open an HTTP connection to url: " + urlString);
e.printStackTrace();
}
finally
{
System.out.println("end request");
}
}
}
Have you tried adding
con.setRequestProperty("myparam", "xyz"); to your code?