I am new to Jersey Java REST WebService framework. I am trying to write a service method which consumes and produces JSON. My service code is below. It is simplest code, just for studying purpose.
#Path("/myresource")
public class MyResource {
#Path("/sendReceiveJson")
#GET
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public String sendReceiveJson(String name)
{
System.out.println("Value in name: " + name);
return "{\"serviceName\": \"Mr.Server\"}";
}
}
And following is JerseyClient code.
public class Program {
public static void main(String[] args) throws Exception{
String urlString="http://localhost:8080/MyWebService/webresources/myresource/sendReceiveJson";
URL url=new URL(urlString);
URLConnection connection=url.openConnection();
connection.setDoOutput(true);
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write("{\"clientName\": \"Mr.Client\"}");
out.close();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String decodedString;
while ((decodedString = in.readLine()) != null) {
System.out.println(decodedString);
}
in.close();
}
}
But when i run service and then client, i am unable to send/receive JSON data. I get Exception at connection.getInputStream() which is
Server returned HTTP response code: 405 for URL: http://localhost:8080/hellointernet/webresources/myresource/sendReceiveJson
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1625)
Please guide me, what needs to correct, or whether i am in wrong direction.
Your resource method is annotated as #GET which means any input data would have to be query string parameters.
In this context #Consumes(MediaType.APPLICATION_JSON) doesn't make a lot of sense as only APPLICATION_FORM_URLENCODED is supported via GET.
When you client calls setDoOutput(true) it probably switches your HTTP call to a POST hence causing the 405 Method Not Allowed.
If you want to consume JSON you should change your #GET annotation with #POST instead. Your client call should then work if it's indeed a POST. You can specify it with the following method:
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
httpCon.setDoOutput(true);
httpCon.setRequestMethod("POST");
This API is pretty low level though, so I'd highly recommend you use Jersey's Client API instead. See https://jersey.java.net/documentation/1.17/client-api.html
Related
I know we can use the /graphiql endpoint to test the created or deployed GraphQL API.
I need to consume a GraphQL API which is already there using a Java code. How can I do it.
How can I test a GraphQL end-point using a postman like application, or is it even possible.
Depending on your situation, utilizing Spring RestTemplate might be simplest thing to do.
public class Person {
#JsonProperty("query")
public final String query = "mutation($name:String, $gender:String, $age:Int) { updateDetails (name: $name, gender: $gender, age: $age) }";
#JsonProperty("variables")
public final Map<String, String> variables;
...
}
...
(new RestTemplate()).postForEntity("http://example.com/graphql", new Person("David", "male", 12));
Could go even simpler by avoiding Spring and using HttpClient, building same JSON document using StringBuilder.
Alternatively Apollo Andoid can autogenerate client code for you.
An example, to work for me...
username and password are wrong :) But, URL is ok...
with that, I don't use RestTemplate, any jars, etc..
private static void test_LivePharma() {
try {
URL url = new URL("https://stores-hml.funcionalmais.com/graphql");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-Type", "application/json");
String input="{\"query\":\"mutation{createToken(login:\\\"112233\\\",password:\\\"112233\\\"){ token}}\\n\"}";
OutputStream os = conn.getOutputStream();
os.write(input.getBytes());
os.flush();
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();
}
}
Consuming graphql API in your backend code, will require multiple steps such as.
Defining the schema
Installing the dependencies
Defining the graphql endpoint
import com.coxautodev.graphql.tools.SchemaParser;
import javax.servlet.annotation.WebServlet;
import graphql.servlet.SimpleGraphQLServlet;
#WebServlet(urlPatterns = "/graphql")
public class GraphQLEndpoint extends SimpleGraphQLServlet {
public GraphQLEndpoint() {
super(SchemaParser.newParser()
.file("schema.graphqls") //parse the schema file created earlier
.build()
.makeExecutableSchema());
}
}
Here is a detailed guide to do the same : Graphql-java-backend-implementation
Yes, it is possible to send the request using postman. You can simply copy the schema in the body.
Doing GraphQL request using Postman
Hi I have a web service class in service proxy which is having a method which returns void. I have to check whether the service is up and active. Since the method is returning void i am not able to get the status of the service. Is there any way to check the status of this web service method by using or without using ping?
Below is my webservice method which is having return type void. This web service method will do some validations and trigger another method so that it will not return any value.
#GET
#Path("/triggers/{name}")
public void triggerMethod(#PathParam("name") String triggername, #Context HttpServletRequest aHttpRequest){
//code
}
Below is the code already existing for ping function, but it will check the status from the response. This code is working for the webservices methods which is returnig response and accepts APPLICATION_JSON.
private void invoketrigger(ServiceDataDTO myData){
try{
target.request().headers(getRequestHeaders()).accept(MediaType.APPLICATION_JSON).get();
Client client = ClientBuilder.newClient();
WebTarget target = client.target(myData.getServiceURI());
Response response = target.request().headers(getRequestHeaders()).accept(MediaType.APPLICATION_JSON).get();
if(response.getStatus() == 200){
status = "green";
}
}
The code which I tried for my method is given below.
private void invoketrigger(ServiceDataDTO myData){
try{
target.request().headers(getRequestHeaders()).accept(MediaType.APPLICATION_JSON).get();
URL url = new URL(myData.getServiceURI());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
connection.setRequestMethod("GET");
connection.connect();
int response = connection.getResponseCode();
if(response == 200){
myData.setServiceStatus(ServicesDashboardConstants.STATUS_OK);
}
}catch( Exception e){
System.out.println(e);
}
}
I'm completely sure that you can't do that without returning anything. the client side will not know if the request is done or not unless if the service returned is OK,
otherwise the client side will wait for the response.
so you have to make your method returning an object of type Response. and you don't need to add anything to response just tell the method to return 200 with
response.ok (200) ; // this will tell the method what is the status code response
I'm learning web services using Java. I'm technically a noob, this is the code I've written, which works, I just don't know which method has what advantage over another, like which one is more secure? Which one will be more faster?
I'm not asking for complete too broad an answer. A short concise one will do.
I've created a REST service using Jersey 2.x and I've created client to consume the said REST service.
POST resource is as follows,
#POST
#Path("postactivity")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public String createActivity(
#QueryParam("id") int id,
#QueryParam("description") String description,
#QueryParam("duration") int duration,
#QueryParam("name")String name)
{
//My code that creates Activity object from QueryParams is here.
}
Now I've created a Client which is a Java Application. I'm consume the above REST Service above in following two ways.
Method 1 Using HTTPURLConnection
private static void doPost(){
QueryString qs = new QueryString("id", "123"); //QueryString is a class created to build query, not important to the question.
qs.add("duration", "12");
qs.add("description", "This is description");
qs.add("name", "This is Name");
String url = "http://localhost:8080/webservices/webapi/activities/activity?" + qs;
URL obj;
try {
obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestProperty("Content-Type","application/json");
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "Mozilla 5.0");
con.setDoOutput(true);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
Activity activity = GSON.fromJson(response.toString(), Activity.class); //This is for checking if i'm getting correct data back which I'm sending.
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Method 2 Using WebTarget available via Jersey
private static void doPost(){
Response entity = webTarget
.path("activities/postactivity")
.queryParam("id",2204)
.queryParam("description","Foo")
.queryParam("duration",100)
.queryParam("name", "Bar")
.request()
.post(null);
String entityRead = entity.readEntity(String.class);
System.out.println(entityRead);
Activity activityRead = GSON.fromJson(entityRead, Activity.class);
}
Thanks.
Honestyl i have two things to write to you:
1. The HttpURLConnection is the Java personal way of doing a retrieve of a web affiliate (like web services) but you have a better and stress-free way of doing it with Jersey and this will make things faster and smoother for you. For some persons they even say that the Jersey style is the High-level API while the HttpURLConnection is called the low-level API.
2. Your question was able to provide me with a necessary solution to a problem i have had for the past two days with consuming a #Queryparam POST webmethod. I really appreciate this.
Thanks
I have a REStful webservice (java, jersey) to do some stuff.
every function that calls an ajax request (GET or POST) with an url to the REST controller works fine... except of the recent ones and I do not know why.. i tried everything and stuck with this problem for nearly three days (wrote 3 different functions, changed from GET to POST, rewrote the function with new pathannotiation, tried to call on pageload.. renamed everything), I realy appreciate ANYTHING that could help me...
if the url contains rest/* the controller forwards it to the class which implements the needed functions..
JS function
function testFunc() {
$.ajax({
url: "rest/name/wut",
type: "GET",
contentType: "application/json;charset=utf-8",
success: function(response) {
alert("LSKDFJLSDKJFLKSD " + response);
},
error: function(response) {
alert("ma oidaaaa " + JSON.stringify(response));
}
});
};
Java Code in the RESTClass...
#GET
#Path("/wut")
#Produces(MediaType.APPLICATION_JSON)
private String wut() {
JSONObject json = new JSONObject();
json.put("print", "wuut");
return json.toString();
}
It does not matter if the method is doing anything useful or not... it just returns 404 no element found.
(it is not even called) Therefore i tried different new methods in the RESTClass... like:
#GET
#Path("/wut")
#Produces(MediaType.APPLICATION_JSON)
private String wut() throws IOException {
URL url = new URL(url);
StringBuffer response = new StringBuffer();
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
BufferedReader in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return response.toString();
}
I am using this snipped in another method, which is working.. I replaced the real URL with "url" for posting btw.
I also tried different MediaTypes: WILDCARD, TEXT/PLAIN...
And to just return a String...
Anyone any ideas (and SORRY for the bad english, I am really desperate so i did not do a spellcheck and english is not my native :( )
Two ideas:
First, declare your wut() method as public: public String wut()
Second, try to call your method in a browser, for example http://localhost/rest/name/wut and see what happens
I would try to use an absolute path:
Change:
url: "rest/name/wut",
to
url: "/rest/name/wut",
The error message tells me that, your client did not try the address the server provides.
I just realized that it is possible to define something like this in my RESTful resource .java file:
#GET
#Produces("text/plain")
public String getPlainTextHello() { ... }
#GET
#Produces("application/json")
public String getJSONHello() { ... }
Isn't that fantastic? But wait the moment....
PROBLEM
I am consuming my API with simple client. Something like this code with help of HttpURLConnection:
URL obj = new URL("http://some.url/res/hello");
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
conn.setRequestMethod("GET");
... /* get response ... conn.getInputStream() */
How the server 'know' which one method call to serve the client?
Regards.
First of all you should consider using the same method for different types of "produces":
#GET
#Produces({ "application/xml", "text/plain"})
public String getHello() { ... }
The different types of "produces" could be handled by JAXB (in case the response is an object...).
You can define the client side "accept" mime type by using:
String uri =
"http://localhost:8080/hello/";
URL url = new URL(uri);
HttpURLConnection connection =
(HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "application/json");
This question provides more insights (and other client side frameworks) related with this problem: REST. Jersey. How to programmatically choose what type to return: JSON or XML?
You'd probably want a generic function to do all the common work, and then simply pass this work to the response specific functions you outlined.
getHello(String responseType)
{
// do all your work you'd end up doing in both functions
switch (responseType):
case ("json") {
return getJSONHello(work);
}
case ("text") {
return getPlainTextHello(work);
}
}
I made some more checks on this and what works for me is just settings Accept:
...
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", mime);
...
where mime is "text/plain" or "application/json". This way my server calls one of the GET function.
Anyway I am confused why most answers suggest to use a common one function to serve a #GET and check for type inside this function...