基于Servlet完成的文件上传和下载
注意:这里采用的是servlet的注解方式,即要求在Servlet3.1版本以上。另,Tomcat7.0版本以上
建议最低采用如图所示环境进行开发!
开发环境如图:
采用 Jdk1.8 + Tomcat 9.0 + JavaEE 8.0 、开发工具采用的是IntellJ IDEA
1.创建实体类
package cn.javabs.demo.entity; /** * 资源文件 = 资源路径 + 资源名称 */ public class Source { private int id; private String author; private String sourceName;//资源名称 private String sourcePath;//资源路径 private int downCount; // 下载的次数 private String createTime ; @Override public String toString() { return "Source{" + "id=" + id + ", author='" + author + '\'' + ", sourceName='" + sourceName + '\'' + ", sourcePath='" + sourcePath + '\'' + ", downCount=" + downCount + ", createTime='" + createTime + '\'' + '}'; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getSourceName() { return sourceName; } public void setSourceName(String sourceName) { this.sourceName = sourceName; } public String getSourcePath() { return sourcePath; } public void setSourcePath(String sourcePath) { this.sourcePath = sourcePath; } public int getDownCount() { return downCount; } public void setDownCount(int downCount) { this.downCount = downCount; } public String getCreateTime() { return createTime; } public void setCreateTime(String createTime) { this.createTime = createTime; } }
2.1 创建工具类 - 数据库连接池
package cn.javabs.demo.utils; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.InputStream; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; /** * DruidUtils数据库连接池工具类设计 * @author Mryang */ public class DruidUtils { public static DataSource dataSource; static { try { String myFile = "druid.properties"; InputStream is = DruidUtils.class.getClassLoader().getResourceAsStream(myFile); Properties props = new Properties(); props.load(is); dataSource = DruidDataSourceFactory.createDataSource(props); } catch (Exception e) { throw new RuntimeException(e); } } /** * 获取数据源 * @return */ public static DataSource getDataSource(){ return dataSource; } /** * 通过数据源获取连接 * @return */ public static Connection getConnection(){ try { return dataSource.getConnection(); } catch (SQLException e) { throw new RuntimeException(e); } } }
2.2 创建工具类配置文件
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/testSource_demo username=root password=sorry
3.1 创建DAO接口
package cn.javabs.demo.dao; import cn.javabs.demo.entity.Source; import java.util.List; public interface SourceDao { /** * 添加资源 --- 上传 * @param source * @return */ int saveSource(Source source); /** * 删除资源 * @param id * @return */ int removeSource(int id); /** * 修改资源 * @param source * @return */ int editSource(Source source); /** * 查询全部资源 * @return */ List<Source> getAllSources(); /** * 根据编号查询资源 * @param id * @return */ Source getSourceById(int id); /** * 根据模糊得注意名称查询资源 - 目前不开发本功能 * @param sourcename * @return */ List<Source> getSourceByLikeName(String sourcename); }
3.2 创建DAO接口的实现类
package cn.javabs.demo.dao.impl; import cn.javabs.demo.dao.SourceDao; import cn.javabs.demo.entity.Source; import cn.javabs.demo.utils.DruidUtils; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import java.sql.SQLException; import java.util.List; public class SourceDaoImpl implements SourceDao { QueryRunner qr = new QueryRunner(DruidUtils.getDataSource()); @Override public int saveSource(Source source) { try { int result = qr.update("insert into source(author,sourceName,sourcePath,downCount,createTime) values (?,?,?,?,?)", source.getAuthor(), source.getSourceName(), source.getSourcePath(), source.getDownCount(), source.getCreateTime() ); return result; } catch (SQLException e) { throw new RuntimeException(e); } } @Override public int removeSource(int id) { try { return qr.update("delete from source" ,id); } catch (SQLException e) { throw new RuntimeException(e); } } @Override public int editSource(Source source) { try { return qr.update("update source set author = ? ,sourceName = ?,sourcePath = ?,downCount = ?,createTime = ? where id = ?" , source.getAuthor(), source.getSourceName(), source.getSourcePath(), source.getDownCount(), source.getCreateTime(), source.getId() ); } catch (SQLException e) { throw new RuntimeException(e); } } @Override public List<Source> getAllSources() { try { return qr.query("select * from source" ,new BeanListHandler<Source>(Source.class)); } catch (SQLException e) { throw new RuntimeException(e); } } @Override public Source getSourceById(int id) { try { return qr.query("select * from source where id = ?" ,new BeanHandler<Source>(Source.class),id); } catch (SQLException e) { throw new RuntimeException(e); } } @Override public List<Source> getSourceByLikeName(String sourcename) { return null; } }
4.1 创建Service接口
package cn.javabs.demo.service.impl; import cn.javabs.demo.dao.SourceDao; import cn.javabs.demo.dao.impl.SourceDaoImpl; import cn.javabs.demo.entity.Source; import cn.javabs.demo.service.SourceService; import java.util.List; import java.util.UUID; public class SourceServiceImpl implements SourceService { SourceDao sourceDao = new SourceDaoImpl(); /** * 添加资源 * * @param source * @return */ @Override public int addSource(Source source) { return sourceDao.saveSource(source); } /** * 删除资源 * * @param id * @return */ @Override public int delSource(int id) { return sourceDao.removeSource(id); } /** * 修改资源 * * @param source * @return */ @Override public int updateSource(Source source) { return sourceDao.editSource(source); } /** * 查询所有资源 * * @return list */ @Override public List<Source> findAllSources() { String stringId = UUID.randomUUID().toString(); return sourceDao.getAllSources(); } /** * 根据id查询资源 * * @param id * @return */ @Override public Source findSourceById(int id) { return sourceDao.getSourceById(id); } /** * 模糊查询 * * @param sourcename * @return */ @Override public List<Source> findSourceByLikeName(String sourcename) { return sourceDao.getSourceByLikeName(sourcename); } }
4.2 创建Service接口的实现类
package cn.javabs.demo.service.impl; import cn.javabs.demo.dao.SourceDao; import cn.javabs.demo.dao.impl.SourceDaoImpl; import cn.javabs.demo.entity.Source; import cn.javabs.demo.service.SourceService; import java.util.List; import java.util.UUID; public class SourceServiceImpl implements SourceService { SourceDao sourceDao = new SourceDaoImpl(); /** * 添加资源 * * @param source * @return */ @Override public int addSource(Source source) { return sourceDao.saveSource(source); } /** * 删除资源 * * @param id * @return */ @Override public int delSource(int id) { return sourceDao.removeSource(id); } /** * 修改资源 * * @param source * @return */ @Override public int updateSource(Source source) { return sourceDao.editSource(source); } /** * 查询所有资源 * * @return list */ @Override public List<Source> findAllSources() { String stringId = UUID.randomUUID().toString(); return sourceDao.getAllSources(); } /** * 根据id查询资源 * * @param id * @return */ @Override public Source findSourceById(int id) { return sourceDao.getSourceById(id); } /** * 模糊查询 * * @param sourcename * @return */ @Override public List<Source> findSourceByLikeName(String sourcename) { return sourceDao.getSourceByLikeName(sourcename); } }
5. 创建Servlet
package cn.javabs.demo.servlet; import cn.javabs.demo.entity.Source; import cn.javabs.demo.service.SourceService; import cn.javabs.demo.service.impl.SourceServiceImpl; import org.apache.commons.beanutils.BeanUtils; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.List; /** * 资源管理 * |-- 上传 * |-- 下载 */ @WebServlet("/sourceServlet") @MultipartConfig(maxFileSize = 1024*50*1024) public class SourceServlet extends HttpServlet { Source source = new Source(); SourceService sourceService = new SourceServiceImpl(); protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet( request, response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); // response.setContentType("text/html;charset=utf-8"); String op = request.getParameter("op"); switch (op){ case "uploadSource": uploadSource(request,response); break; case "downloadSource": downloadSource(request,response); break; case "delSource": delSource(request,response); break; case "findAllSources": findAllSources(request,response); break; default: System.out.println("没有找到指定参数"); } } /** * 删除资源 * @param request * @param response */ private void delSource(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id = request.getParameter("id"); int sourceId = Integer.parseInt(id); int resultRows = sourceService.delSource(sourceId); if (resultRows > 0){ request.setAttribute("msg","资源删除成功!"); request.getRequestDispatcher("/message.jsp").forward(request,response); }else{ request.setAttribute("msg","删除资源失败,请核查相关信息!"); request.getRequestDispatcher("/message.jsp").forward(request,response); } } /** * 下载资源 * @param request * @param response */ private void downloadSource(HttpServletRequest request, HttpServletResponse response) { String id = request.getParameter("id"); int sourceId = Integer.parseInt(id); source = sourceService.findSourceById(sourceId); // 如果有资源,就可以进行下载 if (source != null){ // 获取资源文件的路径和名称 String sourcePath = source.getSourcePath(); String sourceName = source.getSourceName(); String fileName = sourcePath + sourceName; System.out.println("fileName:" + fileName); File file = new File(fileName); if (file.exists()){ try { FileInputStream fileInputStream = new FileInputStream(file); String filename = URLEncoder.encode(file.getName(), "utf-8"); byte[] b = new byte[fileInputStream.available()]; fileInputStream.read(b); response.setCharacterEncoding("utf-8"); response.setHeader("Content-Disposition","attachment; filename="+filename+""); //获取响应报文输出流对象 ServletOutputStream out =response.getOutputStream(); //输出 out.write(b); out.flush(); out.close(); } catch (Exception e) { throw new RuntimeException(e); } } } } /** * 查询所有资源 * @param request * @param response * @throws ServletException * @throws IOException */ private void findAllSources(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<Source> sources = null; sources = sourceService.findAllSources(); System.out.println("sources:"+sources); Iterator<Source> it = sources.iterator(); while (it.hasNext()){ source = it.next(); if (source.getCreateTime().contains(".")){ int index = source.getCreateTime().indexOf("."); String newTime = source.getCreateTime().substring(0, index); source.setCreateTime(newTime); // sources.add(source); } } System.out.println(sources.size()); if (sources.size()>0 && sources != null){ request.setAttribute("sources",sources); request.getRequestDispatcher("/sourceList.jsp").forward(request,response); }else{ request.setAttribute("msg","新闻查询失败!"); request.getRequestDispatcher("/message.jsp").forward(request,response); } } /** * 上传资源 * @param request * @param response * @throws ServletException * @throws IOException */ private void uploadSource(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1. 定义路径 String realPath = this.getServletContext().getRealPath("/upload/"); // 2. 如果该文件夹不存在、则帮我创建出来 File file = new File(realPath); if (!file.exists()){ file.mkdirs(); } Part sourceName = null; try { // 3. 获取上传文件 sourceName = request.getPart("sourceName"); } catch (Exception e) { throw new RuntimeException("\"文件上传失败,请上传小于5kb的文件\""+e); } // 4. 获取上传文件的文件名 String fileName = sourceName.getSubmittedFileName(); //4.2 更改上传文件名称: String currentDate = new SimpleDateFormat("yyyyMMdd").format(new Date()); // 如果文件名称存在 if (!fileName.equals("") || fileName != null){ fileName = currentDate + "_" + fileName; } sourceName.write(realPath+"/"+fileName); source.setSourcePath(realPath); source.setSourceName(fileName); try { BeanUtils.populate(source,request.getParameterMap()); } catch (Exception e) { throw new RuntimeException(e); } System.out.println("[Source:]" + source); int resultRows = sourceService.addSource(source); System.out.println("4545"); if (resultRows > 0){ request.setAttribute("msg","添加资源成功!"); request.getRequestDispatcher("/message.jsp").forward(request,response); }else{ request.setAttribute("msg","资源添加失败,请核查相关信息!"); request.getRequestDispatcher("/message.jsp").forward(request,response); } } }
6.设计上传页面
6.1 添加资源 - 上传页面
<%-- Created by IntelliJ IDEA. User: Mryang Date: 2019/6/16 Time: 16:53 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>Title</title> <link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/admin/resource/css/style.css"/> </head> <body> <div class="formbody"> <div class="formtitle"><span>资源信息</span></div> <form action="${pageContext.request.contextPath}/sourceServlet?op=uploadSource" method="post" enctype="multipart/form-data"> <ul class="forminfo"> <li> <label>上传人</label> <input class="dfinput" type="text" name="author" id="entityauthor" class="dfinput" data-rule-required="true"/> </li> <li> <label>资源文件</label> <input class="dfinput" type="file" name="sourceName" id="entitysourceName" class="dfinput" data-rule-required="true"/> </li> </ul> </form> </div> </body> </html>
6.2 查询资源 - 下载文件
<%-- Created by IntelliJ IDEA. User: Mryang Date: 2019/6/16 Time: 17:19 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% String contextPath = request.getContextPath(); pageContext.setAttribute("basePath", contextPath); %> <html> <head> <title>用户列表</title> <script src="${pageContext.request.contextPath}/admin/resource/js/jquery-1.7.2.min.js" type="text/javascript" charset="utf-8"></script> <link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/admin/resource/css/style.css"/> <script type="text/javascript"> $(document).ready(function () { $(".click").click(function () { $(".tip").fadeIn(200); }); $(".find").click(function () { // $("#listform").submit(); $("#listform").click(function () { window.location.href = "${basePath}/navigationServlet?op=findNavigationByLikeName&name=" + $("#unm").val(); }); }); $(".tiptop a").click(function () { $(".tip").fadeOut(200); }); $(".sure").click(function () { <%--window.location = "${basePath}${opServlet}?op=delete&id=" + $(".sure_value").val();--%> window.location.href = "${basePath}/navigationServlet?op=delNavigation&id=" + $(".sure_value").val(); $(".tip").fadeOut(100); }); $(".cancel").click(function () { $(".tip").fadeOut(100); }); }); function delete_confirm(e, id) { $(".tip").fadeIn(200); $(".sure_value").val(id); } function gotoPage(page) { $("#pageNo").val(page); $("#listform").submit(); } </script> </head> <body> <div class="place"> <span>位置:</span> <ul class="placeul"> <li><a href="#">导航栏管理</a></li> <li><a href="#">导航栏列表</a></li> </ul> </div> <form action="${basePath}/userServlet?op=findUserByLikeName&username=" method="post" id="listform"> <div class="rightinfo"> <div class="tools"> <ul class="toolbar"> <li style="padding-right: 0px;"> 导航栏名称:<input type="text" name="author" id="unm" class="dfinput" style="width: 150px;"> </li> <li class="find"> <span><img src="${basePath}/admin/resource/img/t06.png"/> </span>查询 </li> </ul> </div> <table class="tablelist"> <thead> <tr> <th>上传人</th> <th>文件名称</th> <th>下载次数</th> <th>创建时间</th> <th width="150px">操作</th> </tr> </thead> <tbody> <c:forEach items="${sources}" var="item"> <tr> <td> ${item.author } </td> <td> ${item.sourceName } </td> <td> ${item.downCount } </td> <td> ${item.createTime } </td> <td> <a class="tablelink" href="${pageContext.request.contextPath}/sourceServlet?op=downloadSource&id=${item.id}">【 下载】</a> <a class="tablelink" href="${pageContext.request.contextPath}/navigationServlet?op=updateNavigationView&id=${item.id}">【修改】</a> <a class="tablelink" href="javascript:delete_confirm(this,'${item.id}')">【 删除】</a> </td> </tr> </c:forEach> </tbody> </table> <div class="tip"> <div class="tiptop"> <span>提示信息</span><a></a> </div> <div class="tipinfo"> <span><img src="${basePath}/admin/resource/img/ticon.png"/> </span> <div class="tipright"> <p>是否确认对信息的删除 ?</p> <cite>如果是请点击确定按钮 ,否则请点取消。</cite> </div> </div> <div class="tipbtn"> <input type="hidden" class="sure_value" value=""/> <input name="" type="button" class="sure" value="确定"/> <input name="" type="button" class="cancel" value="取消"/> </div> </div> </div> </form> <script type="text/javascript"> $('.tablelist tbody tr:odd').addClass('odd'); </script> <%-- <table border="1" width="438"> <c:forEach items="${list}" var="l"> <tr> <td>${l.id}</td> <td>${l.username}</td> <td>${l.birthday}</td> <td> <a href="JavaScript:delUser('${l.id}')">删除</a> <a href="${pageContext.request.contextPath}/userServlet?op=editUser&id=${l.id}">修改</a> </td> </tr> </c:forEach> <c:if test="${username!=admin}"> <script> alert(98); </script> <a href="${pageContext.request.contextPath}/userServlet?op=editUser&id=${l.id}">修改</a> </c:if> </table>--%> </body> </html>
6.3 提示页面
<%-- Created by IntelliJ IDEA. User: Mryang Date: 2019/6/25 Time: 14:58 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>提示信息</title> </head> <body> <h1>${msg}</h1> </body> </html>
7. 下载全套代码
GitHub演示代码下载:https://github.com/yangsir1688/UploadAndDownload_Demo