I have example project StockWatcher using requestbuilder to communicate with servlet (this example). I want to make servlet asynchronous. I have added the following lines to the doGet method:
final AsyncContext ac = request.startAsync();
ac.setTimeout(1 * 60 * 1000);
ac.addListener(new AsyncListener() {
#Override
public void onError(AsyncEvent arg0) throws IOException {
System.out.println("onError");
}
public void onComplete(AsyncEvent event) throws IOException {
System.out.println("onComplete");
queue.remove(ac);
}
public void onTimeout(AsyncEvent event) throws IOException {
System.out.println("onTimeout");
queue.remove(ac);
}
#Override
public void onStartAsync(AsyncEvent arg0) throws IOException {
System.out.println("onStartAsync");
}
});
queue.add(ac);
added asynchronous annotation: #WebServlet(asyncSupported=true)
and changed the rest of doGet method with:
PrintWriter out = ac.getResponse().getWriter();
out.println("Something");
out.flush();
Now there is nothing returning. What do I wrong? Have to change something in client side? Glassfish 3 does not show any errors.
You are not doing anything wrong. GWT uses servlet 2.5 and it blocks if you try something async. I've the same problem right now although I use Vaadin (which uses GWT). A link I've found on the topic: http://comments.gmane.org/gmane.org.google.gwt/48496
There is a page claiming to have the problem solved: http://blog.orange11.nl/2011/02/25/getting-gwt-to-work-with-servlet-3-async-requests/
I have not been able to try this out yet.
Related
Is it possible to have the AppEngine dev server output a quick log message to the eclipse console every time it serves a static file?
For example, if my website loads "background.gif" (as a static file from the file system), I would like to see a line like "GET request for static file /war/resources/images/background.gif by 127.0.0.1" show up in the Eclipse console.
Maybe there is a command-line switch for tomcat (the server that appengine uses locally)? I couldn't find anything relevant here... But I did find some documentation about an "access log valve (?!?)" which might look promising, but I don't know if this does what I am looking for, or even if it does, how I can get any potential output to show up in the Eclipse console.
You can use a servlet Filter to intercept all requests:
public class LoggingFilter implements Filter {
private static final Logger log = Logger.getLogger(LoggingFilter.class.getName());
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = ((HttpServletRequest) request);
log.info(httpRequest.getMethod() + " request for " + httpRequest.getRequestURI() + " from " + httpRequest.getRemoteAddr());
request.getRequestDispatcher(httpRequest.getRequestURI()).forward(request, response);
}
#Override
public void destroy() {
}
}
The only problem is that you can not distinguish between requests static and dynamic content. In order to do so, you could put all static content under one directory and that map this Filter to only that path.
I'm trying to add a custom HeaderResponseContainer in my wicket application. The tutorial looks quite simple (see Positioning of contributions), but when I add these lines and run the application I alwas get an IllegalStateException:
java.lang.IllegalStateException: No FilteringHeaderResponse is present in the request cycle. This may mean that you have not decorated the header response with a FilteringHeaderResponse. Simply calling the FilteringHeaderResponse constructor sets itself on the request cycle
at org.apache.wicket.markup.head.filter.FilteringHeaderResponse.get(FilteringHeaderResponse.java:165)
at org.apache.wicket.markup.head.filter.HeaderResponseContainer.onComponentTagBody(HeaderResponseContainer.java:64)
at org.apache.wicket.markup.html.panel.DefaultMarkupSourcingStrategy.onComponentTagBody(DefaultMarkupSourcingStrategy.java:71)
...
Yes, I already saw the note about FilteringHeaderResponse. But I am not sure where I should call the constructor. I already tried to add it in renderHead before calling response.render but I still get the same exception:
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
FilteringHeaderResponse resp = new FilteringHeaderResponse(response);
resp.render(new FilteredHeaderItem(..., "myKey"));
}
You can create a decorator that wraps responses in a FilteringHeaderResponse:
public final class FilteringHeaderResponseDecorator implements IHeaderResponseDecorator {
#Override
public IHeaderResponse decorate(IHeaderResponse response) {
return new FilteringHeaderResponse(response);
}
}
And that set it during application initialization:
Override
public void init() {
super.init();
setHeaderResponseDecorator(new FilteringHeaderResponseDecorator());
}
I just ran into this same problem and found that the Wicket In Action tutorial leaves out the part about setting up a custom IHeaderResponseDecorator in your main Wicket Application init. The Wicket guide has a more thorough example:
Apache Wicket User Guide - Put JavaScript inside page body
You need something like this in your wicket Application:
#Override
public void init()
{
setHeaderResponseDecorator(new JavaScriptToBucketResponseDecorator("myKey"));
}
/**
* Decorates an original IHeaderResponse and renders all javascript items
* (JavaScriptHeaderItem), to a specific container in the page.
*/
static class JavaScriptToBucketResponseDecorator implements IHeaderResponseDecorator
{
private String bucketName;
public JavaScriptToBucketResponseDecorator(String bucketName) {
this.bucketName = bucketName;
}
#Override
public IHeaderResponse decorate(IHeaderResponse response) {
return new JavaScriptFilteredIntoFooterHeaderResponse(response, bucketName);
}
}
I use the GWT RequestBuilder, and for testing purposes, I'd like to load a json file in the server.
It works perfectly with the DevMode, but throw a 404 error with GWTTestCase.
With RPC, there is a fix adding <servlet path=".." class="..."/>, but what can I do with static content ?
I could easily use #TextResource, but it's not the goal of my UnitTest (which is in fact a functionnal test)
Static resources can be bundled with a module by putting them in the module's public path.
I used (once again) Thomas's answer to resolve the problem. My module is io.robusta.fora.comments.Comment.gwt.xml and I've put my user.json file in the io.robsuta.fora.comments.resources package.
I had so to add in Comment.gwt.xml file : <public path="resources"/>
Then the GWTTestCase is straightforward :
public class GwtRestClientTest extends GWTTestCase{
#Override
public String getModuleName() {
return "io.robusta.fora.comments.Comments";
}
public void testGET(){
String base = GWT.getModuleBaseURL();
System.out.println(base); //-> http://192.168.0.10:53551/io.robusta.fora.comments.Comments.JUnit/
GwtRestClient client = new GwtRestClient(base); //base url
AsyncCallback<String> cb = new AsyncCallback<String>() {
#Override
public void onSuccess(String result) {
System.out.println(result);//->{id:1,email:"jo#robusta.io"}
finishTest();
}
#Override
public void onFailure(Throwable caught) {
caught.printStackTrace();
}
};
client.GET("user.json", null, cb);//fetch my json file with no params
delayTestFinish(3000);
}
}
this isn't my first RPC try. All others worked well, but I can't figure out, why this doesn't.
public void confirmRequest(String requestId, boolean confirmWithDefault, List<String> values, final String laneId){
AsyncCallback<Void> callback = new AsyncCallback<Void>(){
#Override
public void onFailure(Throwable caught)
{
// TODO Auto-generated method stub
}
#Override
public void onSuccess(Void result)
{
Window.alert("jo");
ServiceCalls.this.mainmenu.getSlidePanel().getLaneMenu().getProperLanes().get(laneId)
.getDefaultButton().setText("");
statusFor();
}
};
getLaneProxy().confirmRequest(requestId, confirmWithDefault, values, laneId, callback);
}
When I run the programm, it does not even throw an exception. It just doesn't do what it should do. Then I debugged it and saw that a ClassNotFoundException was thrown at this point.
AsyncCallback< Void> callback = new AsyncCallback<Void>()
Assuming you're using GWT 2.5.0, this is a known issue; upgrade to 2.5.1-rc1 where this is fixed.
I had the same Problem, and found the solution with gridDragon's help.
My problem was that the servlet configuration in web.xml was wrong and so my Impl class couldn't be found.
I need to read data from an xml file that is under the WAR directory.
I'm using RequestBuilder for creating the GET request.
It looks like this:
RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.GET,"customerRecord.xml");
try {
requestBuilder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception) {
requestFailed(exception);
}
public void onResponseReceived(Request request,Response response) {
renderXML(response.getText());
}
});
} catch (RequestException ex) {
requestFailed(ex);
}
Now, the thing is that I don't want to load all of the data. I want to send a parameter that tells the server which part to bring, (let's say - how many lines of data) and then override the doGet method of the servlet and deal with the parameter.
I have 2 questions:
1) how do I declare the path of the servlet? where is the connection between the servlet and the request??
2) What do I write in the url of the RequestBuilder (instead of "customerRecord.xml")? do I need to refer to the servlet there or I can keep it like
May be You mean GWT Service?
You need to create 2 interfaces - Service and ServiceAsync and implementation of Service in server package (on same level as client package). Then You define implementation as servlet (in my JBoss 7.1 it just annotation. in older version servlet mapping):
#WebServlet(name="YourService", urlPatterns={"/%module%/YourService"})
public class YourServiceImpl extends RemoteServiceServlet implements YourService
in Your modeule.xml write:
<servlet path="/YourService" class="org.name.YourServiceImpl"/>
and in the end You can call this service from Your code
YourService.App.getInstance().getSomething(new AsyncCallback<Collection<Something>>() {
#Override
public void onFailure(Throwable caught) {
new MessagePopup("Error: " + caught.getMessage()).center();
}
#Override
public void onSuccess(Collection<Something> result) {
}
});
Interfaces You can create from Your beloved IDE. It's much simpler)
One think which still bothering me - I cannot specify path for servlet in another module.