I try to perfom a put-request against a rest-api written by me, but it always returns 400-Bad Request.
java.io.IOException: Server returned HTTP response code: 400 for URL: http://localhost:8000/api/v0/contacts/2
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
I can call the url with firefox-rest client-plugin as well as another angular client, so I guess I have configured something wrong in my java code.
The server always returns something, so I don't know, why it crashes when I try to get the input stream.
protected String put(String path, String parameters)
throws IOException {
HttpURLConnection connection = getConnection(path, "PUT", parameters);
OutputStreamWriter outputWriter = new OutputStreamWriter(
connection.getOutputStream());
outputWriter.write(parameters);
outputWriter.flush();
outputWriter.close();
InputStream is = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String response = reader.readLine();
while(response != null){
response += reader.readLine();
}
reader.close();
return response;
}
private HttpURLConnection getConnection(String path, String method,String params) throws MalformedURLException, IOException,
ProtocolException {
URL url = new URL(this.api + path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setRequestMethod(method);
connection.setRequestProperty("Content-Length",
String.valueOf(params.length()));
return connection;
}
Sorry for bad english, it's not my mother tongue.
I did ipconfig in cmd prompt and it showed 192.168.1.3. i changed it in the place of localhost in Android app and now i am able to access local web server.
Related
I need to create a hastebin paste in java, but I don't know how.
I tried this
public static String paste(String content) throws MalformedURLException, IOException {
URL url = new URL("https://hasteb.in/documents");
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection) con;
http.addRequestProperty("data", content);
http.setRequestMethod("POST");
http.setDoOutput(true);
InputStream in = new BufferedInputStream(http.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder entirePage = new StringBuilder();
String inputLine;
while ((inputLine = reader.readLine()) != null) {
entirePage.append(inputLine);
}
reader.close();
if (!(entirePage.toString().contains("\"key\":\""))) {
return "UNKNOWN";
}
return "https://hasteb.in/"+entirePage.toString().split("\"key\":\"")[1].split("\",")[0];
}
But it does not work.
Error is Caused by: java.lang.IllegalArgumentException: Illegal character(s) in message header value
Any help?
To do a POST request using HttpURLConnection you need to write the request body using the provided OutputStream functionality rather than setting a HTTP header named "data":
try (OutputStream out = http.getOutputStream()) {
out.write(content.getBytes());
out.flush();
}
This needs to happen BEFORE you start reading from the InputStream (and I would suggest using try-with-resources for that as well).
I'm trying to get an access token from https://www.reddit.com/api/v1/access_token. To do so I need to send a CLIENT_ID and a CLIENT_SECRET to the above URL. I did so using Postman:
As highlighted on the screenshot, I've sent a grant_type as a GET parameter with value client_credentials and an Authorization parameter with value Basic heregoestheencodedkeyandid. The reuest type was set as POST. It worked correctly - I got an access token in a JSON response.
However, when I try to do the same thing by means of Java, I receieve a Server returned HTTP response code: 411 error:
public class RedditExample {
private static String loginLink = "https://www.reddit.com/api/v1/access_token";
public static void main(String[] args) {
RedditExample redditExample = new RedditExample ();
redditExample.login();
}
public boolean login() {
try {
URL loginURL = new URL(loginLink + "?grant_type=client_credentials");
HttpURLConnection connection = (HttpURLConnection) loginURL.openConnection();
setupPOSTConnection(connection);
InputStream input = connection.getInputStream();
String inputString = new Scanner(input, "UTF-8").useDelimiter("\\Z").next();
System.out.println(inputString);
}
catch (Exception e) {
System.out.println(e.toString());
}
return true;
}
private static void setupPOSTConnection(HttpURLConnection connection) throws Exception {
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Authorization", "Basic heregoestheencodedkeyandid");
connection.connect();
}
}
I'm not sure what I'm doing different here, compared to Postman, so any help would be appreciated.
EDIT: Here is what I tried adding:
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestProperty("Content-Length", "0");
connection.setRequestProperty("Content-Length", "10");
String userAgent = "test /u/someuser";
connection.setRequestProperty("User-Agent", userAgent);
Unfortunately, neither worked - the error is still the same.
Setting content-length explicitly is not taken by HttpUrlConnection. So just provide request body with no content.
StringBuilder postDataBuilder = new StringBuilder();
byte[] postData = postDataBuilder.toString().getBytes("UTF-8");
OutputStream out = conn.getOutputStream();
out.write(postData);
out.close();
So the method will be like this:-
private static void setupPOSTConnection(HttpURLConnection connection) throws Exception {
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Authorization", "Basic heregoestheencodedkeyandid");
StringBuilder postDataBuilder = new StringBuilder();
byte[] postData = postDataBuilder.toString().getBytes("UTF-8");
OutputStream out = conn.getOutputStream();
out.write(postData);
out.close();
connection.connect();
}
also i found another way of simply adding one line:-
private static void setupPOSTConnection(HttpURLConnection connection) throws Exception {
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Authorization", "Basic heregoestheencodedkeyandid");
conn.setFixedLengthStreamingMode(0);
connection.connect();
}
HTTP Status Code 411 (Length Required) is sent by the server as a response when it refuses to accept a message without a content-length header, for whatever reason.
A server simply may or may not accept a content without a Content-Length header, and it seems this API is picky. See this post detailing a working POST connection using Java.
I am trying to connect to a URL from a desktop app, and I get the error indicated in the Title of my question
Url:https://capi-eval.signnow.com/api/user
The Code fragment.
public void getUrl(String urlString) throws Exception
{
String postData=String.format("{{\"first_name\":\"%s\",\"last_name\":\"%s\",\"email\":\"%s\",\"password\":\"%s\"}}", "FIRST", "LAST","test#test.com","USER_1_PASSWORD");
URL url = new URL (urlString);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("Content-Length",""+postData.length());
connection.setRequestProperty ("Authorization", "Basic MGZjY2RiYzczNTgxY2EwZjliZjhjMzc5ZTZhOTY4MTM6MzcxOWExMjRiY2ZjMDNjNTM0ZDRmNWMwNWI1YTE5NmI=");
connection.setRequestMethod("POST");
connection.connect();
byte[] outputBytes =postData.getBytes("UTF-8");
OutputStream os = connection.getOutputStream();
os.write(outputBytes);
os.close();
InputStream is;
if (connection.getResponseCode() >= 400) {
is = connection.getErrorStream();
} else {
is = connection.getInputStream();
}
BufferedReader in =
new BufferedReader (new InputStreamReader (is));
String line;
while ((line = in.readLine()) != null) {
System.out.println (line);
}
}
public static void main(String[] arg) throws Exception
{
System.setProperty("jsse.enableSNIExtension", "false");
Test s = new Test();
s.getUrl("https://capi-eval.signnow.com/api/user");
}
When i dig in the response and print error Stream My output is ::
{"errors":[{"code":65536,"message":"Invalid payload"}]}
any help appreciated
thanks
Maybe something wrong caused by unecoding. Just have a try by using Base64.encode.
I keep keep getting the above error when I run the code below. All signs point to a problem with COOKIES from what I've read. If I am correct,how would I go about Implementing the CookieManager to fix this issue? Or how would I fix the issue if it is not an issue with COOKIES?
public class Client {
public Client(){
}
String executePost(String targetURL, String urlParameters){
URL url;
HttpURLConnection connection = null;
try{
//Create connection
url = new URL(targetURL);
connection = (HttpURLConnection)url.openConnection();
connection.setChunkedStreamingMode(0);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length", "" +
Integer.toString(urlParameters.getBytes().length));
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
//send Request
DataOutputStream dataout = new DataOutputStream(connection.getOutputStream());
dataout.writeBytes(urlParameters);
dataout.flush();
dataout.close();
//get response
InputStream is = connection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while((line = br.readLine()) != null){
response.append(line);
response.append('\n');
}
System.out.println(response.toString());
br.close();
return response.toString();
}catch(Exception e){
System.out.println("Unable to full create connection");
e.printStackTrace();
return null;
}finally {
if(connection != null) {
connection.disconnect();
}
}
}
}
I removed : connection.setChunkedStreamingMode(0); and the code worked as it should
String executePost(String targetURL, String urlParameters){
URL url;
HttpURLConnection connection = null;
try{
//Create connection
url = new URL(targetURL);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Language", "en-US");
connection.setRequestProperty("User-Agent",
"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
//send Request
DataOutputStream dataout = new DataOutputStream(connection.getOutputStream());
dataout.writeBytes(urlParameters);
dataout.flush();
dataout.close();
//get response
InputStream is = connection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while((line = br.readLine()) != null){
response.append(line);
response.append('\n');
}
System.out.println(response.toString());
br.close();
return response.toString();
}catch(Exception e){
System.out.println("Unable to full create connection");
e.printStackTrace();
return null;
}finally {
if(connection != null) {
connection.disconnect();
}
}
}
A 403 response means "forbidden".
All signs point to a problem with COOKIES from what I've read. If I am correct,how would I go about Implementing the CookieManager to fix this issue? Or how would I fix the issue if it is not an issue with COOKIES?
It is not as simple as that.
It may be that you need to supply valid credentials (in the form of cookies, basic auth headers, or something else). However, you expect the server to respond with a 401 in that case, or a 302 to redirect your browser the a login page.
It may also be that you've supplied credentials, and they are not sufficient for the request you are trying to perform.
Your best bet is to figure out exactly what is happening when you try to login and use the service from your web browser. Then try to replicate that. Alternatively, read the site documentation or ask the site admins what to do.
If it is your site / server that you are trying to access, then you need to figure out how security is implemented. Perhaps you've misconfigured the server, or neglected to set up / enable login.
It is unlikely (IMO) that you will solve this problem by just setting up a Cookie Manager.
If you see the API documentation of setChunkedStreamingMode, it has been mentioned there that not all servers support this mode. Are you sure that the server you are making a connection to supports this ?
I've created a Java class that connects to an IIS website requiring NTLM authentication. The Java class uses the JCIFS library and is based on the following example:
Config.registerSmbURLHandler();
Config.setProperty("jcifs.smb.client.domain", domain);
Config.setProperty("jcifs.smb.client.username", user);
Config.setProperty("jcifs.smb.client.password", password);
URL url = new URL(location);
BufferedReader reader = new BufferedReader(
new InputStreamReader(url.openStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
The example works fine when executed from the command prompt, but as soon as I try to use the same code in a servlet container (specifically GlassFish), I get an IOException containing the message "Server returned HTTP response code: 401 for URL: ....".
I've tried moving the jcifs jar to the system classpath (%GLASSFISH%/lib), but that doesn't seem to make any difference.
Suggestions are highly appreciated.
It seems that what I was trying to do is already supported in Java 5/6 and I was therefore able to drop the JCIFS API and do something like this instead:
public static String getResponse(final ConnectionSettings settings,
String request) throws IOException {
String url = settings.getUrl() + "/" + request;
Authenticator.setDefault(new Authenticator() {
#Override
public PasswordAuthentication getPasswordAuthentication() {
System.out.println(getRequestingScheme() + " authentication")
// Remember to include the NT domain in the username
return new PasswordAuthentication(settings.getDomain() + "\\" +
settings.getUsername(), settings.getPassword().toCharArray());
}
});
URL urlRequest = new URL(url);
HttpURLConnection conn = (HttpURLConnection) urlRequest.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("GET");
StringBuilder response = new StringBuilder();
InputStream stream = conn.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(stream));
String str = "";
while ((str = in.readLine()) != null) {
response.append(str);
}
in.close();
return response.toString();
}
Sounds like JCIFS does not have the right to set a factory for handling your URLs inside Glassfish. You should check the policy settings (checkSetFactory).
The Config#registerSmbURLHandler() might swallow the SecurityException.