jsp HTTPS Post Request - java

I am trying to send HTTPS Post Request from jsp to Opera Server. But I can't. I have found many HTTP Post Request examples but no HTTPS. I am getting an Error Message now..
java.lang.ClassCastException: sun.net.www.protocol.https.HttpsURLConnectionImpl cannot be cast to com.sun.net.ssl.HttpsURLConnection
My import are as follows for this code
java.security.Security, com.sun.net.ssl.
My code as follows
try{
String data = URLEncoder.encode("AccountID", "UTF-8") + "=" + URLEncoder.encode(accountid, "UTF-8");
data += "&" + URLEncoder.encode("CallerTransactionID", "UTF-8") + "=" + URLEncoder.encode(callertransactionid, "UTF-8");
data += "&" + URLEncoder.encode("CurrentTime", "UTF-8") + "=" + URLEncoder.encode(currenttime, "UTF-8");
data += "&" + URLEncoder.encode("ErrorURL", "UTF-8") + "=" + URLEncoder.encode(errorurl, "UTF-8");
//data += "&" + URLEncoder.encode("FrameURL", "UTF-8") + "=" + URLEncoder.encode(frameurl, "UTF-8");
System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
URL opxurl = new URL("https://opx-test.opera.com/opx/2.0/OPXPaymentEnable");
HttpsURLConnection connopx = (HttpsURLConnection) opxurl.openConnection();
connopx.setDoInput(true);
connopx.setDoOutput(true);
connopx.setRequestMethod("POST");
connopx.setFollowRedirects(true);
connopx.setRequestProperty("Content-length",String.valueOf(data.length()));
connopx.setRequestProperty("Content-Type","application/x-www- form-urlencoded");
// open up the output stream of the connection
DataOutputStream output = new DataOutputStream(connopx.getOutputStream());
// write out the data
int dataLength = data.length();
output.writeBytes(data);
//output.flush();
System.out.println("HOly Portal ResponseDesc Code:"+connopx.getResponseCode()+" : "+connopx.getResponseMessage());
// get ready to read the response from the cgi script
DataInputStream input = new DataInputStream( connopx.getInputStream() );
// read in each character until end-of-stream is detected
for( int c = input.read(); c != -1; c = input.read() )
System.out.print("HolyPortal respnse: "+ (char)c );
input.close();

After all connopx's settings you have to call
connopx.connect();
I use this import and it works in my code:
import javax.net.ssl.HttpsURLConnection;
I don't have the two lines above URL opxurl =
Have a look at this answer with similar issue also.
EDIT:
To avoid error 500 remove space in "application/x-www-form-urlencoded" and add those two lines right after output.writeBytes(data);:
output.flush();
output.close();
Then it should work.

This should be your code
try {
URL url = new URL("yourURL");
URLConnection conn = url.openConnection();
if (conn instanceof HttpsURLConnection) {
// Try again as HTTPS
HttpsURLConnection conn1 = (HttpsURLConnection) url.openConnection();
conn1.setHostnameVerifier(new HostnameVerifier() {
#Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
conn1.getResponseCode();
}
}
catch (MalformedURLException e) {
}
catch (IOException e) {
}

Related

Getting an access token using OAuth, the response appears to be encoded

I'm pretty new to OAuth and am trying to refresh a token using a simple java client. Everything seems to go ok (or I think it does), the problem is I can't tell from the response if it's a good one. The http response code is 200, but when trying to parse the response for access_token, I get a null. Also difficult to troubleshoot is the "raw" response is garbled, or encoded in some way. I was thinking maybe it's byte but it doesn't seem to be. Here's the code:
private static String getClientCredentials() {
String postParams = "grant_type=refresh_token&refresh_token=1234567890";
Pattern pat = Pattern.compile(".*\"access_token\"\\s*:\\s*\"([^\"]+)\".*");
String clientId = "myClientID123";
String clientSecret = "myClientSecret123";
String tokenUrl = "https://www.host.com/oauth2/tenant/token";
String auth = clientId + ":" + clientSecret;
String authentication = Base64.getEncoder().encodeToString(auth.getBytes());
BufferedReader reader = null;
HttpsURLConnection connection = null;
String returnValue = "";
try {
URL url = new URL(tokenUrl);
connection = (HttpsURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Authorization", "Basic " + authentication);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Accept", "application/x-www-form-urlencoded");
connection.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
connection.setRequestProperty("Connection", "keep-alive");
connection.setDoOutput(true);
OutputStream outStream = connection.getOutputStream();
outStream.write(postParams.getBytes());
outStream.flush();
outStream.close();
System.out.println("Resp code: " + connection.getResponseCode());
System.out.println("Resp message: " + connection.getResponseMessage());
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line = null;
StringWriter out = new StringWriter(connection.getContentLength() > 0 ? connection.getContentLength() : 2048);
while ((line = reader.readLine()) != null) {
out.append(line);
}
String response = out.toString();
Matcher matcher = pat.matcher(response);
if (matcher.matches() && matcher.groupCount() > 0) {
returnValue = matcher.group(1);
}
System.out.println("response: " + response);
System.out.println("returnValue: " + returnValue);
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
}
}
connection.disconnect();
}
return returnValue;
}
Here's the console output, sorry, I had to screenshot it because the characters didn't paste right:
Response Screenshot
Am I trying something that isn't allowed or is there a way to decode the response so I can run the pattern match to extract only the access_token? Or am I going about it all wrong? Any help is greatly appreciated in advance!

Posting data from Java and receiving in node.js applicaiton

I have written a demo in Java that posts data once a second:
public static void main(String[] arystrArgs) {
//Get Operating System name and version
String strOSname = System.getProperty("os.name").toLowerCase();
//Display application title and what it is running on
System.out.println("Java Data Posting Demo");
System.out.println("Build date: " + BUILD_DATE + ", Version: " + VERSION_NO);
System.out.println("Running on: " + strOSname.substring(0, 1).toUpperCase()
+ strOSname.substring(1).toLowerCase());
//Post data to server
HttpURLConnection conn = null;
while( true ) {
try {
Thread.sleep(DELAY_BETWEEN_POSTS);
URL url = new URL("http://localhost:8080");
conn = (HttpURLConnection)url.openConnection();
if ( conn != null ) {
//Whatever you wants to post...
String strPostData = "p1=Hello&p2=" + (new Date()).getTime();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-length", Integer.toString(strPostData.length()));
conn.setRequestProperty("Content-Language", "en-GB");
conn.setRequestProperty("charset", "utf-8");
conn.setUseCaches(false);
conn.setDoOutput(true);
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(strPostData);
dos.close();
System.out.println("Post to: " + url.toString() + ", data: " + strPostData);
}
} catch (InterruptedException|IOException ex) {
//ex.printStackTrace();
} finally {
if ( conn != null ) {
conn.disconnect();
conn = null;
}
}
}
}
I have written a Node.js application that listens on port 8080, but I don't see any POST requests in the http handler, I only see GET requests when I use a browser on the same address and port to test.
Snippet from node.js application:
function defaultHandler(request, response) {
try{
if ( request.method == "POST" ) {
var strBody = "";
request.on("data", function(chunk) {
strBody += chunk;
});
request.on("end", function() {
console.log("Received posted data: " + strBody);
});
} else {
console.dir(request);
}
} catch( ex ) {
console.dir(ex);
}
};
var app = http.createServer(defaultHandler);
app.listen(8080);
This is a cut down version, but all I ever see is get requests. I can see that the Java is connecting and posting data, as when I start Node.js and only when I start Node.js, the Java application connects to the URL then starts POSTING with a second delay between posts, it I terminate node, then it stops posting and restarting node causes the posts to resume.
Your Node app never send response to client. You send a lot of request but Java Client never receive response from server. You should execute end method on response.
var http = require('http');
function defaultHandler(request, response) {
try {
if (request.method == "POST") {
var strBody = "";
request.on("data", function(chunk) {
strBody += chunk;
});
request.on("end", function() {
console.log("Received posted data: " + strBody);
});
} else {
console.dir(request);
}
respone.end(); // for example here
} catch (ex) {
console.dir(ex);
}
};
var app = http.createServer(defaultHandler);
app.listen(8080);
Here you can find documentation - https://nodejs.org/api/http.html#http_class_http_serverresponse
I'm not a Java developer, but I think you can try use flush and getResponseCode method on connection.
conn.setDoOutput(true);
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(strPostData);
dos.flush();
dos.close();
int responseCode = conn.getResponseCode();
Fixed, it was the Java, I modified the Java code as follows:
URL url = new URL("http://localhost:8080");
conn = (HttpURLConnection)url.openConnection();
if ( conn != null ) {
//Whatever you wants to post...
String strPostData = "p1=Hello&p2=" + (new Date()).getTime();
conn.setRequestMethod("POST");
conn.setRequestProperty("User-Agent", USER_AGENT);
conn.setRequestProperty("Accept-Language", "en-GB,en;q=0.5");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-length", Integer.toString(strPostData.length()));
conn.setRequestProperty("Content-Language", "en-GB");
conn.setRequestProperty("charset", "utf-8");
conn.setUseCaches(false);
conn.setDoOutput(true);
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(strPostData);
dos.flush();
dos.close();
int intResponse = conn.getResponseCode();
System.out.println("\nSending 'POST' to " + url.toString() +
", data: " + strPostData + ", rc: " + intResponse);;
}

When I do not use from a condition I can get the data from php, But when I use from a condition, I Can not get data from php

My php code is correct. But I have a strange problem when I use a condition in my code. My php code sends the "A" string from server to android. In the following code when I do not use a condition in my code in the GetText() method, I can get the A string and display it in the TextView well. But when I use a condition as follows, I can not get and display the A string in the TextView . Please help me. I do not know that where is this problem.
Pass = pass.getText().toString();
// Create data variable for sent values to server
String data = URLEncoder.encode("name", "UTF-8") + "=" + URLEncoder.encode(Name, "UTF-8");
data += "&" + URLEncoder.encode("email", "UTF-8") + "=" + URLEncoder.encode(Email, "UTF-8");
data += "&" + URLEncoder.encode("user", "UTF-8") + "=" + URLEncoder.encode(Login, "UTF-8");
data += "&" + URLEncoder.encode("pass", "UTF-8") + "=" + URLEncoder.encode(Pass, "UTF-8");
String text = "";
BufferedReader reader = null;
// Send data
try{
// Defined URL where to send data
URL url = new URL("http://127.0.0.1:8080/apps/reg.php");
// Send POST data request
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
// Get the server response
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
// Read Server Response
while((line = reader.readLine()) != null){
// Append server response in string
sb.append(line);
}
text = sb.toString();
} catch(Exception ex){
} finally{
try{
reader.close();
} catch(Exception ex){}
}
// Show response on activity
String A = "A";
if(text.equals(A)){
content.setText(text); //it can not display the text in the TextView
}
}

