getting filenotfoundexception while sending json data using java - java

I am trying to send json data to Influx db using following code:
String url = "http://xx.x.xx.xx:8086/db/monitoring/check_1113?u=root&p=root";
URL obj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
conn.setRequestMethod("PUT");
//String userpass = "user" + ":" + "pass";
//String basicAuth = "Basic " + javax.xml.bind.DatatypeConverter.printBase64Binary(userpass.getBytes("UTF-8"));
//conn.setRequestProperty ("Authorization", basicAuth);
//String data = "{\"format\":\"json\",\"pattern\":\"#\"}";
System.out.println("Data to send: "+"[{\"name\": \"check_222\",\"columns\": [\"time\", \"sequence_number\", \"value\"],\"points\": [["+unixTime+", 1, \"122\"]]}]");
String data = "[{\"name\": \"check_333\",\"columns\": [\"time\", \"sequence_number\", \"value\"],\"points\": [["+14444444444+", 1, \"122\"]]}]";
OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
out.write(data);
out.close();
new InputStreamReader(conn.getInputStream());
System.out.println("Data Sent");
Where xx.xx.xx.xx is the ip of server where influx is deployed and i am using the Ip.
When i do a manual curl with this data (on localhost), the data is sent successfully. curl is provided below:
curl -X POST -d '[{"name": "check_223","columns": ["time", "sequence_number", "value"],"points": [[1445271004000,1,70.8880519867]]}]' 'http://localhost:8086/db/monitoring/series?u=root&p=root'
But when I run the code to send the data via the java program shared above, i get following error:
java.io.FileNotFoundException: http://xx.x.xx.xx:8086/db/monitoring/check_1113?u=root&p=root
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1834)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1439)
at com.snapdeal.hadoop.monitoring.hdfs1.App.sendJsonDataToInflux(App.java:52)
at com.snapdeal.hadoop.monitoring.hdfs1.App.main(App.java:89)
[INFO - 2015-10-20T16:27:13.152Z] ShutdownReqHand - _handle - About to shutdown
And to add to it, I am using phantomJS to get the data from web page and pass that data in the JSON request. But for simplicity I have hard-coded it at present.

This should be relatively obvious. A 405 indicates that the HTTP Method on the request is not supported by the endpoint. The service you are calling does not support a PUT method.

Related

Java doesn't send HTTP POST Request

I'm implementing some simple java class in order to send an HTTP Request with POST method and also another java class in order to receive it.
The server works fine when I make a POST request by means of my browser(Chrome), or an application(I have used Postman in this case) but it ends up with problem when I send HTTP Request with java!
My sending HTTP class is "Sender.java", containing the following snippet:
String url = "http://localhost:8082/";
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// Setting basic post request
con.setRequestMethod("POST");
//con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
//con.setRequestProperty("Content-Type","text/plain");
// Send post request
con.setDoOutput(true);
OutputStream os = con.getOutputStream();
os.write("Just Some Text".getBytes("UTF-8"));
os.flush();
os.close();
//connect to the Server(resides at Server.java)
con.connect();
I have commented some lines of code setting Headers like "Accept-Language" and "Content-Type" because I don't know whether or not are these headers required for the java program to work out?
The server is another java program named "Server.java". Here is the snippet related to reading HTTP Request made by the Sender.java(if need be).
int servPort = 8082;
// Create a server socket to accept HTTP client connection requests
HttpServer server = HttpServer.create(new InetSocketAddress(servPort), 0);
System.out.println("server started at " + servPort);
server.createContext("/", new PostHandler());//PostHandler implements HttpHandler
server.setExecutor(null);
server.start();
All I want is to send a plaintext as the body of my HTTP Request with the Post method. I have read plenty of sites and even related questions at this site. But it still doesn't work out. In other words, whenever I create an HTTP Request from "Sender.java", nothing appears at "Server.java". I just want to know what's wrong with my snippets and how should I fix that?
I tested this and it's working:
//Sender.java
String url = "http://localhost:8082/";
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
OutputStream os = con.getOutputStream();
os.write("Just Some Text".getBytes("UTF-8"));
os.flush();
int httpResult = con.getResponseCode();
con.disconnect();
As you can see, connect is not necessary. The key line is
int httpResult = con.getResponseCode();
When you send a POST form using the browser, it sends the form in a certain format, defined in RFC1866, you have to recreate this on Java when making a post request.
With this format, its important you set the Content-Type header to application/x-www-form-urlencoded, and pass the body as you would do in a url with a get request.
Borrowing some code of my previous answer to POST in Java:
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// Setting basic post request
con.setRequestMethod("POST");
Map<String,String> form = new HashMap<>();
// Define the fields
form.put("username", "root");
form.put("password", "sjh76HSn!"); // This is a fake password obviously
// Build the body
StringJoiner sj = new StringJoiner("&");
for(Map.Entry<String,String> entry : arguments.entrySet())
sj.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "="
+ URLEncoder.encode(entry.getValue(), "UTF-8"));
byte[] out = sj.toString().getBytes(StandardCharsets.UTF_8);
int length = out.length;
// Prepare our `con` object
con.setFixedLengthStreamingMode(length);
con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
con.connect();
try (OutputStream os = con.getOutputStream()) {
os.write(out);
}
Maybe “localhost” in the sender url does not resolve to the same ip that the server binds to? Try changing to 127.0.0.1 or your actual IP address.
try with PrintStream
String url = "http://localhost:8082/";
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// Setting basic post request
con.setRequestMethod("POST");
//con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
//con.setRequestProperty("Content-Type","text/plain");
// Send post request
con.setDoOutput(true);
OutputStream os = con.getOutputStream();
java.io.PrintStream printStream = new java.io.PrintStream(os);
printStream.println("Just Some Text");
con.getInputStream();//Send request
os.flush();
os.close();

