GWT RequestBuilder Post Response return 0 StatusCode - gwt

I have created a very simple servlet that uses HTTP Post method. I have tested it on my local Apache Tomcat server using a simple HTML form that works. I want to integrate it with my GWT app. I am able to call it using FormPanel - in that case it downloads content and there is a flicker in my browser window.
I know I need to use RequestBuilder to access it. But my response.getStatusCode() in my overloaded public void onResponseReceived(Request request, Response response) method always return status as 0 and response.getText() return null
String url = "http://localhost:8080/servlets/servlet/ShapeColor";
builder = new RequestBuilder(RequestBuilder.POST, URL.encode(url));
try {
String json = getJSONString();
//builder.setTimeoutMillis(10000);
builder.setHeader("Access-Control-Allow-Origin", "*");
builder.setHeader("Content-type", "application/x-www-form-urlencoded");
builder.sendRequest(json, new RequestCallback() {
#Override
public void onError(Request request, Throwable exception) {
Window.alert("Couldn't retrieve JSON");
}
#Override
public void onResponseReceived(Request request, Response response) {
if (200 == response.getStatusCode()) {
System.out.println("res:"+response.getText());
} else {
System.out.println("err: " + response.getStatusCode()+","+response.getText());
}
}
});
//Request response = builder.send();
} catch (RequestException e) {
// TODO Auto-generated catch block
}
I have tried many thing including changing my servlet following CORS reference ( https://code.google.com/p/gwtquery/wiki/Ajax#CORS_%28Cross_Origin_Resource_Sharing%29 )
It always works on browser using my test.html, but not from my App. Although, onResponseReceived method always gets called
Thanks
KKM

Have you checked if your call in the app violates the Same-origin policy (http://en.wikipedia.org/wiki/Same-origin_policy) in some way? The GWT RequestBuilder uses XMLHttpRequest internally, so it does fall under the SOP.
Does your GWT app run inside the same domain (server + port) as the servlet? Does it use the same protocol (https or http)?

Related

Is it possible to apply dictionaries for Citrus static response adapter response template?

I'm using Citrus static response adapter to mock services, and I need to change values in its payload for every test case. Ideally I think about usage of dictionaries for each test case. There is sample of my current scenario:
#Autowired
#Qualifier("checkRegistrationEndpointAdapter")
public StaticResponseEndpointAdapter checkRegistrationEndpointAdapter;
protected void setAdapterResponse(StaticResponseEndpointAdapter adapter, String filenamepath){
URL url = this.getClass().getResource(filenamepath);
String payload = null;
try {
payload = Resources.toString(url, Charsets.UTF_8);
} catch (IOException e) {
e.printStackTrace();
}
adapter.setMessagePayload(payload);
}
#CitrusTest
public void TestCase02() throws IOException {
http()
.client(CLIENT)
.post()
.payload(new ClassPathResource("templates/thisStartRequestMsg.xml", getClass()))
.dictionary("TC02");
http()
.client(CLIENT)
.response()
.messageType("xml")
.payload(new ClassPathResource("templates/thisStartResponseMsg.xml", getClass()));
action(new AbstractTestAction() {
#Override
public void doExecute(TestContext testContext) {
setAdapterResponse(checkRegistrationEndpointAdapter, "templates/check-registration-v1CheckRegistrationResponseMsg.xml");
}
});
http()
.client(CLIENT)
.response()
.messageType("xml")
.payload(new ClassPathResource("templates/check-registration-v1CheckRegistrationRequestMsg.xml", getClass()))
.dictionary("TC02");
}
How can I apply dictionary to the payload set in my setAdapterResponse method?
Note: this question relates to Can I use Citrus variable in Citrus static response adapter payload?
Static response adapter has currently no support for data dictionaries. I wonder why you put so much effort into static response adapters? Why not using the full Citrus http server power with receiving the request and providing a response inside the test case?

trying to send httpRequest from server side in GWT

I am trying to make http request to server from my GWT Application
Below is the code i am using which works fine from Client Side ..
But I want to do this from Server side ..
If I can get some solution for that
String url = "http://www.myserver.com/getData?type=3";
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.)
}
public void onResponseReceived(Request request, Response response) {
if (200 == response.getStatusCode()) {
// Process the response in response.getText()
} else {
// Handle the error. Can get the status text from response.getStatusText()
}
}
});
} catch (RequestException e) {
// Couldn't connect to server
}
Reference: www.gwtproject.org/doc/latest/DevGuideServerCommunication.html
com.google.gwt.http.client.RequestBuilder is meant to be used on the GWT client side.
For your server side code to make HTTP requests, I recommend using the Apache HttpClient library.

How to send POST parameters with RequestBuilder?

I'm trying to make a POST request, but I'm not sure how to set parameters. Something like:
RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, url);
StringBuilder sb = new StringBuilder();
sb.append("key1=val1");
sb.append("&key2=val2");
sb.append("&key3=val3");
rb.setRequestData(sb.toString());
that does not seem to be the current way, though. What's the right way to send params like this with the POST?
The answer should be in here Making POST requests with parameters in GWT Try with builder.setHeader("Content-type", "application/x-www-form-urlencoded");
It is opening new window but not passing Post parameters to new window using GWT.
rb.setRequestData(json);
Request response = rb.sendRequest(json.toString(), new RequestCallback() {
public void onError(Request request, Throwable exception) {}
public void onResponseReceived(Request request, Response response) {
Window.open(rb.getUrl(), postTarget, postWinFeatures);
}
});

