7
votes

Is it possible to resend a RequestFactory transmission? I'd like to do the equivalent of this: How to resend a GWT RPC request when using RequestFactory. It is fairly simple to resend the same payload from a previous request, but I also need to place a call to the same method. Here's my RequestTransport class, and I am hoping to just "refire" the original request after taking care of, in this case, a request to the user for login credentials:

package org.greatlogic.rfexample2.client;

import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.Response;
import com.google.web.bindery.requestfactory.gwt.client.DefaultRequestTransport;
/**
 * Every request factory transmission will pass through the single instance of this class. This can
 * be used to ensure that when a response is received any global conditions (e.g., the user is no
 * longer logged in) can be handled in a consistent manner.
 */
public class RFERequestTransport extends DefaultRequestTransport {
//--------------------------------------------------------------------------------------------------
private IClientFactory _clientFactory;
//==================================================================================================
private final class RFERequestCallback implements RequestCallback {
private RequestCallback _requestCallback;
private RFERequestCallback(final RequestCallback requestCallback) {
  _requestCallback = requestCallback;
} // RFERequestCallback()
@Override
public void onError(final Request request, final Throwable exception) {
  _requestCallback.onError(request, exception);
} // onError()
@Override
public void onResponseReceived(final Request request, final Response response) {
  if (response.getStatusCode() == Response.SC_UNAUTHORIZED) {
    _clientFactory.login();
  }
  else {
    _clientFactory.setLastPayload(null);
    _clientFactory.setLastReceiver(null);
    _requestCallback.onResponseReceived(request, response);
  }
} // onResponseReceived()
} // class RFERequestCallback
//==================================================================================================
@Override
protected void configureRequestBuilder(final RequestBuilder builder) {
  super.configureRequestBuilder(builder);
} // configureRequestBuilder()
//--------------------------------------------------------------------------------------------------
@Override
protected RequestCallback createRequestCallback(final TransportReceiver receiver) {
  return new RFERequestCallback(super.createRequestCallback(receiver));
} // createRequestCallback()
//--------------------------------------------------------------------------------------------------
void initialize(final IClientFactory clientFactory) {
  _clientFactory = clientFactory;
} // initialize()
//--------------------------------------------------------------------------------------------------
@Override
public void send(final String payload, final TransportReceiver receiver) {
  String actualPayload = _clientFactory.getLastPayload();
  TransportReceiver actualReceiver;
  if (actualPayload == null) {
    actualPayload = payload;
    actualReceiver = receiver;
    _clientFactory.setLastPayload(payload);
    _clientFactory.setLastReceiver(receiver);
  }
  else {
    actualReceiver = _clientFactory.getLastReceiver();
  }
  super.send(actualPayload, actualReceiver);
} // send()
//--------------------------------------------------------------------------------------------------
}
2
Your code is hard to read, but you're on the right track, so what's the problem with what you tried?Thomas Broyer
My issue is knowing how to initiate the request that triggered the SC_UNAUTHORIZED response. For example, if I have the request requestContext.getFooById(fooId).fire(...) and this request returns the unauthorized response then I want to fire this again. I can send the same payload, and callback to the same receiver, but I don't know how to automatically apply the "fire()" to "getFooId()". (btw, what made my code "hard to read" ... I am very curious?"). Thanks!Andy King
What happens if you send the same payload with the same receiver? My guess is that it should Just Work™. (I find your code hard to read by lack of indentation –primarily–, lack of blank lines, and too many useless comments; it's a matter of taste I guess)Thomas Broyer
It is possible that I could fire any request and that by overwriting the payload it will result in a call to whatever generated the payload originally (in this case getFooById()) ... is that the case?Andy King
Thank you Thomas ... I'll add more blank lines! It's true that I indent by 2, and not 4 ... just taste, as you say.Andy King

2 Answers

1
votes

Based upon Thomas' suggestion I tried sending another request, and just replaced the payload and receiver in the RequestTransport.send() method, and this worked; I guess there is no further context retained by request factory, and that the response from the server is sufficient for RF to determine what needs to be done to unpack the response beyond the request and response that are returned to the RequestCallback.onResponseReceived() method. If anyone is interested in seeing my code then just let me know and I'll post it here.

0
votes

It's possible, but you have a lot to do.

I had the same idea. And i was searching for a good solution for about 2 days. I tried to intercept the server call on RequestContext.java and on other classes. But if you do that you have to make your own implementation for nearly every class of gwt requestfactories. So i decided to go a much simpler approach.

Everywhere where I fired a Request, i handled the response and fired it again. Of course you have to take care, that you don't get in to a loop.