最近刚做完的需求中有通过导入文本文件后,系统将文本文件中的数据保存到数据库中的要求。首先设计数据库,SQL如下:
DROP TABLE IF EXISTS `complaint_phone_to_sim`; CREATE TABLE `complaint_phone_to_sim` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '编号', `user_phone` varchar(13) NOT NULL COMMENT '用户手机号', `is_execute` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否被执行过,0未被执行,1被执行过', `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立时间', PRIMARY KEY (`id`), UNIQUE KEY `user_phone_index` (`user_phone`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
开始编写一个名为ComplaintPhoneToSim类,用于封装,具体代码如下:
package com.astep.yunpay.model.complaint; import java.io.Serializable; import java.util.Date; /** * @author:DJM */ public class ComplaintPhoneToSim implements Serializable { private static final long serialVersionUID = 1L; /*Fields*/ private Long id; private String userPhone; private Integer isExecute; private Date createTime; /*Method of getters and setters*/ public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUserPhone() { return userPhone; } public void setUserPhone(String userPhone) { this.userPhone = userPhone; } public Integer getIsExecute() { return isExecute; } public void setIsExecute(Integer isExecute) { this.isExecute = isExecute; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } /*Method of toString*/ @Override public String toString() { return "ComplaintPhoneToSim [id=" + id + ", userPhone=" + userPhone + ", isExecute=" + isExecute + ", createTime=" + createTime + "]"; } }
系统使用的是MyBatis,具体配置文件如下:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="complaint_phone_to_sim"> <resultMap id="BaseResultMap" type="com.astep.yunpay.model.complaint.ComplaintPhoneToSim"> <id column="id" property="id" jdbcType="BIGINT"/> <result column="user_phone" property="userPhone" jdbcType="VARCHAR"/> <result column="is_execute" property="isExecute" jdbcType="INTEGER" /> <result column="create_time" property="createTime" jdbcType="TIMESTAMP" /> </resultMap> <sql id="Base_Column" > <![CDATA[ id, user_phone, is_execute, create_time ]]> </sql> <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long"> select <include refid="Base_Column"/> from complaint_phone_to_sim where id = #{id} </select> <delete id="deleteByPrimaryKey" parameterType="java.lang.Long"> delete from complaint_phone_to_sim where id = #{id} </delete> <insert id="insert" parameterType="com.astep.yunpay.model.complaint.ComplaintPhoneToSim"> <![CDATA[ insert into complaint_phone_to_sim (user_phone, is_execute, create_time) values (#{userPhone,jdbcType=VARCHAR}, #{isExecute,jdbcType=INTEGER}, now()) ]]> </insert> <update id="updateByPrimaryKeySelective" parameterType="com.astep.yunpay.model.complaint.ComplaintPhoneToSim"> update complaint_phone_to_sim <set> <if test="userPhone != null"> user_phone=#{userPhone,jdbcType=VARCHAR}, </if> <if test="isExecute != null"> is_execute = #{isExecute,jdbcType=INTEGER}, </if> </set> where id = #{id} </update> <update id="updateIsExecute" parameterType="java.lang.Integer"> update complaint_phone_to_sim <set> <if test="isExecute != null"> is_execute = #{isExecute,jdbcType=INTEGER}, </if> </set> </update> <select id="countByPhone" parameterType="java.util.HashMap" resultType="java.lang.Integer"> <![CDATA[ select count(1) from complaint_phone_to_sim ]]> <trim prefix="where" prefixOverrides="and"> <if test="userPhone!=null"> user_phone = #{userPhone,jdbcType=INTEGER} </if> <if test="isExecute!=null"> and is_execute = #{isExecute,jdbcType=INTEGER} </if> </trim> </select> <select id="getList" resultMap="BaseResultMap"> <![CDATA[ SELECT * FROM complaint_phone_to_sim ]]> <trim prefix="where"> <if test="isExecute!=NULL"> is_execute = #{isExecute,jdbcType=INTEGER} </if> </trim> <![CDATA[order by id desc ]]> </select> </mapper>
由于早有封装BaseDao的类,Dao层和Service层在此省略。我写了一个名为UploadServlet的类,具体代码如下:
package com.astep.yunpay.action.complaint; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import com.astep.common.util.SpringUtils; import com.astep.yunpay.model.complaint.ComplaintPhoneToSim; import com.astep.yunpay.service.complaint.impl.ComplaintPhoneToSimService; /** * @author DJM * @CreateDate:2015-07-03 10:20:20 * @Deprecated:Upload the file */ public class UploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; public static final String TempFileDir = "temp"; @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ComplaintPhoneToSimService complaintPhoneToSimService = (ComplaintPhoneToSimService) SpringUtils.getBean("complaintPhoneToSimService"); //创建一个基于硬盘的FileItem工厂类 DiskFileItemFactory factory = new DiskFileItemFactory(); //设置向硬盘写数据时所用的缓冲区的大小,此处为5K factory.setSizeThreshold(5*1024); factory.setRepository(new File(System.getProperty("user.dir"))); //创建一个文件上传处理器 ServletFileUpload servletFileUpload = new ServletFileUpload(factory); //设置允许上传的文件的最大SIZE,此处为2M servletFileUpload.setSizeMax(2*1024*1024); try { @SuppressWarnings("unchecked") List<FileItem> fileItems = servletFileUpload.parseRequest(request); if(fileItems!=null&&fileItems.size()>0){ //遍历FileItem for(FileItem fileItem: fileItems){ //筛选掉普通表单域类型 if(!fileItem.isFormField()){ //筛选掉文件不为文本文件或者文件名为空或者文件大小不在0M至2M之间 if(!fileItem.getName().equals("")&&fileItem.getSize()>0&&fileItem.getSize()<(2*1024*1024)&&fileItem.getName().toLowerCase().endsWith(".txt")){ File dirFile = new File(System.getProperty("user.dir")+File.separator+TempFileDir); //判断文件目录是否存在,若不存在,则创建目录 if(!dirFile.exists()){ dirFile.mkdir(); } File file = new File(dirFile, fileItem.getName()); //判断文件是否存在,若不存在,则创建文件 if(!dirFile.exists()){ file.createNewFile(); } //将FileItem中的数据写入到文件file中 try { fileItem.write(file); } catch (Exception e1) { e1.printStackTrace(); } //按行读取File中的数据 FileReader fileReader = new FileReader(file); BufferedReader reader = new BufferedReader(fileReader); String tempString = null; while((tempString=reader.readLine())!=null){ tempString = tempString.trim(); //过滤空行 if(tempString==null||tempString.equals("")){ continue; } //检查文本内容是否违法 Pattern pt = Pattern.compile("^[0-9]{11}$"); Matcher mt = pt.matcher(tempString); if(!mt.matches()){ continue; } //避免表complaint_phone_to_sim中存在相同的用户手机号 Map<String, Object> conditions = new HashMap<String, Object>(); conditions.put("userPhone", tempString); Integer recordNumber = complaintPhoneToSimService.census(conditions, "countByPhone"); if(recordNumber.intValue()!=0){ continue; } ComplaintPhoneToSim complaintPhoneToSim = new ComplaintPhoneToSim(); complaintPhoneToSim.setUserPhone(tempString); complaintPhoneToSim.setIsExecute(0); complaintPhoneToSim.setCreateTime(new Date()); complaintPhoneToSimService.insert(complaintPhoneToSim); } reader.close(); fileReader.close(); } } } } } catch (FileUploadException e) { e.printStackTrace(); } } }
必须在web.xml中配置Servlet,具体配置如下:
<!-- 上传文件 --> <servlet> <servlet-name>uploadServlet</servlet-name> <servlet-class>com.astep.yunpay.action.complaint.UploadServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>uploadServlet</servlet-name> <url-pattern>/complaint/comprehensive/djm</url-pattern> </servlet-mapping>
前端页面使用的是HTML5跨屏前端框架Amaze UI框架,具体代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML> <html class="no-js"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="description" content="DJM"> <meta http-equiv="keywords" content="DJM"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <title>投诉处理</title> <!-- Set render engine for 360 browser --> <meta name="renderer" content="webkit"> <!-- No Baidu Siteapp--> <meta http-equiv="Cache-Control" content="no-siteapp"/> <link rel="icon" type="image/png" href="${basePath}js/AmazeUI-2.4.1/assets/i/favicon.png"> <!-- Add to homescreen for Chrome on Android --> <meta name="mobile-web-app-capable" content="yes"> <link rel="icon" sizes="192x192" href="${basePath}js/AmazeUI-2.4.1/assets/i/[email protected]"> <!-- Add to homescreen for Safari on iOS --> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="apple-mobile-web-app-title" content="Amaze UI"/> <link rel="apple-touch-icon-precomposed" href="${basePath}js/AmazeUI-2.4.1/assets/i/[email protected]"> <!-- Tile icon for Win8 (144x144 + tile color) --> <meta name="msapplication-TileImage" content="${basePath}js/AmazeUI-2.4.1/assets/i/[email protected]"> <meta name="msapplication-TileColor" content="#0e90d2"> <link rel="stylesheet" href="${basePath}js/AmazeUI-2.4.1/assets/css/amazeui.min.css"> <link rel="stylesheet" href="${basePath}js/AmazeUI-2.4.1/assets/css/app.css"> </head> <body> <!-- 导入文件面板 --> <div class="am-panel am-panel-primary" style="width:99.9%;"> <div class="am-panel-hd"><i class="am-icon-file-text"></i> 导入文件</div> <div class="am-panel-bd"> <form class="am-form" id="uploadTxt" action="djm" method="post" enctype="multipart/form-data"> <fieldset> <div class="am-form-group am-form-file"> <label for="doc-ipt-file-2">投诉号码TXT文件上传</label> <div> <button type="button" class="am-btn am-btn-default am-btn-sm"> <i class="am-icon-cloud-upload"></i> 选择要上传的文件</button> </div> <input type="file" id="doc-ipt-file-2" name="uploadFile"> </div> <hr data-am-widget="divider" style="" class="am-divider am-divider-default"/> <div> <button id="mykey" type="submit" class="am-btn am-btn-default am-radius" data-am-modal="{target: '#my-confirm'}"> <span class="am-icon-check">开始导入</span> </button> </div> </fieldset> </form> </div> </div> <!-- 导入进度 --> <div class="am-panel am-panel-primary" style="width:99.9%;"> <div class="am-panel-hd"><i class="am-icon-refresh"></i> 导入进度</div> <div class="am-panel-bd"> <div class="am-progress am-progress-xs am-progress-striped am-active"> <div class="am-progress-bar am-progress-bar-danger" id="myProgress" style="width: 0%"></div> </div> </div> </div> <!-- 投诉号码处理后产生的投诉详细信息的邮件接收人 --> <div class="am-panel am-panel-primary" style="width:99.9%;"> <div class="am-panel-hd"><i class="am-icon-send-o"></i> 邮件接收人设置</div> <div class="am-panel-bd"> <form class="am-form" id="sendMail" action="complaint_sendMail.do" method="post"> <fieldset> <div class="am-input-group am-input-group-warning"> <span class="am-input-group-label"><i class="am-icon-envelope"></i> 用于接收处理完成后的投诉详细信息邮箱</span> <input type="email" class="am-form-field" name="mailTo" placeholder="邮箱地址" required/> </div> <hr data-am-widget="divider" style="" class="am-divider am-divider-default"/> <button id="confirmMail" type="submit" class="am-btn am-btn-warning am-radius"> <span class="am-icon-check">确认邮箱</span> </button> </fieldset> </form> </div> </div> <!-- 投诉处理进度 --> <div class="am-panel am-panel-primary" style="width:99.9%;"> <div class="am-panel-hd"><i class="am-icon-refresh"></i> 投诉处理进度</div> <div class="am-panel-bd"> <div class="am-progress am-progress-xs am-progress-striped am-active"> <div class="am-progress-bar am-progress-bar-danger" id="complaintProgress" style="width: 0%"></div> </div> </div> </div> <!-- 模态窗口1 --> <div class="am-modal am-modal-confirm" tabindex="-1" id="my-confirm"> <div class="am-modal-dialog"> <div class="am-modal-hd">温馨提示</div> <div class="am-modal-bd"> 系统处理投诉信息耗时较长,建议输入您的邮箱,系统将会将处理完毕的信息发到您的邮箱地址。 </div> <div class="am-modal-footer"> <span class="am-modal-btn" data-am-modal-cancel>不好</span> <span class="am-modal-btn" data-am-modal-confirm>好的</span> </div> </div> </div> <!-- 模态窗口2 --> <div class="am-modal am-modal-confirm" tabindex="-1" id="emailPrompt"> <div class="am-modal-dialog"> <div class="am-modal-hd">温馨提示</div> <div class="am-modal-bd"> 等待系统处理投诉信息较长,建议关闭此页面,系统处理完投诉信息之后,自动会将文件会发送到您的邮箱地址。 </div> <div class="am-modal-footer"> <span class="am-modal-btn" data-am-modal-cancel>不好</span> <span class="am-modal-btn" data-am-modal-confirm>知道了</span> </div> </div> </div> <!--[if (gte IE 9)|!(IE)]><!--> <script src="${basePath}js/AmazeUI-2.4.1/assets/js/jquery.min.js"></script> <!--<![endif]--> <!--[if lte IE 8 ]> <script src="http://libs.baidu.com/jquery/1.11.3/jquery.min.js"></script> <script src="http://cdn.staticfile.org/modernizr/2.8.3/modernizr.js"></script> <script src="${basePath}js/AmazeUI-2.4.1/assets/js/amazeui.ie8polyfill.min.js"></script> <![endif]--> <script src="${basePath}js/AmazeUI-2.4.1/assets/js/amazeui.min.js"></script> <script src="${basePath}js/jquery/form/jquery.form.js"></script> <script type="text/javascript"> $(document).ready(function(){ var uploadFlag = 0; var complaintFlag = 0; var uploadInterval, complaintInterval; $("#mykey").bind("click", function(){ $(this).children("span").html("正在导入"); uploadInterval = setInterval(changeUploadProgress, 1000); }); function changeUploadProgress(){ uploadFlag++; $("#myProgress").attr("style", "width:"+uploadFlag+"%"); console.log("我还在执行"); if(uploadFlag>=100){ clearInterval(uploadInterval); $("#mykey").children("span").html("导入完毕"); } } $("#uploadTxt").ajaxForm(function(){ }); $("#sendMail").ajaxForm(function(){ }); $("#confirmMail").bind("click", function(){ complaintInterval = setInterval(changeComplaintProgress, 12*1000); $("#emailPrompt").modal({ onConfirm: function() { }, onCancel: function() { } }); }); function changeComplaintProgress(){ complaintFlag++; $("#complaintProgress").attr("style", "width:"+complaintFlag+"%"); console.log("我还在执行-complaint"); if(complaintFlag>=100){ clearInterval(complaintInterval); } } }); </script> </body> </html>
效果图如下: