{"id":166727,"date":"2013-01-22T23:53:03","date_gmt":"2013-01-22T19:53:03","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=166727"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=166727","title":{"rendered":"<span class=\"post_title\">\u0422\u0440\u0443\u0434\u043e\u0437\u0430\u0442\u0440\u0430\u0442\u044b \u043d\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u00ab\u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e\u00bb \u043c\u043e\u0434\u0443\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 Email \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0441 \u043c\u043e\u0434\u0443\u043b\u044c\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043e\u0439<\/span>"},"content":{"rendered":"<div class=\"content html_format\">\n<table>\n<tr>\n<td>\u041d\u0430 php \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 mail \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u0447\u043a\u043e\u0439 \u043a\u043e\u0434\u0430! \u0410 \u043d\u0430 java- \u043d\u0443\u0436\u043d\u043e 3 \u043d\u0435\u0434\u0435\u043b\u0438??!<br \/>  (\u0438\u0437 \u0440\u0430\u0437\u0433\u043e\u0432\u043e\u0440\u043e\u0432 \u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438 \u0438 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430\u043c\u0438)<\/td>\n<\/tr>\n<\/table>\n<p>  <img decoding=\"async\" src=\"http:\/\/oneims.com\/blog\/wp-content\/uploads\/2008\/06\/direct-mail-success.jpg\"\/><br \/>   \u0421\u0442\u0430\u0442\u044c\u044f \u043d\u0435 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u0447\u0442\u0443 \u043d\u0430 java. \u041c\u043e\u044f \u0446\u0435\u043b\u044c \u2014 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043c\u043e\u0434\u0443\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 (\u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 ERP River).<\/p>\n<h5>\u0418\u0442\u0430\u043a, \u0437\u0430\u0434\u0430\u0447\u0430: \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043f\u043e email (war).<\/h5>\n<p>  <\/p>\n<h4>\u042d\u0442\u0430\u043f\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438:<\/h4>\n<p>  <a name=\"habracut\"><\/a>   <\/p>\n<h5>\u041d\u0430\u0447\u043d\u0435\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438<\/h5>\n<p>   \u0415\u0441\u043b\u0438 \u043d\u0435 Spring (\u0434\u043b\u044f \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u043e\u043d \u043d\u0435 \u043d\u0443\u0436\u0435\u043d), \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c apache commons-email   <\/p>\n<pre><code class=\"xml\">        &lt;dependency&gt;             &lt;groupId&gt;org.apache.commons&lt;\/groupId&gt;             &lt;artifactId&gt;commons-email&lt;\/artifactId&gt;             &lt;version&gt;1.3&lt;\/version&gt;         &lt;\/dependency&gt;<\/code><\/pre>\n<p>   \u0438 \u043f\u0438\u0448\u0435\u043c <\/p>\n<pre><code class=\"java\">        public class MailSender {             public static void sendMail {                 HtmlEmail email = ...                 ?                 email.send();<\/code><\/pre>\n<p>   \u041f\u043e\u0437\u0432\u043e\u043b\u044c\u0442\u0435, \u043e\u0442\u043a\u0443\u0434\u0430 \u0431\u0440\u0430\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430? \u0425\u0430\u0440\u0434\u043a\u043e\u0434\u0438\u0442\u044c \u0438\u0445, \u0434\u0443\u043c\u0430\u044e, \u043d\u0435 \u043f\u0440\u0438\u0434\u0435\u0442 \u0432 \u0433\u043e\u043b\u043e\u0432\u0443 \u0434\u0430\u0436\u0435 \u043c\u043b\u0430\u0434\u0448\u0435\u043c\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0443, \u043f\u043e\u044d\u0442\u043e\u043c\u0443:<\/p>\n<h5>\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430<\/h5>\n<p>   \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0443 \u043d\u0430\u0441 \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430 \u043e\u0431\u0449\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u043f\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0432\u0441\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u0438 \u043d\u0430\u043c \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0435 \u0434\u043b\u044f \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f:   <\/p>\n<pre><code class=\"xml\">                    ...                     &lt;part key=&quot;email&quot;&gt;                         &lt;entry key=&quot;hostName&quot;&gt;smtp.gmail.com&lt;\/entry&gt;                         &lt;entry key=&quot;user&quot;&gt;sendmail@mycompany.ru&lt;\/entry&gt;                         &lt;entry key=&quot;password&quot;&gt;psw&lt;\/entry&gt;                         &lt;entry key=&quot;smtpPort&quot;&gt;465&lt;\/entry&gt;                         &lt;entry key=&quot;useSSL&quot;&gt;true&lt;\/entry&gt;                         &lt;entry key=&quot;debug&quot;&gt;false&lt;\/entry&gt;                         &lt;entry key=&quot;charset&quot;&gt;UTF-8&lt;\/entry&gt;                         &lt;entry key=&quot;useTLS&quot;&gt;false&lt;\/entry&gt;                     &lt;\/part&gt;                <\/code><\/pre>\n<p>   <\/p>\n<pre><code class=\"java\">        public class MailConfig {             public static &lt;T extends Email&gt; T prepareEmail(T email) {                  email.setHostName(hostName);                  email.setSmtpPort(port);                  email.setSSL(useSSL);                  email.setTLS(useTLS);                  email.setDebug(debug);                  email.setAuthenticator(defaultAuthenticator);                  email.setCharset(charset);                  return email;               }<\/code><\/pre>\n<p>   <\/p>\n<h5>\u0412\u044b\u0437\u043e\u0432 \u0441\u0435\u0440\u0432\u0438\u0441\u0430<\/h5>\n<p>  \u0410\u0433\u0430, \u0443 \u043d\u0430\u0441 \u0441\u0435\u0440\u0432\u0438\u0441- \u043a\u0430\u043a \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0435\u0433\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c?<br \/>  \u0411\u0438\u0437\u043d\u0435\u0441 \u0445\u043e\u0447\u0435\u0442 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e \u043f\u043e \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c, \u0438 \u043d\u0443\u0436\u043d\u043e \u0435\u0449\u0435 \u0438\u043c\u0435\u0442\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u043f\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u043c\u0443 HTTP GET (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0438\u0437 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430):   <\/p>\n<ul>\n<li>\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u043f\u043e HTTP GET:<br \/> \n<pre><code class=\"java\">        public class MailServlet extends CommonServlet {             @Override             protected void doProcess(HttpServletRequest request, HttpServletResponse response, Map&lt;String, String&gt; params) throws IOException, ServletException {                  String from = ConfigUtil.getProperty(&quot;from&quot;, params);                  ...                  MailSender.sendMail(from, to, cc, ..);<\/code><\/pre>\n<p>   <\/li>\n<li>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u0435\u0432-\u0441\u0435\u0440\u0432\u0438\u0441\u0430 (JAX-WS) \u043f\u043e\u0441\u043b\u043e\u0436\u043d\u0435\u0435:\n<pre><code class=\"java\">        @WebService         @SOAPBinding(style = Style.RPC)         public interface MailService {             @WebMethod             public void sendMail(                 @WebParam(name = &quot;from&quot;) String from,                 @WebParam(name = &quot;to&quot;) String to,          @WebService(endpointInterface = &quot;mycompany.MailService&quot;)         public class MailServiceImpl implements MailService {             @Override             public void sendMail(String from, String to, String cc, String subject, String body, String attachmentUrls) throws StateException {                 MailSender.sendMailAndRecordHistory(from, to, cc, subject, body, ..);             }            <\/code><\/pre>\n<p>  \u0438 mailService.wsdl:   <\/p>\n<pre><code class=\"xml\">        &lt;definitions ..                 targetNamespace=&quot;http:\/\/mail.mycompany.com\/&quot; name=&quot;MailServiceImplService&quot;&gt;             &lt;message name=&quot;sendMail&quot;&gt;                 &lt;part name=&quot;from&quot; type=&quot;xsd:string&quot;\/&gt;                 ...              &lt;portType name=&quot;MailService&quot;&gt;                 &lt;operation name=&quot;sendMail&quot; parameterOrder=&quot;from to cc subject body attachmentUrls&quot;&gt;                     &lt;input wsam:Action=&quot;http:\/\/mail.mycompany.com\/MailService\/sendMailRequest&quot; message=&quot;tns:sendMail&quot;\/&gt;                 ...              &lt;binding name=&quot;MailServiceImplPortBinding&quot; type=&quot;tns:MailService&quot;&gt;                 &lt;soap:binding transport=&quot;http:\/\/schemas.xmlsoap.org\/soap\/http&quot; style=&quot;rpc&quot;\/&gt;                 &lt;operation name=&quot;sendMail&quot;&gt;                     &lt;soap:operation soapAction=&quot;&quot;\/&gt;                 ...             &lt;service name=&quot;MailServiceImplService&quot;&gt;                 &lt;port name=&quot;MailServiceImplPort&quot; binding=&quot;tns:MailServiceImplPortBinding&quot;&gt;                     &lt;soap:address location=&quot;http:\/\/mycompany:8080\/mail\/mailService&quot;\/&gt;                 ...            <\/code><\/pre>\n<p>   \u041d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c web.xml (Tomcat)   <\/p>\n<pre><code class=\"xml\">        &lt;listener&gt;             &lt;listener-class&gt;com.sun.xml.ws.transport.http.servlet.WSServletContextListener&lt;\/listener-class&gt;         &lt;\/listener&gt;          &lt;servlet&gt;             &lt;servlet-name&gt;mailService&lt;\/servlet-name&gt;             &lt;servlet-class&gt;com.sun.xml.ws.transport.http.servlet.WSServlet&lt;\/servlet-class&gt;             &lt;load-on-startup&gt;1&lt;\/load-on-startup&gt;         &lt;\/servlet&gt;         &lt;servlet-mapping&gt;             &lt;servlet-name&gt;mailService&lt;\/servlet-name&gt;             &lt;url-pattern&gt;\/mailService&lt;\/url-pattern&gt;         &lt;\/servlet-mapping&gt;          &lt;servlet&gt;             &lt;servlet-name&gt;mailServlet&lt;\/servlet-name&gt;             &lt;servlet-class&gt;com.mycompany.mail.MailServlet&lt;\/servlet-class&gt;             &lt;load-on-startup&gt;1&lt;\/load-on-startup&gt;         &lt;\/servlet&gt;         &lt;servlet-mapping&gt;             ...            <\/code><\/pre>\n<\/li>\n<\/ul>\n<p>   <\/p>\n<h5>\u0412\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 mail-client<\/h5>\n<p>  \u0410 \u043a\u0430\u043a \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0441\u0435\u0434\u043d\u0435\u043c\u0443 \u043c\u043e\u0434\u0443\u043b\u044e \u043d\u0430\u0448\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0431\u044b\u0441\u0442\u0440\u043e \u0434\u0435\u0440\u043d\u0443\u0442\u044c \u043f\u043e \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0438\u0441\u0443 \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0438\u0441? \u041f\u0440\u043e\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u2014 \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c maven \u043c\u043e\u0434\u0443\u043b\u044c mail-client, \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0442 \u043d\u0435\u0433\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u043c \u043d\u0430\u0448 mail \u0441\u0435\u0440\u0432\u0438\u0441 \u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u043b\u044e\u0431\u043e\u043c\u0443 \u043c\u043e\u0434\u0443\u043b\u044e \u2014 \u043d\u0430\u0448\u0435\u043c\u0443 \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0432 \u0441\u0435\u0431\u044f (maven dependency) mail-client:   <\/p>\n<ul>\n<li>\u0414\u0435\u043b\u0430\u0435\u043c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 maven \u043c\u043e\u0434\u0443\u043b\u044c mail-client \u0438 \u043a\u043b\u0430\u0434\u0435\u043c \u0432 \u043d\u0435\u0433\u043e mailService.wsdl \u0438 interface MailService<br \/> \n<pre><code class=\"xml\">        &lt;groupId&gt;com.mycompany&lt;\/groupId&gt;         &lt;artifactId&gt;mail-client&lt;\/artifactId&gt;         &lt;name&gt;Mail Client&lt;\/name&gt;                <\/code><\/pre>\n<p>  <\/li>\n<li>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0434\u043b\u044f \u043f\u043e\u043b\u043d\u043e\u0439 \u0440\u0430\u0434\u043e\u0441\u0442\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0434\u0435\u043b\u0430\u0435\u043c MailWSClient:<br \/>  \u0432\u044b\u0437\u043e\u0432 \u0441\u043e\u0441\u0435\u0434\u043d\u0435\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0439: <br \/> \n<pre><code>MailWSClient.sendMail(... <\/code><\/pre>\n<p>   <\/p>\n<pre><code class=\"java\">        public class MailWSClient {             static String mailWsdl;             private static final Service SERVICE;              static {                 URL url = MailWSClient.class.getClassLoader().getResource(&quot;mailService.wsdl&quot;);                 SERVICE = Service.create(url, new QName(&quot;http:\/\/mail.mycompany.com\/&quot;, &quot;MailServiceImplService&quot;));                 \/\/ get mail endpoint from config                 mailWsdl = Config.getUrlAsString(&quot;mail\/mailService?wsdl&quot;);             }              public static void sendMail(String from, String to, ..){                         getPort().sendMail(from, ..              private static MailService getPort() {                 MailService port = SERVICE.getPort(MailService.class);                 Map&lt;String, Object&gt; requestContext = ((BindingProvider) port).getRequestContext();                 requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, mailWsdl);                 return port;             }                    <\/code><\/pre>\n<\/li>\n<\/ul>\n<p>   <\/p>\n<h5>\u041f\u0440\u0438\u043a\u0440\u0443\u0447\u0438\u0432\u0430\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u044b<\/h5>\n<p>   \u042d\u0433\u0435. \u0412 \u043c\u043e\u0434\u0443\u043b\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u043e\u0431\u043e\u0440\u043e\u0442\u0430 \u0443 \u043d\u0430\u0441 52 \u0432\u0438\u0434\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u0425\u043e\u0440\u043e\u0448\u043e \u0431 \u0431\u044b\u043b\u043e \u043d\u0430\u0448\u0438\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c \u0434\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u0430\u043c\u0438\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d \u043f\u0438\u0441\u044c\u043c\u0430. \u0422\u0435\u043c \u0431\u043e\u043b\u0435\u0435, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 (TemplateService) \u0443 \u043d\u0430\u0441 \u0443\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d.<br \/>    \u0421\u0435\u0440\u0432\u0438\u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u043f\u0440\u043e\u0441\u0442\u043e\u0439: \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043d\u0430 jsp, \u043f\u043e get \u0435\u043c\u0443 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043a\u043b\u044e\u0447 \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442.<\/p>\n<ul>\n<li>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c sendTemplateMail \u0432 MailService, MailWSClient, MailServiceImpl, MailSender, mailService.wsdl \u0438 MailServlet:<br \/> \n<pre><code class=\"java\">             sendTemplateMail(.., templateKey, params);                  <\/code><\/pre>\n<\/li>\n<li>\u0418 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0435\u0433\u043e \u0432 MailSender (\u0443 \u043d\u0430\u0441 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0443\u0434\u043e\u0431\u043d\u0430\u044f \u043e\u0431\u0435\u0440\u0442\u043a\u0430 MyHttpConnection, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0447\u0435\u0440\u0435\u0437 HttpURLConnection.openConnection())<br \/> \n<pre><code class=\"java\">            static void sendTemplateMail(..., String key, String params) {                 LOGGER.info(&quot;Send template mail from ...                 String templateUrl = getUrlAsString(&quot;template?type=mail&format=html&key=&quot; + key ...                 MyHttpConnection conn = MyHttpConnection.connect(templateUrl, params);                 if (conn.isOk()) {                    String body = conn.getMsg();                     sendMail(from, to, cc, MailUtil.getSubject(body), body);                 } else {                     throw LOGGER.getStateException(conn.toString(), ExceptionType.TEMPLATE);                 ...                <\/code><\/pre>\n<p>  \u041f\u043e\u043f\u0443\u0442\u043d\u043e \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0441 subject: \u0441\u0435\u0440\u0432\u0438\u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u043b\u043e \u043f\u0438\u0441\u044c\u043c\u0430. \u0428\u0430\u0431\u043b\u043e\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 html, MailUtil \u0432\u044b\u0434\u0435\u043b\u0430\u0435\u0442 \u0438\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 tiltle \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0435\u0433\u043e \u043a\u0430\u043a subject:<\/p>\n<pre><code class=\"java\">        public class MailUtil {             static Pattern MAIL_TITLE = Pattern.compile(&quot;&lt;title&gt;(.+)&lt;\/title&gt;&quot;, Pattern.MULTILINE);              static String getSubject(String template) {                 Matcher m = MAIL_TITLE.matcher(template);                 return m.find() ? m.group(1) : null;             }<\/code><\/pre>\n<\/li>\n<\/ul>\n<p>   <\/p>\n<h5>\u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442<\/h5>\n<p>   \u0412\u043e\u043e\u0431\u0449\u0435-\u0442\u043e \u0443 \u043d\u0430\u0441 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b. \u0410 \u0447\u0442\u043e, \u0435\u0441\u043b\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0430\u0441 \u0441\u0435\u0440\u0432\u0438\u0441 \u0441 id \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430? \u0428\u0430\u0431\u043b\u043e\u043d\u044b \u0434\u043b\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 TemplateService \u0443\u0436\u0435 \u0435\u0441\u0442\u044c.   <\/p>\n<ul>\n<li>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c sendDocMail \u0432 MailService, MailWSClient, MailServiceImpl, MailSender, mailService.wsdl \u0438 MailServlet.<br \/> \n<pre><code class=\"java\"> sendDocMail(String from, String to, String cc, String key, long docId);                 <\/code><\/pre>\n<\/li>\n<li>\u041e\u043f\u0430\u043d\u044c\u043a\u0438, \u0430 \u0443 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0435\u0441\u0442\u044c \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u0430\u0442\u0442\u0430\u0447\u0438\u0442\u044c \u043a \u043f\u0438\u0441\u044c\u043c\u0443.<br \/>   \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e commons-email \u044d\u0442\u043e \u043b\u0435\u0433\u043a\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442, \u0438 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043e\u0431\u0449\u0438\u0439 maven \u043c\u043e\u0434\u0443\u043b\u044c attach-common, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0430\u0442\u0442\u0430\u0447\u0435\u0439 \u043f\u043e docId:<br \/> \n<pre><code class=\"java\">        public class MailSender {             static void sendDocMail(String from, String to, String cc, String key, long docId) throws StateException {                 List&lt;Attach&gt; list = AttachUtil.getList(docId);                 MailSender.sendTemplateMailAndRecordHistory(from, to, cc, key, &quot;objectid=&quot; + docId, MailUtil.formatAttach(list));             }          public class MailUtil {              \/\/  format attaches as             \/\/       ulr1[name1], ulr2[name2], ...              static String formatAttach(List&lt;Attach&gt; list) {                 return Util.collectionToDelimitedString(list, new Presentable&lt;Attach&gt;() {                     @Override                         public String toString(Attach attach) {                         return AttachConfig.downloadUrl + attach.getUuid() + '[' + attach.getName() + ']';                     }        <\/code><\/pre>\n<\/li>\n<\/ul>\n<p>   <\/p>\n<h5>\u041e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c<\/h5>\n<p>  \u0410 \u0435\u0441\u043b\u0438 \u0441\u0435\u0440\u0432\u0435\u0440 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d? \u041d\u0443\u0436\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0432 \u0431\u0430\u0437\u0435 \u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0442\u0435\u043b\u044c\u2026 \u0417\u0430\u043e\u0434\u043d\u043e \u0440\u0435\u0448\u0438\u043c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043f\u0438\u0441\u044c\u043c\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043f\u043e \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e \u043d\u0430 \u043d\u0435\u0433\u043e \u0437\u0430\u0434\u0430\u0447\u0438 \u0438\u0437 BPM \u2014 \u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0442\u0440\u0438\u0433\u0433\u0435\u0440 \u0432 \u0431\u0430\u0437\u0435: \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u0442\u0440\u043e\u0447\u043a\u0443 TODO. \u041a\u0430\u043a side effect \u0438\u043c\u0435\u0435\u043c \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043d\u0430\u0448\u0438\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0442\u043e\u043c \u0441\u0432\u0435\u0440\u0445\u0443 \u043d\u0430\u043a\u0440\u0443\u0442\u0438\u0442\u044c ui \u043d\u0443 \u0438 \u043f\u0440\u043e\u0441\u0442\u043e SQL \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u043f\u043e\u0434\u0435\u043b\u0430\u0442\u044c.<br \/>  \u0425\u043e\u0440\u043e\u0448\u043e, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u2014 \u043d\u0443\u0436\u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0435\u0449\u0435 \u043e\u0434\u043d\u0430 \u0435\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f.<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0414\u0435\u043b\u0430\u0435\u043c \u0432 \u0431\u0430\u0437\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 mail_action<br \/> \n<pre><code class=\"sql\">        CREATE TABLE hist.mail_action (             id SERIAL,             _from TEXT,             _to TEXT NOT NULL,             _cc TEXT,             subject TEXT,             body TEXT,             attachmenturls TEXT,             state TEXT NOT NULL,             date TIMESTAMP(0) WITHOUT TIME ZONE,             key reference.ui_key,             params TEXT         );<\/code><\/pre>\n<\/li>\n<li>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u044b \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<br \/> \n<pre><code class=\"xml\">        &lt;entry key=&quot;scanTodoInterval&quot;&gt;30&lt;\/entry&gt;         &lt;entry key=&quot;scanFailInterval&quot;&gt;600&lt;\/entry&gt;    <\/code><\/pre>\n<p>   <\/p>\n<pre><code class=\"java\">scanTodoInterval = ConfigUtil.getInt(SCAN_TODO_INTERVAL, mailProps, 60);  \/\/ default 60 sec scanFailInterval = ConfigUtil.getInt(SCAN_FAIL_INTERVAL, mailProps, 600); \/\/ default 10 min    <\/code><\/pre>\n<p>   \u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0432 MailSender \u0437\u0430\u043f\u0438\u0441\u044c \u0438\u0441\u0442\u043e\u0440\u0438\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0432 \u0431\u0430\u0437\u0443 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c (OK \u0438\u043b\u0438 Exception).<br \/>   \u0421\u043a\u0430\u043d\u0438\u0440\u0443\u0435\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 mail_action \u0438 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f state (TODO, EmailException) \u043e\u0442\u0441\u044b\u043b\u0430\u0435\u043c \u043f\u0438\u0441\u044c\u043c\u043e   <\/p>\n<pre><code class=\"xml\">        &lt;listener&gt;             &lt;listener-class&gt;com.mycompany.common.web.SchedulerListener&lt;\/listener-class&gt;         &lt;\/listener&gt;    <\/code><\/pre>\n<p>   <\/p>\n<pre><code class=\"java\">        public class MailWebScanner implements WebScheduler {             private final MailScanner todoScanner = new MailScanner(&quot;TODO&quot;);             private final MailScanner failScanner = new MailScanner(&quot;org.apache.commons.mail.EmailException&quot;);              @Override             public void activate(ServletContext servletContext) {                 todoScanner.startScanning(MailConfig.scanTodoInterval);                 failScanner.startScanning(MailConfig.scanFailInterval);             }              @Override             public void deactivate() {                 todoScanner.deactivate();                 failScanner.deactivate();             }              @Override             public void shutdown() {                 AsyncExecutor.shutdown();             }         }          public class MailScanner extends Scanner {             private static final BeanListHandler&lt;MailBean&gt; HANDLER = new BeanListHandler&lt;MailBean&gt;(MailBean.class);             private final String startWith;              public MailScanner(String startWith) {                 this.startWith = startWith;             }              void startScanning(int interval) {                 activate(new Runnable() {                     @Override                     public void run() {                         for (MailBean mail : getMailToSend()) {                             MailSender.sendTemplateMailAndRecordHistory(                         }                     }                 }, interval, false);             }             ...              List&lt;MailBean&gt; getMailToSend() {                 return SqlUtil.executeQuery(&quot;select * from hist.mail_action where state like '&quot; + startWith + &quot;%'&quot;, HANDLER);             ...    <\/code><\/pre>\n<\/li>\n<\/ul>\n<p>   <\/p>\n<h5>\u0414\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u043d\u0435 \u043b\u044e\u0431\u0438\u0442 \u0436\u0434\u0430\u0442\u044c: \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c<\/h5>\n<p>   \u0422\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0438\u0441 \u0442\u0435\u043f\u0435\u0440\u044c \u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432 \u043a \u043e\u0442\u043a\u0430\u0437\u0430\u043c, \u0434\u0430\u0434\u0438\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c \u043d\u0430\u0448\u0435\u0433\u043e \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043d\u0435 \u0436\u0434\u0430\u0442\u044c \u043e\u0442\u0432\u0435\u0442\u0430. \u0412\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0441\u0435\u0440\u0441\u0432\u0438\u0441\u0430 \u0441 \u043f\u043e\u0441\u0442\u0444\u0438\u043a\u0441\u043e\u043c Async \u0438 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439 @OneWay \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u0432\u044b\u0437\u043e\u0432\u044b MailWSClient \u0444\u043b\u0430\u0433 async \u0438 \u0432\u044b\u0437\u043e\u0432 AsyncExecutor (\u043d\u0430\u0448\u0435\u0439 \u043e\u0431\u0435\u0440\u0442\u043a\u0438 \u043f\u043e\u0432\u0435\u0440\u0445 ScheduledThreadPoolExecutor):  <\/p>\n<pre><code class=\"java\">        public class MailWSClient {             public static void sendMail(final String from, final String to, final String cc, final String subject, final String body, final String attachmentUrls, boolean async) throws StateException {                 send(new Runnable() {                     @Override                     public void run() {                        getPort().sendMail(mask(from), mask(to), mask(cc), mask(subject), mask(body), mask(attachmentUrls));                     }                 }, async);             }              public static void sendTemplateMail(final String from, final String to, final String cc, final String key, final String params, final String attachmentUrls, boolean async) throws StateException {                 ...               public static void sendDocMail(final String from, final String to, final String cc, final String key, final long docId, boolean async) throws StateException {                 ...              private static void send(Runnable task, boolean async) {                 if (async) {                    AsyncExecutor.submit(task);                 } else {                    task.run();                 }              }<\/code><\/pre>\n<p>   <\/p>\n<h5>\u0427\u0438\u043d\u0438\u043c \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u043a<\/h5>\n<p>   \u041e\u043b\u0438\u0447\u043d\u043e, \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442! \u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u043e\u0436\u043d\u043e \u0444\u0438\u043a\u0441\u0438\u0442\u044c \u0431\u0430\u0433\u0438 \u2014 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438 \u0432 \u043f\u0438\u0441\u044c\u043c\u0435 \u043d\u0435 \u0432\u0438\u0434\u043d\u044b \u0441\u043d\u0430\u0440\u0443\u0436\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u0438\u043d\u0442\u0440\u0430\u043d\u0435\u0442\u0430\u2026 \u0412\u0435\u0434\u044c \u043e\u043d\u0438 \u0443 \u043d\u0430\u0441 \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u0445 \u0437\u0430\u0434\u0430\u043d\u044b \u0447\u0435\u0440\u0435\u0437 &lt;img src=\u00ab\u043d\u0430\u0448\u0438 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b\u00bb, \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0432\u043e \u0432\u0441\u0435\u043c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u043c \u043c\u0438\u0440\u0435 \u0438\u0445 \u043d\u0435 \u0443\u0432\u0438\u0434\u0438\u0448\u044c.<\/p>\n<p>  \u0414\u0435\u043b\u0430\u0435\u043c \u0438\u0445 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u043c\u0438:   <\/p>\n<pre><code class=\"java\">        public class MailSender {             static void sendMailAndRecordHistory(String from, String to, String cc, String key, String params, String attachmentUrls, long docId) throws StateException {                 ...                 String embedImgBody = MailUtil.embedImg(body, email);          public class MailUtil {             static final Pattern HTML_URL = Pattern.compile(&quot;&lt;img src=(?:\\&quot;|')(.+)(?:\\&quot;|')&quot;, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);             public static String embedImg(String body, final HtmlEmail email) throws EmailException {                 return StringUtil.resolveReplacement(body, HTML_URL, new Presentable&lt;Matcher&gt;() {                     @Override                     public String toString(Matcher matcher) {                         String url = matcher.group(1);                         cid = email.embed(url, UUID.nameUUIDFromBytes(url.getBytes()).toString());                     }                     return &quot;&lt;img src=\\&quot;cid:&quot; + cid + &quot;\\&quot;&quot;;                  ...                <\/code><\/pre>\n<p>   <\/p>\n<h5>\u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 (data:image\/png;base64,encoded_img) \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438<\/h5>\n<p>   \u041d\u043e\u0432\u0430\u044f \u0437\u0430\u0434\u0443\u043c\u043a\u0430 \u0431\u0438\u0437\u043d\u0435\u0441\u0430 \u2014 \u043f\u043e \u043e\u0448\u0438\u0431\u043a\u0435 \u0438\u0437 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u0430 support mail \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442 \u044d\u043a\u0440\u0430\u043d\u0430. <br \/>  <a href=\"http:\/\/html2canvas.hertzen.com\">\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 UI \u043d\u0430\u0439\u0434\u0435\u043d\u043e<\/a> \u2014 \u0445\u043e\u0434 \u0437\u0430 \u043d\u0430\u043c\u0438. \u0414\u043b\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u043f\u0438\u0448\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d error_mail.jsp   <\/p>\n<pre><code class=\"xml\">            &lt;%@page pageEncoding=&quot;UTF-8&quot; %&gt;             &lt;html&gt;             &lt;head&gt;                 &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text\/html; charset=UTF-8&quot;&gt;                 &lt;title&gt;Error Report&lt;\/title&gt;             &lt;\/head&gt;             &lt;body&gt;             &lt;h2&gt;Error Report from '${user}'&lt;\/h2&gt;             &lt;b&gt;Message:&lt;\/b&gt;                 &lt;pre&gt;                 ${message}                 &lt;\/pre&gt;             &lt;b&gt;Screenshot:&lt;\/b&gt;&lt;br&gt;             &lt;img src=&quot;${screenshot}&quot;&gt;             &lt;\/body&gt;             &lt;\/html&gt;         <\/code><\/pre>\n<p>  \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u2014 exception message \u0438 base64_encoded_screenshot \u2014 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432 TemplateService \u0438\u0437 \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u0423 \u043d\u0430\u0441 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b: \u043d\u0430\u0448\u0430 \u0441\u0430\u043c\u043e\u043f\u0438\u0441\u043d\u0430\u044f \u043e\u0431\u0435\u0440\u0442\u043a\u0430 MyHttpConnection \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 GET \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c base64_encoded_screenshot. \u041f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0434\u0435\u043b\u0430\u0442\u044c POST \u0438 \u0435\u0449\u0435 \u0440\u0430\u0437 \u0434\u0435\u043b\u0430\u0442\u044c URLEncoder.encode \u0438\u0437 \u0437\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0441 &quot;+&quot;. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e- \u0432 \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0435\u0439 \u043f\u043e\u0447\u0442\u0435 inline \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430 \u043d\u0435 \u0432\u0438\u0434\u043d\u0430 \ud83d\ude41 \u0427\u0442\u043e \u0436, \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0435\u0435 \u0442\u0430\u043a\u0436\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c:   <\/p>\n<pre><code class=\"java\">        public class MailUtil {             static Pattern DATA_PROTOCOL = Pattern.compile(&quot;^data:(.+);(.+),&quot;);              public static String embedImg(String body, final HtmlEmail email) throws EmailException {                 return StringUtil.resolveReplacement(body, HTML_URL, new Presentable&lt;Matcher&gt;() {                 @Override                 public String toString(Matcher matcher) {                     String url = matcher.group(1);                     String cid;                     try {                     Matcher m = DATA_PROTOCOL.matcher(url);                     if (m.find()) {                         final String cType = m.group(1);                         final String encoding = m.group(2);                         final String content = url.substring(m.toMatchResult().end());                          cid = email.embed(new javax.activation.DataSource() {                             @Override                             public InputStream getInputStream() throws IOException {                                 try {                                     return javax.mail.internet.MimeUtility.decode(new ByteArrayInputStream(IOUtil.getBytes(content)), encoding);                                 } catch (MessagingException e) {                                     throw LOGGER.getIllegalStateException(&quot;Image encoding failed&quot;, e);                                 }                             }                             \/\/ empty realization for other javax.activation.DataSource methods                             ...                         }, UUID.randomUUID().toString());                     } else {                         cid = email.embed(url, UUID.nameUUIDFromBytes(url.getBytes()).toString());                     }                     return &quot;&lt;img src=\\&quot;cid:&quot; + cid + &quot;\\&quot;&quot;;             ...         <\/code><\/pre>\n<p>   <\/p>\n<h5>\u0424\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430: \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c<\/h5>\n<p>    \u041e\u0434\u043d\u0430\u043a\u043e, \u043b\u044e\u0431\u043e\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 get \u0437\u0430\u043f\u0440\u043e\u0441 \u0438\u0437 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430- \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043f\u0438\u0441\u044c\u043c\u043e \u0441 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0441\u0435\u043a\u0440\u0435\u0442\u043d\u044b\u043c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u043c. \u041d\u0435\u0445\u043e\u0440\u043e\u0448\u043e. \u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u0438\u043a\u0440\u0443\u0442\u0438\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043a \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0443 \u0441 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u043c docId \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c: \u0435\u0441\u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u0440\u0438\u0448\u0435\u043b \u043f\u043e \u043f\u043e get, \u0437\u0430\u043b\u043e\u0433\u0438\u043d\u0435\u043d \u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432 \u043d\u0430\u0448\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u0443.<br \/>   \u0418\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441 \u043b\u043e\u0433\u0438\u043d\u043e\u043c \u0443\u0436\u0435 \u0431\u044b\u043b\u0430 \u0441\u0434\u0435\u043b\u0430\u043d\u0430 \u0438 \u0432\u043e\u043a\u0440\u0443\u0433 \u043d\u0435\u0435 \u043c\u043d\u043e\u0433\u043e \u0447\u0442\u043e \u0432\u0435\u0440\u0442\u0435\u043b\u043e\u0441\u044c, \u0430 \u0442\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0443 \u043d\u0430\u0441 \u043e\u0434\u043d\u0430, \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0447\u0435\u0440\u0435\u0437 REST \u0438 \u043a\u0443\u043a\u0438 \u0443\u0440\u043e\u0432\u043d\u044f \u0434\u043e\u043c\u0435\u043d\u0430 \u0441 \u0434\u043e\u0432\u0435\u0440\u0438\u0435\u043c \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c \u043c\u0435\u0436\u0434\u0443 \u0441\u0430\u043c\u0438\u043c\u0438 \u043c\u043e\u0434\u0443\u043b\u044f\u043c\u0438, \u043d\u043e \u044d\u0442\u043e \u0443\u0436\u0435 \u2014 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f.<\/p>\n<h5>\u0418\u0442\u043e\u0433\u0438 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043f\u043e\u0447\u0442\u044b:<\/h5>\n<p>   \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c 2 maven \u043c\u043e\u0434\u0443\u043b\u044f \u0441 \u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438 (\u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u044f \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0442\u0438\u043f\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432, \u043e\u0431\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0438 JUnit \u0442\u0435\u0441\u0442\u043e\u0432)   <\/p>\n<ul>\n<li><b>mail-client<\/b><br \/> \n<ul>\n<li>MailService: \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 (sendMail, sendTemplateMail, sendDocMail)<\/li>\n<li>MailWSClient: \u043e\u0431\u0435\u0440\u0442\u043a\u0430 \u043a \u043a\u043b\u0438\u0435\u043d\u0442\u0443, \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0430\u044f endPoint \u0438\u0437 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438<\/li>\n<li>mailService.wsdl<\/li>\n<\/ul>\n<p>   <\/li>\n<li><b>mail-service<\/b><br \/> \n<ul>\n<li>MailSender: \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430<\/li>\n<li>MailServiceImpl: \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0438\u0441\u0430, \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 MailSender<\/li>\n<li>MailServlet: \u0441\u0435\u0440\u0432\u043b\u0435\u0442 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 HTTP GET<\/li>\n<li>MailBean: \u0431\u0438\u043d \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0441\u0442\u0440\u043e\u043a\u0438 \u0438\u0437 \u0431\u0430\u0437\u044b \u0447\u0435\u0440\u0435\u0437 commons-dbutils<\/li>\n<li>MailConfig: \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f<\/li>\n<li>MailScanner: \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043f\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438<\/li>\n<li>MailWebScanner: \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043b\u0438\u0441\u0442\u0435\u043d\u0435\u0440\u0430 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0449\u0435\u0433\u043e 2 \u0441\u043a\u0430\u043d\u043d\u0435\u0440\u0430 MailScanner<\/li>\n<li>MailUtil: \u0443\u0442\u0438\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b<\/li>\n<li>EmailExceptionHandler: \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 exceptions, \u043d\u0435 \u0434\u043e\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u0442\u0441\u044f AddressException<\/li>\n<li>sun-jaxws.xml, web.xml<\/li>\n<\/ul>\n<p>   <\/li>\n<\/ul>\n<p>   \u0422\u0435\u0440\u043f\u0435\u043b\u0438\u0432\u044b\u0439 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c, \u0434\u043e\u0448\u0435\u0434\u0448\u0438\u0439 \u0434\u043e \u043a\u043e\u043d\u0446\u0430 \u0441\u0442\u0430\u0442\u044c\u0438 \u043c\u043e\u0436\u0435\u0442 \u0441\u0430\u043c \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0442\u0440\u0443\u0434\u043e\u0437\u0430\u0442\u0440\u0430\u0442 \u043d\u0430 \u00ab\u0437\u0430\u0434\u0430\u0447\u0443 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u043f\u043e\u0447\u0442\u044b\u00bb \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e. \u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435.<\/p>\n<hr\/>\n<p>   <\/p>\n<h5>\u0421\u0441\u044b\u043b\u043a\u0438:<\/h5>\n<p>   <\/p>\n<ul>\n<li><a href=\"http:\/\/commons.apache.org\/email\/userguide.html\">Apache Email user guide<\/a><\/li>\n<li><a href=\"http:\/\/commons.apache.org\/dbutils\/examples.html\">Apache dbutils examples<\/a><\/li>\n<li><a href=\"http:\/\/html2canvas.hertzen.com\">\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u0430 \u044d\u043a\u0440\u0430\u043d\u0430<\/a><\/li>\n<li><a href=\"http:\/\/www.riverbpm.com\/\">ERP River<\/a><\/li>\n<\/ul>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/166727\/\"> http:\/\/habrahabr.ru\/post\/166727\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\">\n<table>\n<tr>\n<td>\u041d\u0430 php \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 mail \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u0447\u043a\u043e\u0439 \u043a\u043e\u0434\u0430! \u0410 \u043d\u0430 java- \u043d\u0443\u0436\u043d\u043e 3 \u043d\u0435\u0434\u0435\u043b\u0438??!<br \/>  (\u0438\u0437 \u0440\u0430\u0437\u0433\u043e\u0432\u043e\u0440\u043e\u0432 \u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438 \u0438 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430\u043c\u0438)<\/td>\n<\/tr>\n<\/table>\n<p>  <img decoding=\"async\" src=\"http:\/\/oneims.com\/blog\/wp-content\/uploads\/2008\/06\/direct-mail-success.jpg\"\/><br \/>   \u0421\u0442\u0430\u0442\u044c\u044f \u043d\u0435 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u0447\u0442\u0443 \u043d\u0430 java. \u041c\u043e\u044f \u0446\u0435\u043b\u044c \u2014 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043c\u043e\u0434\u0443\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 (\u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 ERP River).<\/p>\n<h5>\u0418\u0442\u0430\u043a, \u0437\u0430\u0434\u0430\u0447\u0430: \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043f\u043e email (war).<\/h5>\n<p>  <\/p>\n<h4>\u042d\u0442\u0430\u043f\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438:<\/h4>\n<p>  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-166727","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/166727","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=166727"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/166727\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=166727"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=166727"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=166727"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}