Using a marker interface, CustomDto, I was able to get the compiler to be a 
lot happier. But I had some trouble trying to figure out Tomas' suggestion. 
So I'll post my current code here to see if there are additional 
refinements suggested.

*Generic Request/Response encapsulation classes:*

public class CustomRequest<T> implements Action<CustomResponse<T>>, 
CustomDto
{
private static final long serialVersionUID = 2497682157216814807L;
 private T request;
 public CustomRequest(){}
 public CustomRequest(T req)
{
request = req;
}
 public void setRequest(T request)
{
this.request = request;
}
 public T getRequest()
{
return request;
}
}

public class CustomResponse<T> implements Response, CustomDto
{
private static final long serialVersionUID = -7854717568064553824L;
private T response;
private String statusString = "";
private int msgStatus = 0;
 public CustomResponse(){}
 public CustomResponse(T rsp)
{
response = rsp;
}
 public T getResponse()
{
return response;
}
 public void setResponse(T response)
{
this.response = response;
}

        // getters and setters
}

*Here is my generic service and async interface:*

@RemoteServiceRelativePath("CustomService") 
public interface CustomService extends RemoteService
{
CustomResponse<CustomDto> sendRequest(CustomRequest<CustomDto> req);
}

public interface CustomServiceAsync
{
void sendRequest(CustomRequest<CustomDto> req, 
AsyncCallback<CustomResponse<CustomDto>> callback);
}

*My abstract service:*

public abstract class AbstractCustomService extends RemoteServiceServlet
{
        private static jniConnection;

// static System.loadLibrary() call for JNI connection.
 public CustomResponse<CustomDto> sendRequest(CustomRequest<CustomDto> req)
{
CustomResponse<CustomDto> response = null;
 try
{
if (jniConnection == null)
{
// custom JNI connection code.
}
 response = handleRequest(req);
}
catch (Exception ex)
{
ex.printStackTrace();
}
 return response;
}
 protected abstract CustomResponse<CustomDto> 
handleRequest(CustomRequest<CustomDto> req);

*And then my service implementation:*
*
*
public class CustomServiceImpl extends AbstractCustomService 
implements CustomService
{
private static final long serialVersionUID = 8883630570739973203L;
 @Override
public CustomResponse<CustomDto> handleRequest(CustomRequest<CustomDto> req)
{
if (req.getRequest().getClass().equals(LoginDto.class))
return handleLogin(req);
else if (req.getRequest().getClass().equals(GetStuffDto.class))
return handleGetStuff(req);
                else if 
(req.getRequest().getClass().equals(UpdateFooDto.class))
return handleUpdateFoo(req);
else
return null;
}

private CustomResponse<CustomDto> handleLogin(CustomRequest<CustomDto> req)
{
LoginDto dto = (LoginDto) req.getRequest();
                LoginJniReq request = new LoginJniReq();
                // copy fields from DTO to JniReq
                // send JniReq, check status, copy results into dto
                CustomResponse<CustomDto> rsp = 
CustomResponse<CustomDto>(dto);
                // set status and statusString on rsp
                return rsp;
         }

private CustomResponse<CustomDto> handleLogin(CustomRequest<CustomDto> req)
{
              ...
         }

private CustomResponse<CustomDto> handleLogin(CustomRequest<CustomDto> req)
{
              ...
         }
}

With this setup, adding handling for each of the ~40 DTOs only requires:

   - Adding a check in CustomServiceImpl::handleRequest() to properly route 
   the request.
   - Adding a CustomServiceImpl::handleAction() method to get the data from 
   the backend and return it.
   - Adding an ActionTest class for testing the DTO processing.

This is a great reduction from needing to create two separate interfaces, 3 
classes, and a test class for every DTO! 

Things would be a bit more simple in my implementation if I didn't have to 
deal with the JNI backend or the fact that the DTOs don't have 
status/statusString fields. But that neither of those can be changed. I 
also am likely going to need to put some session tokens/state in the 
CustomRequest/CustomResponse encapsulating classes eventually. So that 
extra encapsulation is likely to be quite helpful down the road.

Thank you for the help!


On Wednesday, August 14, 2013 11:24:08 AM UTC-4, Michael Prentice wrote:
>
> Thomas are you saying that instead of having this in the interface:
>
> sendRequest(GenericDto dto, AsyncCallback<GenericDto>);
>
> I should have a different method in the interface for each DTO? i.e.:
>
> sendLoginReq(LoginDto dto, AsyncCallback<LoginDto >);
> sendGetStuffReq(GetStuffDto dto, AsyncCallback<GetStuffDto>);
> sendUpdateFooReq(UpdateFooDto dto, AsyncCallback<UpdateFooDto>);
>
> It would eliminate the need for a handler method (handleRequest()) in my 
> serviceImpl, but that work would be replaced with the boilerplate of 
> defining each method in the service/serviceAsync interfaces. I suppose that 
> it separates the logic a bit better to do it this way.
>
> Jens' idea of creating a Serializable marker interface/base class for all 
> of my DTOs and then specifying that instead of Serializable, looks like it 
> will resolve the issues with being too generic and causing GWT to generate 
> too much JS. I've seen a lot of talk on this topic, so I knew what that 
> error meant. I just wasn't quite sure how I was going to solve it 
> (especially at 9pm ;).
>
> I'll give these a shot today and see how they work. Thanks a ton for the 
> input guys!
>
> On Wednesday, August 14, 2013 10:22:19 AM UTC-4, Thomas Broyer wrote:
>>
>> It's still unclear to me why you can't have X methods on the same 
>> service/async interface, each with its own request/response (whether to use 
>> those encapsulations is another matter that Jens already dealt about)
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to google-web-toolkit+unsubscr...@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at http://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to