gwt: making remote calls fails - sop? - gwt

I am writing some interface for users to collect data and send to a server. I went for GWT for various reasons.
Now, when I try to call my server:
String url = "http://127.0.0.1:3000/data/collection.xml";
RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, URL.encode(url));
Request request = builder.sendRequest(data, new RequestCallback() {
public void onResponseReceived(Request request, Response response) {
if (200 == response.getStatusCode()) {
result.setText("SUCCESS!");
} else {
result.setText("ERROR with code: " + response.getStatusCode());
My server gets the request (a POST with some data) but I get ERROR with code: 0 (!) all the time. I guess this has to do with SOP. I read lots about this SOP but I am even more confused now. I tried to follow this tutorial but that's using a different approach (I managed to adapt it to issue GET calls only, but return objects are always null).
Can anyone point me into the right direction? thanks

You can not call any service from another server because of SOP. What you can do, you can use your original server as proxy to other servers.. I would recommend you to read this tutorial.

Related

Spring Cloud Gateway Routing Based On Content of the Request Body

I need to create a reverse proxy that takes incoming request and based on the content of the request body, route the request to specific URI.
This is for a routing micro service that acts like a reverse proxy and does routing based on some information from each request body. This means for each request I need to parse the request body and get the "username" field and then make a JDBC connection to fetch additional information from the database. Based on that information in database, it would finally redirect the request to the correct URI.
From what I have now, I have 2 blocking methods. The first one is the parsing for the request body, the other one is the JDBC connection to the database. I understand that I should not put any blocking calls inside the gateway filter. I just don't know what I should do in this case. I could have both operations running async but in the end I still need the information from database to do routing.
#Bean
public RouteLocator apiLocator(RouteLocatorBuilder builder, XmlMapper xmlMapper) {
return builder.routes()
.route(r -> r
.path("/test")
.and()
.readBody(String.class, s -> true) // Read the request body, data will be cached as cachedRequestBodyObject
.filters(f -> f.filter(new GatewayFilter() {
#Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
try {
// The following method is blocking and should not be put here
xmlMapper.readValue((String) exchange.getAttribute("cachedRequestBodyObject"), Map.class);
} catch (Exception e) {
//TODO
}
return chain.filter(exchange);
}
}))
.uri("http://localhost:8080"))
.build();
}
The above example only includes the blocking parsing as my request body is XML based. My IDE is warning me of having a blocking call there which I really appreciate.
Any help is greatly appreciated. Thank you everyone!
After some research, Mono.fromCallable seems to be a good fit. I then asked the same question directly under the github repo, it turns out that using a servlet app may be better. For anyone who is interested to see what I came up with, please take a look here https://github.com/spring-cloud/spring-cloud-gateway/issues/1229

Can I retrieve a file from server with GET in rest

Can I return a file with my get request? I want to return a word document to calling angularJS service through REST GET method. Not sure if it is even possible.
You're a bit light on detail, so I'm gonna be a bit light on answer.
A REST request is just... a request. The REST side of things is more the way URLs are defined that what actually happens in the request process itself, which is all still vanilla HTTP.
So, same as with any GET request, if you want to return binary data, set the headers appropriately (<cfheader>), then return the file (<cfcontent>).
So this is how I did it, luckily I got this:
http://smithcustomdev.com/2010/10/20/download-file-to-browser-using-cfscript/
All I have to do was make the method remote and listen to REST service
<cfscript>
private void function serveFile(string filePath){
var fileContent = fileRead(expandPath(filePath));
var context = getPageContext();
context.setFlushOutput(false);
var response = context.getResponse().getResponse();
response.reset();
response.setContentType("text/csv");
response.setContentLength(len(fileContent));
response.setHeader("Content-Disposition","attachment; filename=#listLast(filePath,'\')#");
var out = response.getOutputStream();
out.write(ToBinary(ToBase64(fileContent)));
out.flush();
out.close();
}
</cfscript>

gwt getModuleBaseURL on same server creates an java.lang.UnsatisfiedLinkError

I have a single GWT web-application integrated with Spring MVC. I have a working Controller which works perfectly and is unit tested to accept POSTed JSON data and returns JSON data.
From within the same application, to avoid any SOP cross-site domain issues, I am making a call with a RequestBuilder to POST the same json data, and I expect JSON data back.
I created a basic java class that should make a call, but I have a few issues. This running web-app is running in hosted mode in Jetty in Eclipse. I have done a ton of research on how GWT should make a call to an existing web-service with a simple HTP request.
The first issue from my unit test is that:
String baseUrl = GWT.getModuleBaseURL();
is not working and I get:
java.lang.UnsatisfiedLinkError: com.google.gwt.core.client.impl.Impl.getModuleBaseURL()Ljava/lang/String;
I think I know what the correct URL should be, so when I hard-code the url correctly, and execute this code:
String url = getRootUrl() + "rest/pendingInvoices/searchAndCount";
System.out.println("PendingInvoiceDataSource: getData: url=" + url);
// Send request to server and catch any errors.
RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, url);
builder.setHeader("Accept", "application/json");
builder.setHeader("Content-type", "application/json");
// builder.setRequestData(requestData);
try
{
System.out.println("PendingInvoiceDataSource: SEND REQUEST: getData: requestData=" + requestData);
Request request = builder.sendRequest(requestData, new RequestCallback()
{
public void onError(Request request, Throwable exception)
{
System.out.println("Couldn't retrieve JSON");
}
#Override
public void onResponseReceived(Request request, Response response)
{
if (200 == response.getStatusCode())
{
// updateTable(JsonUtils.safeEval(response.getText()));
System.out.println("data=" + response.getText());
}
else
{
System.out.println("Couldn't retrieve JSON (" + response.getStatusText() + ")");
}
}
});
}
catch (RequestException e)
{
System.out.println("Couldn't retrieve JSON");
}
I get this error on he sendRequest:
java.lang.UnsatisfiedLinkError: com.google.gwt.xhr.client.XMLHttpRequest.create()Lcom/google/gwt/xhr/client/XMLHttpRequest;
at com.google.gwt.xhr.client.XMLHttpRequest.create(Native Method)
at com.google.gwt.http.client.RequestBuilder.doSend(RequestBuilder.java:383)
at com.google.gwt.http.client.RequestBuilder.sendRequest(RequestBuilder.java:261)
I think this might be a quick fix, or maybe something small I have forgotten, so I'll try some more testing and see what I can find.
Everything client in GWT is only meant to run on the client-side: compiled to JS or in DevMode.
Only shared, server and vm classes can be used on the server-side.
If you want to get your server URL, use the appropriate methods from the HttpServletRequest (or whatever it is in Spring MVC as it seems from how you tagged the question that's what you're using).
If you want to make HTTP requests from your server, use an HttpURLConnection, or OkHttp, Apache Http Components or similar libraries, or even Spring's own HTTP client API.
Actually, it was only the Unit Test that was having a problem. Once I actually tried to run the deployed code, it all worked. I'll still try h GWTTestCase as suggested in order to get the unit test working.
But everything worked correctly when I ran the deployed code.
I also changed: String baseUrl = GWT.getModuleBaseURL();
which gave me:
http://localhost:8888/MyProject
To: String baseUrl = GWT.getHostPageBaseURL();
which gave me:
http://localhost:8888/
and that all worked.

GWT JSONPRequestBuilder - "Unknown Token :" error in browser console with Timeout exception at the end

I am trying to call a Restful WS from GWT using JSOPRequestBuilder. I have a similar issue which was reported in the link
http://groups.google.com/group/google-web-toolkit/browse_thread/thread/ef93383aca7a3dfc/d4dc5bad1a9110ea
But, I could not figure out the solution. Kindly help me at the earliest.
My JAX-WS resource code snippet from server
#GET
#Produces(MediaType.APPLICATION_JSON)
public DealerAddress getDealerAddress(#QueryParam("dealerId") String sDealerId) {
DealerAddress dlrAd = new DealerAddress("test", "test", "test", "test", 10, new Date(), new Date());
return dlrAd;
}
Jersey returns a JSON object of DealerAddress.
Now rest URL "https://127.0.0.1:8181/application/rest/OrderManagementResource?alt=json-in-script&dealerId=DLR1"
works absolutely fine when i tried request in browser.
It even works with RequestBuilder approach from GWT but not with JSONPRequestBuilder approach.
Code snippet to invoke WS from GWT using JSONPRequestBuilder
JsonpRequestBuilder jsonPReqBuilder = new JsonpRequestBuilder();
jsonPReqBuilder.setTimeout(100000);
jsonPReqBuilder.setCallbackParam("callback");
jsonPReqBuilder.requestObject("https://127.0.0.1:8181/application/rest/OrderManagementResource?alt=json-in-script&dealerId=DLR1" , new AsyncCallback<DealerAddressJSON>() {
#Override
public void onFailure(Throwable caught) {
// TODO Auto-generated method stub
caught.printStackTrace();
Window.alert("Inside error"+caught.getLocalizedMessage());
}
#Override
public void onSuccess(DealerAddressJSON result) {
// TODO Auto-generated method stub
Window.alert("Inside success"+result);
}
});
where as DealerAddressJSON is a JavaScriptObject type class.
I could see that my JAX Rest resource getting called and saying returning from server.
Also, I could see that in Firebug that the response comes in browser but fails with an exception "Unknown token :"
At the end I always get a Timeout exception.
Now I am in big question whether the way we return JSON from JAX-RS resource is a problem in server
or
JSONPRequestBuilder calling procedure is a problem? I could not understand the callback changes which some of the links explained on this issue.
Kindly help me.
You are probably sending back JSON, while the JSONPRequestBuilder expects JSONP. These are not the same thing.
JSON is just the data, as is - make the request using AJAX (i.e. the RequestBuilder), and the contents can be read directly. These requests can only be made to the same server. Example JSON data:
{"response":"success", "items":[{"id":1}, {"id":2}]}
In contrast, JSONP is designed for cross-origin requests, so instead of just containing the data, the data is wrapped up in a JavaScript. Since your JSON service isn't wrapping the a response in a js function call, this isn't working. Example JSONP data:
callback_1({"response":"success", "items":[{"id":1}, {"id":2}]})
The callback changes with each request, so the server is supposed to change that callback function based on what the client requested each time.

GWT - Way around Access-Control-Allow-Origin?

I'm making an internet application with GWT, and one of the features that I've been stuck on for a few weeks is getting the users contact data from google data. I've tried things like GWT-GData and they don't seem to play nicely with the current version of GWT, so I tried going the more traditional approach with OAuth and doing an HTTP Get request. I haven't been receiving anything back as a response, and couldn't figure out why, and I happened across my javascript error log and I'm getting:
"Origin [site name here] is not allowed by Access-Control-Allow-Origin"
I've done some reading and I have a decent idea of what's going on, but I don't know how to get around it in GWT. I've found plenty of read-ups on how to get around it with other platforms, but I haven't seen anything for GWT. Can anyone offer any wisdom?
Edit:
Here is the code I'm using:
public static void doGet(String url, String oauthToken) {
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);
try {
Request request = builder.sendRequest(oauthToken, new RequestCallback() {
#Override
public void onError(Request request, Throwable e) {
GWT.log(e.toString(), e);
}
#Override
public void onResponseReceived(Request request, Response response) {
Window.alert("HEADER:" + response.getHeadersAsString()
+ "\nSTATUS: " + response.getStatusText()
+ "\nTEXT: " + response.getText());
}
});
} catch (RequestException e) {
GWT.log(e.toString(), e);
}
}
There's nothing you can do but configure the server to accept the origin of the request (i.e. add it to the returned Access-Control-Allow-Origin.
Because it's GData, it might however simply be a mistake on your side re. the requested URL: there's no Access-Control-Allow-Origin when you request data in Atom format, only when requesting JSON (and the value is then * which allows everyone, so shouldn't cause any issue like you're seeing): http://code.google.com/p/chromium/issues/detail?id=45980#c2
While this doesn't answer the original question, the following may help others who have the same underlying issue that arrived at this page (I'm using a GWT client with a Groovy web server). This did the trick on the server:
HttpExchange.getResponseHeaders().add("Access-Control-Allow-Origin","*");