Php рдкрд░, рдореЗрд▓ рднреЗрдЬрдиреЗ рдХреЛ рдХреЛрдб рдХреА рдПрдХ рд▓рд╛рдЗрди рдХреЗ рд╕рд╛рде рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ! рдФрд░ рдЬрд╛рд╡рд╛ рдкрд░- рдЖрдкрдХреЛ 3 рд╕рдкреНрддрд╛рд╣ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ ??! (рдбреЗрд╡рд▓рдкрд░реНрд╕ рдФрд░ рдкреНрд░рдмрдВрдзрдХреЛрдВ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рд╕реЗ) |

рд▓реЗрдЦ рдЬрд╛рд╡рд╛ рдореЗрдВ рдореЗрд▓ рднреЗрдЬрдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╣реИред рдореЗрд░рд╛ рд▓рдХреНрд╖реНрдп рдмрдбрд╝реЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдИрдЖрд░рдкреА рдирджреА рдХреЗ рд╡рд┐рдХрд╛рд╕) рдХреЗ рдореЙрдбреНрдпреВрд▓рд░ рд╡рд┐рдХрд╛рд╕ рдХреА рдЬрдЯрд┐рд▓рддрд╛ рдХреЛ рджрд┐рдЦрд╛рдирд╛ рд╣реИред
рддреЛ, рдХрд╛рд░реНрдп: рдИрдореЗрд▓ рднреЗрдЬрдиреЗ рд╕реЗрд╡рд╛ (рдпреБрджреНрдз) рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред
рд╡рд┐рдХрд╛рд╕ рдХреЗ рдЪрд░рдг:
рднреЗрдЬрдиреЗ рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ
рдпрджрд┐ рд╕реНрдкреНрд░рд┐рдВрдЧ рдирд╣реАрдВ рд╣реИ (рдПрдХ рдЫреЛрдЯреЗ рдореЙрдбреНрдпреВрд▓ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ), рддреЛ рд╣рдо рдЕрдкрд╛рдЪреЗ рдХреЙрдордиреНрд╕-рдИрдореЗрд▓ рдХрдиреЗрдХреНрдЯ рдХрд░рддреЗ рд╣реИрдВ
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-email</artifactId> <version>1.3</version> </dependency>
рдФрд░ рд▓рд┐рдЦреЛ
public class MailSender { public static void sendMail { HtmlEmail email = ... ? email.send();
рдХреНрд╖рдорд╛ рдХрд░реЗрдВ, рдореБрдЭреЗ рдореЗрд▓ рд╕рд░реНрд╡рд░ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХрд╣рд╛рдВ рдорд┐рд▓ рд╕рдХрддреА рд╣реИрдВ? рдЙрдиреНрд╣реЗрдВ рд╣рд╛рд░реНрдбрдХреЛрдб, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ, рдпрд╣ рдПрдХ рдЬреВрдирд┐рдпрд░ рдбреЗрд╡рд▓рдкрд░ рдХреЗ рд▓рд┐рдП рднреА рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдЗрд╕рд▓рд┐рдП:
рдореЗрд▓ рд╕рд░реНрд╡рд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди
рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╣реА рдкреВрд░реЗ рд╕рд┐рд╕реНрдЯрдо рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХрд╛ рд╕рд╛рдорд╛рдиреНрдп рдХрд╛рдо рдкреВрд░рд╛ рдХрд░ рд▓рд┐рдпрд╛ рд╣реИ, рдФрд░ рд╣рдо рдЗрд╕реЗ рдХреЗрд╡рд▓ рдореЗрд▓ рдореЙрдбреНрдпреВрд▓ рдХреЗ рд▓рд┐рдП рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
... <part key="email"> <entry key="hostName">smtp.gmail.com</entry> <entry key="user">sendmail@mycompany.ru</entry> <entry key="password">psw</entry> <entry key="smtpPort">465</entry> <entry key="useSSL">true</entry> <entry key="debug">false</entry> <entry key="charset">UTF-8</entry> <entry key="useTLS">false</entry> </part>
public class MailConfig { public static <T extends Email> 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; }
рд╕реЗрд╡рд╛ рдХреЙрд▓
рд╣рд╛рдБ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╕реЗрд╡рд╛ рд╣реИ, рд╣рдо рдЗрд╕реЗ рдХреИрд╕реЗ рдХреЙрд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ?
рд╡реНрдпрд╡рд╕рд╛рдп рд╡реЗрдм рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдПрдХреАрдХрд░рдг рдЪрд╛рд╣рддрд╛ рд╣реИ, рдФрд░ рдЖрдкрдХреЛ рдЕрднреА рднреА рд╕рд░рд▓ HTTP рдЬреАрдИрдЯреА (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╕реЗ рд╕реАрдзреЗ рдХреЙрд▓) рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рднреЗрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
- HTTP GET рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рднреЗрдЬрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ:
public class MailServlet extends CommonServlet { @Override protected void doProcess(HttpServletRequest request, HttpServletResponse response, Map<String, String> params) throws IOException, ServletException { String from = ConfigUtil.getProperty("from", params); ... MailSender.sendMail(from, to, cc, ..);
- рдПрдХ рд▓рд╣рд░ рд╕реЗрд╡рд╛ (JAX-WS) рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИ:
@WebService @SOAPBinding(style = Style.RPC) public interface MailService { @WebMethod public void sendMail( @WebParam(name = "from") String from, @WebParam(name = "to") String to, @WebService(endpointInterface = "mycompany.MailService") 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, ..); }
рдФрд░ mailService.wsdl:
<definitions .. targetNamespace="http://mail.mycompany.com/" name="MailServiceImplService"> <message name="sendMail"> <part name="from" type="xsd:string"/> ... <portType name="MailService"> <operation name="sendMail" parameterOrder="from to cc subject body attachmentUrls"> <input wsam:Action="http://mail.mycompany.com/MailService/sendMailRequest" message="tns:sendMail"/> ... <binding name="MailServiceImplPortBinding" type="tns:MailService"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/> <operation name="sendMail"> <soap:operation soapAction=""/> ... <service name="MailServiceImplService"> <port name="MailServiceImplPort" binding="tns:MailServiceImplPortBinding"> <soap:address location="http://mycompany:8080/mail/mailService"/> ...
Web.xml (рдЯреЙрдордХреИрдЯ) рдордд рднреВрд▓рдирд╛
<listener> <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class> </listener> <servlet> <servlet-name>mailService</servlet-name> <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mailService</servlet-name> <url-pattern>/mailService</url-pattern> </servlet-mapping> <servlet> <servlet-name>mailServlet</servlet-name> <servlet-class>com.mycompany.mail.MailServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> ...
рдореЗрд▓-рдХреНрд▓рд╛рдЗрдВрдЯ рдХрд╛ рдЖрд╡рдВрдЯрди
рдФрд░ рдЕрдм рд╣рдорд╛рд░реЗ рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдкрдбрд╝реЛрд╕реА рдореЙрдбреНрдпреВрд▓ рд╡реЗрдм рд╕реЗрд╡рд╛ рдкрд░ рд╣рдорд╛рд░реА рд╕реЗрд╡рд╛ рдХреЛ рдЬрд▓реНрджреА рдХреИрд╕реЗ рдЦреАрдВрдЪ рд╕рдХрддрд╛ рд╣реИ? рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рдорд╛рд╡реЗрди рдореЗрд▓-рдХреНрд▓рд╛рдЗрдВрдЯ рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдЪрдпрди рдХрд░рдирд╛ рд╣реИ, рд╣рдорд╛рд░реА рдореЗрд▓ рд╕реЗрд╡рд╛ рдХреЛ рдЗрд╕ рдкрд░ рдирд┐рд░реНрднрд░ рдмрдирд╛рдирд╛ рд╣реИ, рдФрд░ рдХрд┐рд╕реА рднреА рдореЙрдбреНрдпреВрд▓ рдХреЛ рдЕрдиреБрдорддрд┐ рджреЗрдирд╛ рд╣реИ - рд╣рдорд╛рд░реЗ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ (рдорд╛рд╡реЗрди рдирд┐рд░реНрднрд░рддрд╛) рдореЗрд▓-рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░рдирд╛ рд╣реИ:
- рд╣рдо рдПрдХ рдЕрд▓рдЧ рдорд╛рд╡реЗрди рдореЗрд▓-рдХреНрд▓рд╛рдЗрдВрдЯ рдореЙрдбреНрдпреВрд▓ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдореЗрдВ рдореЗрд▓рд╕реНрд╡рд╛рдЗрдЯреНрд╕рдбреАрдбреАрдПрд▓ рдФрд░ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрд▓рд╕реЗрд╡рд╛рдЗрди рдбрд╛рд▓рддреЗ рд╣реИрдВ
<groupId>com.mycompany</groupId> <artifactId>mail-client</artifactId> <name>Mail Client</name>
- рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдорд╛рд░реЗ рдЖрдВрддрд░рд┐рдХ рдЧреНрд░рд╛рд╣рдХ рдХреЗ рдкреВрд░реНрдг рдЖрдирдВрдж рдХреЗ рд▓рд┐рдП, рд╣рдо MailWSClient рдмрдирд╛рддреЗ рд╣реИрдВ:
рдкрдбрд╝реЛрд╕реА рдореЙрдбреНрдпреВрд▓ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реЛрдЧрд╛:
MailWSClient.sendMail(...
public class MailWSClient { static String mailWsdl; private static final Service SERVICE; static { URL url = MailWSClient.class.getClassLoader().getResource("mailService.wsdl"); SERVICE = Service.create(url, new QName("http://mail.mycompany.com/", "MailServiceImplService"));
рд╣рдо рдкреИрдЯрд░реНрди рдХреЛ рддреЗрдЬ рдХрд░рддреЗ рд╣реИрдВ
Egeред рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдкреНрд░рдмрдВрдзрди рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ 52 рдкреНрд░рдХрд╛рд░ рдХреЗ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рд╣реИрдВред рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рд╣рдорд╛рд░реЗ рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЛ рдкрддреНрд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕реНрд╡рдпрдВ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рджрд┐рдпрд╛ рдЬрд╛рдПред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдРрд╕реА рд╕реЗрд╡рд╛ (рдЯреЗрдореНрдкреНрд▓реЗрдЯ рд╕рд░реНрд╡рд┐рд╕) рдкрд╣рд▓реЗ рд╣реА рд▓рд╛рдЧреВ рдХреА рдЬрд╛ рдЪреБрдХреА рд╣реИред
рдЯреЗрдореНрдкреНрд▓реЗрдЯ рд╕реЗрд╡рд╛ рд╕рд░рд▓ рд╣реИ: рдЬреЗрдПрд╕рдкреА рдкрд░ рд▓рд╛рдЧреВ рдХреА рдЬрд╛рддреА рд╣реИ, рдХреБрдВрдЬреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдХреЗ рдФрд░ рдкреИрд░рд╛рдореАрдЯрд░ рдЗрд╕реЗ рднреЗрдЬреЗ рдЬрд╛рддреЗ рд╣реИрдВ, рд╕рдорд╛рдкреНрдд рдкрд╛рда рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рддрд╛ рд╣реИред
- MailService, MailWSClient, MailServiceImpl, MailSender, mailService.wsdl рдФрд░ MailServlet рдкрд░ SendTemplateMail рдЬреЛрдбрд╝реЗрдВ:
sendTemplateMail(.., templateKey, params);
- рдФрд░ рд╣рдо рдЗрд╕реЗ MailSender рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ (рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдЖрд╡рд░рдг MyHttpConnection рд╣реИ рдЬрд┐рд╕реЗ HttpURLConnection.openConnection () рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ)
static void sendTemplateMail(..., String key, String params) { LOGGER.info("Send template mail from ... String templateUrl = getUrlAsString("template?type=mail&format=html&key=" + 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); ...
рд░рд╛рд╕реНрддреЗ рдХреЗ рд╕рд╛рде, рдореБрдЭреЗ рд╡рд┐рд╖рдп рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдирд╛ рдерд╛: рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕реЗрд╡рд╛ рдХреЗрд╡рд▓ рд╕рдВрджреЗрд╢ рдирд┐рдХрд╛рдп рджреЗрддрд╛ рд╣реИред рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛ HTML рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рд▓реМрдЯрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, MailUtil рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕реЗ рдЯрд┐рд▓реНрдЯ рдирд┐рдХрд╛рд▓рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рд╡рд┐рд╖рдп рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ:
public class MailUtil { static Pattern MAIL_TITLE = Pattern.compile("<title>(.+)</title>", Pattern.MULTILINE); static String getSubject(String template) { Matcher m = MAIL_TITLE.matcher(template); return m.find() ? m.group(1) : null; }
рджрд╕реНрддрд╛рд╡реЗрдЬ рднреЗрдЬрдирд╛
рджрд░рдЕрд╕рд▓, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рджрд╕реНрддрд╛рд╡реЗрдЬ рд╣реИрдВред рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рд╣рдо рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЛ рдЖрдИрдбреА рдХреЗ рд╕рд╛рде рд╕реЗрд╡рд╛ рдХрд╣рддреЗ рд╣реИрдВ? рдЯреЗрдореНрдкреНрд▓реЗрдЯ рд╕рд░реНрд╡рд┐рд╕ рдореЗрдВ рджрд╕реНрддрд╛рд╡реЗрдЬреЛрдВ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдореМрдЬреВрдж рд╣реИрдВред
- SendDocMail рдХреЛ MailService, MailWSClient, MailServiceImpl, MailSender, mailService.wsdl рдФрд░ MailServlet рдореЗрдВ рдЬреЛрдбрд╝реЗрдВред
sendDocMail(String from, String to, String cc, String key, long docId);
- рдЕрдЬреА, рдФрд░ рджрд╕реНрддрд╛рд╡реЗрдЬреЛрдВ рдореЗрдВ рд╕рдВрд▓рдЧреНрдирдХ рд╣реИрдВ рдЬреЛ рдкрддреНрд░ рд╕реЗ рдЬреБрдбрд╝реЗ рд╣реЛрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдХреЙрдордиреНрд╕-рдИрдореЗрд▓ рдпрд╣ рдЖрд╕рд╛рди рдмрдирд╛рддрд╛ рд╣реИ, рдФрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдорд╛рд╡реЗрди рдЕрдЯреИрдЪ-рдХреЙрдорди рдореЙрдбреНрдпреВрд▓ рд╣реИ, рдЬрд┐рд╕реЗ рдЖрдк docId рдХреЗ рд▓рд┐рдП рдЕрдиреБрд▓рдЧреНрдирдХреЛрдВ рдХреА рд╕реВрдЪреА рдХреЗ рд▓рд┐рдП рдкреВрдЫ рд╕рдХрддреЗ рд╣реИрдВ:
public class MailSender { static void sendDocMail(String from, String to, String cc, String key, long docId) throws StateException { List<Attach> list = AttachUtil.getList(docId); MailSender.sendTemplateMailAndRecordHistory(from, to, cc, key, "objectid=" + docId, MailUtil.formatAttach(list)); } public class MailUtil {
рджреЛрд╖ рд╕рд╣рд┐рд╖реНрдгреБрддрд╛
рдФрд░ рдЕрдЧрд░ рд╕рд░реНрд╡рд░ рдЕрд╕реНрдерд╛рдпреА рд░реВрдк рд╕реЗ рдЕрдиреБрдкрд▓рдмреНрдз рд╣реИ? рдЖрдкрдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЗрддрд┐рд╣рд╛рд╕ рдХреЛ рд╕рд╣реЗрдЬрдиреЗ рдФрд░ рдПрдХ рдкреБрд╢ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ ... рдЙрд╕реА рд╕рдордп, рд╣рдо рдмреАрдкреАрдПрдо рд╕реЗ рдЙрд╕реЗ рдХрд╛рд░реНрдп рд╕реМрдВрдкрдХрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдПрдХ рдкрддреНрд░ рднреЗрдЬрдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░реЗрдВрдЧреЗ - рдЗрд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЯреНрд░рд┐рдЧрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ: рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ TODO рд░реЗрдЦрд╛ рдбрд╛рд▓реЗрдВред рдПрдХ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯ рдХреЗ рд░реВрдк рдореЗрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрдкрдиреЗ рд╕рдВрджреЗрд╢ рднреЗрдЬрдиреЗ рдХрд╛ рдЗрддрд┐рд╣рд╛рд╕ рд╣реИ, рддреЛ рдЖрдк рдКрдкрд░ рд╕реЗ ui рдХреЛ рд╣рд╡рд╛ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдореЗрдЬ рдкрд░ SQL рдкреНрд░рд╢реНрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рд╕реНрдХреИрдирд┐рдВрдЧ рддрдВрддреНрд░ рд╣реИ - рд╣рдореЗрдВ рдмрд╕ рдПрдХ рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
- рд╣рдо рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ mail_action рддрд╛рд▓рд┐рдХрд╛ рдмрдирд╛рддреЗ рд╣реИрдВ
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 );
- рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рд╕реНрдХреИрди рдЕрдВрддрд░рд╛рд▓ рдЬреЛрдбрд╝реЗрдВ
<entry key="scanTodoInterval">30</entry> <entry key="scanFailInterval">600</entry>
scanTodoInterval = ConfigUtil.getInt(SCAN_TODO_INTERVAL, mailProps, 60);
рд╣рдо MailSender рдХреЛ рд░рд╛рдЬреНрдп (рдУрдХреЗ рдпрд╛ рдЕрдкрд╡рд╛рдж) рдХреЗ рд╕рд╛рде рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рднреЗрдЬрдиреЗ рдХреЗ рдЗрддрд┐рд╣рд╛рд╕ рдХреЛ рд░рд┐рдХреЙрд░реНрдб рдХрд░рдиреЗ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред
рд╣рдо mail_action рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рд╕реНрдХреИрди рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд░рд╛рдЬреНрдп рдХреА рд╕реНрдерд┐рддрд┐ (TODO, EmailException) рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдПрдХ рдИрдореЗрд▓ рднреЗрдЬрддреЗ рд╣реИрдВ
<listener> <listener-class>com.mycompany.common.web.SchedulerListener</listener-class> </listener>
public class MailWebScanner implements WebScheduler { private final MailScanner todoScanner = new MailScanner("TODO"); private final MailScanner failScanner = new MailScanner("org.apache.commons.mail.EmailException"); @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<MailBean> HANDLER = new BeanListHandler<MailBean>(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<MailBean> getMailToSend() { return SqlUtil.executeQuery("select * from hist.mail_action where state like '" + startWith + "%'", HANDLER); ...
рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рдЗрдВрддрдЬрд╛рд░ рдХрд░рдирд╛ рдкрд╕рдВрдж рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ: рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ
рдЪреВрдВрдХрд┐ рд╣рдорд╛рд░реА рд╕реЗрд╡рд╛ рдЕрдм рд╡рд┐рдлрд▓рддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рд░реЛрдзреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдорд╛рд░реА рд╡реЗрдм рд╕реЗрд╡рд╛ рдХреЗ рд╣рдорд╛рд░реЗ рдЧреНрд░рд╛рд╣рдХ рдЙрддреНрддрд░ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рди рдХрд░реЗрдВред Async рдкреЛрд╕реНрдЯрдлрд╝рд┐рдХреНрд╕ рдФрд░ @OneWay рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рд╕рд╛рде рд╕рднреА рд╕реЗрд╡рд╛ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рд╣рдо MailyncClient рдХреЙрд▓ рдореЗрдВ Async рдлрд╝реНрд▓реИрдЧ рдФрд░ AsyncExecutor (рд╢реЗрдбреНрдпреВрд▓ рдХрд┐рдП рдЧрдП рд╣рдорд╛рд░реЗ рд╢реЗрдбреНрдпреВрд▓рд░ TopTreadPoolExecutor) рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ:
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(); } }
рдЫрд╡рд┐ рд╕рдВрд▓рдЧреНрдирдХ рдареАрдХ рдХрд░реЗрдВ
рдЦреИрд░, рд╕рдм рдХреБрдЫ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ! рдЕрдВрдд рдореЗрдВ, рдЖрдк рдмрдЧреНрд╕ рдХреЛ рдареАрдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рдкрддреНрд░ рдореЗрдВ рдЪрд┐рддреНрд░ рд╣рдорд╛рд░реЗ рдЗрдВрдЯреНрд░рд╛рдиреЗрдЯ рдХреЗ рдмрд╛рд╣рд░ рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗ рд░рд╣реЗ рд╣реИрдВ ... рдЖрдЦрд┐рд░рдХрд╛рд░, рд╡реЗ <img src = "рд╣рдорд╛рд░реЗ рдЖрдВрддрд░рд┐рдХ рд╕рдВрд╕рд╛рдзрдиреЛрдВ" рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдореЗрдВ рд╕реЗрдЯ рд╣реИрдВ, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЖрдк рдЙрдиреНрд╣реЗрдВ рдмрд╛рдХреА рджреБрдирд┐рдпрд╛ рдореЗрдВ рдирд╣реАрдВ рджреЗрдЦреЗрдВрдЧреЗред
рд╣рдо рдЙрдиреНрд╣реЗрдВ рдирд┐рд░реНрдорд┐рдд рдХрд░рддреЗ рд╣реИрдВ:
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("<img src=(?:\"|')(.+)(?:\"|')", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); public static String embedImg(String body, final HtmlEmail email) throws EmailException { return StringUtil.resolveReplacement(body, HTML_URL, new Presentable<Matcher>() { @Override public String toString(Matcher matcher) { String url = matcher.group(1); cid = email.embed(url, UUID.nameUUIDFromBytes(url.getBytes()).toString()); } return "<img src=\"cid:" + cid + "\""; ...
рд╣рдо рдмрд┐рд▓реНрдЯ-рдЗрди (рдбреЗрдЯрд╛: рдЗрдореЗрдЬ / рдкреАрдПрдирдЬреА; рдмреЗрд╕ 64, рдПрдирдХреЛрдбреЗрдб_рдордЧ) рдмрдбрд╝реА рддрд╕реНрд╡реАрд░реЗрдВ рднреЗрдЬрддреЗ рд╣реИрдВ
рдПрдХ рдирдпрд╛ рд╡реНрдпрд╛рдкрд╛рд░ рд╡рд┐рдЪрд╛рд░ рдЧрд▓рддреА рд╕реЗ рдЧреНрд░рд╛рд╣рдХ рдХреЗ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╕реЗ рдореЗрд▓ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рднреЗрдЬрдирд╛ рд╣реИред
рдпреВрдЖрдИ рдкрд░ рд╕рдорд╛рдзрд╛рди рдкрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рдЪрд╛рд▓ рд╣рдорд╛рд░реА рд╣реИред рдЯреЗрдореНрдкреНрд▓реЗрдЯ рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП, error_mail.jsp рдЯреЗрдореНрдкреНрд▓реЗрдЯ рд▓рд┐рдЦреЗрдВ
<%@page pageEncoding="UTF-8" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Error Report</title> </head> <body> <h2>Error Report from '${user}'</h2> <b>Message:</b> <pre> ${message} </pre> <b>Screenshot:</b><br> <img src="${screenshot}"> </body> </html>
рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреИрд░рд╛рдореАрдЯрд░ - рдЕрдкрд╡рд╛рдж рд╕рдВрджреЗрд╢ рдФрд░ base64_encoded_screenshot - рд╣рдорд╛рд░реА рд╕реЗрд╡рд╛ рд╕реЗ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рд╕реЗрд╡рд╛ рдореЗрдВ рднреЗрдЬреЗ рдЬрд╛рддреЗ рд╣реИрдВред рд╣рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдПрдБ рд╣реИрдВ: рд╣рдорд╛рд░реЗ рд╕реНрд╡-рд▓рд┐рдЦрд┐рдд рдЖрд╡рд░рдг MyHttpConnection, GET рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ base64_encoded_screenshot рдирд╣реАрдВ рднреЗрдЬ рд╕рдХрддрд╛ рд╣реИред рдЖрдкрдХреЛ POST рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдФрд░ URLEncoder.encode рдХреЛ рдлрд┐рд░ рд╕реЗ "+" рдХреА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рдХрд╛рд░рдг рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЗрдирд▓рд╛рдЗрди рдореЗрд▓ рдореЗрдВ рддрд╕реНрд╡реАрд░ рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗ рд░рд╣реА рд╣реИ :( рдареАрдХ рд╣реИ, рдЖрдкрдХреЛ рдЗрд╕реЗ рднреА рд╕рдВрд▓рдЧреНрди рдХрд░рдирд╛ рд╣реЛрдЧрд╛:
public class MailUtil { static Pattern DATA_PROTOCOL = Pattern.compile("^data:(.+);(.+),"); public static String embedImg(String body, final HtmlEmail email) throws EmailException { return StringUtil.resolveReplacement(body, HTML_URL, new Presentable<Matcher>() { @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("Image encoding failed", e); } }
рдЕрдВрддрд┐рдо рдмрд┐рдВрджреБ: рд╕реБрд░рдХреНрд╖рд╛
рд╣рд╛рд▓рд╛рдВрдХрд┐, рдХреЛрдИ рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╕реЗ рдПрдХ рдЕрдиреБрд░реЛрдз рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдПрдХ рд╢реАрд░реНрд╖ рдЧреБрдкреНрдд рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЗ рд╕рд╛рде рдПрдХ рдИрдореЗрд▓ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реИред рдкрд╛рд╕ рдХрд┐рдП рдЧрдП docId рдХреЗ рд╕рд╛рде рдбреЙрдХреНрдпреВрдореЗрдВрдЯ рдХреЗ рд▓рд┐рдП рдпреВрдЬрд░ рдПрдХреНрд╕реЗрд╕ рдЪреЗрдХ рдХреЛ рдлрд╛рд╕реНрдЯ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдФрд░ рдЖрдо рддреМрд░ рдкрд░ рдЪреЗрдХ рдХрд░реЗрдВ: рдпрджрд┐ рд░рд┐рдХреНрд╡реЗрд╕реНрдЯ рдЧреЗрдЯ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЖрдпрд╛ рд╣реИ, рддреЛ рдХреНрдпрд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╣рдорд╛рд░реЗ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рд▓реЙрдЧ рдЗрди рд╣реИред
рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рдХрд┐ рд▓реЙрдЧрд┐рди рд╡рд╛рд▓рд╛ рдкреГрд╖реНрда рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдмрд╣реБрдд рд╕рд╛рд░реА рдЧрддрд┐рд╡рд┐рдзрд┐ рдереА, рдФрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рд╣реИ, рдореИрдВрдиреЗ рд╕реНрд╡рдпрдВ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдмреАрдЪ рд╕рд░реНрд╡рд░ рдЕрдиреБрд░реЛрдзреЛрдВ рдореЗрдВ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдХреЗ рд╕рд╛рде REST рдФрд░ рдбреЛрдореЗрди-рд╕реНрддрд░реАрдп рдХреБрдХреАрдЬрд╝ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рдЬрд╛рдВрдЪ рдХреА, рд▓реЗрдХрд┐рди рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╣реИ - рдЕрд▓рдЧ рд▓реЗрдЦред
рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдореЗрд▓ рднреЗрдЬрдиреЗ рд╡рд╛рд▓реЗ рдХрд╛рд░реНрдп рдХрд╛ рд╕рд╛рд░рд╛рдВрд╢:
рдкрд░рд┐рдгрд╛рдо рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд╕рд╛рде 2 рдорд╛рд╡реЗрди рдореЙрдбреНрдпреВрд▓ рдереЗ (рдмреБрдирд┐рдпрд╛рджреА рдврд╛рдВрдЪреЗ рдХреА рдЧрд┐рдирддреА рдирд╣реАрдВ рдХрд░рдирд╛ рдЬреИрд╕реЗ рдХрд┐ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди, рдЕрдЯреИрдЪрдореЗрдВрдЯ, рдЯреЗрдореНрдкреНрд▓реЗрдЯ, рд╕рд╛рдорд╛рдиреНрдп рднрд╛рдЧ рдФрд░ JUititments)
- рдореЗрд▓-рдЧреНрд░рд╛рд╣рдХ
- MailService: рдЗрдВрдЯрд░рдлрд╝реЗрд╕ (sendMail, sendTemplateMail, sendDocMail)
- MailWSClient: рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕реЗ рдПрдВрдбрдкреЙрдЗрдВрдЯ рдХреЛ рдЙрдЬрд╛рдЧрд░ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрд╡рд░рдг
- mailService.wsdl
- рдореЗрд▓-рд╕реЗрд╡рд╛
- MailSender: рдЦреБрдж рднреЗрдЬ рд░рд╣рд╛ рд╣реИ
- MailServiceImpl: рд╡реЗрдм рд╕реЗрд╡рд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди, MailSender рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдирд┐рдзрд┐рдордВрдбрд▓
- MailServlet: HTTP GET рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд░реНрд╡рд▓реЗрдЯ
- MailBean: рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрдо рдХреЙрдордиреНрд╕-рдбрдмрд▓реНрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ
- MailConfig: рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди
- MailScanner: рд╕реНрдЯреЗрдЯрд╕ рднреЗрдЬрдХрд░ рдЯреЗрдмрд▓ рдХреЛ рд╕реНрдХреИрди рдХрд░реЗрдВ
- MailWebScanner: рд╣рдорд╛рд░реА рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рд╢реНрд░реЛрддрд╛ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЬреЛ 2 MailScanner рд╕реНрдХреИрдирд░ рд▓реЙрдиреНрдЪ рдХрд░рддрд╛ рд╣реИ
- MailUtil: рдпреВрдЯрд┐рд▓рд┐рдЯреА рдореЗрдердбреНрд╕
- EmailExceptionHandler: рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдирд╛, AddressException рджреНрд╡рд╛рд░рд╛ рд╕рдВрдмреЛрдзрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛
- sun-jaxws.xml, web.xml
рдПрдХ рд░реЛрдЧреА рдкрд╛рдардХ, рдЬреЛ рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рддрдХ рдкрд╣реБрдБрдЪ рдЧрдпрд╛ рд╣реИ, рд╡рд╣ рдЦреБрдж "рдореЗрд▓ рднреЗрдЬрдиреЗ рд╡рд╛рд▓реЗ рдХрд╛рд░реНрдп" рдХреЗ рд▓рд┐рдП рд╢реНрд░рдо рд▓рд╛рдЧрддреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдФрд░ рдкрд░рд┐рдгрд╛рдореА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рддреБрд▓рдирд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред
рд╕рдВрджрд░реНрдн: