GWT: form post works only on the local server, not with the app engine - google-app-engine

i have a form with a FormPanel, a FileUpload and a Button
final FormPanel formPanel = new FormPanel();
formPanel.setAction("uploadServlet");
formPanel.setMethod(FormPanel.METHOD_POST);
formPanel.setEncoding(FormPanel.ENCODING_MULTIPART);
formPanel.setSize("100%", "100%");
setWidget(formPanel);
AbsolutePanel absolutePanel = new AbsolutePanel();
formPanel.setWidget(absolutePanel);
absolutePanel.setSize("249px", "70px");
final FileUpload fileUpload = new FileUpload();
fileUpload.setName("uploadFormElement");
absolutePanel.add(fileUpload, 0, 0);
Button btnOpen = new Button("Open");
absolutePanel.add(btnOpen, 10, 30);
Button btnCancel = new Button("Cancel");
absolutePanel.add(btnCancel, 63, 30);
this.setText("Open...");
this.setTitle(this.getText());
this.setAnimationEnabled(true);
this.setGlassEnabled(true);
btnOpen.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
formPanel.submit();
}
});
the servlet gets called but the request contains a error message "error post".
When i try it on the local server it works, the request contains the file, but on the app engine server only the error
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<?> items = null;
String json = null;
try {
items = upload.parseRequest(request);
}
catch (FileUploadException e) {
e.printStackTrace();
}
Iterator<?> it = items.iterator();
while (it.hasNext()) {
System.out.println("while (it.hasNext()) {");
FileItem item = (FileItem) it.next();
json = item.getString();
}
response.setContentType("text/html");
ServletOutputStream out = response.getOutputStream();
response.setContentLength(json.length());
out.write(json.getBytes());
out.close();
}

DiskFileItemFactory is the default implementation for the commons-fileupload library, and based in it's javadoc:
This implementation creates FileItem instances which keep their content either in memory, for smaller items, or in a temporary file on disk, for larger items. The size threshold, above which content will be stored on disk, is configurable, as is the directory in which temporary files will be created.
If not otherwise configured, the default configuration values are as follows:
Size threshold is 10KB. Repository is the system default temp directory, as returned by System.getProperty("java.io.tmpdir").
So as you see, this implementation is going to write in filesystem when it does not have enough memory.
In GAE, there are many constrains, like the memory you are allow to use, or the prohibition of writing in the filesystem.
Your code should fail in GAE developing mode, but maybe you have not reached the memory limitation, or whatever since GAE dev tries to emulate the same constrains than production server, but it is not identical.
Said, that I could take a look to gwtupload library, they have a servlet for GAE which can save files in different ways: BlobStore, FileApi and MemCache.

Related

How can I convert a filled iText PDF template into an Input Stream?

