GWT FormPanel onSubmitComplete event not firing when downloading a file - events

I created servlet to download file from a server. In GWT I created a FormPanel and I am able to download a file.
Problem is, that I want to fire an event, when the file is ready. I tried to use onSubmitComplete event, but it isn't firing.
I found a suggestion, to change ContetType to "text/html", but still no luck. I found, that the problem lies in writing to OutputStream - when commented out, event is fired.
Here is my servlet code
public void handleRequest(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
response.setHeader("Content-Disposition", "attachment; filename=File.xls");
HSSFWorkbook workbook = new HSSFWorkbook();
try {
workbook = fileCreator.getWorkbook();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
OutputStream out = response.getOutputStream();
workbook.write(out);
out.close();
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().print("something");
response.flushBuffer();
}
So file is downloaded successfully, but event is not triggered. Even when I just get OutputStream and close it (without writing to it), event stops working.
When I remove whole "writing-to-output-stream" code, event works like a charm.
Any suggestions?
UPDATE
Here is code for FormPanel and its handlers, meby there is a problem?
Form:
downloadFileFormPanel.setEncoding(FormPanel.ENCODING_URLENCODED);
downloadFileFormPanel.setMethod(FormPanel.METHOD_POST);
VerticalPanel panel = new VerticalPanel();
panel.setWidth(UIConstatns.SIZE_100percent);
downloadFileFormPanel.setWidget(panel);
downloadFileButton = new Button(messages.EXPORT_LIMITS());
downloadFileButton.setWidth(UIConstatns.SIZE_100percent);
downloadFileButton.addStyleName("navigation-button");
panel.add(downloadFileButton);
Handlers
private void registerExportLimitsHandler() {
registerHandler(getView().getDownloadFileButton().addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
getView().showLoadingDialog();
getDownloadFileForm().submit();
}
}));
}
private void registerFormSubmitCompleteHandler() {
getView().getDownloadFileForm().addSubmitCompleteHandler(new SubmitCompleteHandler() {
public void onSubmitComplete(SubmitCompleteEvent event) {
Window.alert("download complete");
getView().hideLoadingDialog();
}
});
}

According to the Javadoc of ServletResponse#getWriter() you can either use response.getOutputStream() or response.getWriter() to write the body of the response, but not both. Furthermore it is better to set the status code of the response before writing the body. Please try the following:
// ...
response.setStatus(HttpServletResponse.SC_OK);
OutputStream out = response.getOutputStream();
workbook.write(out);
out.flush();
out.close();
// response.getWriter().print("something");
// response.flushBuffer();

You did not post the line where you create your FormPanel so I'm not sure if this was your problem:
Looks like the FormPanel(String target) constructor does not work with the SubmitCompleteHandler. With the default constructor it seems to work.

Related

Endpoint is not connected in httpclient5-beta

