i'm trying to develop in Java a Rest WebService (i'm using RestEasy) that accept a generic JSonObject (i'm using JSON Simple 1.1.1).
What I've done so far:
#Path("/message")
public class TestRestService {
#POST
#Path("/{param}")
#Consumes("application/json")
public Response printMessage(JSONObject inputJsonObj) {
String result = "Restful example : " + inputJsonObj;
System.out.println(result);
return Response.status(200).entity(result).build();
}
}
And this is my client:
public static void main(String[] args) {
try {
URL url = new URL("http://localhost:8080/myProject/rest/message/");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
String input = "{\"qty\":100,\"name\":\"iPad 4\"}";
OutputStream os = conn.getOutputStream();
os.write(input.getBytes());
os.flush();
if (conn.getResponseCode() != HttpURLConnection.HTTP_CREATED) {
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
conn.disconnect();
} catch (MalformedURLException e) { }
catch (IOException e) { }
}
Unfortunately i'm getting a 405 error, which means the path i suppose doesn't exist...
Can anybody help me?
thanks!
It seems like you are missing the /{param}-part of your Path. Right now you have nothing following the part from /message but your webserver can not find a method which accepts just the pass to /message. Since you are not trying to use the /{param} in your method i would suggest you just remove the #Path-Annotation from your method. This is possible because the Framework will just try and use the #Path annotation on the next level (here this is your class-level and this would be your /message path) with the HTTP-method annotated to your method. If the /{param} should be an optional parameter i would suggest using the #QueryParameter annotation in your method-head. For further information on this annotation you should read the docs for the javax.ws.rs framework.
Kind regards
Related
I'm a QA with desire to learn more about Java programming and problem I'm experiencing is this:
I'm trying to POST Employee data to the database of some fake Rest API, but I'm getting
Cannot write to a URLConnection if doOutput=false - call
setDoOutput(true)"
So far, I tried some ideas from StackOverflow, but inexperienced as I am, I could easily fall deeper into a problem.
So URL is: http://dummy.restapiexample.com/api/v1/create and firstly I created an Employee class of json object:
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
Employees em = new Employees();
em.setEmployeeName("Alex");
em.setEmployeeSalary("1234");
em.setEmployeeAge("28");
try{
URL url = new URL("http://dummy.restapiexample.com/api/v1/create");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Unsuccessful call: HTTP error : "
+ conn.getResponseCode());
}
// URLConnection urlc = url.openConnection();
// urlc.setDoOutput(true);
PrintWriter pw = new PrintWriter(conn.getOutputStream());
pw.print(new Gson().toJson(em));
pw.close();
pw.flush();
BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream())
);
String json = "";
String output;
while ((output = br.readLine()) != null) {
json += output;
}
conn.disconnect();
System.out.println("Employee name: " + em.getEmployeeName());
}
catch (MalformedURLException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
Well, using one of your ideas and added next lines of code (it's commented in above code):
URLConnection urlc = url.openConnection();
urlc.setDoOutput(true);
So the code looks like:
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
Employees em = new Employees();
em.setEmployeeName("Alex");
em.setEmployeeSalary("1234");
em.setEmployeeAge("28");
try{
URL url = new URL("http://dummy.restapiexample.com/api/v1/create");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Unsuccessful call: HTTP error : "
+ conn.getResponseCode());
}
URLConnection urlc = url.openConnection();
urlc.setDoOutput(true);
PrintWriter pw = new PrintWriter(urlc.getOutputStream());
pw.print(new Gson().toJson(em));
pw.close();
pw.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(
(urlc.getInputStream())));
String json = "";
String output;
while ((output = br.readLine()) != null) {
json += output;
}
conn.disconnect();
System.out.println("Employee name: " + em.getEmployeeName());
}
catch (MalformedURLException e) {
e.printStackTrace(); }
catch (IOException e) {
e.printStackTrace();
}
}}
With this second code I'm not getting that error, but there is no inserting to the database(checking that using postman, with GET method)...
Well, what am I missing? I guess, I'm missing something basic...
Using url.openConnection twice means you get two different connections. You send the request to the second connection, and try to read the response from the first connection. You should call doOutput on the connection you open originally.
The second problem is you're calling getResponseCode before the request is sent. In http, the request must be sent entirely before the server sends a response. You should move the code that calls doOutput and writes the request body before the code that tries to check the response code.
I'm trying to use HttpURLConnection for connecting to server from Android app which I'm developing. For now, I'm testing the connection code not in an app but as a plain java program with main class. I guess this doesn't make any difference as far as HttpUrlConnection.
Please examine the code snippet. Another issue is even errorStream is throwing null. This I feel is because of malformed URL.
private static String urlConnectionTry() {
URL url; HttpURLConnection connection = null;
try {
String urlParameters = "email=" + URLEncoder.encode("email", "UTF-8") +
"&pwd=" + URLEncoder.encode("password", "UTF-8");
//Create connection
url = new URL("http://example.com/login");
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
connection.setRequestProperty("uuid", getUuid());
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setInstanceFollowRedirects(true);
//Send request
DataOutputStream wr = new DataOutputStream (
connection.getOutputStream ());
wr.writeBytes (urlParameters);
wr.flush ();
wr.close ();
//Get Response
InputStream is = connection.getErrorStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
return response.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if(connection != null) {
connection.disconnect();
}
}
}
private static String getUuid() {
try {
Document doc=Jsoup.connect("http://example.com/getUuid").get();
Elements metaElems = doc.select("meta");
for (Element metaElem : metaElems) {
if(metaElem.attr("name").equals("uuid")) {
return metaElem.attr("content");
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
You're probably receiving 401 because the credentials that was sent to the server is not authorized- it's probably not registered or the password is incorrect.
As for the null error stream, take a look at this SO answer.
If the connection was not connected, or if the server did not have an error while connecting or if the server had an error but no error data was sent, this method will return null.
It is probably better if you check first the response code using HttpUrlConnection#getResponseCode(). Decide on whether you'll be checking the contents of the error stream based on the response code you get.
public class RestClient {
public static void main(String[] args) {
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("fromSku","NONE" );
jsonObject.put("toSku","ASA5500-ENCR-K8" );
jsonObject.put("modelNo", "ASAV10");
jsonObject.put("serialNo", "ASATSTSN");
System.out.println(jsonObject);
URL url = new URL("http://licruleswb- dev.cloudapps.cisco.com/LicenseRules/rest/invokeASARule");
URLConnection connection = url.openConnection();
connection.setDoOutput(true);
String encodedCredentials = new String(
org.apache.commons.codec.binary.Base64.encodeBase64
(org.apache.commons.codec.binary.StringUtils.getBytesUtf8("username:password"))
);
System.out.println(encodedCredentials);
connection.setRequestProperty ("Authorization", encodedCredentials);
connection.setRequestProperty("Content-Type", "application/json");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write(jsonObject.toString());
out.close();
BufferedReader in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
System.out.println(in.toString());
while (in.readLine() != null) {
System.out.println(in.readLine());
}
System.out.println("\nREST Service Invoked Successfully..");
in.close();
} catch (Exception e) {
System.out.println("\nError while calling REST Service");
System.out.println(e);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Output:
<html><head>
</head><body>
<p>The document has moved here.</p>
null
REST Service Invoked Successfully..
Can anyone help me out to resolve this issue. This link is working perfectly fine if used in REST Client ad on But with this java program it's throwing a 302 error.
I came across your thread when trying something similar. For me the problem was solved by concatenating "Basic " with encodedCredentials variable, making it "Basic EncodedValue".
I tried to understand how to send REST request to server. If I have to implement this as a request in java using httpconnections or any other connections, how would I do that?
POST /resource/1
Host: myownHost
DATE: date
Content-Type: some standard type
How should this be structured in a standard way?
URL url= new URL("http://myownHost/resource/1");
HttpsURLConnection connect= (HttpsURLConnection) url.openConnection();
connect.setRequestMethod("POST");
connect.setRequestProperty("Host", "myOwnHost");
connect.setRequestProperty("Date","03:14:15 03:14:15 GMT");
connect.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
There are many options, Apache HTTP client (http://hc.apache.org/httpcomponents-client-4.4.x/index.html) is one of them (and makes things very easy)
Creating REST requests can be as easy as this (using JSON in this case):
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet getRequest = new HttpGet(
"http://localhost:8080/RESTfulExample/json/product/get");
getRequest.addHeader("accept", "application/json");
HttpResponse response = httpClient.execute(getRequest);
if (response.getStatusLine().getStatusCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatusLine().getStatusCode());
}
BufferedReader br = new BufferedReader(
new InputStreamReader((response.getEntity().getContent())));
Update: Sorry the link to the documentation was updated.Posted the new one.
you should use json here
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class NetClientPost {
// http://localhost:8080/RESTfulExample/json/product/post
public static void main(String[] args) {
try {
URL url = new URL("http://myownHost/resource/1");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
String input = "{\"DATE\":\"03:14:15 03:14:15 GMT\",\"host\":\"myownhost\"}";
OutputStream os = conn.getOutputStream();
os.write(input.getBytes());
os.flush();
if (conn.getResponseCode() != HttpURLConnection.HTTP_CREATED) {
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
more over it browse link
There are several ways to call a RESTful service with Java but it's not required to use raw level APIs ;-)
It exists some RESTful frameworks like Restlet or JAX-RS. They address both client and server side and aim to hide the technical plumbing of such calls. Here is a sample of code describing how to do your processing with Restlet and a JSON parser:
JSONObject jsonObj = new JSONObject();
jsonObj.put("host", "...");
ClientResource cr = new Client("http://myownHost/resource/1");
cr.post(new JsonRepresentation(jsonObject);
// In the case of form
// Form form = new Form ();
// form.set("host", "...");
// cr.post(form);
You can notice that in the previous snippet, headers Content-type, Date are automatically set for you based on what you sent (form, JSON, ...)
Otherwise a small remark, to add an element you should use a method POST on the element list resource (http://myownHost/resources/) or a method PUT if you have the unique identifier you want to use to identify it (http://myownHost/resources/1). This link could be useful to you: https://templth.wordpress.com/2014/12/15/designing-a-web-api/.
Hope it helps you,
Thierry
I have setup a java servlet which accepts parameters from the URL and have it working properly:
public class GetThem extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
try {
double lat=Double.parseDouble(request.getParameter("lat"));
double lon=Double.parseDouble(request.getParameter("lon"));
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println(lat + " and " + lon);
} catch (Exception e) {
e.printStackTrace();
}
}
}
So visiting this link:
http://www.example.com:8080/HttpPost/HttpPost?lat=1&lon=2 would output:
"1.0 and 2.0"
I'm currently calling it from another java program using this code:
try{
URL objectGet = new URL("http://www.example.com:8080/HttpPost/HttpPost?lat=" + Double.toString(dg.getLatDouble()) + "&lon=" + Double.toString(dg.getLonDouble()));
URLConnection yc = objectGet.openConnection();
BufferedReader in = new BufferedReader(
new InputStreamReader(
yc.getInputStream()));
in = new BufferedReader(
new InputStreamReader(
yc.getInputStream()));
...
Now I want to change it so that I'm not using the URL parameters to pass this data to the server. I want to send much larger messages to this server. I am aware that I need to use http post rather than http get to achieve this but am not sure how to do it.
Do I need to change anything on the server side which is receiving data? What do I need to do on the client side which is posting this data?
Any help would be greatly appreciate thanks.
Ideally I'd like to send this data in JSON format.
Below there's sample from the first link found by "java HTTP POST example" in google.
try {
// Construct data
StringBuilder dataBuilder = new StringBuilder();
dataBuilder.append(URLEncoder.encode("key1", "UTF-8")).append('=').append(URLEncoder.encode("value1", "UTF-8")).
append(URLEncoder.encode("key2", "UTF-8")).append('=').append(URLEncoder.encode("value2", "UTF-8"));
// Send data
URL url = new URL("http://hostname:80/cgi");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(dataBuilder.toString());
wr.flush();
// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
// Process line...
}
wr.close();
rd.close();
} catch (Exception e) {
}
I think you should be using HTTPClient instead of handling connections and streams. Check http://hc.apache.org/httpclient-3.x/tutorial.html