What is format to send a response to an HttpURLConnection.getInputStream() and avoid "Invalid Http Response"?

My server sends a response to an HTTPUrlConnection in this manner:
ServerSocket servSok = new ServerSocket(portNmb);
Socket sok = servSok.accept();
processTheIncomingData(sok.getInputStream());
Writer wrtr = new OutputStreamWriter(sok.getOutputStream());
wrtr.write("<html><body>123 Hello World</body></html>"); // <------- format?
wrtr.flush();
the client
HttpURLConnection conn = (HttpUTLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setDoOutput(true);
conn.setDoInput(true);
sendSomeData(conn.getOutputStream());
String mssg = conn.getResponseMessage(); // <----- Invalid Http Response
conn.getResponseCode() also gives the same "Invalid http response."
I agree with #JBNizet. HTTP is a very complex protocol. You should use a server.
But if you are writing this for a toy project, here is some code to get you started.
Do not use any of this in production :)
String content = "<html><body>123 Hello World</body></html>";
Writer wrtr = new OutputStreamWriter(sok.getOutputStream());
wrtr.write("HTTP/1.1 200 OK\n");
wrtr.write("Content-Type: text/html; charset=UTF-8\n");
//assuming content is pure ascii
wrtr.write("Content-Length: " + content.length() + "\n");
wrtr.write("Connection: close\n\n");
wrtr.write(content);
wrtr.flush();
//then close the connection, do not reuse the connection
//as you might not have consumed the full request content

Calling third party REST API with curl in Java

I want to call this curl command to get list of applicant names from Java in JSON
curl -u uname:pass my_REST_Endpoint_provided_by_vendor
here is my code:
URL myURL = new URL("url");
HttpURLConnection conn = (HttpURLConnection) myURL.openConnection();
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
conn.setRequestMethod("PUT");
String basicAuth = "Basic " + javax.xml.bind.DatatypeConverter.printBase64Binary(unamepass.getBytes("UTF-8"));
conn.setRequestProperty ("Authorization", basicAuth);
int code = conn.getResponseCode(); // 200 = HTTP_OK
System.out.println("Response (Code):" + code);
System.out.println("Response (Message):" + conn.getResponseMessage());
If I run this command on my command prompt it runs fine and gives me the output but if I run this code I get Response (Code):405
java.io.IOException: Server returned HTTP response code: 405 for URL:
Where am I going wrong?
You are getting an 405 error because you are using the HTTP Method PUT instead of GET, which is used by curl by default. Remove the line:
conn.setRequestMethod("PUT");

Java - How to send form-data or www-form-urlencoded data over an HttpUrlConnection