GWT - spring security - session timeout

I have a GWT + Spring Security web app. I was trying to add:
<security:session-management invalid-session-url="/X.html"/>
However, when I try to test this. It seems I see a:
com.google.gwt.user.client.rpc.InvocationException
with message as the HTML content of X.html. Can someone please advise on how to fix this?
Because GWT communicates with a server via Ajax RPC requests, the browser will not be redirected to X.html. What you need to do in your service calls is throw an exception if they are not authorized and handle in in void onFailure(Throwable caught) method of your AsyncCallback.
If you want to redirect to /X.html try:
Window.Location.replace(GWT.getHostPageBaseURL()+"X.html");
However, if you want to send the request to the server use RequestBuilder:
String url = GWT.getHostPageBaseURL() + "/X.html";
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL.encode(url));
try {
Request request = builder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception) {
// invalid request
}
public void onResponseReceived(Request request, Response response) {
if (200 == response.getStatusCode()) {
// success
} else {
// sth went wrong
}
}
});
} catch (RequestException e) {
// couldn't connect to server
}

How to recognize a a http error code from within GWT?

When my users try to do an action our website after their session has expired (for instance, if they left their browser open), the server responds with a HTTP Status 405 because the user is no longer logged in.
When this happens, I want to redirect the user to the login screen.
How can I recognize when a 405 error code is returned within GWT so I can then redirect the users?
Thanks
Edit:
Here's the filter I'm using:
public class AuthenticationFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
if (req instanceof HttpServletRequest) {
boolean isLoggedIn = CustomSecurity.login((HttpServletRequest)req);
if (isLoggedIn) {
// TODO: How to redirect the user here???
}
}
chain.doFilter(req, res);
}
public void init(FilterConfig arg0) throws ServletException {
}
}
web.xml content:
<filter>
<filter-name>Authentication Filter</filter-name>
<filter-class>com.company.AuthenticationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Authentication Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
How can I make that redirect the user? Also, is there a way to force the whole browser to redirect? Since this goes into a widget, I think a Window.Location.assign('url') will only redirect the widget's HTML content.
I currently work on a GWT application that does something very similar to what you are asking. However, we handle these redirects in a standard javax.servlet.Filter subclass that we define in our web.xml as per usual and it is mapped to /* so it catches all requests (we use this filter for many other reasons as well).
I don't know if you are also using a Filter or perhaps even just some sort of catch-all Servlet in your GWT app, but if you are then the solution to your issue is quite easy. You will have a handle to the HttpServletRequest and you can see if the getSession(false) method returns null then you know that the user who sent the request no longer has a session. Then you can just do a standard response.sendRedirect(...) to your login page.
For GWT-RPC you will get a StatusCodeException whenever the server returns anything but a 200 response code. The status code can be retrieved from the exception and you can redirect via GWT by using Window.Location.assign(url). For RequestBuilder the status code cqan be accessed via response.getStatusCode().
EDIT: Here is code to redirect if GWT's window isn't that root window.
private native void redirect(String url)/*-{
var win = $wnd;
while (win.parent != null && win.parent != win)
win = win.parent;
win.location = url;
}-*/;
In your RequestCallback implementation, you can check response.getStatusCode(). We have Spring Security on the backend, which is wired up to force the user to a form based login page if they are not authenticated. Upon authentication, it redirects them back.
For example:
#Override
public void onResponseReceived(Request request, Response response) {
if (SC_UNAUTHORIZED == response.getStatusCode()) {
Window.Location.reload();
}
}
use a try / catch for coders sakes!
AsyncCallback<String> callback = new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
try {
throw caught;
} catch (StatusCodeException statusCodeException) {
Util.handleException(statusCodeException);
} catch (Throwable exception) {
Util.handleException(exception);
}
}
public void onSuccess(String result) {
Window.alert("Result : " + result);
}
};
then to process your results
final static public void handleException(StatusCodeException exception) {
String errorMessage = exception.toString() +
"\n CODE: " + exception.getStatusCode() +
"\n MESSAGE: " + exception.getEncodedResponse();
Window.alert("ERROR: " + errorMessage);
}
final static public void handleException(Throwable exception) {
String errorMessage = exception.toString() + "\n";
for (StackTraceElement trace : exception.getStackTrace()) {
errorMessage += trace.getClassName() + " :: " +
trace.getMethodName() + " :: " +
trace.getLineNumber() + "\n";
}
Window.alert("ERROR: " + errorMessage);
}
remember that overloading is your friend! Dont forgot that if you do not compile your code in detailed or pretty you will get garbage for the stack trace. Unless of course someone figured out how to hack the JSStackEmulation class
http://code.google.com/p/google-web-toolkit/wiki/WebModeExceptions