java邮件发送和短信发送(二)

    上次介绍了基于Velocity模板java邮件发送,这次我们对程序做了一次重构,实现的是根据相应的请求发送邮件或者短信。

   首先我们来定义一个顶层消息接口:

    /** * 功能: 系统消息发送服务 <p> * 用法: * @version 1.0 */ public interface MessageService { /** * 根据消息模板表中的消息编号取得消息模板,填充,发送 * * @param bmtCode 消息模板表中的消息编号 * @param params 填充模板内容的参数 * @param to 消息的接收人 * @throws CheckException 模板不存在,或是发送消息出现异常 */ public void sendMessage(String bmtCode,Map params, String... to) throws CheckException; }

 

    接着我们实现该接口:

    public class MessageServiceImpl implements MessageService{ /** * Logger for this class */ private static final Logger logger = Logger.getLogger(MessageServiceImpl.class); @Autowired private BaseMessageTempletDAO baseMessageTempletDAO; @Autowired private SenderFactory senderFactory; @Override public void sendMessage(String bmtCode, Map params, String... to) throws CheckException { // 检查参数 if (StringUtils.isEmpty(bmtCode) || ArrayUtils.isEmpty(to)){ throw new CheckException("模板编号不能为空,或消息的接收人不能为空"); } // 从数据库取出模板 BaseMessageTempletEO queryParam = new BaseMessageTempletEO(); queryParam.setBmtCode(bmtCode); BaseMessageTempletEO template = null; try { template = baseMessageTempletDAO.selectEOByEO(queryParam); } catch (Exception e) { // 查询失败 logger.error("查询模板:" + bmtCode + " 时发生异常", e); throw new CheckException(e); } // 检查模板是否存在 if (template == null){ logger.info("编号为: " + bmtCode + " 的消息模板不存在."); throw new CheckException("编号为: " + bmtCode + " 的消息模板不存在."); } // 检查消息类型 String msgType = template.getBmtType(); if (StringUtils.isEmpty(msgType)){ logger.info("编号为: " + bmtCode + " 的消息模板消息类型未知."); throw new CheckException("编号为: " + bmtCode + " 的消息模板消息类型未知,无法发送."); } // 解析标题 String title = null; if (StringUtils.isNotEmpty(template.getBmtTitle()) && params != null){ try { title = VelocityParserUtil.getInstance().parseVelocityTemplate(template.getBmtTitle(),params); } catch (Exception e) { logger.error("编号为: " + bmtCode + " 的消息模板解析 <标题 > 时失败"); throw new CheckException(e); } } // 解析内容 String content = null; if (StringUtils.isNotEmpty(template.getBmtContent()) && params != null){ try { content = VelocityParserUtil.getInstance().parseVelocityTemplate(template.getBmtContent(),params); } catch (Exception e) { logger.error("编号为: " + bmtCode + " 的消息模板解析 <内容> 时失败"); throw new CheckException(e); } } // 发送 Sender sender = senderFactory.getSender(msgType); if (sender == null){ // 找不到对应类型的发送器 logger.error("编号为: " + bmtCode + " 的消息模板,类型为: " + msgType + " 没有对应的消息发送器"); throw new CheckException("编号为: " + bmtCode + " 的消息模板,类型为: " + msgType + " 没有对应的消息发送器"); } sender.sender(title, content, to); } }

 

  

 

    大家看到了代码涉及到了DAO和Factory,这里注入DAO是因为我们把消息发送的相关信息都放进了数据库存储起来,我们根据识别号,去判断发送短息还是邮件,发送的模板是什么等等。那我们写一个发送消息的工厂类SendFactory:

    /** * 功能: 根据不同的消息类型,取得适应的消息发送器 * <p> * 用法: * * @version 1.0 */ public class SenderFactory { @Autowired @Qualifier("mailSenderAdapt") private Sender mailSender; @Autowired @Qualifier("smsSenderAdapt") private Sender smsSender; public Sender getSender(String type) { Sender sender = null; if (BaseMessageTempletEO.BMT_TYPE_MAIL.equalsIgnoreCase(type)) { // 邮件 sender = mailSender; } else if (BaseMessageTempletEO.BMT_TYPE_SMS.equalsIgnoreCase(type)) { // 短信 sender = smsSender; } return sender; } }

 

    如你所看到的我们会if的判断得知该请求是要发送邮件还是发送短信。

    我们暂时放下前面的,定义一个顶层接口Sender:

    /** * 功能: 消息发送器接口<p> * 用法: * @version 1.0 */ public interface Sender { /** * @param title 消息的标题 * @param content 消息的内容 * @param to 消息的接收人 * @throws CheckException */ public void sender(String title, String content, String... to) throws CheckException; }

 

    然后我们要分别定义邮件和短信接口,并实现顶层接口Sender:

   public class SmsSenderAdapt implements Sender { @Autowired @Qualifier("smsSenderImpl_commons") private SmsSender smsSender; @Override public void sender(String title, String content, String... to) throws CheckException { smsSender.sendSms(to, content); } }

 

    public class MailSenderAdapt implements Sender { @Autowired @Qualifier("emailSenderImpl_commons") private EmailSender emailSender; @Autowired private ConfigService configService; @Override public void sender(String title, String content, String... to) throws CheckException { // 从数据库取发件人,及发件人姓名 String from = configService.getConfig(BasePropertyID.MAIL_SMTP_FROM_ID); String fromName = configService.getConfig(BasePropertyID.MAIL_SMTP_FROMNAME_ID); Mail mail = new Mail(); mail.setFrom(from); mail.setFromName(fromName); mail.setTo(to); mail.setSubject(title); mail.setContent(content); emailSender.sendEmail(mail); } }

 

    后面对sendEmail(mail)这个已经在上一篇实现了,大家可以返回去看一下,是不是明白了呢?

    接下来我详细介绍发送短信的代码。

    那好我们来时先刚刚短信的接口:

    /** * 功能: 短信发送服务 * <p> * 用法: * * @version 1.0 */ public class SmsSenderImpl implements SmsSender,InitializingBean { /** * Logger for this class */ private static final Logger logger = Logger.getLogger(SmsSenderImpl.class); @Autowired private ConfigService configService; private String smsUrl; private String cpidName; private String cpidValue; private String pwdName; private String pwdValue; private String pidName; private String pidValue; private String phoneName; private String msgName; private int maxLength = 60; // 默认值 @Override public void sendSms(String mobilePhone, String message) throws CheckException { send(message, mobilePhone); } @Override public void sendSms(String[] mobilePhones, String message) throws CheckException { if (ArrayUtils.isEmpty(mobilePhones)){ throw new CheckException("手机号码不能为空"); } for (String phone : mobilePhones) { sendSms(phone, message); } } /** * 如果超过短信的长度,则分成几条发 * @param content * @param phoneNo * @return * @throws CheckException */ private String send(String content,String phoneNo) throws CheckException{ content = StringUtils.trimToEmpty(content); phoneNo = StringUtils.trimToEmpty(phoneNo); if (StringUtils.isEmpty(content)){ throw new CheckException("短信内容为空"); } if (StringUtils.isEmpty(phoneNo)){ throw new CheckException("手机号为空"); } // 如果服务未准备好,先初始化 if (!isReady()) { try { init(); // 初始化后,服务仍未准备好 if (!isReady()) { throw new CheckException("邮件服务初始化异常"); } } catch (Exception e) { logger.error("send(String, String)", e); throw new CheckException("邮件服务初始化异常"); } } // 如果超过最大长度,则分成几条发送 int count = content.length() / maxLength; int reminder = content.length() % maxLength; if (reminder != 0 ){ count += 1; } StringBuffer result = new StringBuffer(); int i = 0; while (count > i){ result.append(doSend(StringUtils.substring(content, i*maxLength, (i+1)*maxLength),phoneNo)); result.append(";"); i ++; } return result.toString(); } private boolean isReady(){ return !(smsUrl == null || cpidName == null || cpidValue == null || pwdName == null || pwdValue == null || pidName == null || pidValue == null || phoneName == null || msgName == null || maxLength <= 0); } /** * @param content * @param phoneNo * @return * @throws CheckException */ private String doSend(String content,String phoneNo) throws CheckException{ // 使用httpclient模拟http请求 HttpClient client = new HttpClient(); // 设置参数编码 client.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "GBK"); PostMethod method = new PostMethod(smsUrl); method.addParameter(cpidName, cpidValue); method.addParameter(pidName, pidValue); method.addParameter(pwdName, pwdValue); method.addParameter(phoneName, phoneNo); method.addParameter(msgName, content); BufferedReader br = null; String reponse = null; try { int returnCode = client.executeMethod(method); if (returnCode != HttpStatus.SC_OK) { // 请求出错 throw new CheckException("短信接口异常"); } br = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream())); reponse = br.readLine(); String responseCode = StringUtils.substring(reponse, 0, 1); if (!"0".equals(responseCode)){ throw new CheckException(getResponseMsg(responseCode)); } } catch (Exception e) { logger.error("doSend(String, String)", e); if (e instanceof CheckException){ throw (CheckException)e; }else{ throw new CheckException("未知异常"); // 未知异常 } } finally { method.releaseConnection(); if (br != null) try { br.close(); } catch (Exception e1) { logger.error("doSend(String, String)", e1); e1.printStackTrace(); } } return reponse; } public void afterPropertiesSet() throws Exception { // 初始化 init(); } private void init() throws Exception{ smsUrl = configService.getConfig(BasePropertyID.SMS_URL_ID); cpidName = configService.getConfig(BasePropertyID.SMS_CPID_NAME_ID); cpidValue = configService.getConfig(BasePropertyID.SMS_CPID_VALUE_ID); pwdName = configService.getConfig(BasePropertyID.SMS_PWD_NAME_ID); pwdValue = configService.getConfig(BasePropertyID.SMS_PWD_VALUE_ID); pidName = configService.getConfig(BasePropertyID.SMS_PID_NAME_ID); pidValue = configService.getConfig(BasePropertyID.SMS_PID_VALUE_ID); phoneName = configService.getConfig(BasePropertyID.SMS_PHONE_NAME_ID); msgName = configService.getConfig(BasePropertyID.SMS_MSG_NAME_ID); maxLength = configService.getConfigByInteger(BasePropertyID.SMS_MSG_MAXLENGTH_ID); } private String getResponseMsg(String code){ String msg = "未知返回值:" + code; if ("1".equals(code)) { msg = "手机号码非法"; } else if ("2".equals(code)) { msg = "用户存在于黑名单列表"; } else if ("3".equals(code)) { msg = "接入用户名或密码错误"; } else if ("4".equals(code)) { msg = "产品代码不存在"; } else if ("5".equals(code)) { msg = "IP非法"; } else if ("6".equals(code)) { msg = "源号码错误"; } else if ("7".equals(code)) { msg = "调用网关错误"; } else if ("8".equals(code)) { msg = "消息长度超过60"; } else if ("-1".equals(code)) { msg = "短信内容为空"; } else if ("-2".equals(code)) { msg = "手机号为空"; }else if ("-3".equals(code)) { msg = "邮件服务初始化异常"; }else if ("-4".equals(code)) { msg = "短信接口异常"; } return msg; } }

    和邮件发送是不是很类似,相信大家应该会理解吧。O(∩_∩)O哈哈~,我这里发送的配置信息都直接初始化在了java代码里,大家也可以试着将其配置在xml文件里,这样更改更方便。

你可能感兴趣的:(java,exception,String,null,Class,Autowired)