getting Blank response from php server while access from other country in android

I made a andoid application in which I am getting response from php server, requesting in POST format. I am using below code for http connection:
// random string as boundary for multi-part http post
String strBoundary = "3i2ndDfv2rTHiSisAbouNdArYfORhtTPEefj3q2f";
String endLine = "\r\n";
OutputStream os;
String url = encodeUrl(methodType, graphURL, params);
Log.d("url - ",url);
Log.d("Method Type - ", methodType + " URL - " + url);
HttpURLConnection conn = (HttpURLConnection) new URL(url)
.openConnection();
conn.setConnectTimeout(60000);
conn.setReadTimeout(30000);
conn.setRequestProperty("User-Agent", System.getProperties()
.getProperty("http.agent"));
if (!methodType.equals("GET")) {
Bundle dataparams = new Bundle();
for (String key : params.keySet()) {
if (params.getByteArray(key) != null) {
dataparams.putByteArray(key, params.getByteArray(key));
}
}
// use method override
if (!params.containsKey("method")) {
params.putString("method", methodType);
}
if (params.containsKey("access_token")) {
#SuppressWarnings("deprecation")
String decoded_token = URLDecoder.decode(params
.getString("access_token"));
params.putString("access_token", decoded_token);
}
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + strBoundary);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.connect();
os = new BufferedOutputStream(conn.getOutputStream());
os.write(("--" + strBoundary + endLine).getBytes());
os.write((encodePostBody(params, strBoundary)).getBytes());
os.write((endLine + "--" + strBoundary + endLine).getBytes());
if (!dataparams.isEmpty()) {
for (String key : dataparams.keySet()) {
os.write(("Content-Disposition: form-data; filename=\""
+ key + "\"" + endLine).getBytes());
os
.write(("Content-Type: content/unknown" + endLine + endLine)
.getBytes());
os.write(dataparams.getByteArray(key));
os.write((endLine + "--" + strBoundary + endLine)
.getBytes());
}
}
os.flush();
}
String response = "";
try {
response = parseXmlSvn(conn.getInputStream());
} catch (FileNotFoundException e) {
// Error Stream contains JSON that we can parse to a FB error
//response = read(conn.getErrorStream());
Log.i("RESPONSE",""+response);
}
Log.i("RESPONSE", ""+response);
return response;
Everything is working fine on my demo server, I uploaded my PHP service to clients server. I am getting proper response from his server also.
But when client access app in 3G or 4G in some other country in his android devices, he is getting Blank response while the same service of same server can be accessible in iOS code easily by him. Is it some packet loss while getting response or any other problem?
I would really appreciate any help you can give me.
Thanks

