Well... After trying every possible solution/url-mapping, I went with fast and ugly one.
The gist is to have a single "catch all" mail servlet, to work as a dispatcher to other, specific, servlets. It's like a giant switch
, where the parameter is the request URL.
This is NOT what I wished for, but it works, and seems to be the only one that does.
I have a single servlet IncomingMail
that handles ALL incoming mail. period.
So now, the only mapping of URLs under /_ah/mail/
is the following:
<servlet>
<servlet-name>IncomingMail</servlet-name>
<servlet-class>IncomingMail</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>IncomingMail</servlet-name>
<url-pattern>/_ah/mail/*</url-pattern>
</servlet-mapping>
In addition, I have the following servlet, mapped as a "plain-old-servlet":
(notice the <url-pattern>
, not a "mail mapped" servlet)
<servlet>
<servlet-name>GetUserMail</servlet-name>
<servlet-class>GetUserMail</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>GetUserMail</servlet-name>
<url-pattern>/serv/userMail</url-pattern>
</servlet-mapping>
The catch-all servlet (would eventually) look like a giant switch:
public class IncomingMail extends HttpServlet {
private final String USER_MAIL_PREFIX="http://appid.appspot.com/_ah/mail/user.";
private final String USER_MAIL_SERVLET="/serv/userMail";
...
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String url = req.getRequestURL().toString();
System.out.println("IncomingMail called, with URL: "+url);
String email;
String servlet;
if (url.startsWith(USER_MAIL_PREFIX)) {
email=url.replace(USER_MAIL_PREFIX, "");
servlet=USER_MAIL_SERVLET;
}//userMail
if (url.startsWith(OTHER_PREFIX)) {
//Redirect to OTHER servlet
}
...
System.out.println("forward to '"+servlet+"', with email '"+email+"'");
RequestDispatcher dispatcher=req.getRequestDispatcher(servlet);
try {
req.setAttribute("email", email);
dispatcher.forward(req, resp);
} catch (ServletException e) {
System.err.println(e);
}
}
}
The destination servlet (GetUserMail
in this case), does a getRequestParameter("email")
, to see the specific destined mailbox.
It will receive all mails sent to 'user.%un%@appid.appspotmail.com', where %un% is a username in the application space.
The email parameter received by the servlet would be of the form '%un%@appid.appspotmail.com', without the discerning prefix.
Each such "specific" servlet, would get "its cut" from the mail dispatcher servlet, with the email parameter already without the discerning prefix.
One note I will add under security:
If you're worried of bogus requests to the "specific servlets", just define them all under a common virtual namespace say /servmail/
in your site, and define a new <security-constraint>
to allow requests to originate only within the application itself.
Like so (inside web.xml
):
<security-constraint>
<web-resource-collection>
<web-resource-name>MailServlets</web-resource-name>
<description>policy for specific mail servlets</description>
<url-pattern>/servmail/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
Would still love to hear from someone that tried and succeeded in doing a wildcard <url-pattern>
mail mapping, other than a catch-all one.