From 0bbf4a65cb8a6a4d930bff9c6ee2e53c9f8015c6 Mon Sep 17 00:00:00 2001 From: Bret McGowen Date: Tue, 26 Apr 2016 19:21:39 -0400 Subject: [PATCH 1/2] Added JavaMail API examples for App Engine --- appengine/mail/README.md | 23 ++++ appengine/mail/pom.xml | 66 ++++++++++ .../appengine/mail/EmailFilterSnippets.txt | 107 +++++++++++++++ .../appengine/mail/MailHandlerServlet.java | 45 +++++++ .../example/appengine/mail/MailServlet.java | 124 ++++++++++++++++++ .../src/main/webapp/WEB-INF/appengine-web.xml | 26 ++++ .../mail/src/main/webapp/WEB-INF/web.xml | 34 +++++ 7 files changed, 425 insertions(+) create mode 100644 appengine/mail/README.md create mode 100644 appengine/mail/pom.xml create mode 100644 appengine/mail/src/main/java/com/example/appengine/mail/EmailFilterSnippets.txt create mode 100644 appengine/mail/src/main/java/com/example/appengine/mail/MailHandlerServlet.java create mode 100644 appengine/mail/src/main/java/com/example/appengine/mail/MailServlet.java create mode 100644 appengine/mail/src/main/webapp/WEB-INF/appengine-web.xml create mode 100644 appengine/mail/src/main/webapp/WEB-INF/web.xml diff --git a/appengine/mail/README.md b/appengine/mail/README.md new file mode 100644 index 00000000000..d3663f112aa --- /dev/null +++ b/appengine/mail/README.md @@ -0,0 +1,23 @@ +# JavaMail API Email Sample for Google App Engine Standard Environment + +This sample demonstrates how to use [JavaMail][javamail-api] on [Google App Engine +standard environment][ae-docs]. + +See the [sample application documentaion][sample-docs] for more detailed +instructions. + +[ae-docs]: https://cloud.google.com/appengine/docs/java/ +[javamail-api]: http://javamail.java.net/ +[sample-docs]: https://cloud.google.com/appengine/docs/java/mail/ + +## Setup +1. Update the `` tag in `src/main/webapp/WEB-INF/appengine-web.xml` + with your project name. +1. Update the `` tag in `src/main/webapp/WEB-INF/appengine-web.xml` + with your version name. + +## Running locally + $ mvn appengine:devserver + +## Deploying + $ mvn appengine:update diff --git a/appengine/mail/pom.xml b/appengine/mail/pom.xml new file mode 100644 index 00000000000..d3456d3827b --- /dev/null +++ b/appengine/mail/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + war + 1.0-SNAPSHOT + com.example.appengine + appengine-mail + + com.google.cloud + doc-samples + 1.0.0 + ../.. + + + + javax.servlet + servlet-api + jar + provided + + + com.google.appengine + appengine-api-1.0-sdk + + + javax.mail + mail + 1.4.7 + + + + + ${project.build.directory}/${project.build.finalName}/WEB-INF/classes + + + org.apache.maven.plugins + 3.3 + maven-compiler-plugin + + 1.7 + 1.7 + + + + + com.google.appengine + appengine-maven-plugin + ${appengine.sdk.version} + + + + diff --git a/appengine/mail/src/main/java/com/example/appengine/mail/EmailFilterSnippets.txt b/appengine/mail/src/main/java/com/example/appengine/mail/EmailFilterSnippets.txt new file mode 100644 index 00000000000..1ee0544fd64 --- /dev/null +++ b/appengine/mail/src/main/java/com/example/appengine/mail/EmailFilterSnippets.txt @@ -0,0 +1,107 @@ +// [START handle_discussion_email] +public class HandleDiscussionEmail extends MailHandlerBase { + + public HandleDiscussionEmail() { super("discuss-(.*)@(.*)"); } + + @Override + protected boolean processMessage(HttpServletRequest req, HttpServletResponse res) + throws ServletException + { + MimeMessage msg = getMessageFromRequest(req); + Matcher match = getMatcherFromRequest(req); + ... + } + +} +// [END handle_discussion_email] + +// [START email_filter] + + HandleDiscussionEmail + pkg.HandleDiscussionEmail + + + HandleDiscussionEmail + /_ah/mail/* + +// [END email_filter] + +// [START abstract_mail_handler] +public abstract class MailHandlerBase implements Filter { + + private Pattern pattern = null; + + protected MailHandlerBase(String pattern) { + if (pattern == null || pattern.trim().length() == 0) + { + throw new IllegalArgumentException("Expected non-empty regular expression"); + } + this.pattern = Pattern.compile("/_ah/mail/"+pattern); + } + + @Override public void init(FilterConfig config) throws ServletException { } + + @Override public void destroy() { } + + /** + * Process the message. A message will only be passed to this method + * if the servletPath of the message (typically the recipient for + * appengine) satisfies the pattern passed to the constructor. If + * the implementation returns false, control is passed + * to the next filter in the chain. If the implementation returns + * true, the filter chain is terminated. + * + * The Matcher for the pattern can be retrieved via + * getMatcherFromRequest (e.g. if groups are used in the pattern). + */ + protected abstract boolean processMessage(HttpServletRequest req, HttpServletResponse res) throws ServletException; + + @Override + public void doFilter(ServletRequest sreq, ServletResponse sres, FilterChain chain) + throws IOException, ServletException { + + HttpServletRequest req = (HttpServletRequest) sreq; + HttpServletResponse res = (HttpServletResponse) sres; + + MimeMessage message = getMessageFromRequest(req); + Matcher m = applyPattern(req); + + if (m != null && processMessage(req, res)) { + return; + } + + chain.doFilter(req, res); // Try the next one + + } + + private Matcher applyPattern(HttpServletRequest req) { + Matcher m = pattern.matcher(req.getServletPath()); + if (!m.matches()) m = null; + + req.setAttribute("matcher", m); + return m; + } + + protected Matcher getMatcherFromRequest(ServletRequest req) { + return (Matcher) req.getAttribute("matcher"); + } + + protected MimeMessage getMessageFromRequest(ServletRequest req) throws ServletException { + MimeMessage message = (MimeMessage) req.getAttribute("mimeMessage"); + if (message == null) { + try { + Properties props = new Properties(); + Session session = Session.getDefaultInstance(props, null); + message = new MimeMessage(session, req.getInputStream()); + req.setAttribute("mimeMessage", message); + + } catch (MessagingException e) { + throw new ServletException("Error processing inbound message", e); + } catch (IOException e) { + throw new ServletException("Error processing inbound message", e); + } + } + return message; + } +} +// [END abstract_mail_handler] diff --git a/appengine/mail/src/main/java/com/example/appengine/mail/MailHandlerServlet.java b/appengine/mail/src/main/java/com/example/appengine/mail/MailHandlerServlet.java new file mode 100644 index 00000000000..4cb653fc64d --- /dev/null +++ b/appengine/mail/src/main/java/com/example/appengine/mail/MailHandlerServlet.java @@ -0,0 +1,45 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.appengine.mail; + +// [START mail_handler_servlet] +import java.io.IOException; +import java.util.Properties; + +import javax.mail.MessagingException; +import javax.mail.Session; +import javax.mail.internet.MimeMessage; + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class MailHandlerServlet extends HttpServlet { + + @Override + public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { + Properties props = new Properties(); + Session session = Session.getDefaultInstance(props, null); + try { + MimeMessage message = new MimeMessage(session, req.getInputStream()); + } catch (MessagingException e) { + // ... + } + // ... + } +} +// [END mail_handler_servlet] diff --git a/appengine/mail/src/main/java/com/example/appengine/mail/MailServlet.java b/appengine/mail/src/main/java/com/example/appengine/mail/MailServlet.java new file mode 100644 index 00000000000..b655b5a2da2 --- /dev/null +++ b/appengine/mail/src/main/java/com/example/appengine/mail/MailServlet.java @@ -0,0 +1,124 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.appengine.mail; + +// [START simple_includes] +import java.io.IOException; +import java.util.Properties; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.AddressException; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; +// [END simple_includes] + +// [START multipart_includes] +import java.io.InputStream; +import java.io.ByteArrayInputStream; +import java.io.UnsupportedEncodingException; +import javax.activation.DataHandler; +import javax.mail.Multipart; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMultipart; +// [END multipart_includes] + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@SuppressWarnings("serial") +public class MailServlet extends HttpServlet { + + @Override + public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { + String type = req.getParameter("type"); + if (type != null && type.equals("multipart")) { + resp.getWriter().print("Sending HTML email with attachment."); + sendMultipartMail(); + } else { + resp.getWriter().print("Sending simple email."); + sendSimpleMail(); + } + } + + private void sendSimpleMail() { + // [START simple_example] + Properties props = new Properties(); + Session session = Session.getDefaultInstance(props, null); + + try { + Message msg = new MimeMessage(session); + msg.setFrom(new InternetAddress("admin@example.com", "Example.com Admin")); + msg.addRecipient(Message.RecipientType.TO, + new InternetAddress("user@example.com", "Mr. User")); + msg.setSubject("Your Example.com account has been activated"); + Transport.send(msg); + } catch (AddressException e) { + // ... + } catch (MessagingException e) { + // ... + } catch (UnsupportedEncodingException e) { + // ... + } + // [END simple_example] + } + + private void sendMultipartMail() { + Properties props = new Properties(); + Session session = Session.getDefaultInstance(props, null); + + String msgBody = "..."; + + try { + Message msg = new MimeMessage(session); + msg.setFrom(new InternetAddress("admin@example.com", "Example.com Admin")); + msg.addRecipient(Message.RecipientType.TO, + new InternetAddress("user@example.com", "Mr. User")); + msg.setSubject("Your Example.com account has been activated"); + msg.setText(msgBody); + + // [START multipart_example] + String htmlBody = ""; // ... + byte[] attachmentData = null; // ... + Multipart mp = new MimeMultipart(); + + MimeBodyPart htmlPart = new MimeBodyPart(); + htmlPart.setContent(htmlBody, "text/html"); + mp.addBodyPart(htmlPart); + + MimeBodyPart attachment = new MimeBodyPart(); + InputStream attachmentDataStream = new ByteArrayInputStream(attachmentData); + attachment.setFileName("manual.pdf"); + attachment.setContent(attachmentDataStream, "application/pdf"); + mp.addBodyPart(attachment); + + msg.setContent(mp); + // [END multipart_example] + + Transport.send(msg); + + } catch (AddressException e) { + // ... + } catch (MessagingException e) { + // ... + } catch (UnsupportedEncodingException e) { + // ... + } + } +} diff --git a/appengine/mail/src/main/webapp/WEB-INF/appengine-web.xml b/appengine/mail/src/main/webapp/WEB-INF/appengine-web.xml new file mode 100644 index 00000000000..ad2b031c27c --- /dev/null +++ b/appengine/mail/src/main/webapp/WEB-INF/appengine-web.xml @@ -0,0 +1,26 @@ + + + + + + YOUR-PROJECT-ID + YOUR-VERSION-ID + true + + + + mail + + + diff --git a/appengine/mail/src/main/webapp/WEB-INF/web.xml b/appengine/mail/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000000..e1cc2ed230e --- /dev/null +++ b/appengine/mail/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,34 @@ + + + + mail + com.example.appengine.mail.MailServlet + + + mail + / + + + + + mailhandler + com.example.appengine.mail.MailHandlerServlet + + + mailhandler + /_ah/mail/* + + + + mail + /_ah/mail/* + + + admin + + + + From 02fee3e4d42d8309e2ec17b3ee004955c156c2f1 Mon Sep 17 00:00:00 2001 From: Bret McGowen Date: Thu, 28 Apr 2016 15:00:28 -0400 Subject: [PATCH 2/2] Added BounceHandlerServlet and HandleEmailDiscussion.java --- appengine/mail/pom.xml | 3 + .../appengine/mail/BounceHandlerServlet.java | 54 +++++++++++++++ .../appengine/mail/HandleDiscussionEmail.java | 43 ++++++++++++ ...ilterSnippets.txt => MailHandlerBase.java} | 69 +++++++++++-------- .../appengine/mail/MailHandlerServlet.java | 6 +- .../src/main/webapp/WEB-INF/appengine-web.xml | 3 + .../main/webapp/WEB-INF/logging.properties | 27 ++++++++ .../mail/src/main/webapp/WEB-INF/web.xml | 49 ++++++++++++- 8 files changed, 221 insertions(+), 33 deletions(-) create mode 100644 appengine/mail/src/main/java/com/example/appengine/mail/BounceHandlerServlet.java create mode 100644 appengine/mail/src/main/java/com/example/appengine/mail/HandleDiscussionEmail.java rename appengine/mail/src/main/java/com/example/appengine/mail/{EmailFilterSnippets.txt => MailHandlerBase.java} (66%) create mode 100644 appengine/mail/src/main/webapp/WEB-INF/logging.properties diff --git a/appengine/mail/pom.xml b/appengine/mail/pom.xml index d3456d3827b..19318a04121 100644 --- a/appengine/mail/pom.xml +++ b/appengine/mail/pom.xml @@ -19,12 +19,15 @@ Copyright 2016 Google Inc. All Rights Reserved. 1.0-SNAPSHOT com.example.appengine appengine-mail + + com.google.cloud doc-samples 1.0.0 ../.. + javax.servlet diff --git a/appengine/mail/src/main/java/com/example/appengine/mail/BounceHandlerServlet.java b/appengine/mail/src/main/java/com/example/appengine/mail/BounceHandlerServlet.java new file mode 100644 index 00000000000..0868f5b9c1e --- /dev/null +++ b/appengine/mail/src/main/java/com/example/appengine/mail/BounceHandlerServlet.java @@ -0,0 +1,54 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.appengine.mail; + +// [START bounce_handler_servlet] +import com.google.appengine.api.mail.BounceNotification; +import com.google.appengine.api.mail.BounceNotificationParser; + +import java.io.IOException; +import java.util.logging.Logger; +import javax.mail.MessagingException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class BounceHandlerServlet extends HttpServlet { + + private static final Logger log = Logger.getLogger(BounceHandlerServlet.class.getName()); + + @Override + public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { + try { + BounceNotification bounce = BounceNotificationParser.parse(req); + log.warning("Bounced email notification."); + // The following data is available in a BounceNotification object + // bounce.getOriginal().getFrom() + // bounce.getOriginal().getTo() + // bounce.getOriginal().getSubject() + // bounce.getOriginal().getText() + // bounce.getNotification().getFrom() + // bounce.getNotification().getTo() + // bounce.getNotification().getSubject() + // bounce.getNotification().getText() + // ... + } catch (MessagingException e) { + // ... + } + } +} +// [END bounce_handler_servlet] diff --git a/appengine/mail/src/main/java/com/example/appengine/mail/HandleDiscussionEmail.java b/appengine/mail/src/main/java/com/example/appengine/mail/HandleDiscussionEmail.java new file mode 100644 index 00000000000..d1db81cf5c8 --- /dev/null +++ b/appengine/mail/src/main/java/com/example/appengine/mail/HandleDiscussionEmail.java @@ -0,0 +1,43 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.appengine.mail; + +// [START example] +import javax.mail.internet.MimeMessage; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.ServletException; +import java.util.logging.Logger; +import java.util.regex.Matcher; + +public class HandleDiscussionEmail extends MailHandlerBase { + + private static final Logger log = Logger.getLogger(HandleDiscussionEmail.class.getName()); + public HandleDiscussionEmail() { super("discuss-(.*)@(.*)"); } + + @Override + protected boolean processMessage(HttpServletRequest req, HttpServletResponse res) + throws ServletException + { + log.info("Received e-mail sent to discuss list."); + MimeMessage msg = getMessageFromRequest(req); + Matcher match = getMatcherFromRequest(req); + // ... + return true; + } +} +// [END example] diff --git a/appengine/mail/src/main/java/com/example/appengine/mail/EmailFilterSnippets.txt b/appengine/mail/src/main/java/com/example/appengine/mail/MailHandlerBase.java similarity index 66% rename from appengine/mail/src/main/java/com/example/appengine/mail/EmailFilterSnippets.txt rename to appengine/mail/src/main/java/com/example/appengine/mail/MailHandlerBase.java index 1ee0544fd64..b8458224e53 100644 --- a/appengine/mail/src/main/java/com/example/appengine/mail/EmailFilterSnippets.txt +++ b/appengine/mail/src/main/java/com/example/appengine/mail/MailHandlerBase.java @@ -1,32 +1,41 @@ -// [START handle_discussion_email] -public class HandleDiscussionEmail extends MailHandlerBase { - - public HandleDiscussionEmail() { super("discuss-(.*)@(.*)"); } - - @Override - protected boolean processMessage(HttpServletRequest req, HttpServletResponse res) - throws ServletException - { - MimeMessage msg = getMessageFromRequest(req); - Matcher match = getMatcherFromRequest(req); - ... - } - -} -// [END handle_discussion_email] - -// [START email_filter] - - HandleDiscussionEmail - pkg.HandleDiscussionEmail - - - HandleDiscussionEmail - /_ah/mail/* - -// [END email_filter] - -// [START abstract_mail_handler] +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.appengine.mail; + +import javax.mail.internet.MimeMessage; +import javax.mail.MessagingException; +import javax.mail.Session; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import java.io.IOException; +import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Base class for handling the filtering of incoming emails in App Engine. + */ +// [START example] public abstract class MailHandlerBase implements Filter { private Pattern pattern = null; @@ -104,4 +113,4 @@ protected MimeMessage getMessageFromRequest(ServletRequest req) throws ServletEx return message; } } -// [END abstract_mail_handler] +// [END example] diff --git a/appengine/mail/src/main/java/com/example/appengine/mail/MailHandlerServlet.java b/appengine/mail/src/main/java/com/example/appengine/mail/MailHandlerServlet.java index 4cb653fc64d..47eee63801b 100644 --- a/appengine/mail/src/main/java/com/example/appengine/mail/MailHandlerServlet.java +++ b/appengine/mail/src/main/java/com/example/appengine/mail/MailHandlerServlet.java @@ -18,6 +18,7 @@ // [START mail_handler_servlet] import java.io.IOException; +import java.util.logging.Logger; import java.util.Properties; import javax.mail.MessagingException; @@ -28,7 +29,9 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -public class MailHandlerServlet extends HttpServlet { +public class MailHandlerServlet extends HttpServlet { + + private static final Logger log = Logger.getLogger(MailHandlerServlet.class.getName()); @Override public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { @@ -36,6 +39,7 @@ public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOEx Session session = Session.getDefaultInstance(props, null); try { MimeMessage message = new MimeMessage(session, req.getInputStream()); + log.info("Received mail message."); } catch (MessagingException e) { // ... } diff --git a/appengine/mail/src/main/webapp/WEB-INF/appengine-web.xml b/appengine/mail/src/main/webapp/WEB-INF/appengine-web.xml index ad2b031c27c..176888c9b7d 100644 --- a/appengine/mail/src/main/webapp/WEB-INF/appengine-web.xml +++ b/appengine/mail/src/main/webapp/WEB-INF/appengine-web.xml @@ -20,7 +20,10 @@ + mail + + mail_bounce diff --git a/appengine/mail/src/main/webapp/WEB-INF/logging.properties b/appengine/mail/src/main/webapp/WEB-INF/logging.properties new file mode 100644 index 00000000000..2939d57bcbe --- /dev/null +++ b/appengine/mail/src/main/webapp/WEB-INF/logging.properties @@ -0,0 +1,27 @@ +# +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# A default java.util.logging configuration. +# (All App Engine logging is through java.util.logging by default). +# +# To use this configuration, copy it into your application's WEB-INF +# folder and add the following to your appengine-web.xml: +# +# +# +# +# +# Set the default logging level for all loggers to WARNING +.level=INFO diff --git a/appengine/mail/src/main/webapp/WEB-INF/web.xml b/appengine/mail/src/main/webapp/WEB-INF/web.xml index e1cc2ed230e..f8bae043de6 100644 --- a/appengine/mail/src/main/webapp/WEB-INF/web.xml +++ b/appengine/mail/src/main/webapp/WEB-INF/web.xml @@ -1,4 +1,16 @@ + / - + + + HandleDiscussionEmail + com.example.appengine.mail.HandleDiscussionEmail + + + HandleDiscussionEmail + /_ah/mail/* + + + + + + [END incoming_mail_servlet] --> + + + + bouncehandler + com.example.appengine.mail.BounceHandlerServlet + + + bouncehandler + /_ah/bounce + + + + bounce + /_ah/bounce + + + admin + + +