Hi I m trying to use httpcomponents5 beta to make persistent connection, I have tried the example given in their site, the code is as follows,
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom().setSoTimeout(Timeout.ofSeconds(45)).setSelectInterval(10000).setSoReuseAddress(true).setSoKeepAlive(true).build();
final SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(new TrustAllStrategy()).build();
final PoolingAsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder.create().setConnectionTimeToLive(TimeValue.of(1, TimeUnit.DAYS)).setTlsStrategy(new H2TlsStrategy(sslContext, NoopHostnameVerifier.INSTANCE)).build();
client = HttpAsyncClients.createMinimal(protocol, H2Config.DEFAULT, null, ioReactorConfig, connectionManager);
client.start();
final org.apache.hc.core5.http.HttpHost target = new org.apache.hc.core5.http.HttpHost("localhost", 8000, "https");
Future<AsyncClientEndpoint> leaseFuture = client.lease(target, null);
AsyncClientEndpoint asyncClientEndpoint = leaseFuture.get(60, TimeUnit.SECONDS);
final CountDownLatch latch = new CountDownLatch(1);
final AsyncRequestProducer requestProducer = AsyncRequestBuilder.post(target.getSchemeName()+"://"+target.getHostName()+":"+target.getPort()+locationposturl).addParameter(new BasicNameValuePair("info", requestData)).setEntity(new StringAsyncEntityProducer("json post data will go here", ContentType.APPLICATION_JSON)).setHeader("Pragma", "no-cache").setHeader("from", "http5").setHeader("Custom", customheaderName).setHeader("Secure", secureHeader).build();
locEndPoint.execute(requestProducer, SimpleResponseConsumer.create(), new FutureCallback<SimpleHttpResponse>() {
#Override
public void completed(final SimpleHttpResponse response) {
if (response != null) {
if (response.getCode() > -1) {
try {
System.out.println("http5:: COMPLETED : RESPONSE "+response.getBodyText());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
latch.countDown();
}
#Override
public void failed(final Exception ex) {
System.out.println("http5:: FAILED : "+target+locationposturl);
LoggerUtil.printStackTrace(ex);
System.out.println("http5::Exception Request failed "+LoggerUtil.getStackTrace(ex));
latch.countDown();
}
#Override
public void cancelled() {
System.out.println("http5:: CANCELLED : "+target+locationposturl);
System.out.println(http5::Exception Request cancelled");
latch.countDown();
}
});
latch.await();
This code works without a problem for the first time,but when I send a subsequent requests it throws an exception as follows,
http5:: Exception occured java.lang.IllegalStateException: Endpoint is
not connected at
org.apache.hc.core5.util.Asserts.check(Asserts.java:38) at
org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager$InternalConnectionEndpoint.getValidatedPoolEntry(PoolingAsyncClientConnectionManager.java:497)
at
org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager$InternalConnectionEndpoint.execute(PoolingAsyncClientConnectionManager.java:552)
at
org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient$InternalAsyncClientEndpoint.execute(MinimalHttpAsyncClient.java:405)
at
org.apache.hc.core5.http.nio.AsyncClientEndpoint.execute(AsyncClientEndpoint.java:81)
at
org.apache.hc.core5.http.nio.AsyncClientEndpoint.execute(AsyncClientEndpoint.java:114)
What may be the problem with endpoint, I m forcing endpoint to keep alive for a day, kindly shed some light on this

Generated PDF not send in the browser

I build a PDF document with iText library, and i want to get this document by clicking a link in the webapp.
But, it happens... nothing. No error message, no exception, really nothing.
I really don't master IO Streaming, so I think I made a mistake on this point, but after few hours of research, I don't know and I need a bit of help.
I have two methods. The first is the one to create pdf doc.
public void exporterPDF(SomeObjectIWillUse o) {
Document documentPDF = new Document(PageSize.A4);
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter writer = PdfWriter.getInstance(documentPDF, baos);
documentPDF.open();
documentPDF.addTitle("Test ! ");
Paragraph par = new Paragraph("Liste des participants");
documentPDF.add(par)
documentPDF.close();
telechargerPdfViaVue(FacesContext.getCurrentInstance(), baos, "filename.pdf");
} catch (Exception e) {
// TODO Auto-generated catch block
JsfUtils.addMessageByCode(FacesMessage.SEVERITY_FATAL, "drc.export.generation.pdf.erreur");
}
}
And the second is use to send the document.
public static final void telechargerPdfViaVue(FacesContext context, ByteArrayOutputStream baos, String fileName) throws IOException, DocumentException {
ExternalContext externalContext = context.getExternalContext();
externalContext.setResponseContentType("application/pdf");
externalContext.setResponseHeader("Expires", "0");
externalContext.setResponseHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
externalContext.setResponseHeader("Pragma", "public");
externalContext.setResponseHeader("Content-disposition", "attachment;filename=" + fileName);
externalContext.setResponseContentLength(baos.size());
OutputStream out = externalContext.getResponseOutputStream();
baos.writeTo(out);
externalContext.responseFlushBuffer();
context.responseComplete();
}
and it's called on my web page by a simple commandeLink
<p:commandLink id="exportPdf" action="#{myBean.exporterPDF(o)}">
Literally, in debug mode, all is done, but nothing happen...
Thank you for your help!
More informations, I use :
- JSF 2.2.7
- Spring 4.0.6

show servlet's response.getWriter().println() before servlet's ends

first of all I want to say that I am new in html/jsp/java/servlets, etc... and thanks to this forum i managed to get my first webapp working. But now I am having a problem and i couldnt find a solution on the site.
The problem is that I call a servlet from a jsp, this servlet deploys different applications and I simply want to show the println that I call in the servlet before de servlet ends, right now, even If I have 10 println in different moments of the deploy process, the server only shows them when the servlets ends processing, which doesnt hace much sense for my app because i am trying to show the different steps of the deploy.
The servlet code is something like this:
public class Deploys extends HttpServlet {
String HOME = System.getenv("TRACE_HOME");
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
final PrintWriter out = res.getWriter();
String broker = req.getParameter("Broker");
String eg = req.getParameter("Eg");
String servicio = req.getParameter("cboServicios");
String bar = req.getParameter("cboBarFiles");
// deploy
BrokerProxy b;
try {
out.println("connecting to server");
b = utils.connect("LOCALQM");
out.println("connect succesfull");
ExecutionGroupProxy e = b.getExecutionGroupByName(eg);
String path = HOME + "\\deploys\\files\\" + servicio + "\\";
DeployResult dr = e.deploy(path + bar,true, 60000);
out.println("Deployment completion code = "+dr.getCompletionCode());
} catch (ConfigManagerProxyLoggedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (ConfigManagerProxyPropertyNotInitializedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
and the server shows this all at the same time
connecting to server
connect succesfull
starting deploy
deploy completed
I read that the way to to this is using ajax an jquetr but I couldnt find an example of how to do it, so if any one can help will be very appreciated
It's because it only does everything when the servlet is fully deployed, so it will do everything on the servlet almost instantly. At least that's how I learned it.
I think you could only do it editing the server or something like that. I don't think it's possible to do it on jQuery or ajax because the servlet would already be deployed. What you can do, however, is to do those outputs at servlet execution, so it prints while it's processing the code.
OK, I found a solution, I am not sure if its the best way to do it or if it is just a workaround, but it works!
I used flush() and the most important is that I had to set the response type in the servlet.
This is how my "hello world" servlet used to test this case finally works.
public class HolaMundo extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/css");
PrintWriter out = response.getWriter();
out.println("Hello World! entrada");
out.flush();
try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
out.println("Hello World! salida");
out.flush();
}
}

Android 4.4 socketio can't connect to https link

I know this is an old question but I really tried every method online and none of them works for me. I really don't know what to do.
I'm trying to connect my Android 4.4 to node.js by socketIO. I'm using gottox's client: https://github.com/Gottox my socket address is a https link. so I read through lots of articles about the incompatible of this api and https connection.
so I changed the websocketTransport class as suggested as follow:
public WebsocketTransport(URI uri, IOConnection connection) {
super(uri);
this.connection = connection;
SSLContext context = null;
try {
context = SSLContext.getInstance("TLS", "HarmonyJSSE");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
}
try {
context.init(null, null, null);
} catch (KeyManagementException e) {
e.printStackTrace();
}
if("wss".equals(uri.getScheme()) && context != null) {
this.setWebSocketFactory(new DefaultSSLWebSocketClientFactory(context));
}
}
and my code to connect to the socketIO is:
// connecting node server
Log.v("connect to node server", "");
SocketIO socket = new SocketIO();
SocketIO.setDefaultSSLSocketFactory(SSLContext.getDefault());
socket.addHeader("Cookie", "PHPSESSID=" + sessID);
socket.connect("https://live.xxxxxxxx.com:8080/",new IOCallback() {
#Override
public void on(String arg0, IOAcknowledge arg1,
Object... arg2) {
// TODO Auto-generated method stub
}
#Override
public void onConnect() {
// TODO Auto-generated method stub
}
#Override
public void onDisconnect() {
// TODO Auto-generated method stub
}
#Override
public void onError(SocketIOException arg0) {
// TODO Auto-generated method stub
arg0.printStackTrace();
}
#Override
public void onMessage(String arg0, IOAcknowledge arg1) {
// TODO Auto-generated method stub
}
#Override
public void onMessage(JSONObject arg0, IOAcknowledge arg1) {
// TODO Auto-generated method stub
}
});
for my node server, I need to pass a phpsessid in the header, so I added the header as above. but everytime I still got silence mistake. it just didn't work.
here's my log:
io.socket.SocketIOException: Error while handshaking
at io.socket.IOConnection.handshake(IOConnection.java:335)
at io.socket.IOConnection.access$7(IOConnection.java:294)
at io.socket.IOConnection$ConnectThread.run(IOConnection.java:201)
Caused by: java.net.SocketTimeoutException: Read timed out
at com.android.org.conscrypt.NativeCrypto.SSL_read(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:689)
at java.io.InputStream.read(InputStream.java:162)
at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:142)
at java.io.BufferedInputStream.read(BufferedInputStream.java:227)
at com.android.okhttp.internal.Util.readAsciiLine(Util.java:316)
at com.android.okhttp.internal.http.RawHeaders.fromBytes(RawHeaders.java:308)
at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:135)
at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:644)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:347)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:179)
at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:246)
at io.socket.IOConnection.handshake(IOConnection.java:320)
... 2 more
I/io.socket(9077): Cleanup
I have no idea what's going on but I think the problem is android is still using it's own crap ssl factory. so anyone know how to solve this? I read online that android 4.4 r using different standard for https. Is that the problem?

