webResource.get(String.class) return null - java

I created a Jersey client program to consume a REST web service that return XML.
Client client = Client.create();
WebResource webResource = client.resource("http://xyz:abc/myRestservice/getval");
I use the webResource get method to store the return value in a string variable:
String s = webResource.get(String.class);
I get no errors. But variable "s" shows null as output:
System.out.println("- "+s);
Output:
-
Process exited with exit code 0.
When I test the same web service locally (using the JDeveloper IDE without a client program), it returns value.
update:
I found that the variable "s" was showing null because of an exception (explained below) in the web service program.
The web service program uses an opaque (OracleTypes.OPAQUE) variable to store the XMLTYPE value retrieved from a stored function in ORACLE database. The opaque variable is then
assigned to a new XMLType using a cast. This somehow works while testing in JDeveloper IDE internal weblogic server.
But it doesn't work when I deploy this web service in a remote weblogic server and try to consume using a client program.
I get an exception - "oracle.sql.OPAQUE cannot be cast to oracle.xdb.XMLType".
Most probably due to some missing Jar in the remote weblogic server I guess, but not sure which jar.

You are almost there. What you should really be doing is get a ClientResponse.class and not String.class.
Here's a sample:
ClientResponse response = webResource.get(ClientResponse.class);
String responseString = response.getEntity(String.class);
Once you start using this jersey rest client you will know a bit more that per REST api contract, you will also have to set the "requestType" and the "responseAccept" as a part of the webResource. Without that, you might end up having some other weird errors as well.
Here's another sample:
ClientResponse response = webResource.type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_XML).post(ClientResponse.class);
String responseStringXML = response.getEntity(String.class);
where:
the request type (data format that the REST API expects in the body) is: "application/json" and
the response type (data format that the REST API returns) is: "application/xml"
Note that I used POST(.post method) instead of get because in normal GET request, a body is not expected (and thus no request Type is needed). The POST example was just for reference. For GET, You will still need a response type though, something along the lines of:
ClientResponse response = webResource.accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
String responseStringXML = response.getEntity(String.class);
I hope that helps !

Related

Jersey 2 - return Client's Response from resource method