I am attempting to use a REST API that only supports passing JSON data through the form-data or www-form-urlencoded attributes. So, my question is, how do I use an HttpUrlConnection to attach multiple form data items? When I use the API through the browser the request looks like this in Chrome:
Form Data
adds:
updates: [{"attributes":{"OBJECTID":2241,"OTHER_FIELD":"500"}}]
deletes:
gdbVersion:
rollbackOnFailure:
f: pjson
But I can't figure out how to replicate this in Java.
This is what I've tried so far:
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setUseCaches(false);
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
urlConnection.addRequestProperty("f", "json");
urlConnection.addRequestProperty("adds", null);
urlConnection.addRequestProperty("updates", "[{\"attributes\":{\"OBJECTID\":2241,\"OTHER_FIELD\":\"500\"}}]");
urlConnection.addRequestProperty("deletes", null);
urlConnection.addRequestProperty("rollbackOnFailure", "true");
urlConnection.addRequestProperty("gdbVersion", null);
But it doesn't attach the data as it should...
To those interested I am trying to connect to an ArcGIS feature service API so that I can add, update, or delete features but here I am using ApplyEdits
So I figured out how to solve this and here is the solution:
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
First set the request to be a POST request and that there will be some output
StringBuilder encodedUrl = new StringBuilder("adds=" + URLEncoder.encode("[{\"attributes\":{\"OBJECTID\":2241,\"MAXIMOID_PRE\":\"HYD\"}}]", "UTF-8"));
encodedUrl.append("&updates=" + URLEncoder.encode("", "UTF-8"));
encodedUrl.append("&deletes=" + URLEncoder.encode("", "UTF-8"));
encodedUrl.append("&f=" + URLEncoder.encode("json", "UTF-8"));
encodedUrl.append("&rollbackOnFailure=" + URLEncoder.encode("true", "UTF-8"));
encodedUrl.append("&gdbVersion=" + URLEncoder.encode("", "UTF-8"));
This is how each of the form-data values gets set. Each key value is just a java string and then the value is encoded using the URLEncoder.encode. Using this string that has all of the form-data elements we then write it to the outputstream:
final BufferedWriter bfw = new BufferedWriter(new OutputStreamWriter(urlConnection.getOutputStream()));
bfw.write(encodedUrl);
bfw.flush();
bfw.close();
Then after that the response can be received and parsed out.

Java HttpsURLConnection reuse

What am I trying to achieve:
I have a piece of Java code that's meant to connect to a web server in HTTPS. I want to use JVM's built-in HttpsURLConnection only. The intention is to keep the http connection open for an authenticated user and keep sending and receiving GET/POST requests. Once authenticated, all GET/POST requests will have the same PHP session ID I received from piece of php code at the web server. That PHP is actually the one that takes in the requests from my java app, processes (DB handling) and outputs in XML to my client for my better data handling.
The Problem:
I need to keep the same HttpsURLConnection open for the URL (since all requests are going to the same documentroot) and keep changing the parameters in the GET as I move along the client application. But as HTTP is intended to serve only one request at a time, I do not get to resend data without reinitializing the HttpsURLConnection. In that case, my session ID gets changed (because of obvious reasons of new HTTP connection) and I end up nowhere. Below is the piece of code I crafted out of my main app to clarify what I did (please disregard braces close):
try{
URL url = new URL("https://localhost:8443/?type=login&username=testu&password=testp");
HttpsURLConnection conn = (HttpsURLConnection)(url).openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("Connection","Keep-Alive");
System.out.println("Connecting...");
conn.connect();
System.out.println("Response: " + conn.getResponseCode());
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
System.out.println("" + in.readLine());
url = new URL("https://localhost:8443/?type=login&username=testu1&password=testp1");
conn = (HttpsURLConnection)url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream()));
System.out.println("Connecting..." + conn.getRequestMethod());
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
System.out.println("Response: " + conn.getResponseCode());
System.out.println("" + in.readLine());
System.out.println("" + conn.getHeaderFields());
} catch (MalformedURLException ex) {
System.out.println(ex);
} catch (IOException ex) {
System.out.println(ex);
}
}
Sample output from above code:
Connecting...
Response: 200
fipfk4pq0ov68bssicug3pv0d3testu
Connecting...POST
Response: 200
hqe9j1kmbdc98f5q1g2vkepb11testu1
Query:
Is it possible to keep my HttpsURLConnection still pointing to the same URL, while I change the GET request parameters?

Categories