I have a problem on HttpURLConnection in post method. Everything is working fine on get method however, when I try to use Post method. I'm getting this error message.
Exception in thread "main" java.io.IOException: Server returned HTTP response code: 403 for URL
Here's my code snippet. I hope you could help me about this.
URL url = new URL(my url/userInfo);
String encoding = Base64.getEncoder().encodeToString(("username:password").getBytes("UTF-8"));
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "text/plain");
connection.setRequestProperty("Authorization", "Basic " + encoding);
connection.setRequestProperty("x-csrf-token", "fetch");
String csrfToken = connection.getHeaderField("x-csrf-token");
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
String output = in.readLine();
in.close();
String content = data // expected data to retrieve
URL url2 = new URL(my URL);//another url to push the data retrieve
HttpURLConnection connection2 = (HttpsURLConnection) url2.openConnection();
connection2.setDoInput(true);
connection2.setDoOutput(true);
connection2.setRequestMethod("POST");
connection2.setRequestProperty("Authorization", "Basic " + encoding);
connection2.setRequestProperty("Accept", "application/json");
connection2.setRequestProperty("x-CSRFToken", csrfToken);
connection2.setRequestProperty("cache-control", "no-cache");
OutputStream os = connection2.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
osw.write(data);//this is where the data will be pushed
osw.flush();
osw.close();
os.close();
the idea is, we need first to get the x-csrf-token and data from the first link, which is okay. After GET Method execution, the POST method will occur. unfortunately, the post method is not working. I'm getting the error message shown above. By the way, we tried to do a post method in POSTMAN and it' working fine.
Hoping you could help me about this.
Related
NOTICE UPDATE!!
The problem got solved and i added my own answer in the thread
In short, I have attempted to add the parameter "scan_id" value but since it is a POST i can't add the value directly in the url path.
using the code i already have, how would i go about modifying or adding so that the url is correct, that is, so that it accepts my POST?.
somehow i have been unable to find any examples that have helped me in figuring out how i would go about doing this..
I know how to do a POST with a payload, a GET with params. but a post with Params is very confusing to me.
Appreciate any help. (i'd like to continue using HttpUrlConnection unless an other example is provided that also tells me how to send the request and not only configuring the path.
I've tried adding it to the payload.
I've tried UriBuilder but found it confusing and in contrast with the rest of my code, so wanted to ask for help with HttpUrlConnection.
URL url = new URL("http://localhost/scans/{scan_id}/launch");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("tmp_value_dont_mind_this", "432432");
con.setRequestProperty("X-Cookie", "token=" + "43432");
con.setRequestProperty("X-ApiKeys", "accessKey="+"43234;" + " secretKey="+"43234;");
con.setDoInput(true);
con.setDoOutput(true); //NOT NEEDED FOR GETS
con.setRequestMethod("POST");
con.setRequestProperty("Accept", "application/json");
con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
//First example of writing (works when writing a payload)
OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream(), "UTF-8");
writer.write(payload);
writer.close();
//second attemp at writing, doens't work (wanted to replace {scan_id} in the url)
DataOutputStream writer = new DataOutputStream(con.getOutputStream());
writer.writeChars("scan_id=42324"); //tried writing directly
//writer.write(payload);
writer.close();
Exception:
Exception in thread "main" java.io.IOException: Server returned HTTP response code: 400 for URL: http://localhost/scans/launch
I'd like one of the three response codes because then i know the Url is correct:
200 Returned if the scan was successfully launched.
403 Returned if the scan is disabled.
404 Returned if the scan does not exist.
I've tried several urls
localhost/scans/launch,
localhost/scans//launch,
localhost/scans/?/launch,
localhost/scans/{scan_id}/launch,
So with the help of a friend and everyone here i solved my problem.
The below code is all the code in an entire class explained bit by bit. at the bottom you have the full class with all its syntax etc, that takes parameters and returns a string.
in a HTTP request there are certain sections.
Such sections include in my case, Request headers, parameters in the Url and a Payload.
depending on the API certain variables required by the API need to go into their respective category.
My ORIGINAL URL looked like this: "http://host:port/scans/{scan_id}/export?{history_id}"
I CHANGED to: "https://host:port/scans/" + scan_Id + "/export?history_id=" + ID;
and the API i am calling required an argument in the payload called "format" with a value.
String payload = "{\"format\" : \"csv\"}";
So with my new URL i opened a connection and set the request headers i needed to set.
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
The setDoOutput should be commented out when making a GET request.
con.setDoInput(true);
con.setDoOutput(true);
con.setRequestMethod("POST");
con.setRequestProperty("Accept", "application/json");
con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
con.setRequestProperty("X-Cookie", "token=" + token);
con.setRequestProperty("X-ApiKeys", "accessKey="+"23243;" +"secretKey="+"45543;");
Here i write to the payload.
//WRITING THE PAYLOAD to the http call
OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream(), "UTF-8");
writer.write(payload);
writer.close();
After i've written the payload i read whatever response i get back (this depends on the call, when i do a file download (GET Request) i don't have a response to read as i've already read the response through another piece of code).
I hope this helps anyone who might encounter this thread.
public String requestScan(int scan_Id, String token, String ID) throws MalformedInputException, ProtocolException, IOException {
try {
String endpoint = "https://host:port/scans/" + scan_Id + "/export?history_id=" ID;
URL url = new URL(endpoint);
String payload= "{\"format\" : \"csv\"}";
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setDoInput(true);
con.setDoOutput(true);
con.setRequestMethod("POST");
con.setRequestProperty("Accept", "application/json");
con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
con.setRequestProperty("X-Cookie", "token=" + token);
con.setRequestProperty("X-ApiKeys", "accessKey="+"324324;" +
"secretKey="+"43242;");
//WRITING THE PAYLOAD to the http call
OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream(), "UTF-8");
writer.write(payload);
writer.close();
//READING RESPONSE
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBuffer jsonString = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
jsonString.append(line);
}
br.close();
con.disconnect();
return jsonString.toString();
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
As discussed here the solution would be to change the content type to application/x-www-form-urlencoded, but since you are already using application/json; charset=UTF-8 (which I am assuming is a requirement of your project) you have no choise to redesign the whole thing. I suggest you one of the following:
Add another GET service;
Add another POST service with content type application/x-www-form-urlencoded;
Replace this service with one of the above.
Do not specify the content type at all so the client will accept anything. (Don't know if possible in java)
If there are another solutions I'm not aware of, I don't know how much they would be compliant to HTTP protocol.
(More info)
Hope I helped!
Why you are not using like this. Since you need to do a POST with HttpURLConnection, you need to write the parameters to the connection after you have opened the connection.
String urlParameters = "scan_id=42324";
byte[] postData = urlParameters.getBytes(StandardCharsets.UTF_8);
DataOutputStream dataOutputStream = new DataOutputStream(conn.getOutputStream());
dataOutputStream.write(postData);
Or if you have launch in the end, just change the above code to the following,
String urlParameters = "42324/launch";
byte[] postData = urlParameters.getBytes(StandardCharsets.UTF_8);
DataOutputStream dataOutputStream = new DataOutputStream(conn.getOutputStream());
dataOutputStream.write(postData);
URL url = new URL("http://localhost/scans/{scan_id}/launch");
That line looks odd to me; it seems you are trying to use a URL where you are intending the behavior of a URI Template.
The exact syntax will depend on which template implementation you choose; an implementation using the Spring libraries might look like:
import org.springframework.web.util.UriTemplate;
import java.net.url;
// Warning - UNTESTED code ahead
UriTemplate template = new UriTemplate("http://localhost/scans/{scan_id}/launch");
Map<String,String> uriVariables = Collections.singletonMap("scan_id", "42324");
URI uri = template.expand(uriVariables);
URL url = uri.toURL();
I am opening an HttpURLConnection and with POST method, I am sending a JSON request that I build form another class. The JSON is structured correctly since I have validated it on debugging. The exception is thrown when trying to read the output response given from the server. This is the Error given
java.io.IOException: Server returned HTTP response code: 400 for URL:
However when I manually try to enter the Url from a web browser with a POST method chrome extension. I can view the response and everything works. So I am sure it has something to do with the following code where I make the connection and read/write.
URL obj = new URL(url);
HttpURLConnection connection = (HttpURLConnection) obj.openConnection();
//add request header
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
//mapping objects to json
BatchRequest requestParameters = new BatchRequest(o,d);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(requestParameters);
connection.setDoOutput(true);
DataOutputStream os = new DataOutputStream(connection.getOutputStream());
os.writeBytes(json);
os.flush();
os.close();
// this is where the program throws the exception
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
Both the URL and the JSON request are correct since They work when I try a manual conenction over a browser.
A DataOutputStream is not needed. Just:
OutputStream os = con.getOutputStream();
I have written a Java Code to test the Watson Question and Answers API. However, I'm getting response code 500, when I run it. I have checked the api url and my login credentials. The problem seems to be somewhere else. Any hints or debugging suggestions would be of great help.
String url = "https://watson-wdc01.ihost.com/instance/526/deepqa/v1/question";
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
//add reuqest header
String userCredentials = "username:password";
String basicAuth = "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes());
con.setRequestProperty ("Authorization", basicAuth);
con.setRequestProperty("X-SyncTimeout", "30");
con.setRequestProperty("Accept", "application/json");
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Cache-Control", "no-cache");
con.setRequestMethod("POST");
String query = "{\"question\": {\"questionText\": \"" + "What are the common respiratory diseases?" + "\"}}";
System.out.println(query);
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(query);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
//print result
System.out.println(response.toString());
When i open the same url with the browser I get this:
Watson Error!!
Error Encountered!!
Unable to communicate with Watson.
Whats wrong? Could it be something with the configuration? Or is the server down?
Any hints or debugging suggestions would be of great help.
Attempt the same request using your web browser ... or the curl utility.
Capture and output the contents of the error stream.
I don't think that this is the cause of your problems, but it is wrong anyway:
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(query);
wr.flush();
You are writing to an API that expects text (JSON). You should therefore use a Writer, not a data (binary) output stream:
Writer wr = new OutputStreamWriter(con.getOutputStream(), "LATIN-1");
wr.write(query);
wr.flush();
I am currently developing an application that needs to interact with the server but i'm having a problem with receiving the data via POST. I'm using Django and then what i'm receiving from the simple view is:
<QueryDict: {u'c\r\nlogin': [u'woo']}>
It should be {'login': 'woooow'}.
The view is just:
def getDataByPost(request):
print '\n\n\n'
print request.POST
return HttpResponse('')
and what i did at the src file on sdk:
URL url = new URL("http://192.168.0.148:8000/data_by_post");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setChunkedStreamingMode(0);
String parametros = "login=woooow";
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
urlConnection.setRequestProperty("charset","utf-8");
urlConnection.setRequestProperty("Content-Length", "" + Integer.toString(parametros.getBytes().length));
OutputStream os = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter( new OutputStreamWriter(os, "UTF-8"));
writer.write(parametros);
writer.close();
os.close();
I changed the Content-Length to see if that was a problem and then the problem concerning thw value of login was fixed but it was by hard coding (which is not cool).
ps.: everything except the QueryDict is working well.
What could i do to solve this? Am i encoding something wrong at my java code?
thanks!
Just got my problem solved with a few modifications concearning the parameters and also changed some other things.
Having parameters set as:
String parameters = "parameter1=" + URLEncoder.encode("SOMETHING","UTF-8");
then, under an AsyncTask:
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
//not using the .setRequestProperty to the length, but this, solves the problem that i've mentioned
conn.setFixedLengthStreamingMode(params.getBytes().length);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
PrintWriter out = new PrintWriter(conn.getOutputStream());
out.print(params);
out.close();
String response = "";
Scanner inStream = new Scanner(conn.getInputStream());
while (inStream.hasNextLine()) {
response += (inStream.nextLine());
}
Then, with this, i got the result from django server:
<QueryDict: {u'parameter1': [u'SOMETHING']}>
which is what i was wanting.
I need to send a POST request to a URL and send some request parameters. I am using HttpURLConnectionAPI for this. But my problem is I do not get any request parameter in the servlet. Although I see that the params are present in the request body, when I print the request body using request.getReader. Following is the client side code. Can any body please specify if this is correct way to send request parameters in POST request?
String urlstr = "http://serverAddress/webappname/TestServlet";
String params = "¶mname=paramvalue";
URL url = new URL(urlstr);
HttpURLConnection urlconn = (HttpURLConnection) url.openConnection();
urlconn.setDoInput(true);
urlconn.setDoOutput(true);
urlconn.setRequestMethod("POST");
urlconn.setRequestProperty("Content-Type", "text/xml");
urlconn.setRequestProperty("Content-Length", String.valueOf(params.getBytes().length));
urlconn.setRequestProperty("Content-Language", "en-US");
OutputStream os = urlconn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(params);
writer.close();
os.close();
To be cleaner, you can encode to send the values.
String data = URLEncoder.encode("key1", "UTF-8") + "=" + URLEncoder.encode("value1", "UTF-8");
data += "&" + URLEncoder.encode("key2", "UTF-8") + "=" + URLEncoder.encode("value2", "UTF-8");
URL url = new URL("http://yourserver.com/whatever");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
Like #Kal said, get rid of the leading & and don't bother with the BufferedWriter. This works for me:
byte[] bytes = parameters.getBytes("UTF-8");
httpUrlConnection.setRequestProperty("Content-Length", String.valueOf(bytes.length));
httpUrlConnection.setRequestMethod("POST");
httpUrlConnection.setDoOutput(true);
httpUrlConnection.connect();
outputStream = httpUrlConnection.getOutputStream();
outputStream.write(bytes);