Android C2DM: Could not verify SSL certificate javax.net.ssl.SSLHandshakeException

I'm receiving the following SSLHandshakeException when trying to send a push notification through the C2DM servers.
javax.net.ssl.SSLHandshakeException: Could not verify SSL certificate for: https://android.apis.google.com/c2dm/send
The code to send the message is as follows, and is running on App Engine. Everything works fine when I use cURL, so I know that the server authentication code and device registration ID are correct.
public static void sendHttpPostToC2dmService(String msg, PrintWriter out) {
String authCode = "XXXX";
String regID = "YYYY";
try {
URL url = new URL("https://android.apis.google.com/c2dm/send");
String data = URLEncoder.encode("registration_id", "UTF-8") + "="
+ URLEncoder.encode(regID, "UTF-8");
data += "&"
+ URLEncoder.encode("Authorization: GoogleLogin auth",
"UTF-8") + "="
+ URLEncoder.encode(authCode, "UTF-8");
data += "&" + URLEncoder.encode("collapse_key", "UTF-8") + "="
+ URLEncoder.encode("something", "UTF-8");
data += "&" + URLEncoder.encode("data.message", "UTF-8") + "="
+ URLEncoder.encode(msg, "UTF-8");
out.println("data=" + data);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
OutputStreamWriter writer = new OutputStreamWriter(
connection.getOutputStream());
writer.write(data);
writer.close();
out.println("responseCode=" + connection.getResponseCode());
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
String responseLine = new BufferedReader(new InputStreamReader(
connection.getInputStream())).readLine();
out.println("responseLine=" + responseLine);
} else {
// Server returned HTTP error code.
}
} catch (MalformedURLException e) {
out.println("MalformedURL");
out.println(e.getMessage());
} catch (IOException e) {
out.println("IOException");
out.println(e.getMessage());
e.printStackTrace(out);
}
}
It seems like others have also had this problem, but I haven't been able to find a clear solution (at least not one I'm able to understand). Appreciate any help.
You need to use HttpsURLConnection instead of HttpURLConnection.
AFAIK, HttpURLConnection doesn't verify hostnames.
If you are in the testing phase, you could use the non-secure url to push a notification.
http://android.apis.google.com/c2dm/send
I also got around this issue by adding a certificate validation callback to accept any certificate, but this was on a C# server. I'm sure there is a Java equivalent for this.
In production code you would want to verify the correct certificate or maybe just encrypt the data you are sending.

Categories

Resources