Related
I have a synchronous code based on httpURLConnection, and I have to convert it to the asynchronous mode.
Basic synchronous mode is fully functional, it works properly. To make it in the asynchronous way I am trying to use HttpClient with sendAsync method (JDK11). But I am stuck.
The summory of the project, as follows:
1) Several test classes, that extend abstractAPITest class.
2) This abstractAPITest class has the function of establishing the connection, and now I am working on it.
3) class User that invokes test classes
4) Main class that creates User instances in several threads and runs them.
Probably I should move the open connection function into User class or into main class? idk.
Here is what I have originally (sync):
byte[] sendRequest(JSONObject jsonObject, String username, String password) throws IOException, URISyntaxException {
HttpURLConnection httpURLConnection = (HttpURLConnection) (new URL(this.apiUrl)).openConnection();
if (username != null && password != null) {
String userPassword = username + ":" + password;
httpURLConnection.setRequestProperty("Authorization", "Basic " + DatatypeConverter.printBase64Binary(userPassword.getBytes()));
}
httpURLConnection.setRequestProperty("Content-Type", "application/json");
httpURLConnection.setDoOutput(true);
DataOutputStream dataOutputStream = new DataOutputStream(httpURLConnection.getOutputStream());
dataOutputStream.write(jsonObject.toString().getBytes());
dataOutputStream.flush();
log.info("REST send: JSONObject");
if (httpURLConnection.getResponseCode() != 200) {
log.error("REST send error");
throw new IOException();
} else {
byte[] responseBody = null;
StringBuilder data = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
data.append(line);
responseBody = data.toString().getBytes();
}
br.close();
return responseBody;
}
}
and what I have as async:
byte[] request = jsonObject.toString().getBytes();
String userPassword;
if (username != null && password != null) {
userPassword = username + ":" + password;
} else {
throw new NullPointerException("No username and/or password.");
}
byte[] responseBody = null;
byte[] request = jsonObject.toString().getBytes();
var client = HttpClient.newHttpClient();
var httpRequest = HttpRequest.newBuilder()
.uri(new URI(apiUrl))
.version(HttpClient.Version.HTTP_2)
.header("Content-Type", "application/json")
.header("Authorization", "Basic " + DatatypeConverter.printBase64Binary(userPassword.getBytes()))
.POST(HttpRequest.BodyPublishers.ofByteArray(request))
.build();
HttpResponse.BodyHandler<String> bodyHandler = HttpResponse.BodyHandlers.ofString();
CompletableFuture<HttpResponse<String>> future = client.sendAsync(httpRequest, bodyHandler);
future.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
byte[] responseBody = null; // DON'T PAY ATTENTION
return responseBody; // TO THESE TWO LINES
}
private static String basicAuthorization(String username, String password) {
String userPassword = null;
if (username != null && password != null) {
userPassword = username + ":" + password;
}
return "Basic " + DatatypeConverter.printBase64Binary(userPassword.getBytes());
}
So I need this async method do the same as sync method does, but asynchronously. So what can I do next?
I'm trying to send cookies to the server, but it doesn't work. Please tell me thats wrong. Here is my code.
At first, I take cookie in the POST request.
> Map <String, List<String>> headerFields = postRequest.getHeaderFields();
> List<String> cookiesHeader = headerFields.get("Set-Cookie");
Later, in the GET request, i'm send cookie to the server.
getRequest.setRequestProperty("Cookie", cookiesHeader.toString());
Help me. I'm beginner, not judge strictly.
Here all my code.
#Override
protected String doInBackground(Void... params) {
Log.i(TAG, "doInBackground");
String store_id = "";
final String COOKIES_HEADER = "Set-Cookie";
final String COOKIE = "Cookie";
try {
Thread.sleep(4000);
Log.i(TAG, "httpRequest start");
String parametrs = mPhone.getText().toString();
String parametrs2 = mPass.getText().toString();
JSONObject allParams = new JSONObject();
HttpURLConnection postRequest = null;
InputStream inputStream = null;
byte[] data = null;
try {
URL serverUrl = new URL("https://api.fianitlombard.ru/mobile/auth");
postRequest = (HttpURLConnection) serverUrl.openConnection();
postRequest.setReadTimeout(10000 /* milliseconds */);
postRequest.setConnectTimeout(15000 /* milliseconds */);
postRequest.setRequestMethod("POST");
postRequest.setDoInput(true);
postRequest.setDoOutput(true);
postRequest.setRequestProperty("Content-Type", "application/json; charset=utf-8");
postRequest.connect();
allParams.put("phone", parametrs);
allParams.put("password", parametrs2);
Log.i(TAG, "allParams" + allParams);
OutputStream bos = (postRequest.getOutputStream());
bos.write(allParams.toString().getBytes());
String helpInfo = postRequest.getResponseMessage();
Log.i(TAG, "helpInfo =" + helpInfo);
responseCode = postRequest.getResponseCode();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Map<String, List<String>> headerFields = postRequest.getHeaderFields();
List<String> cookiesHeader = headerFields.get(COOKIES_HEADER);
if (responseCode == 200) {
inputStream = postRequest.getInputStream();
byte[] buffer = new byte[8192]; // Такого вот размера буфер
// Далее, например, вот так читаем ответ
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
baos.write(buffer, 0, bytesRead);
}
data = baos.toByteArray();
resultString = new String(data, "UTF-8");
Log.i(TAG, "responseCode = " + responseCode);
Log.i(TAG, "resultCode = " + resultString);
JSONObject jsonObject = new JSONObject(resultString);
store_id = jsonObject.getString("store_id");
Log.i(TAG, "store_id =" + store_id);
bos.close();
baos.close();
postRequest.disconnect();
}
if (responseCode == 403) {
Log.i(TAG, "responseCode = " + responseCode);
}
HttpURLConnection getRequest = null;
try {
URL serverUrl1 = new URL("https://api.fianitlombard.ru/mobile/checksession?version=1.0.8");
URI uri = URI.create("https://api.fianitlombard.ru/mobile/checksession?version=1.0.8");
getRequest = (HttpURLConnection) serverUrl1.openConnection();
getRequest.setReadTimeout(20000 /* milliseconds */);
getRequest.setConnectTimeout(25000 /* milliseconds */);
getRequest.setRequestMethod("GET");
getRequest.setRequestProperty("Content-Type", "application/json; charset=utf-8");
getRequest.setRequestProperty(COOKIE, cookiesHeader.toString());
Log.i(TAG, "Cookie = " + cookiesHeader.toString());
getRequest.connect();
int responceGetCode = getRequest.getResponseCode();
String responceGetInfo = getRequest.getResponseMessage();
Log.i(TAG, "responceGetCode = " + responceGetCode);
Log.i(TAG, "responceGetInfo = " + responceGetInfo);
if (responceGetCode == 200) {
//Все хорошо
}
if (responceGetCode == 400) {
// Устарела версия, нужно обновление
}
if (responceGetCode == 403) {
//Проблемы с авторизацией
} else {
//Что то другое.
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (getRequest != null)
getRequest.disconnect();
}
} catch (IOException e1) {
e1.printStackTrace();
}
if (postRequest != null) {
postRequest.disconnect();
}
Log.i(TAG, "httpRequest end");
}
catch (InterruptedException | JSONException e) {
e.printStackTrace();
}
return store_id;
}
change below line
getRequest.setRequestProperty(COOKIE, cookiesHeader.toString());
to
getRequest.setRequestProperty( COOKIE, cookiesHeader.get( 0 ) );
toString() method of List will return the hashCode() but not the actual values of List
try to use the following method to get the cookie :
String getHeaderField("Set-Cookie")
you set the cookie by using the lists toString method, which will not give you the current cookie representation, but instead a string matching "[var1, var2, var3]"
The server sends the following in its response header to set a cookie field.
Set-Cookie:name=value
If there is a cookie set, then the browser sends the following in its request header.
Cookie:name=value
See the HTTP Cookie article at Wikipedia for more information.
I am trying to send a Push notification to my android device with the new Firebase service.
I registered and setup an app, also I put all the code needed to receive notification in the android app.
Via the Firebase Console I can send a notification to my app and it is received and shown.
Now I want to write a java standalone server, to send a notification to ALL devices. This is my current code:
final String apiKey = "I added my key here";
URL url = new URL("https://fcm.googleapis.com/fcm/send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Authorization", "key=" + apiKey);
conn.setDoOutput(true);
String input = "{\"notification\" : {\"title\" : \"Test\"}, \"to\":\"test\"}";
OutputStream os = conn.getOutputStream();
os.write(input.getBytes());
os.flush();
os.close();
int responseCode = conn.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + input);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// print result
System.out.println(response.toString());
And this is the result that I am getting back from their servers:
{"multicast_id":6602141464107786356,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
Unfortunately, simply removing the "to" tag doesn't work, I am getting a code 400 returned then.
I read that I need to register the device, send the device id to the server and save it there and then loop over all registered devices on the server to send the message.
Isn't there an easier way, to just send a message to all devices, just like in the console?
Your help is really appreciated, since I have been trying to get this to work all day long =(
Regards,
Dustin
I don't believe this is possible. Instead, what I would suggest is register all devices to the same topic and then you can message all the devices at once. Here is the help documentation on this:
Send Topic Messages from the Server
https://firebase.google.com/docs/cloud-messaging/topic-messaging
This solution send Push notification to Firebase using Apache HttpClient:
HttpClient client = HttpClientBuilder.create().build();
HttpPost post = new HttpPost("https://fcm.googleapis.com/fcm/send");
post.setHeader("Content-type", "application/json");
post.setHeader("Authorization", "key=AIzaSyBSxxxxsXevRq0trDbA9mhnY_2jqMoeChA");
JSONObject message = new JSONObject();
message.put("to", "dBbB2BFT-VY:APA91bHrvgfXbZa-K5eg9vVdUkIsHbMxxxxxc8dBAvoH_3ZtaahVVeMXP7Bm0iera5s37ChHmAVh29P8aAVa8HF0I0goZKPYdGT6lNl4MXN0na7xbmvF25c4ZLl0JkCDm_saXb51Vrte");
message.put("priority", "high");
JSONObject notification = new JSONObject();
notification.put("title", "Java");
notification.put("body", "Notificação do Java");
message.put("notification", notification);
post.setEntity(new StringEntity(message.toString(), "UTF-8"));
HttpResponse response = client.execute(post);
System.out.println(response);
System.out.println(message);
Use below code to send push notifications to multiple devices :
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.google.android.gcm.server.Message;
import com.google.android.gcm.server.MulticastResult;
import com.google.android.gcm.server.Result;
import com.google.android.gcm.server.Sender;
public class PushNotifactionHelper {
public final static String AUTH_KEY_FCM = "your key ";
public final static String API_URL_FCM = "https://fcm.googleapis.com/fcm/send";
public static void sendPushNotification(List<String> deviceTokenList) {
Sender sender = new Sender(AUTH_KEY_FCM);
Message msg = new Message.Builder().addData("message", "Message body")
.build();
try {
MulticastResult result = sender.send(msg, deviceTokenList, 5);
for (Result r : result.getResults()) {
if (r.getMessageId() != null)
System.out.println("Push Notification Sent Successfully");
else
System.out.println("ErrorCode " + r.getErrorCodeName());
}
} catch (IOException e) {
System.out.println("Error " + e.getLocalizedMessage());
}
}
}
Note : use gcm.server.jar
Your JSON will be like this:
{
"registration_ids": [
"fcm token 1",
"fcm token 2",
"fcm token 3"
],
"data": {
"message": "msg"
},
"notification": {
"title": "App name",
"text": " your msg"
}
}
public void sendGroupPush(Context context, ArrayList tokenlist, String message) {
String msg = message;
String title = context.getString(R.string.app_name);
JSONArray regId = null;
JSONObject objData = null;
JSONObject data = null;
JSONObject notif = null;
try {
regId = new JSONArray();
for (int i = 0; i < tokenlist.size(); i++) {
regId.put(tokenlist.get(i));
}
data = new JSONObject();
data.put("message", message);
notif = new JSONObject();
notif.put("title", title);
notif.put("text", msg);
objData = new JSONObject();
objData.put("registration_ids", regId);
objData.put("data", data);
objData.put("notification", notif);
Log.e("!_#rj#_group_PASS:>", objData.toString());
} catch (JSONException e) {
e.printStackTrace();
}
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST, Constants.FCM_PUSH_GROUP_URL, objData,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.e("!_#rj#_##_SUCESS", response + "");
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("!_#rj#_##_Errors--", error + "");
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Authorization", "key=" + Constants.FCM_API_KEY);
params.put("Content-Type", "application/json");
Log.e("!_#rj#_##PUSH_headrers", "::> " + params);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(context);
int socketTimeout = 1000 * 60;// 60 seconds
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
jsObjRequest.setRetryPolicy(policy);
requestQueue.add(jsObjRequest);
}
public static String FCM_PUSH_URL = "https://fcm.googleapis.com/fcm/send";
Here I have very simple solution for sending push message group as well
individual
public class FCM {
final static private String FCM_URL = "https://fcm.googleapis.com/fcm/send";
/**
*
* Method to send push notification to Android FireBased Cloud messaging
Server.
* #param tokenId Generated and provided from Android Client Developer
* #param server_key Key which is Generated in FCM Server
#param message which contains actual information.
*
*/
static void send_FCM_Notification(String tokenId, String server_key, String
message){
try{
// Create URL instance.
URL url = new URL(FCM_URL);
// create connection.
HttpURLConnection conn;
conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
//set method as POST or GET
conn.setRequestMethod("POST");
//pass FCM server key
conn.setRequestProperty("Authorization","key="+server_key);
//Specify Message Format
conn.setRequestProperty("Content-Type","application/json");
//Create JSON Object & pass value
JSONObject infoJson = new JSONObject();
infoJson.put("title","Alankit");
infoJson.put("body", message);
JSONObject json = new JSONObject();
json.put("to",tokenId.trim());
json.put("notification", infoJson);
System.out.println("json :" +json.toString());
System.out.println("infoJson :" +infoJson.toString());
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(json.toString());
wr.flush();
int status = 0;
if( null != conn ){
status = conn.getResponseCode();
}
if( status != 0){
if( status == 200 ){
//SUCCESS message
BufferedReader reader = new BufferedReader(new
InputStreamReader(conn.getInputStream()));
System.out.println("Android Notification Response : " + reader.readLine());
}else if(status == 401){
//client side error
System.out.println("Notification Response : TokenId : " + tokenId + " Error occurred :");
}else if(status == 501){
//server side error
System.out.println("Notification Response : [ errorCode=ServerError ] TokenId : " + tokenId);
}else if( status == 503){
//server side error
System.out.println("Notification Response : FCM Service is Unavailable
TokenId : " + tokenId);
}
}
}catch(MalformedURLException mlfexception){
// Prototcal Error
System.out.println("Error occurred while sending push Notification!.." + mlfexception.getMessage());
}catch(Exception mlfexception){
//URL problem
System.out.println("Reading URL, Error occurred while sending push
Notification!.." + mlfexception.getMessage());
}
}
static void send_FCM_NotificationMulti(List<String> putIds2, String
tokenId,
String server_key, String message){
try{
// Create URL instance.
URL url = new URL(FCM_URL);
// create connection.
HttpURLConnection conn;
conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
//set method as POST or GET
conn.setRequestMethod("POST");
//pass FCM server key
conn.setRequestProperty("Authorization","key="+server_key);
//Specify Message Format
conn.setRequestProperty("Content-Type","application/json");
//Create JSON Object & pass value
JSONArray regId = null;
JSONObject objData = null;
JSONObject data = null;
JSONObject notif = null;
regId = new JSONArray();
for (int i = 0; i < putIds2.size(); i++) {
regId.put(putIds2.get(i));
}
data = new JSONObject();
data.put("message", message);
notif = new JSONObject();
notif.put("title", "Alankit Universe");
notif.put("text", message);
objData = new JSONObject();
objData.put("registration_ids", regId);
objData.put("data", data);
objData.put("notification", notif);
System.out.println("!_#rj#_group_PASS:>"+ objData.toString());
System.out.println("json :" +objData.toString());
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(objData.toString());
wr.flush();
int status = 0;
if( null != conn ){
status = conn.getResponseCode();
}
if( status != 0){
if( status == 200 ){
//SUCCESS message
BufferedReader reader = new BufferedReader(new
InputStreamReader(conn.getInputStream()));
System.out.println("Android Notification Response : " +
reader.readLine());
}else if(status == 401){
//client side error
System.out.println("Notification Response : TokenId : " + tokenId + "
Error occurred :");
}else if(status == 501){
//server side error
System.out.println("Notification Response : [ errorCode=ServerError ]
TokenId : " + tokenId);
}else if( status == 503){
//server side error
System.out.println("Notification Response : FCM Service is Unavailable
TokenId : " + tokenId);
}
}
}catch(MalformedURLException mlfexception){
// Prototcal Error
System.out.println("Error occurred while sending push Notification!.." +
mlfexception.getMessage());
}catch(IOException mlfexception){
//URL problem
System.out.println("Reading URL, Error occurred while sending push
Notification!.." + mlfexception.getMessage());
}catch (Exception exception) {
//General Error or exception.
System.out.println("Error occurred while sending push Notification!.." +
exception.getMessage());
}
}
}
Calling should be like that :
public class TestFCM {
static List<String> putIds;
public static void main(String[] args) {
//Just I am passed dummy information
// DeviceID's
String tokenId1 = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
String tokenId = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy";
String server_key ="<Server Key>" ;
String message = "Welcome alankit Push Service.";
putIds= new ArrayList<>();
putIds.add(tokenId1);
putIds.add(tokenId);
/* for Group*/
FCM.send_FCM_NotificationMulti(putIds,tokenId,server_key,message);
/*for indevidual*/
FCM.send_FCM_Notification( tokenId,server_key,message);
}
}
your code is perfect just recheck the registration id of the user whom you are sending the notification. In place of to use the users device regid.
It worked perfect for me.
Android client side code should be:
//subscribe_topic with name "ALL"
FirebaseMessaging.getInstance().subscribeToTopic("ALL");
Server side:
string json = "{\"to\": \"/topics/ALL\",\"data\": {\"message\": \"This is a Cloud Messaging Topic Message\",}}";
#Autowired
AndroidPushNotificationsService androidPushNotificationsService;
#RequestMapping(value = "/send", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<String> send() {
JSONObject body = new JSONObject();
// JsonArray registration_ids = new JsonArray();
// body.put("registration_ids", registration_ids);
body.put("to", "xxxxxxxxxxxxxxxxxxxjPwZpLgLpji_");
body.put("priority", "high");
// body.put("dry_run", true);
JSONObject notification = new JSONObject();
notification.put("body", "body string here");
notification.put("title", "title string here");
// notification.put("icon", "myicon");
JSONObject data = new JSONObject();
data.put("key1", "value1");
data.put("key2", "value2");
body.put("notification", notification);
body.put("data", data);
HttpEntity<String> request = new HttpEntity<>(body.toString());
CompletableFuture<FirebaseResponse> pushNotification = androidPushNotificationsService.send(request);
CompletableFuture.allOf(pushNotification).join();
try {
FirebaseResponse firebaseResponse = pushNotification.get();
if (firebaseResponse.getSuccess() == 1) {
log.info("push notification sent ok!");
} else {
log.error("error sending push notifications: " + firebaseResponse.toString());
}
return new ResponseEntity<>(firebaseResponse.toString(), HttpStatus.OK);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return new ResponseEntity<>("the push notification cannot be send.", HttpStatus.BAD_REQUEST);
}
you can get the classes from here: https://github.com/AndreiD/testingpushnotifications
The Use the below code to send push to multiple devices using FCM.
public void sendAndroidPush(String input) {
final String apiKey = ServerKey or legacyServerKey;
StringBuffer response = new StringBuffer();
try {
URL url = new URL("https://fcm.googleapis.com/fcm/send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Authorization", "key=" + apiKey);
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
os.write(input.getBytes());
os.flush();
os.close();
int responseCode = conn.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + input);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
} catch(Exception e) {
e.printStackTrace();
}
// print result
System.out.println(response.toString());
}
JSONArray devices = new JSONArray();
devices.put("Your Actual Device Token");
JSONObject payloadObj = new JSONObject();
try {
JSONObject notifyObj = new JSONObject();
notifyObj.put("title","Your Title");
notifyObj.put("text", "Your Text");
payloadObj.put("registration_ids",devices.toString());
payloadObj.put("notification",notifyObj.toString());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
sendAndroidPush(payloadObj.toString());
All you need is Firebase Server Key for authorization purpose.
You just have to write http client code, you can use any programming language for that purpose.
Check out this Github Repo.
It has complete Java Rest Client project for sending firebase push notification from java server.
I am successfully using this code to send HTTP requests with some parameters via GET method
void sendRequest(String request)
{
// i.e.: request = "http://example.com/index.php?param1=a¶m2=b¶m3=c";
URL url = new URL(request);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setInstanceFollowRedirects(false);
connection.setRequestMethod("GET");
connection.setRequestProperty("Content-Type", "text/plain");
connection.setRequestProperty("charset", "utf-8");
connection.connect();
}
Now I may need to send the parameters (i.e. param1, param2, param3) via POST method because they are very long.
I was thinking to add an extra parameter to that method (i.e. String httpMethod).
How can I change the code above as little as possible to be able to send paramters either via GET or POST?
I was hoping that changing
connection.setRequestMethod("GET");
to
connection.setRequestMethod("POST");
would have done the trick, but the parameters are still sent via GET method.
Has HttpURLConnection got any method that would help?
Is there any helpful Java construct?
Any help would be very much appreciated.
In a GET request, the parameters are sent as part of the URL.
In a POST request, the parameters are sent as a body of the request, after the headers.
To do a POST with HttpURLConnection, you need to write the parameters to the connection after you have opened the connection.
This code should get you started:
String urlParameters = "param1=a¶m2=b¶m3=c";
byte[] postData = urlParameters.getBytes( StandardCharsets.UTF_8 );
int postDataLength = postData.length;
String request = "http://example.com/index.php";
URL url = new URL( request );
HttpURLConnection conn= (HttpURLConnection) url.openConnection();
conn.setDoOutput( true );
conn.setInstanceFollowRedirects( false );
conn.setRequestMethod( "POST" );
conn.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty( "charset", "utf-8");
conn.setRequestProperty( "Content-Length", Integer.toString( postDataLength ));
conn.setUseCaches( false );
try( DataOutputStream wr = new DataOutputStream( conn.getOutputStream())) {
wr.write( postData );
}
Here is a simple example that submits a form then dumps the result page to System.out. Change the URL and the POST params as appropriate, of course:
import java.io.*;
import java.net.*;
import java.util.*;
class Test {
public static void main(String[] args) throws Exception {
URL url = new URL("http://example.net/new-message.php");
Map<String,Object> params = new LinkedHashMap<>();
params.put("name", "Freddie the Fish");
params.put("email", "fishie#seamail.example.com");
params.put("reply_to_thread", 10394);
params.put("message", "Shark attacks in Botany Bay have gotten out of control. We need more defensive dolphins to protect the schools here, but Mayor Porpoise is too busy stuffing his snout with lobsters. He's so shellfish.");
StringBuilder postData = new StringBuilder();
for (Map.Entry<String,Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
}
byte[] postDataBytes = postData.toString().getBytes("UTF-8");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
conn.setDoOutput(true);
conn.getOutputStream().write(postDataBytes);
Reader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
for (int c; (c = in.read()) >= 0;)
System.out.print((char)c);
}
}
If you want the result as a String instead of directly printed out do:
StringBuilder sb = new StringBuilder();
for (int c; (c = in.read()) >= 0;)
sb.append((char)c);
String response = sb.toString();
I couldn't get Alan's example to actually do the post, so I ended up with this:
String urlParameters = "param1=a¶m2=b¶m3=c";
URL url = new URL("http://example.com/index.php");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(urlParameters);
writer.flush();
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
writer.close();
reader.close();
I find HttpURLConnection really cumbersome to use. And you have to write a lot of boilerplate, error prone code. I needed a lightweight wrapper for my Android projects and came out with a library which you can use as well: DavidWebb.
The above example could be written like this:
Webb webb = Webb.create();
webb.post("http://example.com/index.php")
.param("param1", "a")
.param("param2", "b")
.param("param3", "c")
.ensureSuccess()
.asVoid();
You can find a list of alternative libraries on the link provided.
import java.net.*;
public class Demo{
public static void main(){
String data = "data=Hello+World!";
URL url = new URL("http://localhost:8084/WebListenerServer/webListener");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
con.getOutputStream().write(data.getBytes("UTF-8"));
con.getInputStream();
}
}
i have read above answers and have created a utility class to simplify HTTP request. i hope it will help you.
Method Call
// send params with Hash Map
HashMap<String, String> params = new HashMap<String, String>();
params.put("email","me#example.com");
params.put("password","12345");
//server url
String url = "http://www.example.com";
// static class "HttpUtility" with static method "newRequest(url,method,callback)"
HttpUtility.newRequest(url,HttpUtility.METHOD_POST,params, new HttpUtility.Callback() {
#Override
public void OnSuccess(String response) {
// on success
System.out.println("Server OnSuccess response="+response);
}
#Override
public void OnError(int status_code, String message) {
// on error
System.out.println("Server OnError status_code="+status_code+" message="+message);
}
});
Utility Class
import java.io.*;
import java.net.*;
import java.util.HashMap;
import java.util.Map;
import static java.net.HttpURLConnection.HTTP_OK;
public class HttpUtility {
public static final int METHOD_GET = 0; // METHOD GET
public static final int METHOD_POST = 1; // METHOD POST
// Callback interface
public interface Callback {
// abstract methods
public void OnSuccess(String response);
public void OnError(int status_code, String message);
}
// static method
public static void newRequest(String web_url, int method, HashMap < String, String > params, Callback callback) {
// thread for handling async task
new Thread(new Runnable() {
#Override
public void run() {
try {
String url = web_url;
// write GET params,append with url
if (method == METHOD_GET && params != null) {
for (Map.Entry < String, String > item: params.entrySet()) {
String key = URLEncoder.encode(item.getKey(), "UTF-8");
String value = URLEncoder.encode(item.getValue(), "UTF-8");
if (!url.contains("?")) {
url += "?" + key + "=" + value;
} else {
url += "&" + key + "=" + value;
}
}
}
HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
urlConnection.setUseCaches(false);
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); // handle url encoded form data
urlConnection.setRequestProperty("charset", "utf-8");
if (method == METHOD_GET) {
urlConnection.setRequestMethod("GET");
} else if (method == METHOD_POST) {
urlConnection.setDoOutput(true); // write POST params
urlConnection.setRequestMethod("POST");
}
//write POST data
if (method == METHOD_POST && params != null) {
StringBuilder postData = new StringBuilder();
for (Map.Entry < String, String > item: params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(URLEncoder.encode(item.getKey(), "UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(item.getValue()), "UTF-8"));
}
byte[] postDataBytes = postData.toString().getBytes("UTF-8");
urlConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
urlConnection.getOutputStream().write(postDataBytes);
}
// server response code
int responseCode = urlConnection.getResponseCode();
if (responseCode == HTTP_OK && callback != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
// callback success
callback.OnSuccess(response.toString());
reader.close(); // close BufferReader
} else if (callback != null) {
// callback error
callback.OnError(responseCode, urlConnection.getResponseMessage());
}
urlConnection.disconnect(); // disconnect connection
} catch (IOException e) {
e.printStackTrace();
if (callback != null) {
// callback error
callback.OnError(500, e.getLocalizedMessage());
}
}
}
}).start(); // start thread
}
}
I see some other answers have given the alternative, I personally think that intuitively you're doing the right thing ;). Sorry, at devoxx where several speakers have been ranting about this sort of thing.
That's why I personally use Apache's HTTPClient/HttpCore libraries to do this sort of work, I find their API to be easier to use than Java's native HTTP support. YMMV of course!
GET and POST method set like this... Two types for api calling 1)get() and 2) post() . get() method to get value from api json array to get value & post() method use in our data post in url and get response.
public class HttpClientForExample {
private final String USER_AGENT = "Mozilla/5.0";
public static void main(String[] args) throws Exception {
HttpClientExample http = new HttpClientExample();
System.out.println("Testing 1 - Send Http GET request");
http.sendGet();
System.out.println("\nTesting 2 - Send Http POST request");
http.sendPost();
}
// HTTP GET request
private void sendGet() throws Exception {
String url = "http://www.google.com/search?q=developer";
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(url);
// add request header
request.addHeader("User-Agent", USER_AGENT);
HttpResponse response = client.execute(request);
System.out.println("\nSending 'GET' request to URL : " + url);
System.out.println("Response Code : " +
response.getStatusLine().getStatusCode());
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
System.out.println(result.toString());
}
// HTTP POST request
private void sendPost() throws Exception {
String url = "https://selfsolve.apple.com/wcResults.do";
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url);
// add header
post.setHeader("User-Agent", USER_AGENT);
List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
urlParameters.add(new BasicNameValuePair("sn", "C02G8416DRJM"));
urlParameters.add(new BasicNameValuePair("cn", ""));
urlParameters.add(new BasicNameValuePair("locale", ""));
urlParameters.add(new BasicNameValuePair("caller", ""));
urlParameters.add(new BasicNameValuePair("num", "12345"));
post.setEntity(new UrlEncodedFormEntity(urlParameters));
HttpResponse response = client.execute(post);
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + post.getEntity());
System.out.println("Response Code : " +
response.getStatusLine().getStatusCode());
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
System.out.println(result.toString());
}
}
I had the same issue. I wanted to send data via POST.
I used the following code:
URL url = new URL("http://example.com/getval.php");
Map<String,Object> params = new LinkedHashMap<>();
params.put("param1", param1);
params.put("param2", param2);
StringBuilder postData = new StringBuilder();
for (Map.Entry<String,Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
}
String urlParameters = postData.toString();
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(urlParameters);
writer.flush();
String result = "";
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = reader.readLine()) != null) {
result += line;
}
writer.close();
reader.close()
System.out.println(result);
I used Jsoup for parse:
Document doc = Jsoup.parseBodyFragment(value);
Iterator<Element> opts = doc.select("option").iterator();
for (;opts.hasNext();) {
Element item = opts.next();
if (item.hasAttr("value")) {
System.out.println(item.attr("value"));
}
}
Try this pattern:
public static PricesResponse getResponse(EventRequestRaw request) {
// String urlParameters = "param1=a¶m2=b¶m3=c";
String urlParameters = Piping.serialize(request);
HttpURLConnection conn = RestClient.getPOSTConnection(endPoint, urlParameters);
PricesResponse response = null;
try {
// POST
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(urlParameters);
writer.flush();
// RESPONSE
BufferedReader reader = new BufferedReader(new InputStreamReader((conn.getInputStream()), StandardCharsets.UTF_8));
String json = Buffering.getString(reader);
response = (PricesResponse) Piping.deserialize(json, PricesResponse.class);
writer.close();
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
conn.disconnect();
System.out.println("PricesClient: " + response.toString());
return response;
}
public static HttpURLConnection getPOSTConnection(String endPoint, String urlParameters) {
return RestClient.getConnection(endPoint, "POST", urlParameters);
}
public static HttpURLConnection getConnection(String endPoint, String method, String urlParameters) {
System.out.println("ENDPOINT " + endPoint + " METHOD " + method);
HttpURLConnection conn = null;
try {
URL url = new URL(endPoint);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(method);
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "text/plain");
} catch (IOException e) {
e.printStackTrace();
}
return conn;
}
This answer covers the specific case of the POST Call using a Custom Java POJO.
Using maven dependency for Gson to serialize our Java Object to JSON.
Install Gson using the dependency below.
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
<scope>compile</scope>
</dependency>
For those using gradle can use the below
dependencies {
implementation 'com.google.code.gson:gson:2.8.5'
}
Other imports used:
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.*;
import org.apache.http.impl.client.CloseableHttpClient;
import com.google.gson.Gson;
Now, we can go ahead and use the HttpPost provided by Apache
private CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httppost = new HttpPost("https://example.com");
Product product = new Product(); //custom java object to be posted as Request Body
Gson gson = new Gson();
String client = gson.toJson(product);
httppost.setEntity(new StringEntity(client, ContentType.APPLICATION_JSON));
httppost.setHeader("RANDOM-HEADER", "headervalue");
//Execute and get the response.
HttpResponse response = null;
try {
response = httpclient.execute(httppost);
} catch (IOException e) {
throw new InternalServerErrorException("Post fails");
}
Response.Status responseStatus = Response.Status.fromStatusCode(response.getStatusLine().getStatusCode());
return Response.status(responseStatus).build();
The above code will return with the response code received from the POST Call
here i sent jsonobject as parameter //jsonobject={"name":"lucifer","pass":"abc"}//serverUrl = "http://192.168.100.12/testing" //host=192.168.100.12
public static String getJson(String serverUrl,String host,String jsonobject){
StringBuilder sb = new StringBuilder();
String http = serverUrl;
HttpURLConnection urlConnection = null;
try {
URL url = new URL(http);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setUseCaches(false);
urlConnection.setConnectTimeout(50000);
urlConnection.setReadTimeout(50000);
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Host", host);
urlConnection.connect();
//You Can also Create JSONObject here
OutputStreamWriter out = new OutputStreamWriter(urlConnection.getOutputStream());
out.write(jsonobject);// here i sent the parameter
out.close();
int HttpResult = urlConnection.getResponseCode();
if (HttpResult == HttpURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(new InputStreamReader(
urlConnection.getInputStream(), "utf-8"));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
Log.e("new Test", "" + sb.toString());
return sb.toString();
} else {
Log.e(" ", "" + urlConnection.getResponseMessage());
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if (urlConnection != null)
urlConnection.disconnect();
}
return null;
}
Hello pls use this class to improve your post method
public static JSONObject doPostRequest(HashMap<String, String> data, String url) {
try {
RequestBody requestBody;
MultipartBuilder mBuilder = new MultipartBuilder().type(MultipartBuilder.FORM);
if (data != null) {
for (String key : data.keySet()) {
String value = data.get(key);
Utility.printLog("Key Values", key + "-----------------" + value);
mBuilder.addFormDataPart(key, value);
}
} else {
mBuilder.addFormDataPart("temp", "temp");
}
requestBody = mBuilder.build();
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
OkHttpClient client = new OkHttpClient();
Response response = client.newCall(request).execute();
String responseBody = response.body().string();
Utility.printLog("URL", url);
Utility.printLog("Response", responseBody);
return new JSONObject(responseBody);
} catch (UnknownHostException | UnsupportedEncodingException e) {
JSONObject jsonObject=new JSONObject();
try {
jsonObject.put("status","false");
jsonObject.put("message",e.getLocalizedMessage());
} catch (JSONException e1) {
e1.printStackTrace();
}
Log.e(TAG, "Error: " + e.getLocalizedMessage());
} catch (Exception e) {
e.printStackTrace();
JSONObject jsonObject=new JSONObject();
try {
jsonObject.put("status","false");
jsonObject.put("message",e.getLocalizedMessage());
} catch (JSONException e1) {
e1.printStackTrace();
}
Log.e(TAG, "Other Error: " + e.getLocalizedMessage());
}
return null;
}
I higly recomend http-request built on apache http api.
For your case you can see example:
private static final HttpRequest<String.class> HTTP_REQUEST =
HttpRequestBuilder.createPost("http://example.com/index.php", String.class)
.responseDeserializer(ResponseDeserializer.ignorableDeserializer())
.build();
public void sendRequest(String request){
String parameters = request.split("\\?")[1];
ResponseHandler<String> responseHandler =
HTTP_REQUEST.executeWithQuery(parameters);
System.out.println(responseHandler.getStatusCode());
System.out.println(responseHandler.get()); //prints response body
}
If you are not interested in the response body
private static final HttpRequest<?> HTTP_REQUEST =
HttpRequestBuilder.createPost("http://example.com/index.php").build();
public void sendRequest(String request){
ResponseHandler<String> responseHandler =
HTTP_REQUEST.executeWithQuery(parameters);
}
For general sending post request with http-request: Read the documentation and see my answers HTTP POST request with JSON String in JAVA, Sending HTTP POST Request In Java, HTTP POST using JSON in Java
I took Boann's answer and used it to create a more flexible query string builder that supports lists and arrays, just like php's http_build_query method:
public static byte[] httpBuildQueryString(Map<String, Object> postsData) throws UnsupportedEncodingException {
StringBuilder postData = new StringBuilder();
for (Map.Entry<String,Object> param : postsData.entrySet()) {
if (postData.length() != 0) postData.append('&');
Object value = param.getValue();
String key = param.getKey();
if(value instanceof Object[] || value instanceof List<?>)
{
int size = value instanceof Object[] ? ((Object[])value).length : ((List<?>)value).size();
for(int i = 0; i < size; i++)
{
Object val = value instanceof Object[] ? ((Object[])value)[i] : ((List<?>)value).get(i);
if(i>0) postData.append('&');
postData.append(URLEncoder.encode(key + "[" + i + "]", "UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(val), "UTF-8"));
}
}
else
{
postData.append(URLEncoder.encode(key, "UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(value), "UTF-8"));
}
}
return postData.toString().getBytes("UTF-8");
}
For those having trouble receiving the request on a php page using $_POST because you expect key-value pairs:
While all the answers where very helpful, I lacked some basic understanding on which string actually to post, since in the old apache HttpClient I used
new UrlEncodedFormEntity(nameValuePairs); (Java)
and then could use $_POST in php do get the key-value pairs.
To my understanding now one has build that string manually before posting. So the string needs to look like
val data = "key1=val1&key2=val2"
but instead just adding it to the url it is posted (in the header).
The alternative would be to use a json-string instead:
val data = "{\"key1\":\"val1\",\"key2\":\"val2\"}" // {"key1":"val1","key2":"val2"}
and pull it in php without $_POST:
$json_params = file_get_contents('php://input');
// echo_p("Data: $json_params");
$data = json_decode($json_params, true);
Here you find a sample code in Kotlin:
class TaskDownloadTest : AsyncTask<Void, Void, Void>() {
override fun doInBackground(vararg params: Void): Void? {
var urlConnection: HttpURLConnection? = null
try {
val postData = JsonObject()
postData.addProperty("key1", "val1")
postData.addProperty("key2", "val2")
// reformat json to key1=value1&key2=value2
// keeping json because I may change the php part to interpret json requests, could be a HashMap instead
val keys = postData.keySet()
var request = ""
keys.forEach { key ->
// Log.i("data", key)
request += "$key=${postData.get(key)}&"
}
request = request.replace("\"", "").removeSuffix("&")
val requestLength = request.toByteArray().size
// Warning in Android 9 you need to add a line in the application part of the manifest: android:usesCleartextTraffic="true"
// https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted
val url = URL("http://10.0.2.2/getdata.php")
urlConnection = url.openConnection() as HttpURLConnection
// urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded") // apparently default
// Not sure what these are for, I do not use them
// urlConnection.setRequestProperty("Content-Type", "application/json")
// urlConnection.setRequestProperty("Key","Value")
urlConnection.readTimeout = 5000
urlConnection.connectTimeout = 5000
urlConnection.requestMethod = "POST"
urlConnection.doOutput = true
// urlConnection.doInput = true
urlConnection.useCaches = false
urlConnection.setFixedLengthStreamingMode(requestLength)
// urlConnection.setChunkedStreamingMode(0) // if you do not want to handle request length which is fine for small requests
val out = urlConnection.outputStream
val writer = BufferedWriter(
OutputStreamWriter(
out, "UTF-8"
)
)
writer.write(request)
// writer.write("{\"key1\":\"val1\",\"key2\":\"val2\"}") // {"key1":"val1","key2":"val2"} JsonFormat or just postData.toString() for $json_params=file_get_contents('php://input'); json_decode($json_params, true); in php
// writer.write("key1=val1&key2=val2") // key=value format for $_POST in php
writer.flush()
writer.close()
out.close()
val code = urlConnection.responseCode
if (code != 200) {
throw IOException("Invalid response from server: $code")
}
val rd = BufferedReader(
InputStreamReader(
urlConnection.inputStream
)
)
var line = rd.readLine()
while (line != null) {
Log.i("data", line)
line = rd.readLine()
}
} catch (e: Exception) {
e.printStackTrace()
} finally {
urlConnection?.disconnect()
}
return null
}
}
Now I had to do an HTTP request class, it is probably not the most efficient class, but it works.
I collected some codes from this page and made it more dynamic.
Anyone who needs a complete code, I attached it below.
For an example of how to use it, you can look at the main method.
Also, if you are willing to improve classes online, you are more than welcome to help me make this class better.
import java.net.*;
import java.util.*;
import java.nio.charset.*;
import java.io.*;
public class HttpRequest {
String result = "";
HttpRequest(String _url, String _method, Map<String, String> _postData, String _contentType) {
try {
URL url = new URL( _url );
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection)con;
http.setRequestMethod(_method); // PUT is another valid option
http.setDoOutput(true);
StringJoiner sj = new StringJoiner("&");
for(Map.Entry<String,String> entry : _postData.entrySet())
sj.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "=" + entry.getValue());
//sj.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "=" + URLEncoder.encode(entry.getValue()));
byte[] out = sj.toString().getBytes(StandardCharsets.UTF_8);
int length = out.length;
http.setFixedLengthStreamingMode(length);
http.setRequestProperty("Content-Type", _contentType);
http.setRequestProperty( "charset", "utf-8");
http.setRequestProperty( "Content-Length", Integer.toString( length ));
http.setInstanceFollowRedirects( false );
http.setUseCaches( false );
http.connect();
try(OutputStream os = http.getOutputStream()) {
os.write(out);
}
if (http.getResponseCode() == HttpURLConnection.HTTP_OK) {
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(http.getInputStream()))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
result = result + line;
}
}
} else {
System.out.println("Bad response!");
}
}catch (IOException e) {
// writing exception to log
e.printStackTrace();
}
}
HttpRequest(String _url, String _method, Map<String, String> _postData) {
this(_url, _method, _postData, "text/html");
}
HttpRequest(String _url, String _method) {
this(_url, _method, new HashMap<String, String>());
}
HttpRequest(String _url) {
this(_url, "GET");
}
public String toString() {
return result;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Map<String, String> postData = new HashMap<String, String>();
postData.putIfAbsent("email", "test#test.com");
postData.putIfAbsent("password", "test");
HttpRequest result = new HttpRequest("https://httpbin.org/anything", "POST", postData, "application/x-www-form-urlencoded");
System.out.println(result.toString());
}
}
Appears that you also have to callconnection.getOutputStream() "at least once" (as well as setDoOutput(true)) for it to treat it as a POST.
So the minimum required code is:
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//connection.setRequestMethod("POST"); this doesn't seem to do anything at all..so not useful
connection.setDoOutput(true); // set it to POST...not enough by itself however, also need the getOutputStream call...
connection.connect();
connection.getOutputStream().close();
You can even use "GET" style parameters in the urlString, surprisingly. Though that might confuse things.
You can also use NameValuePair apparently.
I have a following functionality: I create through the user form a new user. After i had submitted the entered data, created user get the bar-code, which would be used for get access to the other system section by scanning that bar-code with hand-scanner. So how can i get any value (in my case that bar-code from json calls (Post, Get, JSON) with Selenium WebDriver on Java?
Selenium has nothing to do with json. You can use Apache HttpClient library for sending GET, POST, PUT and DELETE requests and receiving the responses. Given below is a simplified function for all cases.
public static HttpResponse sendRequest(String requestType, String body,String url,
String... headers) throws Exception {
try {
HttpGet getRequest = null;
HttpPost postRequest;
HttpPut putRequest;
HttpDelete delRequest;
HttpResponse response = null;
HttpClient client = new DefaultHttpClient();
// Collecting Headers
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
for (String arg : headers) {
//Considering that you are applying header name and values in String format like this "Header1,Value1"
nvps.add(new BasicNameValuePair(arg.split(",")[0], arg
.split(",")[1]));
}
System.out.println("Total Headers Supplied " + nvps.size());
if (requestType.equalsIgnoreCase("GET")) {
getRequest = new HttpGet(url);
for (NameValuePair h : nvps) {
getRequest.addHeader(h.getName(), h.getValue());
}
response = client.execute(getRequest);
}
if (requestType.equalsIgnoreCase("POST")) {
postRequest = new HttpPost(url);
for (NameValuePair h : nvps) {
postRequest.addHeader(h.getName(), h.getValue());
}
StringEntity requestEntity = new StringEntity(body,"UTF-8");
postRequest.setEntity(requestEntity);
response = client.execute(postRequest);
}
if (requestType.equalsIgnoreCase("PUT")) {
putRequest = new HttpPut(url);
for (NameValuePair h : nvps) {
putRequest.addHeader(h.getName(), h.getValue());
}
StringEntity requestEntity = new StringEntity(body,"UTF-8");
putRequest.setEntity(requestEntity);
response = client.execute(putRequest);
}
if (requestType.equalsIgnoreCase("DELETE")) {
delRequest = new HttpDelete(url);
for (NameValuePair h : nvps) {
delRequest.addHeader(h.getName(), h.getValue());
}
response = client.execute(delRequest);
}
return response;
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
Selenium only deals with browsers.
Java has classes that do http requests.
see the code below:
private HttpURLConnection setODataConnection(String url, String method) {
try {
URL obj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
conn.setRequestMethod(method);
// add request header
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json;odata=verbose");
return conn;
} catch (Exception e) {
Assert.fail(e.getMessage());
return null;
}
}
private StringBuilder sendODataRequest(HttpURLConnection conn) {
try {
int responseCode = conn.getResponseCode();
String method = conn.getRequestMethod();
System.out.println("\nSending '" + method + "' request to URL : " + conn.getURL());
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return response;
} catch (Exception e) {
Assert.fail(e.getMessage());
return null;
}
}
private ArrayList<String> getByFullUrl(String fullUrl, String entity) {
HttpURLConnection conn = setODataConnection(fullUrl, "GET");
StringBuilder response = sendODataRequest(conn);
ArrayList<String> s = new ArrayList<String>();
Pattern p = Pattern.compile(entity + "\" : (.*?)\\}");
Matcher m = p.matcher(response);
while (m.find()) {
s.add(m.group(1).replace("\"", ""));
}
return s;
}
public ArrayList<String> get(String table, String entity) {
String url = oDataUrl + table + "?$select=" + entity;
return getByFullUrl(url, entity);
}
public void post(String table, String bodyDetails) {
String url = oDataUrl + table;
HttpURLConnection conn = setODataConnection(url, "POST");
conn.setDoOutput(true);
try {
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes("details={" + bodyDetails + "}");
wr.flush();
wr.close();
} catch (Exception e) {
Assert.fail(e.getMessage());
}
sendODataRequest(conn);
}
public void put(String table, String id, String bodyDetails) {
String url = oDataUrl + table + "(" + id + ")";
HttpURLConnection conn = setODataConnection(url, "PUT");
conn.setDoOutput(true);
try {
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes("details={" + bodyDetails + "}");
wr.flush();
wr.close();
} catch (Exception e) {
Assert.fail(e.getMessage());
}
sendODataRequest(conn);
}