BlobStore Redirects being ignored by ServletModule wired servlets - google-app-engine

After the blobstore handles the upload request of a file it redirects to the url it is given, in this case "/upload". If I configure the UploadServlet url in web.xml like this:
<servlet>
<servlet-name>uploadServlet</servlet-name>
<servlet-class>com.....servlet.UploadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>uploadServlet</servlet-name>
<url-pattern>/upload</url-pattern>
</servlet-mapping>
It works. If I use Guice to wire the servlet:
serve("/upload").with(UploadServlet.class);
I get the error:
Problem accessing /upload. Reason:NOT_FOUND
It seems as though the com.google.inject.servlet.ServletModule does not handle redirects. Is there a way around this?

I have struggled with the same issue myself today. This solved my problem and may be related:
https://groups.google.com/forum/#!topic/google-appengine-java/oqfvEmZGrdw
In dev mode, the blobstore service uses
RequestDispatcher.forward() rather than an HTTP request:
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Of course, may be too late for you but for others it might help :-)

Related

Map a servlet to a cron url?

How do I map a servlet to a cron url? This question results from the comment to the answer in the following post: Use Cron jobs with Appengine Endpoints API
In my project the cron job is called as shown in the log in Google App Engine and the url https://[url-commented-out].appspot.com/_ah/api/stocksApi/v1/stocks executes properly when tested in the web browser and returns the proper value.
But I am getting the error 405: HTTP method GET not supported by this URL, when I try to run it in GAE. I've read https://cloud.google.com/appengine/docs/java/config/cron My code in cron.xml file is:
<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
<url>/_ah/api/stocksApi/v1/stocks</url>
<description>Backend Process Stocks</description>
<schedule>every 1 minutes from 11:10 to 11:30</schedule>
<timezone>America/New_York</timezone>
</cron>
</cronentries>
My web.xml is:
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<servlet>
<servlet-name>SystemServiceServlet</servlet-name>
<servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
<init-param>
<param-name>services</param-name>
<param-value>
[package].StocksEndpoint</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SystemServiceServlet</servlet-name>
<url-pattern>/_ah/spi/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>SystemServiceServlet</servlet-name>
<url-pattern>/_ah/api/*</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>cron</web-resource-name>
<url-pattern>/_ah/api/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<filter>
<filter-name>ObjectifyFilter</filter-name>
<filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ObjectifyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
I am using Android Studio and have added a backend module by following HelloEndpoints and I have a StocksEndpoint.java
file with a getStocks(); method that returns stocks.
First add a servlet mapping for your cron to web.xml:
<!-- stock servlet -->
<servlet>
<servlet-name>StockServlet</servlet-name>
<servlet-class>YOUR.PACKAGE.HERE.StockServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StockServlet</servlet-name>
<url-pattern>/cron/stocks</url-pattern>
</servlet-mapping>
make sure to update the servlet class for your servlet!
Then finally put the new cron url in your cron.xml:
<cron>
<url>/cron/stocks</url>
<description>Backend Process Stocks</description>
<schedule>every 1 minutes from 11:10 to 11:30</schedule>
<timezone>America/New_York</timezone>
</cron>
Unfortunately urls under /_ah/api are restricted and cannot be called from within your App.
There are a couple of ways to go around this but the most accepted option is usually to use a regular servlet to serve Cron requests rather connecting to the endpoint.

Email bouncing when sending mail to appengine

I have set up appengine to allow incoming mail, and if I have my web.xml file with
<servlet>
<servlet-name>mailhandler</servlet-name>
<servlet-class>VerifyReply</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mailhandler</servlet-name>
<url-pattern>/_ah/mail/*</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<url-pattern>/_ah/mail/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
it works and runs the VerifyReply servlet, but if I want to limit incoming emails to only those sent to the verifyreply#... email address with (notice the url-pattern is different than above)
<servlet>
<servlet-name>mailhandler</servlet-name>
<servlet-class>VerifyReply</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mailhandler</servlet-name>
<url-pattern>/_ah/mail/v*</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<url-pattern>/_ah/mail/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
it stops working and I get an email bounce back to the sender. My logs page shows the server ran /_ah/mail/verifyreply#... but it doesn't run the servlet and bounces the email.
Any ideas, I think I am following the guide at https://developers.google.com/appengine/docs/java/mail/receiving
According to the docs, filtering on address is not supported:
When App Engine moved to a standard Java Web Server, the ability to specify richer matching patterns was lost (e.g. one used to be able to specify a url-pattern like /_ah/mail/support*). If such pattern matching is desired, consider using a filter-based approach based on the following code snippets.
It would consider it a bug that specifying the full address does work. The page contains an example on how to do address matching in a mail handler filter (a filter in the servlet sense). You should match the address there and return a 404 if you do not want to accept the message. Or you can just ignore messages you don't want if you don't care about bouncing them.

Remove appstats from web.xml (Java)

it seems ridicolous, but I am unable to remove appstats.
If I remove the following from the web.xml:
<filter>
<filter-name>appstats</filter-name>
<filter-
class>com.google.appengine.tools.appstats.AppstatsFilter</filter-
class>
<init-param>
<param-name>logMessage</param-name>
<param-value>Appstats available: /appstats/details?
time={ID}</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>appstats</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
my static content is not accessible any more and produces a 404 error.
I narrowed it down to the filter and filter-mapping tags, since I
removed the other tags from
http://code.google.com/appengine/docs/java/tools/appstats.html
step by step.
Only if those specific tags remain in the web.xml, the static content
becomes inaccessible after deployment.
Last night I had strange errors in the logs which are linked to source
files of appstats.
Hopefully you guys can help me.
Greets
upscale
Did you also delete the servlet definition :
<servlet>
<servlet-name>appstats</servlet-name>
<servlet-class>com.google.appengine.tools.appstats.AppstatsServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>appstats</servlet-name>
<url-pattern>/appstats/*</url-pattern>
</servlet-mapping>
Also, if you included it, you should clean up your appengine-web.xml :
<admin-console>
<page name="Appstats" url="/appstats" />
</admin-console>

encounter "Error configuring application listener of class org.directwebremoting.servlet.DwrListener"

i found the error of "Error configuring application listener of class org.directwebremoting.servlet.DwrListener" when deploying application using dwr in tomcat6.
Here is my web.xml
<display-name>DWR (Direct Web Remoting)</display-name>
<description>A Simple Demo DWR</description>
<listener>
<listener-class>org.directwebremoting.servlet.DwrListener</listener-class>
</listener>
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<display-name>DWR Servlet</display-name>
<description>Direct Web Remoter Servlet</description>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<!-- This should NEVER be present in live -->
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<!-- Remove this unless you want to use active reverse ajax -->
<init-param>
<param-name>activeReverseAjaxEnabled</param-name>
<param-value>true</param-value>
</init-param>
<!-- By default DWR creates application scope objects when they are first
used. This creates them when the app-server is started -->
<init-param>
<param-name>initApplicationScopeCreatorsAtStartup</param-name>
<param-value>true</param-value>
</init-param>
<!-- WARNING: allowing JSON-RPC connections bypasses much of the security
protection that DWR gives you. Take this out if security is important -->
<init-param>
<param-name>jsonRpcEnabled</param-name>
<param-value>true</param-value>
</init-param>
<!-- WARNING: allowing JSONP connections bypasses much of the security
protection that DWR gives you. Take this out if security is important -->
<init-param>
<param-name>jsonpEnabled</param-name>
<param-value>true</param-value>
</init-param>
<!-- data: URLs are good for small images, but are slower, and could OOM for
larger images. Leave this out (or keep 'false') for anything but small images -->
<init-param>
<param-name>preferDataUrlSchema</param-name>
<param-value>false</param-value>
</init-param>
<!-- This enables full streaming mode. It's probably better to leave this
out if you are running across the Internet -->
<init-param>
<param-name>maxWaitAfterWrite</param-name>
<param-value>-1</param-value>
</init-param>
<init-param>
<param-name>org.directwebremoting.extend.ServerLoadMonitor</param-name>
<param-value>org.directwebremoting.impl.PollingServerLoadMonitor</param-value>
</init-param>
<!--
For more information on these parameters, see:
- http://getahead.org/dwr/server/servlet
- http://getahead.org/dwr/reverse-ajax/configuration
-->
<load-on-startup>1</load-on-startup>
</servlet>
Are you are getting a ClassNotFound error as well ?
Have you placed dwr.jar in the WEB-INF/lib directory of your webapp?

Setting up App Engine to receive email addresses with ids in the address

I am writing an App Engine app that is supposed to receive emails in this form:
addcontact.someID#my-app.appspotmail.com (someID is an alphanumeric ID that I generate).
I have this in my web.xml thinking it would catch emails that start
with 'addcontact.':
<servlet>
<servlet-name>addNewContactServlet</servlet-name>
<servlet-class>com.mycompany.server.AddNewContactServlet</servlet-
class>
</servlet>
<servlet-mapping>
<servlet-name>addNewContactServlet</servlet-name>
<url-pattern>/_ah/mail/addcontact.*</url-pattern>
</servlet-mapping>
However, both on my dev machine and on google's servers email is not
received. On the dev machine I get this message (I get a similar error
in the deployed log)
Message send failure
HTTP ERROR 404
Problem accessing /_ah/mail/
addcontact.z1vnq3p2bvtfsuzbxg13sfon#myapp.appspotmail.com.
Reason:
NOT_FOUND
I can receive email at fully specified addresses or when I use /_ah/mail/*
The google documentation made me believe it was possible to include partial email addresses in web.xml. Am I not using the wildcard correctly? Does the period have something to do with it? Can this be done somehow?
The reason why I think it should work is the google docs at: http://code.google.com/appengine/docs/java/mail/receiving.html
In it there is this example web.xml file:
<servlet>
<servlet-name>handleowner</servlet-name>
<servlet-class>HandleOwner</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>handleowner</servlet-name>
<url-pattern>/_ah/mail/owner*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>handlesupport</servlet-name>
<servlet-class>HandleSupport</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>handleowner</servlet-name>
<url-pattern>/_ah/mail/support*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>catchallhandler</servlet-name>
<servlet-class>MailCatchallServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>catchallhandler</servlet-name>
<url-pattern>/_ah/mail/*</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<url-pattern>/_ah/mail/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
It looks like the support and owner email addresses are wildcarded to match any that begin with that address.
This should work. Are you sure it's not your handler returning the 404? I would suggest trying a couple of things to figure out the source of the problem:
Set up a catchall handler for /_ah/mail/* and check that works
If it does, set up one for a simpler prefix, or exact address.

Resources