I built a reverse proxy (P) to an upstream server (U). A client application (C) will issue a request to P, which will in turn issue a request to U, and the result returned by U should be returned to the client C by proxy P.
When I write the code in P like this (I want the proxy to be as generic as possible, and support multiple result types):
Client client = // get the client
Invocation.Builder builder = // configure the call to U
return builder.get(InputStream.class);
it works for both JSON and binary data, the result is returned, but the Content-Type header is always set to application/octet-stream, which is wrong. I could check the result from U for the type and set it to in the response from my proxy P, but then I would have to mess around with error handling etc. whereas when I just return the InputStream and an error occurs, the builder.get() method throws an exception which is then propagated to the client.
I would actually like to just take the Response returned by U and use it as the return value of P, like this:
Client client = // get the client
Invocation.Builder builder = // configure the call to U
return builder.get(); // returns Response
the client C, in my case a Python 3 requests application, get the following error:
requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response',))
I tried the following code:
Response upstreamResponse = client./* code code */.get();
upstreamResponse.bufferEntity();
return Response.fromResponse(upstreamResponse);
but, alas, the result is the same.
What am I missing?
I would have expected the proxy to pass the content type through (and maybe other things like content-length and status). So it would look a bit more like:
Response upstreamResponse = client./* code code */.get();
upstreamResponse.bufferEntity();
return Response.status(upstreamResponse.status())
.type(upstreamResponse.getMediaType()
// and so on
Realistically, you may or may not want many of the things from the upstreamResponse header too - what about Cookies for example?

Getting Error 400 The request sent by the client was syntactically incorrect (): Using RestTemplate, Spring

I have a client-server architecture in REST, Spring MVC. Tghe client is hitting the server URL and sending two parameters along with it. The server is supposed to reply back to the client with a responce value. One the client side I am using RestTemplate to access server URL. When running, the server URL is getting accessed successfully (server side logic is getting executed), but then I am getting the following error on the client side:
HTTP Status 400 -
--------------------------------------------------------------------------------
type Status report
message
description The request sent by the client was syntactically incorrect ().
The client side code is:
rresult = restTemplate.getForObject("http://localhost:8081/Merchant/api/movieTheater"+params.toString(), ResponseText.class);
The esrver side code is:
#ResponseBody
#RequestMapping(value="movieTheater")
public ResponseText getCustomerInput(#RequestParam("name") String name, #RequestParam("price") Double price) {
System.out.println("Requst URL got accessed here");
ResponseText result = new ResponseText();
Transaction transaction = new Transaction();
transaction.setMovieName(name);
transaction.setTicketPrice(price);
transaction.setDatetime(new Date());
if(transactionService.addTransaction(transaction))
result.setMessage(ResponseStatus.SUCCESS.getStatus());
else
result.setMessage(ResponseStatus.FAILED.getStatus());
return result;
}
When I am accessing the URL separately, it is working fine. I am not sure what I am doing wrong. Please help! Thanks in advance!
I figured it out!!! I have an inner class for creating the JSON structure in the client side. The solution is to make that class static! As it was not static, it was trying to instantiate, and hence, got the error message: "Could not read JSON: No suitable constructor found for type"
I guess the URL "http://localhost:8081/Merchant/api/movieTheater"+params.toString() is incorrect. What's the class name of params and what's the result returned by the mothod toString(). getCustomerInput() method can't get the arguments value when incorrect URL accessed.
URL must be like this
http://localhost:8081/Merchant/api/movieTheater?name=xxx&price=1.01

Error while calling RESTful Web-Service using Jersey Client POST method

Getting an error while trying to consume a Restful web service using
POST method(with form param).
I want to consume a REST application using POST method.
Please find below the resource class I want to access.
#Path("/user")
public class User {
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response get(#FormParam("username") String userName,
#FormParam("userid") String userId ){
}
I tried using Jesry Client for accessing.Please find below the code i tried.
I tried adding values to FormParam as shown below.
Trail 1
WebResource webResource = client.resource("baseURL/user");
String input = "userid:1001,username:demo1";
ClientResponse response = webResource.type("application/x-www-form-urlencoded").post(ClientResponse.class, input);
I am getting a an error response back "The server encountered an internal error () that prevented it from fulfilling this request".
I think I am not adding the values to FormParam properly.
Trial 2
I also tried adding the form params using the below code
MultivaluedMap formData = new MultivaluedMapImpl();
formData.add("userid", "1001");
formData.add("username", "demo1");
ClientResponse response = webResource.type("application/x-www-form-urlencoded").post(ClientResponse.class, formData);
This also resulted in the same error.
Trial 3
Form f = new Form();
f.add("userid", "1001D");
f.add("username", "1001D");
ClientResponse response = webResource.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE).post(ClientResponse.class, f);
This also resulted in the same error.
Any help is appreciated.
Since your error indicates "Server encountered an internal error" you need to look at the server (logs) to see what went wrong. Certainly your 3rd client looks fine to reach the service you defined (assuming you are using something real instead of the string "baseURL").
You can easily test your server is working separately from your client by creating a HTML page to reach the service. Create a HTML form using enctype="application/x-www-form-urlencoded" and posting to your service endpoint (what you are calling "baseURL/user") with form parameters userid and username. When you view the HTML form in a browser and hit the submit button, it will call your server - if you get the same error you can be sure it is nothing to do with your client code.
Hope http://yogeshmprajapati.blogspot.in/2011/12/login-to-fb-from-java.html will help you.

Printing the contents of a Restlet web service request

I am implementing a Restful web service using Restlet - I have not found a way to print the content of the HTTP request. I need to check the content of the http request, to get something like this:
POST http://localhost:8080/students
<Student>
<name>Tony<name/>
<age>19<age/>
<Student/>
I am send a custom object the server resource using the following code
ClientResource c = new CLientResource(url);
c.post(student, Student.Class);
I tried to get the HTTP request also with wireshark , I did not find any http requests, I only found TCP connections.
Anybody knows how to print the content of the http request either on client or server side?
You can use the following on the client side :
clientResource.getResponseEntity().getText();
From the javadoc :
Converts the representation to a string value. Be careful when using
this method as the conversion of large content to a string fully
stored in memory can result in OutOfMemoryErrors being thrown.
By the way, HTTP requests are TCP connections.

SOAP web service calls from Javascript

I'm struggling to successfully make a web service call to a SOAP web service from a web page. The web service is a Java web service that uses JAX-WS.
Here is the web method that I'm trying to call:
#WebMethod
public String sayHi(#WebParam(name="name") String name)
{
System.out.println("Hello "+name+"!");
return "Hello "+name+"!";
}
I've tried doing the web service call using the JQuery library jqSOAPClient (http://plugins.jquery.com/project/jqSOAPClient).
Here is the code that I've used:
var processResponse = function(respObj)
{
alert("Response received: "+respObj);
};
SOAPClient.Proxy = url;
var body = new SOAPObject("sayHi");
body.ns = ns;
body.appendChild(new SOAPObject("name").val("Bernhard"));
var sr = new SOAPRequest(ns+"sayHi",body);
SOAPClient.SendRequest(sr,processResponse);
No response seems to be coming back. When in jqSOAPClient.js I log the xData.responseXML data member I get 'undefined'. In the web service I see the warning
24 Mar 2011 10:49:51 AM com.sun.xml.ws.transport.http.server.WSHttpHandler handleExchange
WARNING: Cannot handle HTTP method: OPTIONS
I've also tried using a javascript library, soapclient.js (http://www.codeproject.com/kb/Ajax/JavaScriptSOAPClient.aspx). The client side code that I use here is
var processResponse = function(respObj)
{
alert("Response received: "+respObj);
};
var paramaters = new SOAPClientParameters();
paramaters.add("name","Bernhard");
SOAPClient.invoke(url,"sayHi",paramaters,true,processResponse);
I've bypassed the part in soapclient.js that fetches the WSDL, since it doesn't work
(I get an: IOException: An established connection was aborted by the software in your host machine on the web service side). The WSDL is only retrieved for the appropriate name space to use, so I've just replaced the variable ns with the actual name space.
I get exactly the same warning on the web service as before (cannot handle HTTP method: OPTIONS) and in the browser's error console I get the error "document is null". When I log the value of req.responseXML in soapclient.js I see that it is null.
Could anyone advise on what might be going wrong and what I should do to get this to work?
I found out what was going on here. It is the same scenario as in this thread: jQuery $.ajax(), $.post sending "OPTIONS" as REQUEST_METHOD in Firefox.
Basically I'm using Firefox and when one is doing a cross domain call (domain of the address of the web service is not the same as the domain of the web page) from Firefox using AJAX, Firefox first sends an OPTIONS HTTP-message (before it transmits the POST message), to determine from the web service if the call should be allowed or not. The web service must then respond to this OPTIONS message to tell if it allows the request to come through.
Now, the warning from JAX-WS ("Cannot handle HTTP method: OPTIONS") suggests that it won't handle any OPTIONS HTTP-messages. That's ok - the web service will eventually run on Glassfish.
The question now is how I can configure Glassfish to respond to the OPTIONS message.
In the thread referenced above Juha says that he uses the following code in Django:
def send_data(request):
if request.method == "OPTIONS":
response = HttpResponse()
response['Access-Control-Allow-Origin'] = '*'
response['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
response['Access-Control-Max-Age'] = 1000
response['Access-Control-Allow-Headers'] = '*'
return response
if request.method == "POST":
# ...
Access-Control-Allow-Origin gives a pattern which indicates which origins (recipient addresses) will be accepted (mine might be a bit more strict than simply allowing any origin) and Access-Control-Max-Age tells after how many seconds the client will have to request permission again.
How do I do this in Glassfish?
Have you actually tested that ws is working properly?
You can use SoapUI for inspecting request/response etc.
When you confirm that ws is working from SoapUI, inspect what is format of raw Soap message. Then try to inspect how it looks before sending with .js method, and compare them.
It might help you understand what is wrong.
Check if this helps
http://bugs.jquery.com/attachment/ticket/6029/jquery-disable-firefox3-cross-domain-magic.patch
it's marked as invalid
http://bugs.jquery.com/ticket/6029
but it might give you some hint
On the other hand, instead to override proper settings for cross-domain scripting might be better if you can create and call local page that will do request to ws and return result.
Or even better, you can create page that will receive url as param and do request to that url and just return result. That way it will be more generic and reusable.

Categories