ObjectMapper Not Handling UTF-8 Properly?

I'm using ObjectMapper to serialize posts in my system to json. These posts contain entries from all over the world and contain utf-8 characters. The problem is that the ObjectMapper doesn't seem to be handling these characters properly. For example, the string "Musée d'Orsay" gets serialized as "Mus?©e d'Orsay".
Here's my code that's doing the serialization:
public static String toJson(List<Post> posts) {
ObjectMapper objectMapper = new ObjectMapper()
.configure(Feature.USE_ANNOTATIONS, true);
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
objectMapper.writeValue(out, posts);
} catch (JsonGenerationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new String(out.toByteArray());
}
Interestingly, the exact same List<Post> posts gets serialized just fine when I return it via a request handler using #ResponseBody using the following configuration:
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
ObjectMapper m = new ObjectMapper()
.enable(Feature.USE_ANNOTATIONS)
.disable(Feature.FAIL_ON_UNKNOWN_PROPERTIES);
MappingJacksonHttpMessageConverter c = new MappingJacksonHttpMessageConverter();
c.setObjectMapper(m);
converters.add(c);
super.configureMessageConverters(converters);
}
Any help greatly appreciated!
Aside from conversions, how about simplifying the process to:
return objectMapper.writeValueAsString(posts);
which speeds up the process (no need to go from POJO to byte to array to decode to char to build String) as well as (more importantly) shortens code.
Not 10 minutes later and I found the problem. The issue wasn't with the ObjectMapper, it was with how I was turning the ByteArrayOutputStream into a string. I changed the code as follows and everything started working:
try {
return out.toString("utf-8");
} catch (UnsupportedEncodingException e) {
return out.toString();
}

Resources