• java毕业设计——基于java+Java Swing+jsp的企业快信系统设计与实现(毕业论文+程序源码)——企业快信系统


    基于java+Java Swing+jsp的企业快信系统设计与实现(毕业论文+程序源码)

    大家好,今天给大家介绍基于java+Java Swing+jsp的企业快信系统设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦。

    文章目录:

    1、项目简介

    1. 系统在开发中,采用了 MYSQL 数据库,同时使用到了 Java Swing、短信猫组件、Java MailAPI 等相关技术。在进行详细设计之前,根据总体设计的结构,确定每部分功能的解决方案,并完成相关技术的可行性分析以及技术原型的实现。在该系统中,采用数据服务器,和客户机相结合形成 B/S 结构,由相关人员或系统管理员执行如系统的备份、恢复、修改等重要操作,从而用来提高系统的安全性,并且降低了了黑客通过 Web 入侵来获取以及改变系统中重要数据信息的可能性。同时,采用 Web 客户机架构 B/S 三层结构,Web 客户机可通过 Internet 或专线连接应用服务器,向其发送指令,从而获取服务。这样做的优点是用浏览器便可进行,使用起来方便快捷,为客户提供了很大的便利。而对于记录管理,系统维护功能而言,主要是对记录信息进行处理,即对数据库信息进行添加,查询,导入和导出操作,这部分功能涉及的主要技术为通过 java连接 MYSQL 数据库,并通过 Java 代码完成对表内信息的查询和添加操作。
    2. 本文首先对企业快信的开发进行了较深入的研究,然后对短信发送与邮件发送原理进行了介绍,接下来对系统的概要设计、功能模块、数据库设计,以及名片夹管理功能与邮件发送功能的具体实现作了细致阐述,最后是系统效果的展示。企业快信系统是一个集短信与邮件为一体的移动商务应用系统。是针对企业内部II及外部不同需求和应用方面,而专门定制开发的系统软件。它完全集成了企业的业务推广、客情沟通、内部管理等应用功能。企业快信的作用是帮助企业解决企业内部、企业与外部沟通难、信息不能及时传播等问题。为此,系统提供邮件群发、短信群发、人员档案、信息的管理等功能。系统是短信猫与邮件在企业商务应用中的典型实例,因此必然受到众多企业的青睐,成为企业通信的最佳选择。

    2、资源详情

    项目难度:中等难度
    适用场景:相关题目的毕业设计
    配套论文字数:23874个字62页
    包含内容:整套源码+完整毕业论文+答辩PPT+任务书+辅导视频+运行截图
    资源文件目录简图如下:
    请添加图片描述


    3、关键词:

    短信发送;邮件发送;企业快信

    4、毕设简介

    提示:以下为毕业论文的简略介绍,项目源码及完整毕业论文下载地址见文末。

    绪论
    1.1 开发背景
    省略

    1.2 国内外发展概况
    省略

    1.3 研究目的和意义
    省略

    1.4 研究主要内容
    在一个提供企业级短信的系统的设计与实现中,把 C/S 和 B/S 架构根据实际情况进行结合,着重对数据库存取中的各种机制进行了深入地研究并且根据系统自身特点进行了选择和加强,采用了MySQL 数据供应器池化,并使用 Windows7 自带的性能监视器来监视链接池,最后讨论了设置链接池大小的各种问题,选择合适的大小,实现高效与安全有效的结合。并且结合 web 开发的实例,对面向对象对多层结构的支持进行了详细的分析。

    基于JAVA的 B/S 架构来进行 web 开发必然是今后的主流,并且由于同时面对多用户及多连接,对数据库存取效率及性能,安全都有很高要求,因此,通过对其具体应用进行研究对相关开发人员和以后的软件开发及应用都有十分重要的意义。

    2 系统分析
    2.1 需求分析
    企业快信的作用是帮助企业解决企业内部、企业与外部沟通难、信息不能及时传播等问题。为此,企业快信系统需要提供邮件群发、短信群发等功能。通过对多数企业日常业务的考察、分析,并结合短信及邮件自身的特点,得出本系统要求具有以下功能。

    用于管理客户和员工信息的名片夹管理功能。
    用于对常用短语及其类别进行管理的信息库管理功能。
    短信群发功能。
    邮件群发功能。
    发送邮件附件的功能。

    2.2 可行性研究
    省略

    2.2.1 经济可行性
    省略

    2.2.2 技术可行性
    开发一个企业快信系统,涉及到的技术问题不会太多,主要用到的技术就是使用短信猫和Java Mail组件来实现收发短信和群发邮件等功能。Java Mail 组件是Sun 公司发布的一种用于读取、编写和发送电子邮件的包,利用它可以方便地实现邮件群发。

    2.3 开发环境
    在开发企业快信时,需要具备下面的软件环境。
    服务器端:
    操作系统:Windows 7。
    Java 开发包:JDK 1.5 以上。
    Web服务器:Tomcat6.0。
    Java Mail 开发包:Java Mail 1.4。
    数据库:MYSQL。
    浏览器:IE 10.0。
    分辨率:最佳效果为1024×768 像素。
    客户端:
    浏览器:IE 10.0。
    分辨率:最佳效果为1024×768 像素。
    由于本系统中需要使用Java Mail 组件,下面将详细介绍如何配置及Java Mail 的开发环境。

    3 系统总体设计
    3.1 系统目标
    根据前面所作的需求分析及用户的需求可知,企业快信属于小型的企业通信软件,在系统实施后,应达到以下目标。
    界面设计友好、美观。
    操作灵活、方便。
    提供功能强大的信息库管理,方便用户进行短信息的编写。
    提供邮件群发功能,提高工作效率。
    在发送短信时,可以直接从现有信息库中获取信息内容。
    对用户输入的数据,进行严格的数据检验,尽可能地避免人为错误。
    数据存储安全、可靠。

    3.2 系统功能结构
    根据企业快信的特点,可以将其分为名片夹管理、信息库管理、短信群发、邮件群发、系统参数设置、系统设置6个部分,其中各个部分及其包括的具体功能模块如图3-1 所示。
    在这里插入图片描述

    图3-1 系统功能结构

    3.3 业务流程图
    企业快信的系统流程如图3-2 所示。
    在这里插入图片描述

    图3-2 系统流程图

    3.4 系统预览
    企业快信由多个程序页面组成,下面仅列出几个典型界面。
    系统登录页面如图3-3所示,该页面用于实现管理员登录功能;主页如图3-4所示,该页面用于实现显示系统导航、操作业务流程和版权信息等功能。

    在这里插入图片描述

    图3-3 系统登录页面
    在这里插入图片描述

    图3-4 主 页

    发送短信页面如图3-5所示,该页面用于实现将短信息同时发给多个接受者的功能;同时,为方便用户还提供了从客户及员工列表中选择接收者及从信息库中选择指定信息的功能。
    在这里插入图片描述

    图3-5 发送短信页面
    邮件群发页面如图3-6所示,该页面用于实现将邮件同时发给多个接受者的功能;同时,为方便用户还提供了从客户及员工列表中选择接收者的功能。
    在这里插入图片描述

    图3-6 邮件群发

    3.5 文件夹组织结构
    在编写代码之前,需要把系统中可能用到的文件夹先创建出来(例如创建一个名为img 的文件夹,用来保存程序中使用的效果图片),这样不但方便以后的开发工作,也可以规范软件的整体架构。本人在开发企业快信时,设计了如图3-7 所示的文件夹架构。在开发时,只需要将所创建的文件保存在相应的文件夹中就可以了。
    在这里插入图片描述

    图3-7 企业快信文件夹组织结构

    4 系统详细设计
    4.1 数据库设计
    4.1.1 数据库分析
    由于本系统是一个小型实用的信息群发系统,提供了名片夹和信息库的功能,用户可以将常用的人员保存到名片夹中,将常用的短语保存到信息库中,以方便使用。基于这个特点以及语言特点,本系统将采用MySQL 数据库作为底层数据库,以方便用户使用本系统。

    4.1.2 数据库概念设计
    根据以上对系统所作的需求分析和系统设计,规划出本系统中使用的数据库实体分别为类型实体、档案实体、常用短语实体、管理员实体。下面将给出几个关键实体的E-R 图。
    档案实体
    档案实体包括编号、客户名称、地址、邮政编码、所属区域、手机号码、邮件地址、银行账户、开户银行和联系人属性,档案实体的E-R 图如图4-1 所示。
    在这里插入图片描述

    图4-1 档案实体E-R 图

    短信实体
    短信实体包括编号、收信人的手机号码、短信内容、发信人和发送时间属性,短信实体的E-R 图如图4-2 所示。
    常用短语
    常用短语实体包括编号、类型和内容,常用短语实体的E-R 图如图4-3 所示。
    在这里插入图片描述

    4.1.3 数据库逻辑结构设计
    在数据库概念设计中已经分析了档案实体、常用短语实体和类型实体,这些实体对象是数据表结的基本模型,最终的数据模型都要实施到数据库中,形成整体的数据结构。图4-4 为通过PowerDesigner创建完成的数据库模
    在这里插入图片描述

    图4-4 数据库模型图
    表tb_customer 的表结构如表4-1 所示。
    表4-1 表tb_customer 的表结构
    在这里插入图片描述

    表4-2 表tb_shortLetter 的表结构
    在这里插入图片描述

    4.2 公共模块设计
    在开发过程中,经常会用到一些公共模块,如数据库连接及操作的类、字符串处理的类及Struts配置等,因此,在开发系统前首先需要设计这些公共模块。下面将具体介绍企业快信系统中所需要的公共模块的设计过程。
    4.2.1 数据库连接及操作类的编写
    数据库连接及操作类通常包括连接数据库的方法getConnection()、执行查询语句的方法executeQuery()、执行更新操作的方法executeUpdate()、关闭数据库连接的方法close().下面将详细介绍如何编写企业快信系统中的数据库连接及操作的类ConnDB。
    (1)定义ConnDB类
    定义用于进行数据库连接及操作的类ConnDB,并将其保存到com.wgh.core包中,同时定义该类中所需的全局变量及构造方法。代码如下:

    public class ConnDB {
    public Connection conn = null; // 声明Connection对象的实例
    public Statement stmt = null; // 声明Statement对象的实例
    public ResultSet rs = null; // 声明ResultSet对象的实例
    private static String propFileName = "/com/connDB.properties"; // 指定资源文件保存的位置
    private static Properties prop = new Properties(); // 创建并实例化Properties对象实例
    private static String dbClassName = " ";//定义保存数据库驱动的变量
    private static String dbUrl =  " "private static String dbUser = "sa";
    private static String dbPwd = "";
    public ConnDB() {	//定义构造方法
    	try {			//捕捉异常
    		//将Properties文件读取到InputStream对象中
    		InputStream in = getClass().getResourceAsStream(propFileName);
    		prop.load(in); // 通过输入流对象加载Properties文件
    		dbClassName = prop.getProperty("DB_CLASS_NAME");//获取数据库驱动
    		dbUrl = prop.getProperty("DB_URL", dbUrl);		//获取URL
    		dbUser = prop.getProperty("DB_USER", dbUser);	//获取登录用户
    		dbPwd = prop.getProperty("DB_PWD", dbPwd);		//获取密码
    	} catch (Exception e) {
    		e.printStackTrace(); // 输出异常信息
    	}
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    (2)将数据保存到资源文件中
    为了方便程序移植,将数据库连接所需信息保存到properties文件中,并将该文件保存在com包中。connDB.properties文件的内容如下:
    DB_CLASS_NAME=com.mysql.jdbc.Driver
    DB_URL=jdbc:mysql://127.0.0.1:3306/db_expressLetter
    DB_USER=sa
    DB_PWD=

    (3)创建数据库连接
    创建连接数据库的方法getConnection(),该方法返回connection对象的一个实例。getConnection()方法的实现代码如下:

    public static Connection getConnection() {
    	Connection conn = null;
    	try {
    		Class.forName(dbClassName).newInstance();
    		conn = DriverManager.getConnection(dbUrl, dbUser, dbPwd);
    	} catch (Exception ee) {
    		ee.printStackTrace();
    	}
    	if (conn == null) {
    	System.err.println("警告: DbConnectionManager.getConnection() 获得数据库链接失败.\r\n\r\n链接类型:"+ dbClassName+ "\r\n链接位置:"	+ dbUrl+ "\r\n用户/密码"+ dbUser + "/" + dbPwd);
    	}
    	return conn;
    }4)创建查询方法
    创建执行查询语句的方法exccuteQuery(),返回值为Resultset结果集。executeQuery()方法的代码如下:
    public ResultSet executeQuery(String sql) {
    	try { // 捕捉异常
    		conn = getConnection(); // 调用getConnection()方法构造Connection对象的一个实例conn
    		stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
    ResultSet.CONCUR_READ_ONLY);
    		rs = stmt.executeQuery(sql);
    	} catch (SQLException ex) {
    		System.err.println(ex.getMessage()); // 输出异常信息
    	}
    	return rs; // 返回结果集对象
    }5)创建更新操作方法
    创建执行更新操作的方法executeUpdate(),返回值为int型的整数,代表更新的行数。executeUpdate()方法的代码如下:
    public int executeUpdate(String sql) {
    	int result = 0; // 定义保存返回值的变量
    	try { // 捕捉异常
    		conn = getConnection(); // 调用getConnection()方法构造Connection对象的一个实例conn
    		stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
    ResultSet.CONCUR_READ_ONLY);
    		result = stmt.executeUpdate(sql); // 执行更新操作
    	} catch (SQLException ex) {
    		result = 0; // 将保存返回值的变量赋值为0
    	}
    	return result; // 返回保存返回值的变量
    	}6)关闭数据库连接
    创建关闭数据库连接的方法close()close()方法的代码如下:
    public void close() {
    	try { // 捕捉异常
    		if (rs != null) { // 当ResultSet对象的实例rs不为空时
    			rs.close(); // 关闭ResultSet对象
    		}
    		if (stmt != null) { // 当Statement对象的实例stmt不为空时
    			stmt.close(); // 关闭Statement对象
    		}
    		if (conn != null) { // 当Connection对象的实例conn不为空时
    			conn.close(); // 关闭Connection对象
    		}
    	} catch (Exception e) {
    		e.printStackTrace(System.err); // 输出异常信息
    	}
    	}
    4.2.2  字符串处理类的编写
    字符串处理类主要用于解决程序中经常出现的有关字符串处理的问题,包括将数据库中及页面中有中文问题的字符串进行正确地显示和对字符串中的空值进行处理的方法。其代码如下:
    public class ChStr {
        public static String toChinese(String strvalue) {
        try {
            if (strvalue == null) {
                return "";
            } else {
                strvalue = new String(strvalue.getBytes("ISO8859_1"), "GBK").trim();
                return strvalue;
            }
        } catch (Exception e) {
            return "";
        }
    }
    //处理字符串中的空值
     public static final String nullToString(String v, String toV) {
         if (v == null || "".equals(v)) {
             v = toV;
         }
         return v;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79

    4.2.3 配置Struts
    Struts框架需要通过一个专门的配置文件来控制,就是struts-config.xml。那么网站是怎么找到这个Struts的配置文件的呢?只要在web.xml中配置一下就可以了。具体实现代码如下:

      <servlet>
        <servlet-name>action</servlet-name>
        <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
      </servlet>
      <servlet>
        <servlet-name>action_tmp</servlet-name>
        <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
        <init-param>
          <param-name>config</param-name>
          <param-value>/WEB-INF/struts-config.xml</param-value>
        </init-param>
      </servlet>
      <servlet-mapping>
        <servlet-name>action</servlet-name>
        <url-pattern>*.do</url-pattern>
      </servlet-mapping>
      <!-- 设置默认文件名称 -->
      <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
      </welcome-file-list>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在web.xml中配置Struts的配置文件,实际就是一个servlet的配置,即在配置serylet的config参数中定义struts的配置文件(包括相对路径)及在servlet的URL访问里使用后缀名。接下来的工作就是如何配置struts-config.xml文件。Struts-config.xml文件的关键代码如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <struts-config>
      <data-sources />
      <form-beans >
        <form-bean name="managerForm" type="com.wgh.actionForm.ManagerForm" />//此处省略其他<form-bean>代码
      </form-beans>
      <action-mappings >
      <!-- 管理员 -->
    	 <action name="managerForm" path="/manager" scope="request" type="com.wgh.action.Manager" validate="true">
    	      <forward name="managerLoginok" path="/main.jsp" />
          <forward name="managerQuery" path="/manager.jsp" />
          <forward name="managerAdd" path="/manager_ok.jsp?para=1" />
          <forward name="pwdQueryModify" path="/pwd_Modify.jsp" />
          <forward name="managerDel" path="/manager_ok.jsp?para=3" />
          <forward name="modifypwd" path="/main.jsp" />
          <forward name="error" path="/error.jsp" />
        </action>//此处省略其他<action >代码
      </action-mappings>
    </struts-config>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    4.3 主页设计
    4.3.1 主页概述
    管理员通过系统登录模块的验证后,可以登录到企业快信的系统主页。系统主页主要包括系统导航栏、显示区和版权信息3部分。其中,导航栏中的功能菜单将根据登录管理员的权限进行显示。例如,系统管理员tsoft登录后,将拥有整个系统的全部功能,因为他是超级管理员。系统主页的运行效果如图4-5 所示。
    在这里插入图片描述

    图4-5 企业快信主页运行效果

    4.3.2 主页技术分析
    在实现系统主页时,最关键的就是如何实现导航菜单.本系统中采用的方法是通过Javascript+CSS样式控制<div>标记来实现。其具体实现方法如下:
    (1)在要显示导航菜单的位置添加相应的主菜单项。具体代码如下:

    <a href="main.jsp">首页</a> |
    <a  onmouseover=showmenu(event,cardClip) onmouseout=delayhidemenu() class='navlink' style="CURSOR:hand" >名片夹管理</a> |
    <a  onmouseover=showmenu(event,infoLibrary) onmouseout=delayhidemenu() class='navlink' style="CURSOR:hand" >信息库管理</a> |
    <a  onmouseover=showmenu(event,shortLetter) onmouseout=delayhidemenu() class='navlink' style="CURSOR:hand" >发送短信</a> |
    <a  href="sendMail.do?action=addMail">邮件群发</a> | 
    <%if(purview.equals("1")){%>
    <a  href="sysParameterSet.do?action=parameterQuery" >系统参数设定</a> |
    <%}%>
    <a onmouseover=showmenu(event,sysSet) onmouseout=delayhidemenu() class='navlink' style="CURSOR:hand">系统设置</a>
    | <a href="#" onClick="quit()">退出系统</a>Javascript中指定各个子菜单的内容,并根据登录管理员的权限控制要显示的菜单项.关键代码如下:
    <script language="javascript">
    var cardClip='<table width=56><tr><td id=customer onMouseOver=overbg(customer) onMouseOut=outbg(customer)><a href=customer.do?action=customerQuery>客户管理</a></td></tr>\
    <tr><td id=personnel onMouseOver=overbg(personnel) onMouseOut=outbg(personnel)><a href=personnel.do?action=personnelQuery>员工管理</a></td></tr>\
    </table>'
    var infoLibrary='<table width=86><tr><td id=infoType onMouseOver=overbg(infoType) onMouseOut=outbg(infoType)><a href=infoType.do?action=infoTypeQuery>信息类别管理</a></td></tr>\
    <tr><td id=shortInfo onMouseOver=overbg(shortInfo) onMouseOut=outbg(shortInfo)><a href=shortInfo.do?action=shortInfoQuery>常用短语管理</a></td></tr>\
    </table>'
    <%if(purview.equals("1")){%>
    	var shortLetter='<table width=86><tr><td id=sendLetter onMouseOver=overbg(sendLetter) onMouseOut=outbg(sendLetter)><a href=sendLetter.do?action=addLetter>发送短信</a></td></tr>\
    <tr><td id=historyQ onMouseOver=overbg(historyQ) onMouseOut=outbg(historyQ)><a href=sendLetter.do?action=historyQuery>查看发送日志</a></td></tr>\
    </table>'
    <%}else{%>
    	var shortLetter='<table width=56><tr><td id=sendLetter onMouseOver=overbg(sendLetter) onMouseOut=outbg(sendLetter)><a href=sendLetter.do?action=addLetter>发送短信</a></td></tr>\
    </table>'
    <%}if(purview.equals("1")){%>
    	var sysSet='<table width=70><tr><td id=manager onMouseOver=overbg(manager) onMouseOut=outbg(manager)><a href=manager.do?action=managerQuery>操作员管理</a></td></tr>\
    <tr><td id=changePWD onMouseOver=overbg(changePWD) onMouseOut=outbg(changePWD)><a  href="manager.do?action=queryPWD">更改口令</a></td></tr>\
    </table>'
    <%}else{%>
    	var sysSet='<table width=70><tr><td id=changePWD onMouseOver=overbg(changePWD) onMouseOut=outbg(changePWD)><a  					href="manager.do?action=queryPWD">更改口令</a></td></tr></table>'
    <%}%>
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    4.4 名片夹管理模块设计
    4.4.1 名片夹管理模块概述
    名片夹管理模块主要包括客户信息管理和员工信息管理,其中,客户信息管理包括查看客户列表、添加客户信息、修改客户信息和删除客户信息4个功能:员工信息管理包括查看员工列表、添加员工信息、修改员工信息和删除员工信息4个功能。

    4.4.2 名片夹管理模块技术分析
    名片夹管理模块主要包括客户管理和员工管理两部分,由于这两部分的买现方法大致相同,所以本节将以客户管理为例介绍名片夹管理模块。在实现客户管理时,需要编写客户管理对应的ActionForm类和Action实现类。下面将详细介绍如何编写客户管理的ActionForm类和创建客户管理的Action实现类。
    (1)编写客户管理的ActionForm类
    在客户管理中,只涉及到一个数据表,即tb_customer(客户信息表),根据这个数据表可以得出客户管理的ActionForm类。客户管理的ActionForm类的名称为CustomerForm,具体代码如下:

    public class CustomerForm extends ActionForm {
    	private String bankNo;		//银行账号
    	private String area;			//所属区域
    	private String email;			//邮箱
    	private String address;			//地址
    	private String mobileTel;		//手机号码
    	private String name;			//客户全称
    	private int ID;				//编号
    	private String bankName;		//开户银行
    	private String postcode;		//邮政编码
    	private String linkName;		//联系人
    	public String getBankNo() {
    		return bankNo;
    	}
    	public void setBankNo(String bankNo) {
    		this.bankNo = bankNo;
    	}//此处省略其他控制客户信息的get()和set()方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    (2)创建客户管理的Action实现类
    客户管理的Action实现类Customer继承了Action类.在该类中,首先需要在该类的构造方法中实例化客户管理的CustomerDAO类(该类用于实现与数据库的交互)。Action实现类的主要方法是execute(),该方法会被自动执行其本身没有具体的事务,是根据通过HttpservletRequest的getParamer()方法获取的action参数值执行相应方法的。客户管理的Action实现类的关键代码如下:

    public class Customer extends Action{
        private CustomerDAO customerDAO = null;
        private ChStr chStr=new ChStr();
        public Customer() {
            this.customerDAO = new CustomerDAO();
        }	
    	public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response){
           String action = request.getParameter("action");
           System.out.println("获取的查询字符串:" + action);
           if (action == null || "".equals(action)) {
            	request.setAttribute("error","您的操作有误!");
              return mapping.findForward("error");
           }else if ("customerQuery".equals(action)) {
                return customerQuery(mapping, form, request,response);
    		}else if("customerAdd".equals(action)){
    			 return customerAdd(mapping, form, request,response);
    		} 
    else if("customerModify".equals(action)){
                return customerModify(mapping, form, request,response);
            }
    			request.setAttribute("error", "操作失败!");
    			return mapping.findForward("error");
    	}
    ……	//此处省略了该类中其他方法,这些方法将在后面的具体过程中给出。
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    4.4.3 查看客户信息列表的实现过程
    查看客户信息列表使用的数据表:tb_customer
    管理员登录后,选择“名片夹管理/客户管理”命令,进入到查看客户列表页面,在该页面中将以列表形式显示全部客户信息,同时提供添加客户信息、修改客户信息、删除客户信息的超链接。查看客户信息列表页面的运行效果如图4-6 所示。
    在这里插入图片描述

    图4-6 客户信息列表页面

    在查看客户信息列表的方法customerQuery()中,首先调用CustomerDAO类中的query()方法查询全部客户信息,再将返回的查询结果保存到HttpServletRequest对象的CustomerQuery参数中.查看客户信息列表的方法CustomerQuery()的具体代码如下:

    private ActionForward customerQuery(ActionMapping mapping, ActionForm form,
            HttpServletRequest request,HttpServletResponse response) {
            request.setAttribute("customerQuery", customerDAO.query(0));
            return mapping.findForward("customerQuery");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    查看客户信息列表使用的CustomerDAO类的方法是query()。该方法只有一个用于指定客户ID的参数id(如果记的值为null,则查询全部客户信息),然后将查询结果保存到List集合中并返回该集合的实例。Query()方法的具体代码如下:

    public List query(int id) {
        	List customerList = new ArrayList();
            CustomerForm cF = null;
            String sql="";
            if(id==0){
                sql = "SELECT * FROM tb_customer";
            }else{
            	sql = "SELECT * FROM tb_customer WHERE ID=" +id+ "";
            }
            ResultSet rs = conn.executeQuery(sql);
            try {
                while (rs.next()) {
                    cF = new CustomerForm();
                    cF.setID(rs.getInt(1));
                    cF.setName(rs.getString(2));
                    ……//此处省略获取并设置其他属性的代码
                    cF.setLinkName(rs.getString(10));
                    customerList.add(cF);
                }
            } catch (SQLException ex) {}
            finally{
    conn.close();//关闭数据库连接}
            return customerList;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    4.4.4 添加客户信息的实现过程
    添加客户信息使用的数据表:tb_customer.
    管理员登录后,选择“名片夹管理/客户管理”命令,进入到查看客户列表页面。在该页面中,单击“添加客户信息”超链接,进入到添加客户信息页面。添加客户信息页面的运行效果如图4-7 所示。
    在这里插入图片描述

    图4-7 添加客户信息页面

    (1)设计添加客户信息页面
    添加客户信息页面主要用于收集输入的客户信息及通过自定义的Javascript函数验证输入信息是否合法,该页面中所涉及的表单元素如表4-3 所示。
    表4-3 表tb_customer的表结构
    在这里插入图片描述

    (2)修改客户的Action实现类
    在添加客户信息页面中输入合法的客户信息后,单击“提交”按钮,网页会访问一个URL,即customer.do?action=customerAdd从该URL地址中可以知道添加客户信息模块涉及到的action的参数值为customerAdd,也就是当action=customerAdd时,会调用添加客户信息的方法customerAdd()。具体实现代码如下

    if("customerAdd".equals(action)){
    			 return customerAdd(mapping, form, request,response);
    }
    
    • 1
    • 2
    • 3

    在添加客户信息的方法customerAdd()首先需要将接收到的表单信息强制转换成ActionForm类型,并用获得指定属性的getXXX()重新设置该属性的setXXX()方法,然后调用customerDAO类中的insert()方法,将添加的客户信息保存到数据表中,并将返回值保存到变量ret中.如果返回值为l,表示信息添加成功,将页面重定向到添加信息成功页面:如果返回值为2,表示该客户信息己经添加,将错误提示信息“该客户信息己经添加!”保存到HttpServletRequest对象的error参数中,然后将页面重定向到错误提示信息页面;否则将错误提示信息“客户信息添加失败里”保存到HttpServletRequest对象的error参数中,并将页面重定向到错误提示页面.添加客户信息的方法customerAdd()的具体代码如下:

    private ActionForward customerAdd(ActionMapping mapping, ActionForm form,
              HttpServletRequest request,HttpServletResponse response) {
          CustomerForm customerForm = (CustomerForm) form;
          //此处需要进行中文转码
          customerForm.setName(chStr.toChinese(customerForm.getName()));
          customerForm.setAddress(chStr.toChinese(customerForm.getAddress()));
          customerForm.setArea(chStr.toChinese(customerForm.getArea()));
    customerForm.setBankName(chStr.toChinese(customerForm.getBankName()));
    customerForm.setLinkName(chStr.toChinese(customerForm.getLinkName()));
          int ret = customerDAO.insert(customerForm);
          System.out.println("返回值ret:"+ret);
          if (ret == 1) {
              return mapping.findForward("customerAdd");
          } else if(ret==2){
              request.setAttribute("error","该客户信息已经添加!");
              return mapping.findForward("error");
          }else {
              request.setAttribute("error","添加客户信息失败!");
              return mapping.findForward("error");
          }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    (3)编写添加客户信息的CustomerDAO类的方法
    添加客户信息使用的customerDAO类的方法是insert()。在insert()方法中,首先从数据表tb_customer中查询输入的客户全称是否存在,如果存在,将标志变最设置为2,否则将输入的信息保存到客户信息表中,并将返回值赋给标志变量,最后返回标志变量。Insert()方法的具体代码如下:

    public int insert(CustomerForm cF) {
          String sql1="SELECT * FROM tb_customer WHERE name='"+cF.getName()+"'";
          ResultSet rs = conn.executeQuery(sql1);
          String sql = "";
          int falg = 0;
              try {
                  if (rs.next()) { falg=2;} else {
                      sql = "INSERT INTO tb_customer (id,name,address,area,postcode,mobileTel,email,bankName,bankNo,linkName) values(null,'" + cF.getName() + "','" +cF.getAddress() +"','"+cF.getArea()+"','"+cF.getPostcode()+"','"+cF.getMobileTel()+"','"+ cF.getEmail()+"','"+cF.getBankName()+"','"+cF.getBankNo()+"','"+cF.getLinkName()+"')";
                      falg = conn.executeUpdate(sql);
                      System.out.println("添加客户信息的SQL:" + sql);
                        conn.close();
                  }
              } catch (SQLException ex) { falg=0;}
          return falg;
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    (4)Struts-config.xml文件配置
    在struts-config.xml文件中配置添加客户信息所涉及的<forward>元素。代码如下:

    <forward name="managerAdd" path="/manager_ok.jsp?para=1" />
    
    • 1

    4.4.5 删除客户信息的实现过程
    在删除客户信息的方法customerDel()中,首先需要将接收到的表单信息强制转换成ActionForm类型,并用获得的记参数的值重新设置该ActionForm的setId()方法,再调用customerDAO类中的delete()方法,删除指定的客户信息,并根据执行结果将页面转到相应页面.删除客户信息的方法customerDel()的具体代码如下:

     private ActionForward customerDel(ActionMapping mapping, ActionForm form,
                  HttpServletRequest request, HttpServletResponse response) {
         CustomerForm customerForm = (CustomerForm) form;
         customerForm.setID(Integer.parseInt(request.getParameter("id")));
         int ret = customerDAO.delete(customerForm);
         if (ret != 0) {
             request.setAttribute("error","删除客户信息失败!!");
             return mapping.findForward("error");
         } else { return mapping.findForward("customerDel"); }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    删除客户信息使用的CustomerDAO类的方法是delete()。在delete()方法中,将从客户信息表tb_customer中删除符合条件的数据,并返回执行结果。delete()方法的具体代码如下:

    public int delete(CustomerForm customerForm) {
    int flag=0;
    try{
      String sql = "DELETE FROM tb_customer where id=" + customerForm.getID() +"";
        flag = conn.executeUpdate(sql);
    }catch(Exception e){
    		System.out.println("删除客户信息时产生的错误:"+e.getMessage());
        }finally{	conn.close();	//关闭数据库连    }
        return flag;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在struts-config.xml文件中配置添加客户信息所涉及的<forward>元素。代码如下:

    <forward name="managerDel" path="/manager_ok.jsp?para=3" />
    
    • 1

    4.5 发送短信模块设计
    4.5.1 发送短信模块功能概述
    发送短信模块主要包括发送短信、查看发送日志两个功能。这两个功能之间的业务流程如图4-8 所示。

    在这里插入图片描述

    图4-8 业务流程图

    发送短信模块是企业快信系统的核心模块之一,操作员可以通过该模块对企业内部的所有或者部分员工,以短信的形式发送企业通知、工资条、具体技术、开会等信息,并且这个信息是群体发送的。

    4.5.2 发送短信的实现过程
    发送短信使用的数据表:tb_shortLetter、tb_shortIfo、tb_info、tb_infoType、tb_customer和tb_personnel。
    管理员登录后,选择“发送短信”命令,进入到发送短信页面。在该页面中展开“名片夹”中的客户列表或员工列表,将显示相应的客户名称或员工姓名,单击指定的客户名称或员工姓名,系统会自动将该客户或员工的手机号码添加到右侧的“接收方手机号码”文本框中。如果用户想从信息库中选择常用短语直接添加到“短信内容”文本框中,可以先在“添加常用短语”下拉列表框中选择相应的类别,然后单击“确定”按钮,在打开的网页对话框中单击要添加的信息,即可将该信息添加到“短信内容”文本框中。短信内容填写完毕,单击“发送”按钮即可发送。发送短信页面的运行效果如图图4-9 所示。

    在这里插入图片描述

    图4-9 企业快信的短信发送界面

    4.5.3 发送短信模块技术分析
    在实现发送短信模块时,需要编写发送短信模块对应的ActionForm类和Action实现类。下面将详细介绍如何编写发送短信模块的ActionForm类和创建发送短信的Action实现类。
    (1) 编写收发短信的ActionForm类
    在发送短信模块中,涉及到tb_shortLetter(短信表)、tb_customer(客户信息表)、tb_personnel(员工信息表)、tb_shortInfo(常用短语表)、tb_infoType(信息类型表)和tb_Parameter(系统参数表)6个数据表,与这6个数据表相对应的ActionForm类分别为ShortLetterForm、CustomerForm、PerrsonnelForm、shortInfoForm、InfoTypyForm、ParameterForm,这些类都是由属性及对应的getXXX()和setXX()方法组成,不再详细介绍。

    (2) 创建发送短信的Action类
    收发短信模块的Action实现类SendLetter维承了Action类.在该类中.首先需要在该类的构造方法中分别实例化收发短信模块的SendLetterDAO类、员工管理摸块的PersonnelDAO类、客户管理模块的CustomerDAO类和信息类别管理模块的InfoTypeDAO类。Action实现类的主要方法是execute(),该方法会被自动执行其本身没有具体的事务,是根据HttpServletRequest的getParameter()方法获取的Action参数值执行相应方法的。发送短信模块Action实现类的关健代码如下:

    public class SendLetter extends Action{
        private SendLetterDAO sendLetterDAO = null;
        private PersonnelDAO personnelDAO=null;
        private CustomerDAO customerDAO=null;
        private InfoTypeDAO infoTypeDAO=null;
        private ChStr chStr=new ChStr();
        public SendLetter() {
            this.sendLetterDAO = new SendLetterDAO();
            this.personnelDAO=new PersonnelDAO();
            this.customerDAO=new CustomerDAO();
            this.infoTypeDAO=new InfoTypeDAO();
        }	
    	public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response){
            String action = request.getParameter("action");
            System.out.println("获取的查询字符串:" + action);
            if (action == null || "".equals(action)) {
            	request.setAttribute("error","您的操作有误!");
                return mapping.findForward("error");
            }else if ("addLetter".equals(action)) {
                return addLetter(mapping, form, request,response);
            }else if("sendLetter".equals(action)){
                return sendLetter(mapping, form, request,response);
            }else if("historyQuery".equals(action)){
            	return queryHistory(mapping, form, request,response);
            }
    			request.setAttribute("error", "操作失败!");
    			return mapping.findForward("error");
    	}
        //编写短信页面应用的查询方法,用于查询收信人列表信息类别
        private ActionForward addLetter(ActionMapping mapping, ActionForm form,
                  HttpServletRequest request,HttpServletResponse response) {
            request.setAttribute("personnelQuery",personnelDAO.query(0));
            request.setAttribute("customerQuery",customerDAO.query(0));
            request.setAttribute("shortInfo",infoTypeDAO.query(0));
            return mapping.findForward("addLetter");
        }
        //群发短信
        private ActionForward sendLetter(ActionMapping mapping, ActionForm form,
                   HttpServletRequest request,HttpServletResponse response){
        	SendLetterForm sendLetterForm=(SendLetterForm) form;
        	sendLetterForm.setContent(chStr.toChinese(sendLetterForm.getContent()));
        	sendLetterForm.setFromMan(chStr.toChinese(sendLetterForm.getFromMan()));
            String ret=sendLetterDAO.sendLetter(sendLetterForm);
            if(ret.equals("ok")){
            	return mapping.findForward("sendLetter");
            }else{
                request.setAttribute("error",ret);
                return mapping.findForward("error");
            }
        }
        //查看历史记录
        private ActionForward queryHistory(ActionMapping mapping, ActionForm form,
                  HttpServletRequest request, HttpServletResponse response) {
            request.setAttribute("history",sendLetterDAO.query());
            return mapping.findForward("queryHistory");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    (3) 编写发送短信的SendLetterDAO类的方法
    发送短信使用的sendLetterDAO类的方法是sendLetter()。在sendLettr()方法中,首先从数据表tb_parameter中查询出系统参数(即使用飞信接口发送短信所使用的端口、帐号、密码等参数),然后调用发送短信的方法mySend(),最后将发送短信的日志信息保存到数据表tbshortLetter中。sendLetter()方法的具体代码如下:

    public class SendLetterDAO {
    	private ConnDB conn=new ConnDB();
    	List parameter = ParameterDAO.query();
    	ParameterForm parameterForm = (ParameterForm) parameter.get(0);
    	private smssend smssendinformation = null;
    	// 发送短信
    	public String sendLetter(SendLetterForm s) {
    		String ret = "";
    		String info="";
    		String sendnum="";
    		String flag="";
    		try {
    			String sql_p="SELECT  * FROM tb_parameter";
    			ResultSet rs=conn.executeQuery(sql_p);
    			if(rs.next()){
    				String phone=parameterForm.getDevice();
    	    		String pwd=parameterForm.getBaud();
    				info=s.getContent();
    				sendnum=s.getToMan();
    				flag=mySend(phone,pwd,sendnum,info);//发送短信
    				if(flag.equals("ok")){
    		            String sql = "INSERT INTO tb_shortLetter values(null,'" +s.getToMan() +"','"+s.getContent()+"','"+s.getFromMan()+"',now())";
    		            int r= conn.executeUpdate(sql);
    		            System.out.println("添加短信发送历史记录的SQL:" + sql);
    		            if(r==0){
    		            	ret="添加短信发送历史记录失败!";
    		            }else{
    		            	ret="ok";
    		            }
    				}else{
    					ret=flag;
    				}				
    			}else{
    				ret="发送短信失败!";
    			}
    		} catch (Exception e) {
    			System.out.println("发送短信产生的错误:" + e.getMessage());
    			ret = "发送短信失败!";
    		}finally{
    			conn.close();
    		}
    		return ret;
    	}
    	public static String mySend(String phone,String pwd,String to,String msg) throws HttpException, IOException{ 
    		String ret="";
            HttpClient client = new HttpClient();  
            PostMethod post = new PostMethod("http://quanapi.sinaapp.com/fetion.php");
    post.addRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");//在头文件中设置转码   
            NameValuePair[] data ={   
                   new NameValuePair("u", phone),  
                   new NameValuePair("p", pwd),  
                   new NameValuePair("to",to),  
                   new NameValuePair("m",msg),  
                   };  
            post.setRequestBody(data);  
            client.executeMethod(post);  
            Header[] headers = post.getResponseHeaders();  
            int statusCode = post.getStatusCode();  
            System.out.println("statusCode:"+statusCode);  
            for(Header h : headers){  
                System.out.println(h.toString());  
            }  
            post.releaseConnection();
            ret = "ok";
            return ret;} 
        //中间省略查询日志的代码
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    (4) struts-config.xml文件配置
    在struts-config.xml文件中配置发送短信所设计的元素。代码如下:

    <forward name=”sendLetter” path=/sendLetter_ok.jsp”/>
    
    • 1

    4.5.4 单元测试
    在开发完收发短信模块后,为了保证程序正常运行,要对模块进行单元测试.单元测试在程序开发中非常重要,只有通过单元测试才能发现模块中的不足之处,才能及时地纠正程序中出现的错误。进入到发送短信页面,在“接收方手机号码”文本框中
    输入相应的手机号码(多个手机号码间用逗号分隔),在“短信内容”文本框中输入短信内容后,单击“发送”按钮,正常情况下,会弹出“短信发送成功”的提示对话框,如果发送失败,则会弹出“短信发送失败”的提示对话框。

    4.6 发送邮件模块设计
    4.6.1 发送邮件模块功能概述
    发送邮件模块也是企业快信系统的核心模块之一,操作员可以通过该模块对企业内部的所有或者部分员工,以E-mail 电子邮件的形式发送企业通知、工资条等。另外,由于E-mail 有信息容量大、包含附件的两大优点,使它支持更多的信息内容,可以携带更丰富的资料,比较适合发送技术信息、会议主题、工作内容等信息,并且这个信息是群体发送的。该模块的运行效果如图4-10 所示。

    在这里插入图片描述

    图4-10 企业快信的邮件发送界面

    4.6.2 发送邮件模块技术分析
    在实现邮件发送模块时,需要编写邮件发送模块对应的ActionForm类和Action实现类。下面将详细介绍如何编写邮件发送模块的ActionForm类和创建邮件发送的Action实现类。
    (1) 编写邮件群发的ActionForm类
    虽然在邮件发送模块中,只涉及到tb_customer(客户信息表)和tb_personnel(员工信息表)两个数据表,但是邮件群发并不是只涉及到与这两个数据表相对应的ActionForm类–CustomerForm和PcrsonnelForm,本模块中还涉及到用于获取发送邮件所需的表单信息的ActionForm类―sendMailForm.
    (2) 创建邮件发送的Action实现类
    邮件发送模块的Action实现类SendMail继承了Action类。在该类中,首先需要在该类的构造方法中分别实例化邮件发送模块的SendMailDAO类、员工管理模块的PersonnelDAO类和客户管理模块的customerDAO类.Action实现类的主要方法是execute(),该方法会被自动执行.这个方法本身没有具体的事务,它是根据HttpServletRequest的getParameter()方法获取的action参数值执行相应方法的。邮件发送模块Action实现类的关键代码如下:

    public class SendMail extends Action{
        private SendMailDAO sendMailDAO = null;
        private PersonnelDAO personnelDAO=null;
        private CustomerDAO customerDAO=null;
        private ChStr chStr=new ChStr();
        public SendMail() {
            this.sendMailDAO = new SendMailDAO();
            this.personnelDAO=new PersonnelDAO();
            this.customerDAO=new CustomerDAO();
        }	
    	public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response){
            String action = request.getParameter("action");
            System.out.println("获取的查询字符串:" + action);
            if (action == null || "".equals(action)) {
         request.setAttribute("error","您的操作有误!");	//将错误信息保存到error中
                return mapping.findForward("error");	//转到显示错误信息的页面
            }else if ("addMail".equals(action)) {
                return addMail(mapping, form, request,response);
            }else if("sendMail".equals(action)){
                return sendMail(mapping, form, request,response);
            }
    			request.setAttribute("error", "操作失败!");
    			return mapping.findForward("error");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    4.6.3 发送邮件模块实现过程
    (1) 发送邮件的Action实现类
    在邮件群发页面中填写相应的邮件信息后,单击“发送”按钮,网页会访问一个URL,即sendMail.do?action=sendMail。从该URL地址中可以知道发送邮件时涉及到的action的参数值为sendMail,也就是当action=sendMail时,会调用群发邮件的方法sendMail()。具体代码如下:

    if("sendMail".equals(action)){
          return sendMail(mapping, form, request,response);
    }
    
    • 1
    • 2
    • 3

    在发送邮件的方法sendMail()中,首先需要将接收到的表单信息强制转换成ActionForm类型,并用获得指定属性的getXXX()方法获取主题、附件、内容属性并进行转码后,再使用setXXX()方法重新设置该属性,然后调用SendMailDAO类中的sendMail()方法发送邮件,并将返回值保存到变量ret中。如果返回值为ok,则表示邮件发送成功,将页面重定向到邮件发送成功页面:否则,将错误提示信息保存到HttpservletRequest对象的errror参数中,并且将页面重定向到错误提示信息页面.群发邮件的方法sendMail()的具体代码如下:

    private ActionForward sendMail(ActionMapping mapping, ActionForm form,
    HttpServletRequest request,HttpServletResponse response){
         SendMailForm sendMailForm=(SendMailForm) form;
         sendMailForm.setTitle(chStr.toChinese(sendMailForm.getTitle()));
         sendMailForm.setAdjunct(chStr.toChinese(sendMailForm.getAdjunct()));
         sendMailForm.setContent(chStr.toChinese(sendMailForm.getContent()));
         int ret=sendMailDAO.sendMail(sendMailForm);
         if(ret==0){
             request.setAttribute("error","邮件发送失败!");
             return mapping.findForward("error");
         }else{
             return mapping.findForward("sendMail");
         }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    (2) 编写发送邮件的SendMailDAO类的方法
    发送邮件使用的SendMailDA0类的方法是sendMail()。具体代码如下:

    public int sendMail(SendMailForm s) {
    	int ret = 0;
    	String from = s.getAddresser();
    	String to = s.getAddressee();
    	String subject = s.getTitle();
    	String content = s.getContent();
    	String password = s.getPwd();
    	String path = s.getAdjunct();
    	try {
    	String mailserver ="smtp."+from.substring(from.indexOf('@')+1,from.length());	//在Internet上发送邮件时的代码
    	Properties prop = new Properties();
    	prop.put("mail.smtp.host", mailserver);
    	prop.put("mail.smtp.auth", "true");
    	Session sess = Session.getDefaultInstance(prop);
    	sess.setDebug(true);
    	MimeMessage message = new MimeMessage(sess);
    	message.setFrom(new InternetAddress(from));	// 给消息对象设置发件人
    	//设置收件人
    	String toArr[]=to.split(",");
    	InternetAddress[] to_mail=new InternetAddress[toArr.length];
    	for(int i=0;i<toArr.length;i++){
    		to_mail[i]=new InternetAddress(toArr[i]);
    	}
    	   message.setRecipients(Message.RecipientType.BCC,to_mail);
    	//设置主题
    	message.setSubject(subject);
    	Multipart mul = new MimeMultipart(); // 新建一个MimeMultipart对象来存放多个BodyPart对象
    	BodyPart mdp = new MimeBodyPart(); // 新建一个存放内容的BodyPart对象
    	mdp.setContent(content, "text/html;charset=gb2312");
    	mul.addBodyPart(mdp); // 将含有信件内容的BodyPart加入到MimeMulitipart对象中
    	if(!path.equals("") && path!=null){	//当存在附件时
    		// 设置信件的附件(用本机上的文件作为附件)
    		mdp = new MimeBodyPart(); // 新建一个存放附件的BodyPart
    		String adjunctname = new String(path.getBytes("GBK"), "ISO-8859-1"); // 此处需要转码,否则附件中包括中文时,将产生乱码
    		path = (System.getProperty("java.io.tmpdir") + "/" + path).replace("\\", "/");
    		System.out.println("路径:" + path);
    		FileDataSource fds = new FileDataSource(path);
    		DataHandler handler = new DataHandler(fds);
    		mdp.setFileName(adjunctname);
    		mdp.setDataHandler(handler);
    		mul.addBodyPart(mdp);
    	}
    	message.setContent(mul); // 把mul作为消息对象的内容
    	message.saveChanges();
    	Transport transport = sess.getTransport("smtp");
    	// 以smtp方式登录邮箱,第1个参数是发送邮件用的邮件服务器SMTP地址,第2个参数为用户名,第3个参数为密码
    	transport.connect(mailserver, from, password);
    	transport.sendMessage(message, message.getAllRecipients());
    	transport.close();
    	ret = 1;
    	} catch (Exception e) {
    	e.printStackTrace();
    	System.out.println("发送邮件产生的错误:" + e.getMessage());
    	ret = 0;	}
    	return ret;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    4.6.4 单元测试
    在开发完邮件群发模块后,为了保证程序正常运行,一定要对模块进行单元测试,下面是原始的实现邮件发送的代码:

    if(!path.equals("") && path!=null){	//当存在附件时
    	// 设置信件的附件(用本机上的文件作为附件)
    	mdp = new MimeBodyPart(); // 新建一个存放附件的BodyPart
    	String adjunctname=path;
    	path = (System.getProperty("java.io.tmpdir") + "/" + path).replace("\\", "/");
    	System.out.println("路径:" + path);
    	FileDataSource fds = new FileDataSource(path);
    	DataHandler handler = new DataHandler(fds);
    	mdp.setFileName(adjunctname);
    	mdp.setDataHandler(handler);
    	mul.addBodyPart(mdp);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    通过上面的代码实现的邮件群发会存在以下问题:当发送带有中文名称的邮件后.使用Outlook软件接收邮件时,附件的名称将产生乱码。这是因为在邮件群发的Action类中,己经将接收到的附件名称转换为GBK编码格式,而在OutLook接收附件时,采用的编码格式为ISO-8859-1,所以此处还需要将其转换为巧IOS-8859-1编码格式。那为什么还要在Action类中进行转码呢?这是因为如果不进行转换,在类中通过文件名获取文件路径时,将不能正常获取。修改后的完成邮件群发的代码如下:

    if(!path.equals("") && path!=null){	//当存在附件时
    	// 设置信件的附件(用本机上的文件作为附件)
    	mdp = new MimeBodyPart(); // 新建一个存放附件的BodyPart
    	String adjunctname = new String(path.getBytes("GBK"), "ISO-8859-1"); // 此处需要转码,否则附件中包括中文时,将产生乱码
    	path = (System.getProperty("java.io.tmpdir") + "/" + path).replace("\\", "/");
    	System.out.println("路径:" + path);
    	FileDataSource fds = new FileDataSource(path);
    	DataHandler handler = new DataHandler(fds);
    	mdp.setFileName(adjunctname);
    	mdp.setDataHandler(handler);
    	mul.addBodyPart(mdp);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    5 技术分析
    5.1 开发技巧与难点分析
    5.1.1 添加收信人
    为了方便用户,系统中需要提供通过单击客户列表(或员工列表)中的客户全称(或员工姓名),即可将该客户(或员工)的联系手机号码添加到“接收方手机号码”文本框中的功能。实现该功能时.需要编写自定义的JavaScript函教add(),在该函数中需要对手机号码进行验证并实现累加手机号码到“接收方手机号码”文本框中的功能。Add()函数的具体代码如下:

    function add(mobileTel){
    	if(checkTel(mobileTel)){
    		s=form1.toMan.value;
    		if(s.length>=11){
    			arrS=s.split(",");
    			flag=false;		//标记是否已经添加
    			for(i=0;i<arrS.length;i++){
    				if(arrS[i]==mobileTel){	//判断该手机号码是否已经添加
    					flag=true;
    					break;
    				}
    			}
    			if(!flag){
    				form1.toMan.value=s+","+mobileTel;
    			}
    		}else{form1.toMan.value=mobileTel;}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    5.1.2 插入短信
    为了方便用户,系统中需要提供将信息库中保存的常用短语添加到“短信内容”文本框中的功能。实现该功能的具体步骤如下:
    (1)在发送短信页面的“添加常用短语”下拉列表框的右侧添加一个“确定”按钮,在该按钮的onClick事件中调用自定义的Javascript函数deal()。关键代码如下:

    function deal(infoType,text){
    	var someValue;
    var str="window.showModalDialog('shortInfo.do?action=selectShortInfo&id="+infoType+"','','dialogWidth=520px;\
    	dialogHeight=430px;status=no;help=no;scrollbars=no')";
    	someValue=eval(str);
    	if(someValue!=undefined){text.value=text.value+someValue;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (2)创建选择指定类别的常用短语的页面selectShortInfo.jsp,并且在该页面中添加用于将选择的常用短语返回到打开该窗口的交量,并且关闭当前窗口的自定义JavaScript函数selectInfo().selectInfo()函数的具体代码如下:

    <script language="javascript">
    	function selectInfo(info){
    		window.returnValue=info;
    		window.close();}
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    (3)在selectShortInfo.jsp中显示常用短语的代码上添加一个空的超链接,并且在其onClick事件中调用selectInfo()函数。具体代码如下:
    <%=s.getContent()%>

    5.2 使用Java Mail 组件
    省略

    结 论
    通过一个典型实用的企业快信应用系统,系统地介绍了如何利用JSP应用程序,实现群发手机短信和群发电子邮件的方法。在实现该企业快信系统时,还添加了几个方便用户使用的功能,例如利用名片夹管理名片信息,以及利用信息库管理信息模板,这样用户就不用反复地填写收信人列表以及编写重复的信息了。

    该系统从问题定义到可行性研究、需求分析、总体设计、详细设计直到最后的系统测试,基本上实现了设计要求的各项功能。实现了名片夹管理、信息库管理、短信发送、邮件群发、系统设置等功能。每个模块都提供了相关的数据库操作,如增、删、查、改。在开发中,采用了 MySQL 数据库、JAVA MAIL 组件技术。短信群发,邮件群发能做到为企业提供实际的应用服务。

    本系统的特点是利用飞信API的原理及方法,实现对单人或多人进行发送短信并利用 JAVA MAIL API 组件的一些类方法实现了邮件群发功能,方便了企业内部之间沟通交流更加方便快捷。但由于时间有限,系统还有很多不足之处。比如系统界面设计不够美观,我会在以后的学习和工作之余不断完善。

    参考文献
    [1] 刘春.企业级JavaMail在Oracle系统中部署[J]. 指挥信息系统与技术,2013,(01)
    [2] 邱宏茂,许朝阳,盖磊. 基于JavaMail的Web Mail系统的实现 [J].计算机应用与软件, 2005,(06)
    [3] 王文帅,张红梅.基于JavaMail的点对点邮件批量发送系统 [D]. 第14届全国计算机、网络在现代科学技术领域的应用学术会议,2009
    [4] 刘芳. 基于短信猫的短信发送平台的设计与实现 [J]. 电脑知识与技术,2013,(31)
    [5] 原泉,蔡晶.针对短信猫接收短信的安全风险分析 [J]. 计算机安全, 2013,(06)
    [6] 徐宇斐.企业快信系统的设计与实现 [D].吉林大学,(2013)
    [7] 路高鹏.短信群发软件的设计与实现 [J].计算机与网络,2013,(05)
    [8] Ratecki, Krzysztof; Sakowicz, Bartosz.Configurable client email application working as web page [R] .MODERN PROBLEMS OF RADIO ENGINEERING, TELECOMMUNICATIONS AND COMPUTER SCIENCE, PROCEEDINGS,2006,(06)
    [9] Kuantama, Endrowednes; Mardjoko, Pono.Design and Construction of Early Flood Warning System Through SMS based on SIM300C GSMModem [R]. (ICICI-BME) ,2013,(03)
    [10] Lv, Fangxing; Xie, Xiaoyao; Zhang, Cuicui. Research and Development of E-mail Program Based on Java [J]. PROCEEDINGS OF THE 3RD INTERNATIONAL CONFERENCE ON ANTI-COUNTERFEITING, SECURITY, AND IDENTIFICATION IN COMMUNICATION,2009

    致 谢
    省略

    外文原文
    省略

    外文翻译
    省略


    5、资源下载

    本项目源码及完整论文如下,有需要的朋友可以点击进行下载

  • 相关阅读:
    PostMan、ApiFox等工具Post请求中@RequestParam和@RequestBody的混合使用如何传参
    【SpringCloud-学习笔记】Nacos配置管理
    priority_queue
    红细胞膜载近红外荧光染料IR780的壳膜/细胞膜荧光染料CM-Dil标记BMSCs的制备
    【毕业设计】大数据客户价值分析(RFM模型)
    【Arduino25】液晶模拟值实验
    详解对于ReadView 机制如何判断当前事务能够看见
    使用 FastAPI 实现服务端的 CRUD
    视频超分之BasicVSR++阅读笔记
    JavaSE之注解
  • 原文地址:https://blog.csdn.net/m0_66238867/article/details/125623668