How to fetch data of remote server in GWT development mode? - gwt

I'm a GWT beginner. I debug my program in GWT development mode. The url is http://127.0.0.1:8888/Replayer.html?gwt.codesvr=127.0.0.1:9997.
I want to get data from existing server which provided data in json format. My code is:
String url = "http://i.abc.com?sid=" + mSessionId + "&action=info";
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL.encode(url));
try {
Request request = builder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception) {
// Couldn't connect to server (could be timeout, SOP
// violation, etc.)
Window.alert("Get fudao info error");
mPrepare = false;
}
#Override
public void onResponseReceived(Request request, Response response) {
GWT.log("statuscodeļ¼š"+response.getStatusCode());
if (200 == response.getStatusCode()) {
// Process the response in response.getText()
Window.alert(response.getText());
mPrepare = true;
} else {
// Handle the error. Can get the status text from
// response.getStatusText()
Window.alert("Get fudao info wrong");
mPrepare = false;
}
}
});
} catch (RequestException e) {
// Couldn't connect to server
}
When run the application, the request failed and its status was "canceled". Is it the reason that I cannot request remote server address from localhost for SOP restrictions?
How to fetch data of remote server in GWT development mode?

Normally can't fetch data from another server form GWT client code. But your local server can serve as proxy, e.g. you sending request to your local server, it will send request to remote server, than it will get response from remote server and give it to the GWT client code. This is basically the easiest solution.

Related

How to Resove Error Related to HttpClient in WebAssembly App

I am trying to test HttpClient in a small WebAssemply App (created using .NET 5).
The program.cs contains following statement to add HttpClient service:
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
The source code of my test Razor Component is posted at the end. Following exception occurred when executing the statement: "HttpResponseMessage response = await http.GetAsync(apiUrl)". The same error occurred when using http.GetFromJsonAsync<>.
I was able to Web API to get data from same website in Blazor Server app. For some reason, I could not make it work in WebAssembly app. Any help will be appreciated.
ERROR MESSAGE
mono_wasm_start_single_stepping 2
crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: TypeError: Failed to fetch
System.Net.Http.HttpRequestException: TypeError: Failed to fetch
at System.Net.Http.BrowserHttpHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.SendAsyncCore(HttpRequestMessage request, HttpCompletionOption completionOption, Boolean async, Boolean emitTelemetryStartStop, CancellationToken cancellationToken)
at WebAssemblyUseWebApi.Pages.Weather.OnInitializedAsync() in C:\projects\my_tryout\WebAssemblyUseWebApi\WebAssemblyUseWebApi\Pages\Weather.razor:line 27
at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle)
=============================================================================
SOURCE CODE
page "/weather"
#inject HttpClient http
<h3>Weather Data</h3>
#if (!string.IsNullOrEmpty(errorMessage))
{
<p>#errorMessage</p>
}
else if (string.IsNullOrEmpty(data))
{
<p>Loading ...</p>
}
else
{
<p>#data</p>
}
#code {
string errorMessage = string.Empty;
public string data;
protected override async Task OnInitializedAsync()
{
string apiUrl = "https://www.metaweather.com/api/location/2471217/";
HttpResponseMessage response = await http.GetAsync(apiUrl);
if (response.IsSuccessStatusCode)
{
data = response.Content.ReadAsStringAsync().Result;
}
else
{
errorMessage = response.ReasonPhrase;
}
}
}
That site does not seem to allow requests from a Browser.
There is no CORS header (access-control-allow-origin=...) in the response.
You can use either Blazor Serverside or add an API server to your WebAssembly project. Do have a look at the Wasm Hosted template before you try to reinvent the wheel.
The issue was resolved when I created an ASPCoreWebAPI app on the server side with following config settings in startup.cs program. These settings allow the WebAssembly app to retrieve data using HTTPClient.
1. In ConfigureServices, Add following
-------------------------------------------------------------------------
services.AddCors(options =>
{
options.AddPolicy(
"Open",
builder => builder.AllowAnyOrigin().AllowAnyHeader());
});
------------------------------------------------------------------------
2. In Configurations, add following
------------------------------------------------------------------------
app.UseCors("Open");
-----------------------------------------------------------------------

Microsoft bot framework: What must a messaging endpoint return?

