ofbiz email发送设备及相干代码导读

    添加时间:2013-6-26 点击量:

    ofibz登岸功能有经由过程电子邮件找会暗码的功能,但找回暗码功能须要设备一个发送email的邮箱账号和smtp办事器的设备,具体设备如下:


    1:在ofbiz数据库的表product_store_email_settings中找到_address字段,将该字段中值全部批改成设备的默认发送账号




    2:在general.properties中设备smtp参数


    # -- The default domainname used in the notification emails links
    # as baseUrl and baseSecureUrl are set in the url.properties file.


    # -- mail notifications enabled (Y|N)
    mail.notifications.enabled=Y


    # -- redirect all mail notifications to this address for testing
    #mail.notifications.redirectTo=


    # -- the default mail server to use
    mail.smtp.relay.host=smtp.126.com


    # -- SMTP Auth settings
    mail.smtp.auth.user=XXXXXXXX----------------------(邮箱名称)
    mail.smtp.auth.password=XXXXXXXXXXXXXXX------(邮箱暗码)


    # -- Additional Required Fields needed for Gmail and other non traditional smtp servers
    # -- These added fields also work for Yahoo business mail for instance
    # -- Gmail smtp port can be either 465 or 587
    mail.smtp.port=25
    # -- Gmail requires StartTLS
    mail.smtp.starttls.enable=true


    # -- Gmail requires a JSSE socket factory, the following socketFactory settings will override JavaMails default socketFactory settings
    # -- Port needs to be the same as mail.smtp.port
    mail.smtp.socketFactory.port=25
    #mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
    #--Fallback [true|false] determines whether you will allow a non secure connection if you are unable to get a secure one
    #mail.smtp.socketFactory.fallback=false


    3:设备完成后须要重启ofbiz,设备才干生效,再次登录找回暗码就能收到一封邮件



    4:找回暗码的相干代码导读


    在controller.xml文件中可以找到找回暗码对应的实现:



        <request-map uri=forgotpassword>
    
    <security https=true auth=false/>
    <event type=java path=org.ofbiz.securityext.login.LoginEvents invoke=forgotPassword/>
    <response name=success type=view value=login/>
    <response name=error type=view value=login/>
    </request-map>


    可以看到具体实如今org.ofbiz.securityext.login.LoginEvents类中的forgotPassword办法实现



    打开在LoginEvents中看到具体调用到一下代码



    public static String emailPassword(HttpServletRequest request, HttpServletResponse response) {
    
    String defaultScreenLocation
    = component://securityext/widget/EmailSecurityScreens.xml#PasswordEmail;

    Delegator delegator
    = (Delegator) request.getAttribute(delegator);
    LocalDispatcher dispatcher
    = (LocalDispatcher) request.getAttribute(dispatcher);
    String productStoreId
    = ProductStoreWorker.getProductStoreId(request);

    String errMsg
    = null;

    Map
    <String, String> subjectData = FastMap.newInstance();
    subjectData.put(
    productStoreId, productStoreId);

    boolean useEncryption = true.equals(UtilProperties.getPropertyValue(security.properties, password.encrypt));

    String userLoginId
    = request.getParameter(USERNAME);
    subjectData.put(
    userLoginId, userLoginId);

    if ((userLoginId != null) && (true.equals(UtilProperties.getPropertyValue(security.properties, username.lowercase)))) {
    userLoginId
    = userLoginId.toLowerCase();
    }

    if (!UtilValidate.isNotEmpty(userLoginId)) {
    // the password was incomplete
    errMsg = UtilProperties.getMessage(resource, loginevents.username_was_empty_reenter, UtilHttp.getLocale(request));
    request.setAttribute(
    _ERROR_MESSAGE_, errMsg);
    return error;
    }

    GenericValue supposedUserLogin
    = null;
    String passwordToSend
    = null;

    try {
    supposedUserLogin
    = delegator.findOne(UserLogin, false, userLoginId, userLoginId);if (supposedUserLogin == null) {
    // the Username was not found
    errMsg = UtilProperties.getMessage(resource, loginevents.username_not_found_reenter, UtilHttp.getLocale(request));
    request.setAttribute(
    _ERROR_MESSAGE_, errMsg);
    return error;
    }
    if (useEncryption) {
    // password encrypted, cant send, generate new password and email to user
    passwordToSend = RandomStringUtils.randomAlphanumeric(Integer.parseInt(UtilProperties.getPropertyValue(security, password.length.min, 5)));
    supposedUserLogin.set(
    currentPassword, HashCrypt.getDigestHash(passwordToSend, LoginServices.getHashType()));
    supposedUserLogin.set(
    passwordHint, Auto-Generated Password);
    if (true.equals(UtilProperties.getPropertyValue(security.properties, password.email_password.require_password_change))){
    supposedUserLogin.set(
    requirePasswordChange, Y);
    }
    }
    else {
    passwordToSend
    = supposedUserLogin.getString(currentPassword);
    }
    }
    catch (GenericEntityException e) {
    Debug.logWarning(e,
    , module);
    Map
    <String, String> messageMap = UtilMisc.toMap(errorMessage, e.toString());
    errMsg
    = UtilProperties.getMessage(resource, loginevents.error_accessing_password, messageMap, UtilHttp.getLocale(request));
    request.setAttribute(
    _ERROR_MESSAGE_, errMsg);
    return error;
    }
    if (supposedUserLogin == null) {
    // the Username was not found
    Map<String, String> messageMap = UtilMisc.toMap(userLoginId, userLoginId);
    errMsg
    = UtilProperties.getMessage(resource, loginevents.user_with_the_username_not_found, messageMap, UtilHttp.getLocale(request));
    request.setAttribute(
    _ERROR_MESSAGE_, errMsg);
    return error;
    }

    StringBuilder emails
    = new StringBuilder();
    GenericValue party
    = null;

    try {
    party
    = supposedUserLogin.getRelatedOne();
    }
    catch (GenericEntityException e) {
    Debug.logWarning(e,
    , module);
    party
    = null;
    }
    if (party != null) {
    Iterator
    <GenericValue> emailIter = UtilMisc.toIterator(ContactHelper.getContactMechByPurpose(party, PRIMARY_EMAIL, false));
    while (emailIter != null && emailIter.hasNext()) {
    GenericValue email
    = emailIter.next();
    emails.append(emails.length()
    > 0 ? , : ).append(email.getString(infoString));
    }
    }

    if (!UtilValidate.isNotEmpty(emails.toString())) {
    // the Username was not found
    errMsg = UtilProperties.getMessage(resource, loginevents.no_primary_email_address_set_contact_customer_service, UtilHttp.getLocale(request));
    request.setAttribute(
    _ERROR_MESSAGE_, errMsg);
    return error;
    }
    //前面主如果从request中获取一些设备参数
    // get the ProductStore email settings
    GenericValue productStoreEmail = null;
    try {
    productStoreEmail
    = delegator.findOne(ProductStoreEmailSetting, false, productStoreId, productStoreId, emailType, PRDS_PWD_RETRIEVE);//从Productstoreemaisetting中获取发送email的账号
    }
    catch (GenericEntityException e) {
    Debug.logError(e,
    Problem getting ProductStoreEmailSetting, module);
    }

    if (productStoreEmail == null) {
    errMsg
    = UtilProperties.getMessage(resource, loginevents.problems_with_configuration_contact_customer_service, UtilHttp.getLocale(request));
    request.setAttribute(
    _ERROR_MESSAGE_, errMsg);
    return error;
    }

    String bodyScreenLocation
    = productStoreEmail.getString(bodyScreenLocation);
    if (UtilValidate.isEmpty(bodyScreenLocation)) {
    bodyScreenLocation
    = defaultScreenLocation;
    }

    // set the needed variables in new context
    Map<String, Object> bodyParameters = FastMap.newInstance();
    bodyParameters.put(
    useEncryption, Boolean.valueOf(useEncryption));
    bodyParameters.put(
    password, UtilFormatOut.checkNull(passwordToSend));
    bodyParameters.put(
    locale, UtilHttp.getLocale(request));
    bodyParameters.put(
    userLogin, supposedUserLogin);
    bodyParameters.put(
    productStoreId, productStoreId);

    Map
    <String, Object> serviceContext = FastMap.newInstance();
    serviceContext.put(
    bodyScreenUri, bodyScreenLocation);
    serviceContext.put(
    bodyParameters, bodyParameters);
    serviceContext.put(
    subject, productStoreEmail.getString(subject));
    serviceContext.put(
    sendFrom, productStoreEmail.get(Address));
    serviceContext.put(
    sendCc, productStoreEmail.get(ccAddress));
    serviceContext.put(
    sendBcc, productStoreEmail.get(bccAddress));
    serviceContext.put(
    contentType, productStoreEmail.get(contentType));
    serviceContext.put(
    sendTo, emails.toString());
    serviceContext.put(
    partyId, party.getString(partyId));

    try {
    Map
    <String, Object> result = dispatcher.runSync(sendMailFromScreen, serviceContext);

    if (ModelService.RESPOND_ERROR.equals(result.get(ModelService.RESPE_MESSAGE))) {
    Map
    <String, Object> messageMap = UtilMisc.toMap(errorMessage, result.get(ModelService.ERROR_MESSAGE));
    errMsg
    = UtilProperties.getMessage(resource, loginevents.error_unable_email_password_contact_customer_service_errorwas, messageMap, UtilHttp.getLocale(request));
    request.setAttribute(
    _ERROR_MESSAGE_, errMsg);
    return error;
    }
    }
    catch (GenericServiceException e) {
    Debug.logWarning(e,
    , module);
    errMsg
    = UtilProperties.getMessage(resource, loginevents.error_unable_email_password_contact_customer_service, UtilHttp.getLocale(request));
    request.setAttribute(
    _ERROR_MESSAGE_, errMsg);
    return error;
    }

    // dont save password until after it has been sent
    if (useEncryption) {
    try {
    supposedUserLogin.store();
    }
    catch (GenericEntityException e) {
    Debug.logWarning(e,
    , module);
    Map
    <String, String> messageMap = UtilMisc.toMap(errorMessage, e.toString());
    errMsg
    = UtilProperties.getMessage(resource, loginevents.error_saving_new_password_email_not_correct_password, messageMap, UtilHttp.getLocale(request));
    request.setAttribute(
    _ERROR_MESSAGE_, errMsg);
    return error;
    }
    }

    if (useEncryption) {
    errMsg
    = UtilProperties.getMessage(resource, loginevents.new_password_createdandsent_check_email, UtilHttp.getLocale(request));
    request.setAttribute(
    _EVENT_MESSAGE_, errMsg);
    }
    else {
    errMsg
    = UtilProperties.getMessage(resource, loginevents.new_password_sent_check_email, UtilHttp.getLocale(request));
    request.setAttribute(
    _EVENT_MESSAGE_, errMsg);
    }
    return success;
    }


    email的发送过程在framework\common\src\org\ofbiz\common\email\EmailServices.java中实现



    public static Map<String, Object> sendMail(DispatchContext ctx, Map<String, ? extends Object> context) {
    
    String communicationEventId
    = (String) context.get(communicationEventId);
    String orderId
    = (String) context.get(orderId);
    Locale locale
    = (Locale) context.get(locale);
    if (communicationEventId != null) {
    Debug.logInfo(
    SendMail Running, for communicationEventId : + communicationEventId, module);
    }
    Map
    <String, Object> results = ServiceUtil.returnSuccess();
    String subject
    = (String) context.get(subject);
    subject
    = FlexibleStringExpander.expandString(subject, context);

    String partyId
    = (String) context.get(partyId);
    String body
    = (String) context.get(body);
    List
    <Map<String, Object>> bodyParts = UtilGenerics.checkList(context.get(bodyParts));
    GenericValue userLogin
    = (GenericValue) context.get(userLogin);

    results.put(
    communicationEventId, communicationEventId);
    results.put(
    partyId, partyId);
    results.put(
    subject, subject);

    if (UtilValidate.isNotEmpty(orderId)) {
    results.put(
    orderId, orderId);
    }
    if (UtilValidate.isNotEmpty(body)) {
    body
    = FlexibleStringExpander.expandString(body, context);
    results.put(
    body, body);
    }
    if (UtilValidate.isNotEmpty(bodyParts)) {
    results.put(
    bodyParts, bodyParts);
    }
    results.put(
    userLogin, userLogin);

    String sendTo
    = (String) context.get(sendTo);
    String sendCc
    = (String) context.get(sendCc);
    String sendBcc
    = (String) context.get(sendBcc);

    // check to see if we should redirect all mail for testing
    String redirectAddress = UtilProperties.getPropertyValue(general.properties, mail.notifications.redirectTo);
    if (UtilValidate.isNotEmpty(redirectAddress)) {
    String originalRecipients
    = [To: + sendTo + , Cc: + sendCc + , Bcc: + sendBcc + ];
    subject
    += originalRecipients;
    sendTo
    = redirectAddress;
    sendCc
    = null;
    sendBcc
    = null;
    }

    String sendFrom
    = (String) context.get(sendFrom);
    String sendType
    = (String) context.get(sendType);
    String port
    = (String) context.get(port);
    String socketFactoryClass
    = (String) context.get(socketFactoryClass);
    String socketFactoryPort
    = (String) context.get(socketFactoryPort);
    String socketFactoryFallback
    = (String) context.get(socketFactoryFallback);
    String sendVia
    = (String) context.get(sendVia);
    String authUser
    = (String) context.get(authUser);
    String authPass
    = (String) context.get(authPass);
    String messageId
    = (String) context.get(messageId);
    String contentType
    = (String) context.get(contentType);
    Boolean sendPartial
    = (Boolean) context.get(sendPartial);
    Boolean isStartTLSEnabled
    = (Boolean) context.get(startTLSEnabled);

    boolean useSmtpAuth = false;

    // define some default
    if (sendType == null || sendType.equals(mail.smtp.host)) {
    sendType
    = mail.smtp.host;
    if (UtilValidate.isEmpty(sendVia)) {
    sendVia
    = UtilProperties.getPropertyValue(general.properties, mail.smtp.relay.host, localhost);
    }
    if (UtilValidate.isEmpty(authUser)) {
    authUser
    = UtilProperties.getPropertyValue(general.properties, mail.smtp.auth.user);
    }
    if (UtilValidate.isEmpty(authPass)) {
    authPass
    = UtilProperties.getPropertyValue(general.properties, mail.smtp.auth.password);
    }
    if (UtilValidate.isNotEmpty(authUser)) {
    useSmtpAuth
    = true;
    }
    if (UtilValidate.isEmpty(port)) {
    port
    = UtilProperties.getPropertyValue(general.properties, mail.smtp.port);
    }
    if (UtilValidate.isEmpty(socketFactoryPort)) {
    socketFactoryPort
    = UtilProperties.getPropertyValue(general.properties, mail.smtp.socketFactory.port);
    }
    if (UtilValidate.isEmpty(socketFactoryClass)) {
    socketFactoryClass
    = UtilProperties.getPropertyValue(general.properties, mail.smtp.socketFactory.class);
    }
    if (UtilValidate.isEmpty(socketFactoryFallback)) {
    socketFactoryFallback
    = UtilProperties.getPropertyValue(general.properties, mail.smtp.socketFactory.fallback, false);
    }
    if (sendPartial == null) {
    sendPartial
    = UtilProperties.propertyValueEqualsIgnoreCase(general.properties, mail.smtp.sendpartial, true) ? true : false;
    }
    if (isStartTLSEnabled == null) {
    isStartTLSEnabled
    = UtilProperties.propertyValueEqualsIgnoreCase(general.properties, mail.smtp.starttls.enable, true);
    }
    }
    else if (sendVia == null) {
    return ServiceUtil.returnError(UtilProperties.getMessage(resource, CommonEmailSendMissingParameterSendVia, locale));
    }

    if (contentType == null) {
    contentType
    = text/html;
    }

    if (UtilValidate.isNotEmpty(bodyParts)) {
    contentType
    = multipart/mixed;
    }
    results.put(
    contentType, contentType);

    Session session;
    MimeMessage mail;
    try {
    Properties props
    = System.getProperties();
    props.put(sendType, sendVia);
    if (UtilValidate.isNotEmpty(port)) {
    props.put(
    mail.smtp.port, port);
    }
    if (UtilValidate.isNotEmpty(socketFactoryPort)) {
    props.put(
    mail.smtp.socketFactory.port, socketFactoryPort);
    }
    if (UtilValidate.isNotEmpty(socketFactoryClass)) {
    props.put(
    mail.smtp.socketFactory.class, socketFactoryClass);
    Security.addProvider(
    new com.sun.net.ssl.internal.ssl.Provider());
    }
    if (UtilValidate.isNotEmpty(socketFactoryFallback)) {
    props.put(
    mail.smtp.socketFactory.fallback, socketFactoryFallback);
    }
    if (useSmtpAuth) {
    props.put(
    mail.smtp.auth, true);
    }
    if (sendPartial != null) {
    props.put(
    mail.smtp.sendpartial, sendPartial ? true : false);
    }
    if (isStartTLSEnabled) {
    props.put(
    mail.smtp.starttls.enable, true);
    }

    session
    = Session.getInstance(props);
    boolean debug = UtilProperties.propertyValueEqualsIgnoreCase(general.properties, mail.debug.on, Y);
    session.setDebug(debug);

    mail
    = new MimeMessage(session);
    if (messageId != null) {
    mail.setHeader(
    In-Reply-To, messageId);
    mail.setHeader(
    References, messageId);
    }
    mail.setFrom(
    new InternetAddress(sendFrom));
    mail.setSubject(subject,
    UTF-8);
    mail.setHeader(
    X-Mailer, Apache OFBiz, The Apache Open For Business Project);
    mail.setSentDate(
    new Date());
    mail.addRecipients(Message.RecipientType.TO, sendTo);

    if (UtilValidate.isNotEmpty(sendCc)) {
    mail.addRecipients(Message.RecipientType.CC, sendCc);
    }
    if (UtilValidate.isNotEmpty(sendBcc)) {
    mail.addRecipients(Message.RecipientType.BCC, sendBcc);
    }

    if (UtilValidate.isNotEmpty(bodyParts)) {
    // check for multipart message (with attachments)
    // BodyParts contain a list of Maps items containing content(String) and type(String) of the attachement
    MimeMultipart mp = new MimeMultipart();
    Debug.logInfo(bodyParts.size()
    + multiparts found,module);
    for (Map<String, Object> bodyPart: bodyParts) {
    Object bodyPartContent
    = bodyPart.get(content);
    MimeBodyPart mbp
    = new MimeBodyPart();

    if (bodyPartContent instanceof String) {
    Debug.logInfo(
    part of type: + bodyPart.get(type) + and size: + bodyPart.get(content).toString().length() , module);
    mbp.setText((String) bodyPartContent,
    UTF-8, ((String) bodyPart.get(type)).substring(5));
    }
    else if (bodyPartContent instanceof byte[]) {
    ByteArrayDataSource bads
    = new ByteArrayDataSource((byte[]) bodyPartContent, (String) bodyPart.get(type));
    Debug.logInfo(
    part of type: + bodyPart.get(type) + and size: + ((byte[]) bodyPartContent).length , module);
    mbp.setDataHandler(
    new DataHandler(bads));
    }
    else if (bodyPartContent instanceof DataHandler) {
    mbp.setDataHandler((DataHandler) bodyPartContent);
    }
    else {
    mbp.setDataHandler(
    new DataHandler(bodyPartContent, (String) bodyPart.get(type)));
    }

    String fileName
    = (String) bodyPart.get(filename);
    if (fileName != null) {
    mbp.setFileName(fileName);
    }
    mp.addBodyPart(mbp);
    }
    mail.setContent(mp);
    mail.saveChanges();
    }
    else {
    // create the singelpart message
    if (contentType.startsWith(text)) {
    mail.setText(body,
    UTF-8, contentType.substring(5));
    }
    else {
    mail.setContent(body, contentType);
    }
    mail.saveChanges();
    }
    }
    catch (MessagingException e) {
    Debug.logError(e,
    MessagingException when creating message to [ + sendTo + ] [ + sendFrom + ] cc [ + sendCc + ] bcc [ + sendBcc + ] subject [ + subject + ], module);
    Debug.logError(
    Email message that could not be created to [ + sendTo + ] had context: + context, module);
    return ServiceUtil.returnError(UtilProperties.getMessage(resource, CommonEmailSendMessagingException, UtilMisc.toMap(sendTo, sendTo, sendFrom, sendFrom, sendCc, sendCc, sendBcc, sendBcc, subject, subject), locale));
    }
    catch (IOException e) {
    Debug.logError(e,
    IOExcepton when creating message to [ + sendTo + ] [ + sendFrom + ] cc [ + sendCc + ] bcc [ + sendBcc + ] subject [ + subject + ], module);
    Debug.logError(
    Email message that could not be created to [ + sendTo + ] had context: + context, module);
    return ServiceUtil.returnError(UtilProperties.getMessage(resource, CommonEmailSendIOException, UtilMisc.toMap(sendTo, sendTo, sendFrom, sendFrom, sendCc, sendCc, sendBcc, sendBcc, subject, subject), locale));
    }

    // check to see if sending mail is enabled
    String mailEnabled = UtilProperties.getPropertyValue(general.properties, mail.notifications.enabled, N);
    if (!Y.equalsIgnoreCase(mailEnabled)) {
    // no error; just return as if we already processed
    Debug.logImportant(Mail notifications disabled in general.properties; mail with subject [ + subject + ] not sent to addressee [ + sendTo + ], module);
    Debug.logVerbose(
    What would have been sent, the addressee: + sendTo + subject: + subject + context: + context, module);
    results.put(
    messageWrapper, new MimeMessageWrapper(session, mail));
    return results;
    }

    Transport trans
    = null;
    try {
    trans
    = session.getTransport(smtp);
    if (!useSmtpAuth) {
    trans.connect();
    }
    else {
    trans.connect(sendVia, authUser, authPass);
    }
    trans.sendMessage(mail, mail.getAllRecipients());
    results.put(
    messageWrapper, new MimeMessageWrapper(session, mail));
    results.put(
    messageId, mail.getMessageID());
    trans.close();
    }
    catch (SendFailedException e) {
    // message code prefix may be used by calling services to determine the cause of the failure
    Debug.logError(e, [ADDRERR] Address error when sending message to [ + sendTo + ] [ + sendFrom + ] cc [ + sendCc + ] bcc [ + sendBcc + ] subject [ + subject + ], module);
    List
    <SMTPAddressFailedException> failedAddresses = FastList.newInstance();
    Exception nestedException
    = null;
    while ((nestedException = e.getNextException()) != null && nestedException instanceof MessagingException) {
    if (nestedException instanceof SMTPAddressFailedException) {
    SMTPAddressFailedException safe
    = (SMTPAddressFailedException) nestedException;
    Debug.logError(
    Failed to send message to [ + safe.getAddress() + ], return code [ + safe.getReturnCode() + ], return message [ + safe.getMessage() + ], module);
    failedAddresses.add(safe);
    break;
    }
    }
    Boolean sendFailureNotification
    = (Boolean) context.get(sendFailureNotification);
    if (sendFailureNotification == null || sendFailureNotification) {
    sendFailureNotification(ctx, context, mail, failedAddresses);
    results.put(
    messageWrapper, new MimeMessageWrapper(session, mail));
    try {
    results.put(
    messageId, mail.getMessageID());
    trans.close();
    }
    catch (MessagingException e1) {
    Debug.logError(e1, module);
    }
    }
    else {
    return ServiceUtil.returnError(UtilProperties.getMessage(resource, CommonEmailSendAddressError, UtilMisc.toMap(sendTo, sendTo, sendFrom, sendFrom, sendCc, sendCc, sendBcc, sendBcc, subject, subject), locale));
    }
    }
    catch (MessagingException e) {
    // message code prefix may be used by calling services to determine the cause of the failure
    Debug.logError(e, [CON] Connection error when sending message to [ + sendTo + ] [ + sendFrom + ] cc [ + sendCc + ] bcc [ + sendBcc + ] subject [ + subject + ], module);
    Debug.logError(
    Email message that could not be sent to [ + sendTo + ] had context: + context, module);
    return ServiceUtil.returnError(UtilProperties.getMessage(resource, CommonEmailSendConnectionError, UtilMisc.toMap(sendTo, sendTo, sendFrom, sendFrom, sendCc, sendCc, sendBcc, sendBcc, subject, subject), locale));
    }
    return results;
    }


    从代码中可以看出发送的大项目组设备都是从context中取出,但smtp的设备是从general.properties文件中获取

    所有随风而逝的都属于昨天的,所有历经风雨留下来的才是面向未来的。—— 玛格丽特·米切尔 《飘》
    分享到: