Kindly don't confuse my question with sending body with POST request using HttpURLConnection.
I want to send body with GET request using HttpURLConnection. Here is code i am using.
public static String makeGETRequest(String endpoint, String encodedBody) {
String responseJSON = null;
URL url;
HttpURLConnection connection;
try {
url = new URL(endpoint);
connection = (HttpURLConnection) url.openConnection();
connection.setInstanceFollowRedirects(true);
connection.setDoOutput(true);
connection.setRequestMethod("GET");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.connect();
OutputStream outputStream = connection.getOutputStream();
outputStream.write(encodedBody.getBytes());
outputStream.flush();
Util.log(connection,connection.getResponseCode()+":"+connection.getRequestMethod());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String responseChunk = null;
responseJSON = "";
while ((responseChunk = bufferedReader.readLine()) != null) {
responseJSON += responseChunk;
}
bufferedReader.close();
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
Util.log(e, e.getMessage());
}
return responseJSON;
}
what happens is that the request type is identified automatically depending on the connection.getInputStream() and connection.getOutPutStream().
when you call connection.getOutPutStream() the request type is automatically set to POST even if you have explicitly set request type to GET using connection.setRequestMethod("GET").
The problem is that i am using 3rd party Web Service(API) which accepts request parameters as body with GET request
<get-request>
/myAPIEndPoint
body = parameter1=value as application/x-www-form-urlencoded
<response>
{json}
I am well aware that most of the case GET don't have request body but many of the web service often uses GET request with parameters as body instead of query string. Kindly guide me how i can send GET request with body in android without using any 3rd party library(OkHttp,Retrofit,Glide etc)
use this code you will need to do a little modification but it will get the job done.
package com.kundan.test;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
public class GetWithBody {
public static final String TYPE = "GET ";
public static final String HTTP_VERSION = " HTTP/1.1";
public static final String LINE_END = "\r\n";
public static void main(String[] args) throws Exception {
Socket socket = new Socket("localhost", 8080); // hostname and port default is 80
OutputStream outputStream = socket.getOutputStream();
outputStream.write((TYPE + "<Resource Address>" + HTTP_VERSION + LINE_END).getBytes());//
outputStream.write(("User-Agent: Java Socket" + LINE_END).getBytes());
outputStream.write(("Content-Type: application/x-www-form-urlencoded" + LINE_END).getBytes());
outputStream.write(LINE_END.getBytes()); //end of headers
outputStream.write(("parameter1=value¶meter2=value2" + LINE_END).getBytes()); //body
outputStream.flush();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
StringBuilder builder = new StringBuilder();
String read = null;
while ((read = bufferedReader.readLine()) != null) {
builder.append(read);
}
String result = builder.toString();
System.out.println(result);
}
}
this the Raw HTTP Request Dump
GET <Resource Address> HTTP/1.1
User-Agent: Java Socket
Content-Type: application/x-www-form-urlencoded
parameter1=value¶meter2=value2
Note : This is for http request if you want https Connection Please refer to the link SSLSocketClient
Related
I'm trying to access FCM from my server app. Checked the example provided into here! But getting error:
java.io.IOException: Server returned HTTP response code: 400 for URL: https://fcm.googleapis.com/v1/projects/unsaarmdm/messages:send
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1627)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at asd.MessagesClientFCMServer.sendMessageToFcm(MessagesClientFCMServer.java:66)
at asd.MessagesClientFCMServer.sendData(MessagesClientFCMServer.java:40)
at asd.MessagesClientFCMServer.main(MessagesClientFCMServer.java:37)
I've already created the firebase project called "unsaarmdm" and downloaded the json file that contains the private key. Also added the Google API Client library into my project.
Below is the code snippets:
private static String FCM_DEALS_ENDPOINT
= "https://fcm.googleapis.com/v1/projects/unsaarmdm/messages:send";
//https://fcm.googleapis.com/v1/projects/unsaarmdm/messages:send
public static void main(String args[]) {
MessagesClientFCMServer fcmClient = new MessagesClientFCMServer();
fcmClient.sendData();
}
private void sendData(){
sendMessageToFcm(getFcmMessageJSONData());
}
//Using HttpURLConnection it send http post request containing data to FCM server
private void sendMessageToFcm(String postData) {
try {
HttpURLConnection httpConn = getConnection();
DataOutputStream wr = new DataOutputStream(httpConn.getOutputStream());
wr.writeBytes(postData);
wr.flush();
wr.close();
BufferedReader in = new BufferedReader(
new InputStreamReader(httpConn.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
log.info(response.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
private static String getAccessToken() throws IOException {
GoogleCredential googleCredential = GoogleCredential
.fromStream(new FileInputStream("C:/dev/Firebase_private_key/unsaarmdm-firebase-adminsdk.json"))
.createScoped(Arrays.asList(SCOPE));
googleCredential.refreshToken();
String token = googleCredential.getAccessToken();
return token;
}
//create HttpURLConnection setting Authorization token
//and Content-Type header
private HttpURLConnection getConnection() throws Exception {
URL url = new URL(FCM_DEALS_ENDPOINT);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("Authorization", "Bearer " + getAccessToken());
httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
httpURLConnection.setDoOutput(true);
httpURLConnection.setUseCaches(false);
httpURLConnection.setRequestMethod("POST");
httpURLConnection.connect();
return httpURLConnection;
}
The url looks more like https://fcm.googleapis.com/fcm/send
This is a weird part, I'm aware the docs say to use the URL you are using, but I have a working implementation (and I know I spent some time debbuging this) with the URL i just mentioned, try and let me know :) we all can learn.
Make sure you include the server key into the Authorization header (which it seems you are doing ok).
I'm making the HTTP GET request from a basic java program to a URL which happens to be "http://localhost:9992/users/john.doe#example.com":
public class Tester {
public static void main(String[] args) {
HttpRequester.doesUserExist("john.doe#example.com");
}
}
The implementation of the HTTPRequester is this:
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpRequester {
private static HttpURLConnection connection = null;
public static boolean doesUserExist(final String email) {
final String targetUrl = Constants.URL_USER_SRVC + email;
System.out.println(targetUrl);
try {
URL url = new URL(targetUrl);
connection = (HttpURLConnection) url.openConnection();
System.out.println(connection.getRequestMethod());
connection.setRequestMethod("GET");
connection.setRequestProperty("Content-Type", "application/json");
connection.setUseCaches(false);
connection.setDoOutput(true);
DataOutputStream outputStream = new DataOutputStream(
connection.getOutputStream());
outputStream.writeBytes(email);
outputStream.close();
InputStream inputStream = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuffer response = new StringBuffer();
String line;
while((line = reader.readLine()) != null) {
response.append(line);
response.append('\r');
}
reader.close();
System.out.println(response.toString());
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
The webservice embedded in a Grizzly server and here are the APIs:
#Path("/users")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public class UserResource {
#GET
public List<User> getUsers() {
return UserService.getUsers();
}
#GET
#Path("/{userEmail}")
public User getUser(#PathParam("userEmail") String userEmail) {
return UserService.getUser(userEmail);
}
}
Please take note that the webservice and java program are two separate projects. When I execute the main method I get this error output in the console:
java.io.IOException: Server returned HTTP response code: 405 for URL: http://localhost:9992/users/john.doe#example.com
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1627)
at com.axa.visualizr.auth.utils.HttpRequester.doesUserExist(HttpRequester.java:30)
at com.axa.visualizr.auth.core.Tester.main(Tester.java:8)
What I think is odd is that the error outputs this at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1627) even though I imported java.net.HttpURLConnection;. I have tried opening the declaration on that line but Eclipse states that it is not an valid line number in that class.
I don't know why it's saying that the method is not allowed when I have setRequestMethod("GET"). Maybe it might be because the java program is not running on any kind of server? The Tester.java is only for testing purposes eventually I will move HTTPRequester to another webservice and make the call from webservice A to webservice B.
Since you are passing something in the requestbody, java is interpreting it as a POST request. Please remove below lines from your code and try:
DataOutputStream outputStream = new DataOutputStream(
connection.getOutputStream());
outputStream.writeBytes(email);
outputStream.close();
Try below code:
final String targetUrl = Constants.URL_USER_SRVC + URLEncoder.encode(email, "UTF-8");
instead of: final String targetUrl = Constants.URL_USER_SRVC + email;
How come I am only allowed to make posts to .com url's but not .asmx url's? Im a bit confused as what I want to generally do is send xml content to a .asmx url web service eventually. Can anyone supply me with tips why this doesn't work, and how I can post to a .asmx file?
public class POSTSenderExample {
public String echoCuties(String query) throws IOException {
// Encode the query
String encodedQuery = URLEncoder.encode(query, "UTF-8");
// This is the data that is going to be send to itcuties.com via POST request
// 'e' parameter contains data to echo
String postData = "e=" + encodedQuery;
URL url = new URL("http://echo.itgeeeks.asmx");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length", String.valueOf(postData.length()));
// Write data
OutputStream os = connection.getOutputStream();
os.write(postData.getBytes());
// Read response
StringBuilder responseSB = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ( (line = br.readLine()) != null)
responseSB.append(line);
// Close streams
br.close();
os.close();
return responseSB.toString();
}
// Run this example
public static void main(String[] args) {
try {
System.out.println(new POSTSenderExample().echoCuties("Hi there!"));
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
Using "POST" is correct.
Instead of calling
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
you have to call
connection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
(if you are using utf-8 encoding which is probably the case).
You also have to set the SOAP Action in the http- Header:
connection.setRequestProperty("SOAPAction", SOAPAction);
You can find the SOAP Action eihter in the wsdl- file. What I did to find out all expected Parameters: I used a working WS Client, and traced the TCP traffic in order to find out the expected HTTP headers.
I have written a code for my swing application to login, i'm supposed to get flag as response from the web service as json format, the trouble I'm facing is that when I post the data I'm getting bad 400 request if I set the certain headers or 500 internal server error if the headers are not set.
Connection Class
public class Connection extends Thread {
private String url1;
private JSONObject data;
String line;
//Constuctor to initialize the variables.
public Connection(String url1, JSONObject data) {
this.url1 = url1;
this.data = data;
start();
}
public void run() {
ConnectionReaderWriter();
}
//To fetch the data from the input stream
public String getResult() {
return line;
}
public String ConnectionReaderWriter() {
URL url;
HttpURLConnection connection = null;
ObjectOutputStream out;
try {
/*URL url = new URL(Url.server_url + url1); //Creating the URL.
URLConnection conn = url.openConnection(); //Opening the connection.
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data); //Posting the data to the ouput stream.
wr.flush();
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
line=rd.readLine(); //Reading the data from the input stream.
wr.close();
rd.close();*/
url = new URL(Url.server_url + url1); //Creating the URL.
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
// Headers
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Accept", "application/json");
// API key has to be passed
connection.setRequestProperty("api_key", "123456");
connection.setUseCaches(false);
//System.out.println(connection.getRequestProperty("api_key"));
connection.setDoInput(true);
connection.setDoOutput(true);
//Send request
out = new ObjectOutputStream(connection.getOutputStream());
out.write(data.toString().getBytes());
out.flush();
System.out.println(data.toString());
int rescode = connection.getResponseCode();
line = connection.getResponseMessage();
System.out.println(line +" : "+ rescode);
BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
line = rd.readLine(); //Reading the data from the input stream.
rd.close();
out.close();
System.out.println("fsgjv: ");
} catch (MalformedURLException ex) {
Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
String nonet = "No Network Connection";
line = nonet;
} catch (IOException ex) {
Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
String nonet = "No Server Connection";
line = nonet;
}
return line; //Return te stream recived from the input stream.
}
}
The error generated is given below.
{"username":"ann.jake#gmail.com","password":"123"}
Bad Request : 400
Jan 20, 2014 6:00:04 PM SupportingClass.Connection ConnectionReaderWriter
SEVERE: null
java.io.IOException: Server returned HTTP response code: 400 for URL: http://192.168.10.241/MobpazAdmin/web/app_dev.php/ws/terminalusers/terminaluserlogins.json
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at sun.net.www.protocol.http.HttpURLConnection$6.run(HttpURLConnection.java:1674)
at sun.net.www.protocol.http.HttpURLConnection$6.run(HttpURLConnection.java:1672)
at java.security.AccessController.doPrivileged(Native Method)
at sun.net.www.protocol.http.HttpURLConnection.getChainedException(HttpURLConnection.java:1670)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1243)
at SupportingClass.Connection.ConnectionReaderWriter(Connection.java:81)
at SupportingClass.Connection.run(Connection.java:40)
Caused by: java.io.IOException: Server returned HTTP response code: 400 for URL: http://192.168.10.241/MobpazAdmin/web/app_dev.php/ws/terminalusers/terminaluserlogins.json
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1625)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468)
at SupportingClass.Connection.ConnectionReaderWriter(Connection.java:78)
... 1 more
Please tell me if i have made any mistake in the code, I have checked the server side code it is working properly. the data that is to be passed is json object given below
{"username":"ann.jake#gmail.com","password":"123"}
The problem has to be coming from the server because it is returning a status code 400. Can you check the server logs to find any more info?
I change this method of access now i'm using a Httpget to achieve same. You have to download the corresponding httpcomponents-client jar file and add it to the library. The code to use is given below
data = URLEncoder.encode("searchvariable", "UTF-8") + "=" + URLEncoder.encode("name", "UTF-8");
HttpGet g = new HttpGet(Url.server_url + url1+"?"+data);
Data is the parameters to be passed along with the URL. The issue happened due to the wrong method of access.
I have something I am trying to achieve.
I have a web application running on my localhost on port 8080.
I have a HTTP Server running on localhost:9005.
I have a JSP form that passes info to a servlet java class, that in turn performs the HTTP post to the URL on the HTTP Server localhost:9010 with the data string.
What I need to do is perform the POST and GET as part of the same connection. I have them working as two separate calls, but not on the same connection. It needs to be the same connection, as I post data, the HTTP Server takes this data, processes it and outputs unique data to this URL. Therefore the GET needs to be part of the same connection as he POST.
Can anyone please help?
This is my Process Request java code:
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.List;
import java.util.Map.Entry;
public class ProcessRequest {
public void sendRequestToGateway() throws Throwable{
String message = URLEncoder.encode("OP1387927", "UTF-8");
try {
URL url = new URL("http://localhost:9005/json");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
writer.write("operator=" + message);
writer.close();
System.out.println("connection.getResponseCode() : " + connection.getResponseCode());
System.out.println("connection.getResponseMessage()" + connection.getResponseMessage());
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
receiveMessageFromGateway();
} else {
// Server returned HTTP error code.
}
//receiveMessageFromGateway();
} catch (MalformedURLException e) {
// ...
} catch (IOException e) {
// ...
}
}
public void receiveMessageFromGateway() throws Throwable {
HttpURLConnection client = null;
OutputStreamWriter wr = null;
BufferedReader rd = null;
StringBuilder sb = null;
String line = null;
try {
URL url = new URL("http://localhost:9005/json");
client = (HttpURLConnection) url.openConnection();
client.setRequestMethod("GET");
client.setDoOutput(true);
client.setReadTimeout(10000);
client.connect();
System.out.println(" *** headers ***");
for (Entry<String, List<String>> headernew : client.getHeaderFields().entrySet()) {
System.out.println(headernew.getKey() + "=" + headernew.getValue());
}
System.out.println(" \n\n*** Body ***");
rd = new BufferedReader(new InputStreamReader(client.getInputStream()));
sb = new StringBuilder();
while ((line = rd.readLine()) != null) {
sb.append(line + '\n');
}
System.out.println("body=" + sb.toString());
} finally {
client.disconnect();
rd = null;
sb = null;
wr = null;
}
}
}
Why don't you just return the result from the original POST?
In general you can't control connection reuse with HttpUrlConnection. You might be able to cast your connection to the specific implementation class and interfere with it but that's a horribly unstable way of doing it.
Apache HttpClient is probably a better option, given the requirements.
You can use Apache HTTP Client for this. Its very simple.
If you are using maven, just add the following lines into your POM file:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.3</version>
</dependency>
In this example, I'm submitting a POST request and after that a GET request.
Take a look:
public static String get(String p_url) throws IOException
{
CloseableHttpClient httpclient = HttpClients.createDefault();
// First request: POST
HttpPost httpPost = new HttpPost("http://the-api-url.com/Login/Auth&token=12345"));
CloseableHttpResponse response_post = httpclient.execute(httpPost);
System.out.println(response_post.getStatusLine());
HttpEntity entity_post = response_post.getEntity();
System.out.println(EntityUtils.toString(entity_post));
// Second request: GET
HttpGet httpGet = new HttpGet(p_url);
CloseableHttpResponse response_get = httpclient.execute(httpGet);
System.out.println(response_get.getStatusLine());
HttpEntity entity_get = response_get.getEntity();
System.out.println(EntityUtils.toString(entity_get));
response_post.close();
response_get.close();
return EntityUtils.toString(entity_get);
}