I am implementing my own messaging endpoint for a MS Teams bot from scratch. I'm almost there. The endpoint does get called with conversationUpdate events, but I see:
There was an error sending this message to your bot: HTTP status code
BadRequest
in the admin on https://dev.botframework.com/bots/channels?id=...
I am probably returning something bad in the HTTP request. As I didn't find anything about the response in the REST API docs, I am just sending the string "{}" with a standard content type.
So what do I actually need to return?
Edit: It appears that the relevant part of the botbuilder-java package is this function in ControllerBase.java:
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
try {
Activity activity = getActivity(request);
String authHeader = request.getHeader("Authorization");
adapter.processIncomingActivity(
authHeader, activity, turnContext -> bot.onTurn(turnContext)
).handle((result, exception) -> {
if (exception == null) {
response.setStatus(HttpServletResponse.SC_ACCEPTED);
return null;
}
if (exception.getCause() instanceof AuthenticationException) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
} else {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
return null;
});
} catch (Exception ex) {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
As far as I can tell, this only sets a return code (202) but does not return any content. I now try to do the same thing in my messaging endpoint, but Teams still complains about "BadRequest".
Edit: I have snooped what the actual BotFramework Java sample does - it just returns a code 202 with an empty request body and no content type. I'm now doing the exact same thing, and Teams still complains that it could not send the message. Kinda giving up here.

how to get a valid response from a php web service on GWT

I'm trying to get data from a php web service (that I've put in my localhost - tested and works fine) in the client side of my GWT application.
I've tried to use the following package com.google.gwt.http.client.* it looks like the code works fine but the response is always 0, it's highly likely to be a corss problem but I still can't figure how to solve it even though I've tried to use requestBuilder.setHeader(..);
here's the code I'm working on:
String url = "http://localhost/geoTrackerTest.php?id=15";
RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.GET, URL.encode(url));
requestBuilder.setHeader("Access-Control-Allow-Origin", "http://localhost");
requestBuilder.setHeader("Access-Control-Allow-Methods", "POST, GET, UPDATE, OPTIONS");
requestBuilder.setHeader("Access-Control-Allow-Headers", "x-http-method-override");
try {
Request request = requestBuilder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception) {
GWT.log("Error: "+exception.getMessage());
}
public void onResponseReceived(Request request, Response response) {
if (200 == response.getStatusCode()) {
GWT.log("response: "+response.getText());
} else {
GWT.log("response code: "+response.getStatusCode());
}
}
});
} catch (RequestException e) {
GWT.log("Request Exception: "+e.getMessage());
}
I'm still getting 0 as a response.
You will need to set the header in response from server side (not from the GWT client side), then you can make Cross Site Requests from GWT RequestBuilder. Something like this on server side:
Response.setHeader("Access-Control-Allow-Origin","http://localhost");
If you only need to send GET requests, you can use JSONP (http://www.gwtproject.org/javadoc/latest/com/google/gwt/jsonp/client/JsonpRequestBuilder.html) instead to send cross domain requests, without headers setting on server side.

RequestBuilder returns empty response

I am using RequestBuilder on the front end of GWT to send a HTTP GET request to a Restlet Web Service. However, the request can get into the web service and the web service return a String (in the format of JSON). The problem is no response is returned when I monitor the process through fireBug. Anybody knows why?
Here is the code:
String url = "http://localhost:8080/Books";
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);
try {
builder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception)
{
exception.printStackTrace();
Window.alert("fail - " + exception.getMessage());
}
public void onResponseReceived(Request request, Response response)
{
Window.alert("success - " + response.getText());
}
});
} catch (RequestException e)
{
e.printStackTrace();
}
response.getText() always return empty.
Thanks in advance!
Ike
Do you do your call to a Restlet server on the same host and port that served the webpage that makes the request ?
I am guessing you are running into http://en.wikipedia.org/wiki/Same_origin_policy
Your problem is the Same Origin Policy. The protocol, domain and port in all your requests must be the same as those where your GWT app is being served. If you're serving in Eclipse at port 8888 and your custom server is at port 8080, this won't be trivial.
Try configuring an apache server to proxy e.g. requests to http://localhost/gwt-app.html to http://localhost:8888/gwt-app.html and everything else to your server at http://localhost:8080/*

Calling remote Servlet from GWT

I am trying to call remote servlet from GWT, actually the GWT-RPC doesn't seems to work, so I am trying to do it using the RequestBuilder.
Here's the code snippet:
String url = "http://some-remote-host:8888/GWTJSTest/SomeServlet?name=" + textBox.getText();
RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.GET, url);
// requestBuilder.setHeader("Origin", "*");
// requestBuilder.setHeader("Access-Control-Allow-Origin", "*");
try
{
requestBuilder.sendRequest(null, new RequestCallback()
{
public void onResponseReceived(Request request, Response response)
{
if (response.getStatusCode() == 200)
{
Window.alert(response.getText());
}else
{
Window.alert(response.getText() + " : " + response.getStatusCode() + response.getStatusText());
}
}
public void onError(Request arg0, Throwable arg1)
{
Window.alert(arg1.toString());
}
});
} catch (RequestException e)
{
Window.alert("CATCH BLOCK: " + e.getMessage());
e.printStackTrace();
}
Actually, IE8 returns the data but after a warning message, but Firefox doesn't! Why is this?
As you see, I am trying to set some request headers but no way.
If you're trying to make a request to your own server and port (the same one that your GWT page is on), replace the first line with:
String url = "/GWTJSTest/SomeServlet?name=" + textBox.getText();
If you're trying to talk to a different server, or a different port on your own server, the Same Origin Policy will keep you from doing that. You'll need to proxy it from your own server.
The remote servlet is the one that needs to set the CORS header that you have:
Access-Control-Allow-Origin: *
Alternatively you can specify just your own domain instead of * if you don't want other domains interacting with the remote servlet.
I've added :
<add-linker name="xs" /> to .gwt.xml
And then replaces GWT-PRC by JsonpRequestBuilder (transforming JSONP between the server and the client)