Consume web service which produces stream (streams some binary data as output) - java

I have a REST Java service which returns a file as a stream. It's similar to the output approaches described here:
Input and Output binary streams using JERSEY?
I also use StreamingOuput as described above.
I now wonder now how to call this method on the client side. I use Swagger but I am not very good with it, and I have no idea how to call my method.
Currently in the web service I have defined
#ApiOperation(value = "Export file from the database", response = File.class)
but I doubt this File.class is a good idea here.
Do I need to modify this response type? What is a good way of calling my service?
When I call my service from the Swagger UI interface I see these response headers.
{
"date": "Sun, 27 Aug 2017 11:14:20 GMT",
"content-disposition": "attachment; filename=\"DealerTexts.xlsx\"",
"x-powered-by": "Servlet/3.1 JSP/2.3 ( Java/Oracle Corporation/1.8)",
"transfer-encoding": "chunked",
"server": "",
"content-type": "application/octet-stream"
}
In the response body it gives me a link which I can click and download the file generated by the web service. So my question is just how I can call this same thing from Java code on the client side.

Related

ContentType.URLENC with sending API REQUEST

I started API testing recently and facing different content-types each time, and i wan to know specific in what case we use ContentType.URLENC, I kinda sure we use it with x-www-form-urlencoded, but still confusing and we use it with usually POST request ?
Firstly, when you want to send infomation to server, you need to tell the server how you structure your message in BODY part. Below is some basic ContentType:
Using key-value with&: you can choose x-www-form-urlencoded.Since there are some special characters in your message, then these need to be encoded. That's why urlencoded.
Eg: name=abc&age=20
Json type: choose application/json .
Eg:
{
"name": "abc",
"age": 20
}
Want to send a file: choose form-data
Secondly, BODY part usually goes with POST and PUT request.

Unable to retrieve data from Sabre PriceQuoteServicesRQ 4.10 SOAP API: XML request schema validation failed: PriceQuoteInfo element is not complete

I have a problem when trying to retrieve data from Manage Price Quote Details (PriceQuoteServicesRQ) 4.10 Sabre SOAP API.
I generated Java classes using the WSDL from Sabre website (https://developer.sabre.com/docs/soap_apis/air/fulfill/manage_price_quote_details/resources).
I am constructing my request object in a following way:
ReservationTypeShort reservation = new ReservationTypeShort();
reservation.setValue("YEZUYS");
PriceQuoteInfoSearchParameters info = new PriceQuoteInfoSearchParameters();
info.setReservation(reservation);
PriceQuoteSearchParameters searchParameters = new PriceQuoteSearchParameters();
searchParameters.getPriceQuoteInfo().add(info);
searchParameters.setResultType(StringResultType.S);
GetPriceQuoteRQ req = new GetPriceQuoteRQ();
req.setSearchParameters(searchParameters);
req.setVersion("4.1.0");
I pretty-printed the object and this is what I got:
"priceQuoteInfo" : [ {
"reservation" : {
"value" : "YEZUYS",
"createDate" : null
},
"status" : [ ],
"type" : null,
"priceQuote" : [ ],
"travelItinerary" : null
} ],
So according to their documentation:
I am supplying all fields that are necessary, however it still doesn't work for me.
Did anybody else had the same problem? What am I missing/what am I doing wrong?
This is the error message I am getting:
XML request schema validation failed: PriceQuoteInfo element is not complete. One of the following fields: Status, Type, PriceQuote, TravelItinerary should be used. Please amend your request and try again.
What I have tried so far?
I asked Sabre Support for help, but they responded with a message that basically says "it works on my end".
I intercepted the XML body:
<ns5:GetPriceQuoteRQ version="4.1.0">
<ns5:SearchParameters resultType="S">
<ns5:PriceQuoteInfo>
<ns5:Reservation>YEZUYS</ns5:Reservation>
</ns5:PriceQuoteInfo>
</ns5:SearchParameters>
</ns5:GetPriceQuoteRQ>
I was missing an empty element <PriceQuote/> in my request.
It can be added by doing:
PriceQuoteInfoSearchParameters info = new PriceQuoteInfoSearchParameters();
info.setReservation(reservation);
info.getPriceQuote().add(new PriceQuoteSearch());
So according to their documentation I am supplying all fields that are necessary [...]
By documentation do you mean the WSDL or some human readable documentation (like PDF, DOCX, web pages, etc)? According to the error message you get, your SOAP request isn't valid. Sabre Support responding with "it works on my end" is another way of saying that you are not doing something correctly on your end. You need to troubleshoot your request.
From what I see, the error message is saying Status, Type, PriceQuote, and TravelItinerary but you are sending status, type, priceQuote, and travelItinerary. XML is case sensitive, and it's possible the service field names are too, so this might be the first thing to check.
Then, two of your fields (type and travelItinerary) are null. Also, priceQuote is empty. Is that OK? This is the next thing to check.
The object you pretty-printed shows a JSON format. Is this actually the format you are sending on the wire to the service? SOAP wants XML, not JSON. You also mention you generated the code from the WSDL. Using what framework or library? Does the generated code send XML?
Like I said, you need to troubleshoot the call:
download SoapUI
feed the WSDL file to SoapUI so that it can generate sample requests for you
fill in those request with real data and make calls to the web service until you get back a successful and expected response
using the same parameters from 3) in your code, perform the same call using your code
use SoapUI's monitoring tools to intercept the request at 4) and inspect the SOAP message you are sending
check the request you are making with your code against the successful request you got by using SoapUI directly
correct any differences until your request made by code is like the one send from SoapUI and it returns a successful and expected response.

Orchestration API - (POST And Get API) using spring boot

I have to construct Orchestration API which calls internally GET API and the response body of GET call should be passed has the request body of POST API automatically using java Spring boot
first :-> get call: /students/{id}/information and response will be
{
"id": "123",
"name": "abc",
"marks": 80
}
Now the above output of get response should be passed as request body for post call. instead of doing manual copying get response and pasting as request body to post call.
it should be done automatically
please post your idea's
thanks

Google Pub/Sub Emulator - Publishing message using Java's HTTP.POST throws 400 Bad Request

I have the Google Pub/Sub emulator running locally on my machine. I am able to publish a message using YARC (Yet Another REST Client) with the following details:
URL:
POST http://localhost:8311/v1/projects/my-project/topics/my-project-test:publish
Payload:
{
"messages": [
{
"attributes": {
"1": 1
}
}
]
}
This results in a 200 response, and I can see in the console output from the emulator that the messages are received.
Now, when I try to do the same using Java's HTTP library, I am consistently getting 400 errors. Here's the code:
String payload = "{\"messages\":[{\"attributes\":{\"1\":1}}]}";
HTTP.Response response = HTTP.POST(options.getPubsubRootUrl() + "/v1/projects/my-project/topics/my-project-test:publish", payload);
I checked the headers in the debugger and found that they are:
Content-Type: application/json
Content-length: ####(some number)
I'm sending Content-Type from the REST client as well (Content-length may be being sent behind the scenes as well)
As far as I can tell these requests are identical, but for some reason doing it from my Java code is causing an error while doing it from a REST client is not.
Is there anything glaring here I'm missing?
Turns out the HTTP class I thought was a standard Java class was org.neo4j.test.server.HTTP, which was auto-imported in Eclipse when I copied that line from elsewhere in my code.
That particular implementation is, I believe, designed to work with a neo4j test server and must do something beyond simple HTTP requests (add some headers or something), resulting in the requests being somehow different than what I was sending from YARC.

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