We develop mobile applications using ionic framework in the client side and rest webservices in server side. From client side, I 'm able to connect with mfp server successfully.
Now I'm trying to connect my web services server with mfp server for sending pushnotifications . But I am getting 405 error.This is the code I have written
URLConnection connection = new URL("http://localhost:9441/mfp/api/az/v1/token").openConnection();
connection.setDoOutput(true); // Triggers POST.
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("grant_type", "client_credentials");
connection.setRequestProperty("scope", "messages.write");
connection.setRequestProperty("scope", "push.application.com.ionicframework.example854621");
InputStream response = connection.getInputStream();
System.out.println("response"+response);
This is the response I'm getting
Exception in thread "main" java.io.IOException: Server returned HTTP response code: 405 for URL: http://180.151.63.116:9441/mfp/api/az/v1/token
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441)
at com.sai.laps.webservice.server.authentication.mfp.main(mfp.java:24)
Where am I going wrong? How can I connect my rest web service server with MFP server?
Any help will be appreciated!
In this case, first I 'ld suggest not to use connection.getOutputStream(). This will create issue.
Next, Please test the connection if it is connecting or not.
You have to add Authorization parameter in setRequestProperty
Yes, I remember, I too have faced the same issue due to some certificate error and I had to import the certificate in Java level and after that it worked. (Although I faced some other challenge (Multiple connection) issue afterwards, but that too worked...see here)
Anyways, you try the below code and if it is yet not connecting, please share the exception message
String wsURL = "https://hostservername:postnumber";
String wsUserName = "someUserName";
String wsPassword = "somePassword";
try{
String authString = wsUserName+":"+wsPassword;
byte[] byteAuthStr = authString.getBytes();
String authBase64Str = Base64.encode(byteAuthStr);
System.out.println(authBase64Str);
URL url = new URL(wsURL);
URLConnection conn = url.openConnection();
HttpURLConnection connection = (HttpURLConnection)conn;
connection.setDoOutput(true);
/*connection.setRequestMethod("GET");
connection.setRequestMethod("POST");*/
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Authorization", "Basic "+authBase64Str);
connection.connect();
System.out.println( connection.getResponseCode());
boolean connected = false;
switch (connection.getResponseCode()) {
case HttpURLConnection.HTTP_OK:
System.out.println(url + " **OK**");
connected = true;
break; // fine, go on
case HttpURLConnection.HTTP_GATEWAY_TIMEOUT:
System.out.println(url + " **gateway timeout**");
break;// retry
case HttpURLConnection.HTTP_UNAVAILABLE:
System.out.println(url + "**unavailable**");
break;// retry, server is unstable
default:
System.out.println(url + " **unknown response code**.");
break ; // abort
}
}catch(Exception ex){
System.err.println("Error creating HTTP connection");
System.out.println(ex.getMessage());
}
}
Related
I am working on a personal project to learn how to work with Rest web services.
I have an API web application in Visual, which is my controller and where the connection to Oracle is made, and a web application in JAVA and with a JSON library, in addition to trying to do it in layers according to what I learned in the institute.
When I make the GET request, I have no problem, they bring me the data, but when I make a POST request as a customer's registrar it is when the problems start and I get the error 411 in java.
I Read looking for the solution that some worked for them by placing the "Content-Length" I don't know if I put it right but I still have the problem.
public int insertarCliente(Cliente c){
globalURL += "?rut=" + c.getRut() + "&nom="+ c.getNombre() +"&app=" + c.getApellidoP() + "&apm=" + c.getApellidoM();
try {
HttpURLConnection conn = Conectar(globalURL);
conn.setRequestMethod("POST");
conn.setRequestProperty("ACCEPT", "application/json");
conn.setRequestProperty("Content-Length", "0");
if (conn.getResponseCode() == 200) {
//InputStreamReader in = new InputStreamReader(conn.getInputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String resp = br.readLine();
JSONObject obj = new JSONObject(resp);
return obj.getInt("resp");
}
} catch (Exception e) {
Logger.getLogger(ClienteDAO.class.getName()).log(Level.SEVERE, null, e);
}
return 0;
}
The problem start in the IF.
And the error that shows me is the following:
Glook2 was successfully deployed in 227 milliseconds.
**Grave: java.lang.RuntimeException: Failed : HTTP Error code : 411**
at Controllers.ClienteDAO.insertarCliente(ClienteDAO.java:50)
at Services.cliente.registrar(cliente.java:104)
at Services.cliente.processRequest(cliente.java:46)
at Services.cliente.doPost(cliente.java:77)
I must emphasize that I have proven in the POSTMAN that the web services method works and correctly adds the data to the database.
String globalURL = "http://localhost:60367/api/Cliente";
HttpURLConnection conn;
public ClienteDAO() {
conn = Conectar(this.globalURL);
}
private HttpURLConnection Conectar(String urlRest) {
try {
URL url;
url = new URL(urlRest);
return (HttpURLConnection) url.openConnection();
} catch (Exception e) {
Logger.getLogger(ClienteDAO.class.getName()).log(Level.SEVERE, null, e);
}
return null;
}
Enable logging as shown here: How to enable wire logging for a java HttpURLConnection traffic?
You will then see1 that the Content-Length header is not sent:
FINE: sun.net.www.MessageHeader#4bf558aa5 pairs:
{POST / HTTP/1.1: null}
{ACCEPT: application/json}
{User-Agent: Java/13}
{Host: localhost:8080}
{Connection: keep-alive}
1: Sample log entry, wrapped for easier reading
That is because HttpURLConnection manages that header.
To send a Content-Length: 0 header, send no output, i.e. replace:
conn.setRequestProperty("Content-length", "0");
with:
conn.setDoOutput(true);
conn.getOutputStream().close();
Logging now shows the header:
FINE: sun.net.www.MessageHeader#5fa7e7ff7 pairs:
{POST / HTTP/1.1: null}
{ACCEPT: application/json}
{User-Agent: Java/13}
{Host: localhost:8080}
{Connection: keep-alive}
{Content-type: application/x-www-form-urlencoded}
{Content-Length: 0}
See also: JDK-6997628: HttpURLConnection strips Content-Length header on Post:
Affects Version/s: 6u22
Status: Open
Resolution: Unresolved
BT2:EVALUATION
The fix for CR 6961084 restricts the setting of some potentially security sensitive headers. Since these headers were allowed to be set in previous releases then of course compatibility is effected. A decision was made that compatibility was secondary to the security risk these headers posed. We understand that there may be valid apps out there that will be effected by this, so the sun.net.http.allowRestrictedHeaders property was added to revert to previous behavior.
BT2:WORK AROUND
Run with -Dsun.net.http.allowRestrictedHeaders=true
I would not recommend using that workaround.
I'm trying to create a client server application and I'm currently stuck. I have this java code on my client.
HttpURLConnection connection;
connection = (HttpURLConnection) new URL("http://www.masterpaint.gr/login.php").openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestProperty("Content-Type","application/json; charset=UTF-8");
connection.setRequestProperty("Accept","application/json: charset=UTF-8");
connection.setRequestMethod("POST");
System.out.println("The request method on client end is " + connection.getRequestMethod());
System.out.println("Server response to connection " + connection.getResponseMessage());
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String buffer;
StringBuilder stringBuilder = new StringBuilder();
while ((buffer = reader.readLine()) != null) {
stringBuilder.append(buffer);
}
System.out.println("The request methond on server end is " + stringBuilder.toString());
And this is the simple test php code on the server.
<?php echo $_SERVER['REQUEST_METHOD']; ?>
Whenever I run this test java program and try to connect I get the same output.
The request method on client end is POST
Server response to connection OK
The request methond on server end is GET
The php script always echoes back that I'm sending a GET request even though
my java code states that use a POST. I have tried connecting to the script through postman using different request methods and it's all fine, so the problem must be in the Java code. Any insight would be greatly appreciated.
I am not having any experience of php but it seems like it is looking for content-length header which will not be send in your case so it is treating this as GET request.
HttpURLConnection connection;
connection = (HttpURLConnection) new URL("http://www.masterpaint.gr/login.php").openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestProperty("Content-Type","application/json; charset=UTF-8");
connection.setRequestProperty("Accept","application/json: charset=UTF-8");
connection.setRequestMethod("POST");
connection.setFixedLengthStreamingMode(0);
System.out.println("The request method on client end is " + connection.getRequestMethod());
System.out.println("Server response to connection " + connection.getResponseMessage());
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String buffer;
StringBuilder stringBuilder = new StringBuilder();
while ((buffer = reader.readLine()) != null) {
stringBuilder.append(buffer);
}
System.out.println("The request methond on server end is " + stringBuilder.toString());
This will set content length 0 as you are not sending any content.
I am using Restful Services on server and trying to maintain the same session after performing login:
URL endpoint = new URL(getString(R.string.url_login));
// Create connection
HttpURLConnection myConnection = (HttpURLConnection) endpoint.openConnection();
myConnection.setRequestMethod("POST");
myConnection.setRequestProperty("User-Agent", "my-rest-app-v0.1");
// Create the data
String myData = "username=" + username + "&password=" + pwd;
// Enable data writing
myConnection.setDoOutput(true);
// Write the data
myConnection.getOutputStream().write(myData.getBytes());
rc = myConnection.getResponseCode();
if (rc == 200) {
String Cookie= myConnection.getHeaderField("Set-Cookie");
URL endpoint2 = new URL(getString(R.string.url_checkUserType));
HttpURLConnection myConnection2 =
(HttpURLConnection)endpoint2.openConnection();
myConnection2.setRequestMethod("GET");
myConnection2.setRequestProperty("User-Agent", "my-rest-app-v0.1");
myConnection2.setRequestProperty("Cookie", Cookie);
rc2 = myConnection2.getResponseCode();
....
}....
The problem is that rc2 is every time 401 as WebService doesn't recognize that requiest is part of the same session. What am I doing wrong?
You may do as follows
on the server side, it checks if the incoming request has a "sessionId" in cookie: if not, create one and return it in response; if yes, it knows the request belongs to a known session
on the client side, after a successful login, retrieve the "sessionId" from the response, and set it in the following requests
==
connection.setRequestProperty("Cookie", "JSESSIONID=" + URLEncoder.encode(jSessionId, "UTF-8"));
The solution was to use Spring RESTful services for Android that worked great for me.
I have a remote server that use basic authentication (HTTP) and i need several calls to different URLs. A example of calling:
URL address = new URL ("hhtp://localhost:8080");
HttpURLConnection connection;
// open connection
connection = (HttpURLConnection) address.openConnection();
String encoding = DatatypeConverter.printBase64Binary((username + ":" + password).getBytes());
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty("Authorization", "Basic " + encoding);
// transform result code into an exception
int code = connection.getResponseCode();
if ((code < 200) || (code >= 300))
{
throw new HttpRetryException(connection.getResponseMessage(), code, address.toString());
}
return connection;
The problem appear that the server take a lot of time authenticating the user. After this first call, we need another page (a different URL) to the same server. How I can keep the session between different calls?
Edit:
A clarification, I'm trying to connect to a Jenkins server.
I am working on a Java desktop application with Java 7. For my application, I want to send data with POST to a server (using HTTP). The server is running on my local machine on localhost.
But if I am trying to connect to the server, an connection reset (SocketTimeoutException) is returned. I can`t connect, I have also tried to connect to a webpage like http://www.google.de, but it also fails. The var body contains the POST data in correct form. (I have also tried to connect with disabled firewall)
My code:
body=body.substring(0,body.length()-2);
HttpURLConnection connection = null;
try {
if (revision){ //Connect to the revision server
this.urlRevision = new URL(this.settingsRevision.getAddress());
connection = (HttpURLConnection) urlRevision.openConnection();
connection.setRequestMethod("POST");
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(true);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length", String.valueOf(body.length()));
connection.connect();
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
writer.write(body);
writer.flush();
this.returnedData = new BufferedReader(new InputStreamReader(connection.getInputStream()));
for(String line; (line = returnedData.readLine()) != null;){
System.out.println(line);
}
writer.close();
this.returnedData.close();
}
} catch (Exception e) {
this.exception=e;
}
You should try close the connection like this:
} finally {
if(connection != null) {
connection.disconnect();
}
}
I have already added it to the comments:
System.setProperty("java.net.preferIPv4Stack" , "true");
Reason: Java is using IPv6 functions on my computer but IPv4 is used for internet connection (on my computer and by my provider (T-Online)).