How to call a servlet from the viewImpl class in GWT? - gwt

I'm using GWT 2.4 with the MVP pattern, with uiBinder, and a widget: GwtUploader. When the user selects a file to upload and clicks a button, I need to make a call to a servlet. I'm not calling a service, I just need to access the HttpRequest so I can pull the file that the widget has uploaded, but I'm not clear how to do this?
Here is the uiHandler code:
#UiHandler("loadFileButton")
void onClickCalculate(ClickEvent e){
String fileName = fileUploader.getFileName();
...

The real answer is you don't. In MVP, the View should defer that kind of behavior to the Presenter, which ideally would defer it to some server-side handler. Check out this answer or this article for examples of how FileUpload can be used for this purpose. Since you mentioned you're using GWTUpload, try reading the Getting Started article.

Related

how to call a GWT module entry point class?

l split my GWT code in different different modules like
PrintPermit.gwt.xml
EmployeeResponse.gwt.xml
Rejected.gwt.xml
and every module has its own entry point class
in my HTML host page I am calling script like
ae.init.EmployeeResponse.nocache.js
I have a menu like
Print Application
Reject Application
New application
whenever user will click on new application default new application will open
as I declare EmployeeResponse.nocache.js statically in my HTML host page.
now I want to call other modules on click button print and reject button
how can i call nocache js for print and reject modules. is there any way to dynamic call.
please help me guys.
Here's how I've done it in the past:
First of all, in the module you want to export, you need to make sure that the code you're going to export doesn't end up obfuscated. This can be accomplished with the liberal use of #JsType; this is the new way of exporting JS, available in GWT 2.8 (as opposed to JSNI).
Your module's entry point onModuleLoad can be empty; it doesn't need to do anything.
Include your JS in the HTML you want to use (maybe the same page as your "main" module)
Check JSInterop documentation (perhaps the one available here) on how you can use native JS in your GWT app (because now, your GWT module became native JS). Import the classes via JSInterop from your library, and use them.
Please be aware of the async nature of the GWT JS loading; your library will be loading in an async manner, just like any JS application (and therefore, it won't be available immediately when your page loads). To overcome this, I've placed a call to a native JS function in my library's onModuleLoad function (i.e. to make sure you notify any potential listeners that the code has loaded; because when onModuleLoad runs, the code surely loaded).
There is a example of an InterAppEventBus:
https://github.com/sambathl/interapp-eventbus
which shows the communication between two GWT applications.
I have adopted it and replaced JSNI with Elemental2 and WebStorage:
https://github.com/FrankHossfeld/InterAppEventBus
Hope that helps.
You can achieve this through separate Html file for each module.
So first of all create separate html for each application e.g. PrintPermit.html and specify corresponding nocache.js in each html.
then on your buttons in menu, add click handlers and in each on click load a corresponding html through Window.open()
e.g. for PrintPermit,
printPermitButton.addClickHandler(new ClickHandler{
#Override
public void onClick(ClickEvent arg0) {
String s = GWT.getHostPageBaseURL() + "PrintPermit.html";
Window.open(s, "PrintPermit", "");
}
});
Please note the window.open will open in new tab in browser, you can also use gwt iframe to open html in same browser page.
Each module will have corresponding nocache.js and will be loaded through html using Window.open()

Create a GWT RPC Service

I’m trying to create a backend for a homepage with GWT. I created a Google Web Application in Eclipse without sample code and now I would like to add the service, but the developer Google guide doesn’t help me. I’m not sure, where to add the interface and how it exactly works.
If I understand the google documentation correctly, I have to add a module and an entry point class, is that correct? It would be great if you could give me some tips and help how to create a rpc service.
If you create a new GWT project in the Eclipse "New Project" wizard, with "Generate project sample code" checked, it will include a fully functioning RPC service with a sample method, which you can then adapt or copy according to your needs.
Out of memory, don't have eclipse in front of me.
First do create a test project with generated testcode, you can delete it afterward.
Yes you will have to add a module.
Create in client the two interfaces for the async calls, inherit it on server side.
Hope I understood your question right.
I'm not sure what would help you the most. Google developer guide was enough for me (at least when I started using it on version 1.6) to create RPC services for my GWT application.
General APP
Module: is the .gwt.xml file. Yes, you'll need it. The GWT compiler will find it automagically and try to compile all the GWT code (the <source> element will tell which subpackage contains Java code that will be converted to JS). It will tell also which class implements the EntryPoint interface. The onModuleLoad will be the code executed when javascript runs in the client page.
RPC
Well, you should first try UI things and only then, when you're confident enough, try the server thing. Anyway the scheme is:
interface MyService extends RemoteService {
List<String> doSomething(String sample, int other);
}
#RemoteServiceRelativePath("../path/to/servlet") // see later
intercace MyServiceAsync {
void doSomething(String sample, int other, AsyncCallback<List<String>> callback);
}
These are the interfaces. Later is the async one. That's what you'll use from client side. Always calling and passing an implementation of AsyncCallback which will receive (sometime later, you don't know when) the result.
First interface is the syncrhonous one. That is what you need to implement on server. You must inherit from RemoteServiceServlet class (it is an implementation of servlet that already does all the values handling), and implement your interface. GWT code does the rest (almost).
public class ServiceImpl extends RemoteServiceServlet implements MyService
{
// implement the method normally
}
From client you'll need to create the service proxy:
private static MyServiceAsync MY_SERVICE = GWT.create(MyService.class);
Yes. I know it's weird how GWT knows MyserviceAsync and MyService work together. Don't worry about that. It works :)
Just use the service like this:
MY_SERVICE.doSomething("value", 111, new AsyncCallback<List<String>>() {
// note that this code executes some time in the future when response from server is back
public void onSuccess(List<String> result) {
Window.alert("Server answered with " + result.size() + " elements!");
}
public void onFailure(Throwable t) {
Window.alert("Server failed: " + t.getMessage());
}
}
Path to server
You'll have to configure your app to make that servlet implementation listen to URL indicated in #RemoteServiceRelativePath. That's the way client knows where to make the request, and the server knows which servlet attends that request. I'd suggest using:
../my-service.gwt as relative path (GWT module gets published in <ROOT>/module_name
and
configuring your web app to use the servlet for /my-service.gwt
But it's entirely upon your preferences :)
Anyway I think Google tutorials are the best. So please copy&paste. Try&modify until you get to understand the whole thing.

GWTTestCase file upload

I am trying to write some gwt testcases to upload files using FileUpload and FormPanel.
My code (unttested) looks like:
#Test
public void testImportXml() {
delayTestFinish(10000);
FormPanel fileForm=new FormPanel();
fileForm.setEncoding(FormPanel.ENCODING_MULTIPART);
fileForm.setMethod(FormPanel.METHOD_POST);
fileForm.setAction(GWT.getModuleBaseURL()+"/xmlupload");
URL myFile=this.getClass().getClassLoader().getResource("myfile.xml");
// FileUpload uploadField; ??
fileForm.addSubmitHandler(new SubmitHandler() {
#Override
public void onSubmit(SubmitEvent event) {
logger.info("submit handler pushed");
}
});
fileForm.submit();
}
I could not find a method to configure FileUpload to use "myFile".
I understood that this is done for browser-security reasons, but it is a massive obstacle when writing testcases.
Does there exist a way to specify filenames for FileUpload for testcases within gwt?
No.
But then one could wonder what is it that you're actually trying to test?
the submit / submit-complete handlers? You'd better fire the events directly at the FormPanel; you could also refactor your code to use some MV* pattern so that the code you're actually testing is not tied to GWT widgets, then you can use a vanilla JUnit test.
the servlet? Then don't use a GWTTestCase, use HttpClient or anything similar and make a request against your servlet, running in a server (best done as an integration test; have a look at Arquillian to make it easier to setup)
the whole interaction between the FormPanel+FileUpload and servlet? Then don't use a GWTTestCase, use Selenium to drive a browser talking to a running server (best done as an integration test or acceptance test)

GWT - Is it possible to create new HTML elements (from the server) or i can just to update the ones loaded on the client?

Im new about this technology, but I would like to know if is possible to create new object (html elements, such div/span/and so on...) dinamically on server and send it to the client, or if i can just load the ones made on client-side when i develop it in the application.
I don't ask how to do it (i think its a delicate argument), but if I can, and (if yes) where i can get some stuff/example/tutorial to do this.
Example
What i usually do :
...
public void onSuccess(Boolean result) {
if(result) {
myFunction();
}
}
...
myFunction() {
InlineLabel label=new InlineLabel();
this.add(label)
}
What im looking for :
...
public void onSuccess(InlineLabel result) {
this.add(result)
}
So, i don't need to load in advance the Object, but load them only if i click on some button (or if i perform an action). This will save a lot of code (that is inutil, if i don't do any action) loaded (as JavaScript) on the client.
As usual, thanks for your time!
GWT does not support the pattern you showed, but you can achieve a similar effect with "code splitting": read http://code.google.com/webtoolkit/doc/latest/DevGuideCodeSplitting.html
With code splitting, the client only downloads the script it needs right away (configured by the developer). If, for example, the user navigates to a more complex area of the UI that requires more widgets, additional code will be downloaded.
I'm not entirely sure I understand your question, but please feel free to amend your question or post a comment if I've missed the mark.
The host page
A GWT app is loaded in the following (simplified) process:
A host page (HTML) is loaded
A bootstrapping script is loaded
A compiled app script is loaded
The host page can contain any HTML you want. The only requirement is that you include a <script> element that loads the GWT bootstrapping script.
As a result, you can have the server return a page that contains any server-generated markup you like.
Server-rendered HTML at runtime
Once your app is running, you can send off asynchronous requests in your code to retrieve arbitrary data from the server. One option is to retrieve server-generated HTML and insert it into your application.
For this option, you'll want to instantiate an HTML widget, then use its setHTML method to insert the server-generated markup into the widget.
Client-generated
As an alternative, you can retrieve structured data from the server via GWT RPC. Objects created on a Java-based server are serialised by GWT on the server and deserialised on the client back into regular objects. You can then pull data out of these objects using accessor methods (getName, getId, etc.). At this point, you have several options:
Generate some HTML using StringBuilder and the like, then use setHTML on an HTML widget.
Generate DOM elements with the DOM class
Set the data into widgets and add them to panels or the root panel.

Is there a tool to convert my GWT RemoteServiceServlet into the correct Service and ServiceAsync interfaces?

I'm working on a GWT project and I find it very tedious to have to add a function to my servlet, then copy and paste the function signature into my Service interface, then copy and paste it into my ServiceAsync interface and change the return parameter to be a callback. Is there a tool or a setting where I can just add public methods to my class and they can get copied into the other interfaces? Even if its not automatic it would be nice to be able to select specific methods and have them copied automatically.
I'm using eclipse and ideally it would update my interface each time I save implementation since thats when it checks my code and complains that my changes break the interface.
If you add the method to your *Service interface, then Eclipse can auto-generate the method ("Add unimplemented methods...") in your *ServiceImpl servlet, which you can then just fill in. Also, if you've got the Google Eclipse plugin installed, it will underline the new method in your *Service interface and complain that it's not in the *ServiceAsync. It might have a CTRL + 1 option to generate it in that interface as well.
You don't really need a tool. Just factor out the many RPC methods by just one method that takes a Request/Response. all you need to do is create subclasses of Request/Response and you don't need to think about adding new methods in the 2 interfaces.
You can use Google Guice on the server side to map the incomming request to a class handling the call... or you could use a visitor approach to forward the incoming request to the code handling the request (without resorting on a big instanceof construct).
Instantiations WindowBuilder GWT Designer does exactly what you are looking for.
The RemoteService Wizard will create all three files at the same time as well as keep them in sync as you make changes.
http://www.instantiations.com/windowbuilder/gwtdesigner/index.html
FWIW - I am only a user/purchaser of this product. I am not employed or in any other way related to Instantiations.