I'm trying to use an existing PDF template and iText to fill in the document, then send the file to our database.
However, I cannot figure out how to convert the finished iText PDF into a usable form - I can display it to the user easily enough, but I cannot get it into a File, InputStream, or even byte[] format to upload to our Database.
public ActionForward doIt(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws java.lang.Exception
{
int docid = Integer.parseInt(form.getDocumentTemplateId());
byte[] byteTemplate = TemplateDb.getTemplate(docId);
PdfReader pdfReader = new PdfReader(byteTemplate);
PdfStamper pdfStamper = new PdfStamper(pdfReader, response.getOutputStream());
AcroFields acroFields = pdfStamper.getAcroFields();
acroFields.setField(//And then I set my acro fields, which works fine);
ByteArrayInputStream inByteStream = new ByteArrayInputStream(byteTemplate );
// This is me calling a separate function to upload the Input Stream - but all that the inByteStream object contains is a blank template
DocumentManager.uploadDocument(inByteStream);
pdfStamper.close();
pdfReader.close();
}

(Android Studio) Connecting an app to Google Endpoints Module

I'm having trouble following the second step here.
I really don't understand how this sample does anything other than return a simple toast message. How does it utilize the API to display that message?
class EndpointsAsyncTask extends AsyncTask<Pair<Context, String>, Void, String> {
private static MyApi myApiService = null;
private Context context;
#Override
protected String doInBackground(Pair<Context, String>... params) {
if(myApiService == null) { // Only do this once
MyApi.Builder builder = new MyApi.Builder(AndroidHttp.newCompatibleTransport(),
new AndroidJsonFactory(), null)
// options for running against local devappserver
// - 10.0.2.2 is localhost's IP address in Android emulator
// - turn off compression when running against local devappserver
.setRootUrl("http://10.0.2.2:8080/_ah/api/")
.setGoogleClientRequestInitializer(new GoogleClientRequestInitializer() {
#Override
public void initialize(AbstractGoogleClientRequest<?> abstractGoogleClientRequest) throws IOException {
abstractGoogleClientRequest.setDisableGZipContent(true);
}
});
// end options for devappserver
myApiService = builder.build();
}
context = params[0].first;
String name = params[0].second;
try {
return myApiService.sayHi(name).execute().getData();
} catch (IOException e) {
return e.getMessage();
}
}
#Override
protected void onPostExecute(String result) {
Toast.makeText(context, result, Toast.LENGTH_LONG).show();
}
I'm afraid my this sample is too complex for my limited knowledge. How exactly do I "talk" to the Google Endpoints Module when running an app? Specifically, What is EndpointsAsyncTask();?
Are there any resources listing all the methods available to me? Is there a simpler example of an app communicating with a Google Cloud Endpoint?
The service methods available to you are defined by the backend source in section 1.
In the example you posted, this line: myApiService.sayHi(name).execute()
is an actual invocation call to the backend that you defined by annotating #ApiMethod("sayHi") on the method in the MyEndpoint.java class of your backend module.
The reason your Android app defines an EndpointsAsyncTask is because slow operations such as calls that hit the network need to happen off of the UI thread to avoid locking the UI. The demo simply puts the returned value into a Toast but you could modify onPostExecute() to do whatever you'd like with the result.
For more info on Google Endpoints check out:
https://cloud.google.com/appengine/docs/java/endpoints/
And for info about using an Android AsyncTask look here:
http://developer.android.com/reference/android/os/AsyncTask.html

CefSharp.Wpf: Open csv, mailto and pdf with Process.Start(...)

I need to handle different content types from f:///. My application renders offline websites in a WPF application. Everything is working except for links to other content files (csv, mailto and pdf).
If I register a CefCustomScheme for "mailto", then I get the ProcessRequestAsync and can run the Process.Start(...). However another blank window also popup.
If I then add a second CefCustomScheme for "file", then nothing happens. None of the ISchemeHandler ProcessRequestAsync methods are invoked.
I must be able to handle all requests, excluding *.html, in a separate handler
Essentially I just want to replicate the behavior of the MS Web-browser Control. There all I did was point to the entry page (index.htm), and everything loaded. Then if a user clicks any link, the control handled the action and started the correct process (content handler, i.e. Excel for Csv).
The code:
// Startup
var settings = new CefSettings();
settings.LogFile = #"c:\temp\ceflog.txt";
settings.LogSeverity = LogSeverity.Verbose;
settings.IgnoreCertificateErrors = true;
CefCustomScheme mailtoScheme = new CefCustomScheme();
mailtoScheme.SchemeName = "mailto";
mailtoScheme.SchemeHandlerFactory = new SchemeHandlerFactory();
CefCustomScheme filesScheme = new CefCustomScheme();
mailtoScheme.SchemeName = "file";
mailtoScheme.SchemeHandlerFactory = new SchemeHandlerFactory();
settings.RegisterScheme(mailtoScheme);
settings.RegisterScheme(filesScheme);
if (!Cef.Initialize(settings))
throw new InvalidOperationException("Failed to initialize the browser factory");
-- SchemeHandlerFactory
public class SchemeHandlerFactory : ISchemeHandlerFactory {
public ISchemeHandler Create() {
return new CustomSchemeHandler();
}
}
-- Handler
public class CustomSchemeHandler : ISchemeHandler {
private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public bool ProcessRequestAsync(IRequest request, ISchemeHandlerResponse response, OnRequestCompletedHandler requestCompletedCallback) {
_log.DebugFormat("Processing url: {0}", request.Dump());
var knownContentTypes = new[] {".csv", ".xsls", ".xlsx", ".pdf", ".txt"};
var ext=Path.GetExtension(request.Url);
if(knownContentTypes.Contains(ext)) {
_log.DebugFormat("Starting process for: {0}",request.Url);
Process.Start(request.Url);
return false;
}
return true;
}
The solution was to implement an IRequestHandler and use the OnBeforeResourceLoad event to check what content was requested. The ISchemeHandler is used for the "mailto" actions.
In my case I had to assign the request handler after the frame loaded. This allowed the web browser to render all content first.
Code sample GitHub example

how to write a file on a web server using WebClient

I am using the following code to write a simple file to a web server in an asynchronous (Silverlight 4) context:
public void WriteToServerAsync(string _input, Uri _uri, Action<bool> _writeComplete)
{
var client = new WebClient();
var bytes = Encoding.UTF8.GetBytes(_input);
var inputStream = new MemoryStream(bytes);
client.OpenWriteCompleted += (s, e) =>
{
var buffer = new byte[4096];
var bytesRead = 0;
while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) != 0)
{
e.Result.Write(buffer, 0, bytesRead);
}
e.Result.Close();
};
client.WriteStreamClosed += (s, e) =>
{
_writeComplete(e.Error == null);
};
client.OpenWriteAsync(_uri);
}
I am calling it with
public void TestWriteToServer()
{
var uri = new Uri( GetAppSetting( "MLCalculations" ) );
WriteToServerAsync("This is some stuff to write", uri, (b) =>
{
// All done!
});
}
The string returned from the GetAppSetting call looks like
http://servername/MainDirectory/Writeable/TestFile.txt
The problem I encounter is in the client.WriteStreamClosed event handler, where e.Error has "The remote server returned an error: NotFound."
On the web server, there is a file structure C:\inetpub\wwwroot\MainDirectory\Writeable. Security on the MainDirectory folder says IIS_IUSRS has Full control and the Writeable folder does, too, although the checkmarks on the MainDirectory are bold and on Writeable they are dimmed.
I also tried placing an "original" file into the target directory, in case it was a "create" issue", but I got the same result.
I do not have any trouble with WebClient.OpenReadAsync.
What am I missing?
The dimmed checks on your folder permission simply mean that those permissions are inherited from the parent folder.
9 times out of 10, the infamous "Not Found" error is caused by an exception server side. If you check out your IIS logs, you will probably be able to track down an entry with a status-code of 500 (server error).
Can you debug the web service? If not, can you edit it to provide additional tracing.
The error is almost certainly caused by an exception in the service itself, so once you have traced the error server-side, you will be well on the way.
If you cant figure it out, perhaps you can post the code for the web service?

Why is Google App Engine servlet getting old no more exist data from file?

I have a Google App Engine servlet, it's supposed to go to my site and get a file, then display the content of that file on the servlet served page, the code looks like this :
public class My_Servlet extends HttpServlet
{
public void init(ServletConfig config) throws ServletException
{
super.init(config);
System.gc();
}
public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException
{
PrintWriter out=response.getWriter();
response.setContentType("text/html");
out.println(getTextFile());
}
String getTextFile()
{
String Text="";
try
{
URL url=new URL("http://example.com/A_Dir/Test.txt");
BufferedReader reader=new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line=reader.readLine())!=null) { Text+=line+"<Br>"; }
reader.close();
}
catch (Exception e) { }
return Text;
}
It worked, but the problem is, after I changed the content in the file "Test.txt" on my site, the Google App is still displaying old data, I checked and double checked the file on my site, the old data is no longer there, and I thought every time I clicked the link served by the GAE, it will call getTextFile(), create the URL, go get the file and parse the lines, but it seems GAE is remembering old data from 3 days ago, and no matter how many times I refreshed the page or updated the GAE app and reloaded it on to the App Engine [and I can see the change made to the updated servlet], it's still serving the more then 3 day old data, why? How to force it dynamically load that file?
GAE is caching the file. Try:
URL url=new URL("http://mysite.com/A_Dir/Test.txt?r="+System.currentTimeMillis());

Resources