ssm项目 “文档上传” 和 “文档下载”

一、文档上传

1.导入依赖

pom.xml文件中导入依赖

        <!-- 文档上传依赖 -->
		<dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>

        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.3</version>
        </dependency>


2. 配置 文档上传解析器

spring-mvc.xml 中配置文件上传解析器

 
<!-- 配置文件上传解析器 -->
    <bean id="multipartResolver"  class="org.springframework.web.multipart.commons.CommonsMultipartResolver    				  ">
        <!-- 设置上传文件的最大尺寸为 5MB=5x1024x1024  字节单位 -->
        <property name="maxUploadSize" value="5242880"/>
    </bean>
        

3. 配置 文档上传工具类

package com.oa.util;
import com.oa.bean.Doc;
import com.oa.service.DocService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.UUID;

public class FileUpLoadUtils {  //文件上传工具类

    @Autowired
    DocService docService;

    /**
     *  文件上传方法
     */
    public static DataResults Fileupload(MultipartFile file, HttpServletRequest request, Doc doc, DocService docService) {
         try {
             //1.获取原始文件名 ( 获取"原始文件名")
             String uploadFileName = file.getOriginalFilename();
             System.out.println("要上传的原始文件名字是:" + uploadFileName);
             //2.截取文件扩展名
             String extendName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1, uploadFileName.length());
             //3.把文件加上随机数,防止文件重复
             String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
             //4.生成的新的服务器文件名
             String newfileName = uuid + "." + extendName;
             System.out.println("生成的新的服务器文件名是:" + newfileName); //防止服务器文件名重名
             //5.获取真实的服务器文件上传地址 (文件的存储位置)
             String filePath = request.getServletContext().getRealPath("S:\\File") + "/" + newfileName;
             System.out.println("服务器运行目录,最终上传的路径:" + filePath);
             //6.执行上传
             //方法中参数为: 该上传文件要存储的"文件夹" 和 该文件的"名称"以及"后缀"
             file.transferTo(new File(filePath)); 
             System.out.println("文件上传结束!");

             //新增对象到数据库
             doc.setFileName(newfileName);
             boolean b=docService.save(doc);
             // DataResults : 数据结果工具类,作用: 显示方法的执行状态,该方法中参数为
             // ResultCode:   状态码枚举
             if (b) {
                 return DataResults.success(ResultCode.SUCCESS);
             } else {
                 return DataResults.fail(ResultCode.FAIL);
             }
         } catch (
                 IOException e) {
             e.printStackTrace();
                 return DataResults.fail(ResultCode.FAIL);
         }
     }
}

4. 配置后端代码 ( 来实现文档的上传 )

4.1配置(controller层) 后端代码
    /**
     *  文档上传
     */
    @ResponseBody
    @PostMapping("/saveDocument")
    public DataResults saveDocument(MultipartFile file, HttpServletRequest request, Doc doc) {
        System.out.println("doc=" + doc);
        //调用文件上传工具类 上传文件
        DataResults dataResults = FileUpLoadUtils.Fileupload(file, request, doc, docService);
        return dataResults;
    }
4.2配置(bean层) Doc对象
package com.oa.bean;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.oa.util.DateUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data  //设置get、set方法
@AllArgsConstructor  //全参数构造方法
@NoArgsConstructor  //没参数构造方法
/*
   用来将指定的数据库表和 JavaBean(一般为与数据库中表相对应的对象/类) 进行映射,@TableName是mybatis-plus中的注解,
   主要是实现实体类型和 数据库中的表实现映射,将两者联系起来("tb_user")
 */
@TableName("tb_doc")
public class Doc {

    @TableId(value="id",type= IdType.AUTO)  //type=IdType.AUTO : 设置id自增
    private Integer id;

    private String createDate=DateUtils.nowTime();

    @TableField("fileName")
    private String fileName;
    private String remark;
    private String title;
    private Integer uid;
    private Integer del=0;

    @TableField(exist = false)  //额外的拓展字段
    private Users users;

}

5. 配置前端代码 ( 来实现文档的上传 )

5.1配置配置(.jsp页面中) 前端代码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<html>
<head>
    <title>人事管理系统</title>
    <!--引入bootstrap -->
    <link href="/css/bootstrap.min.css" rel="stylesheet">
    <!--引入layui -->
    <link href="/layui/css/layui.css" rel="stylesheet">
</head>
<body>
<br/><br/>
<form class="layui-form" id="uploadForm">
    <!--文档标题 -->
    <div class="layui-form-item" style="margin-top: 5px">
        <label class="layui-form-label" style="width: 100px">文件标题&nbsp;</label>
        <div class="layui-input-block" style="margin-right: 50px">
            <input class="form-control" name="title" placeholder="请输入文件标题" type="text" lay-verify="title" id="title"/>
        </div>
    </div>
    <!--文件描述 -->
    <div class="layui-form-item" style="margin-top: 5px">
        <label class="layui-form-label" style="width: 100px">文件描述</label><br>
        <div class="layui-input-block" style="margin-right: 50px">
            <textarea type="text" class="form-control" placeholder="请简单描述文件" rows="5" cols="10" name="remark"
                      id="remark"></textarea>
        </div>
    </div>
    <!--上传文件 -->
    <div class="layui-form-item" style="margin-top: 5px">
        <label class="layui-form-label" style="width: 110px">请选择文件</label>
        <div class="layui-input-inline">
            <button type="button" class="btn-success btn" id="upload"><i class="layui-icon"></i>上传文件</button>
        </div>
    </div>
    <!--按钮组 -->
    <div class="layui-form-item" style="margin-top: 5px">
        <div class="layui-input-inline" style="margin-left: 24px">
            <button class="btn-sm btn btn-primary" id="submit" type="button">上传</button>
            &nbsp;&nbsp;&nbsp;&nbsp;
            <button class="btn btn-sm btn-warning" type="reset">重置</button>
        </div>
    </div>
</form>
<!--引入jquery -->
<script src="/js/jquery-3.1.1.min.js" charset="UTF-8"></script>
<!--引入layui.js -->
<script src="/layui/layui.js" charset="UTF-8"></script>

<script type="text/javascript">
    layui.use(['form', 'layer', 'upload'], function () {
        var form = layui.form,
            layer = layui.layer,
            upload = layui.upload;
        form.verify({
            title: function (value) {
                if (value.length == 0) {
                    return '标题不能为空哦';
                }
            }
        });
        var uploadInit = upload.render({
            elem: '#upload',
            url: '/doc/saveDocument',
            accept: 'file',  //与后端 MultipartFile file 中 file 名称一致
            auto: false,
            data: {title:'w',remark:'s',uid:0},
            bindAction: '#submit',
            before: function () {
                uploadInit.config.data.title = $("#title").val();  //
                uploadInit.config.data.remark = $("#remark").val();
                uploadInit.config.data.uid = ${sessionScope.loginUser.id};
            },
            done: function (result) {
                if (result.code == 200) {
                    layer.msg('上传成功', {icon: 1},function () {
                        window.location.href = "/jsp/doc-doc";
                    });
                }else{
                    layer.msg('上传失败', {icon: 2});
                }
            },
            error: function () {
                layer.msg('上传失败', {icon: 2});
            }
        });
    });
</script>
</body>

5.2“文件上传页面”展示

6. 配置 DataResults工具类 和 ResultCode枚举

6.1 配置 DataResults工具类
package com.oa.util;
import lombok.Data;

/**
 *  DataResults 配合 ResultCode 来使用,来为后端返回操作的状态/数据结果信息给前端
 *  DataResults中的方法的参数为ResultCode枚举中的内容
 */
@Data
public class DataResults {   // DataResults: 数据结果/操作状态

    private int code;    //状态码
    private String msg;   //状态具体描述信息
    private Object data;  //返回的数据

    private DataResults(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public static DataResults success(ResultCode resultCode){
        // resultCode.getCode(), resultCode.getMsg() ---得到传入枚举的code 和 msg信息,并给DataResults类
        DataResults resultCommon = new DataResults(resultCode.getCode(), resultCode.getMsg());
        return resultCommon;  //返回这个对象
    }

    public static DataResults success(ResultCode resultCode, Object data){
        DataResults success = success(resultCode);
        success.setData(data);
        return success;
    }

    public static DataResults fail(ResultCode resultCode){
        return success(resultCode);
    }

}

6.2 配置 ResultCode 枚举
package com.oa.util;

public enum  ResultCode {   // ResultCode: 结果代码/状态码

    SUCCESS(200,"请求成功"),
    NO_DELETE(800,"数据在使用中,勿删除"),
    FAIL(500,"请求失败"),
    TIMEOUT(505,"支付超时"),
    REGISTER_SUCCESS(200,"注册成功"),
    USERNAME_NO_REPEAT(200,"用户名可用"),
    ADD_FAV_SUCCESS(200,"收藏成功!"),
    REMOVE_SUCCESS(200,"移除成功!"),
    CODE_FAIL(9001,"验证码错误"),
    LOGIN_FAIL(9002,"用户名或密码错误"),
    NO_LOGIN(9003,"请先登录"),
    NO_CHECK(9090,"验证失败"),
    REGISTER_FAIL(9005," 注册失败"),
    USERNAME_REPEAT(9006," 用户名重复"),
    LOGIN_FORBID(9007,"用户被禁用"),
    NO_RIGTHS(403,"暂无权限操作"),
    @SuppressWarnings("all")
    REPASSWORD_ERROR(9004,"两次密码不一致"),
    PASSWORD_ERROR(9008,"原密码错误"),
    PASSWORD_EMPTY(9009,"密码不能为空");

    private int code;
    private String msg;

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

    ResultCode(int code, String msg){
        this.code=code;
        this.msg=msg;
    }
}

二、文档下载

1. 配置 文档下载工具类

package com.oa.util;
import com.oa.bean.Doc;
import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

public class FileDownLoadUtils {  //文档下载工具类

    public static ResponseEntity<byte[]> FileDownLoad(Integer id, Doc doc ,HttpServletRequest request) {

        //获得要下载的地址
        String path = request.getSession().getServletContext().getRealPath("doc");

        File file = new File(path, doc.getFileName());
        if (file.exists()) {
            try {
                //设置请求头
                HttpHeaders headers = new HttpHeaders();

                /**
                 *  1.用title(存在中文)为文件名,可能会有乱码问题
                 *
                 *  2.用fileName(不存在中文 )为文件名,不会有乱码问题
                 *  如:  String downName = new String(doc.getFileName().getBytes("utf-8"), "ISO-8859-1");
                 *  ---要保证没有乱码问题可第二种方式
                 *
                 */
                //文件下载的名字, 可能存在乱码问题
 String newFileName = doc.getTitle() + "." + doc.getFileName().split("\\.")[1];    
           String downName = new String(newFileName.getBytes("utf-8"), "ISO-8859-1");

                // 设置以附件的形式下载
                headers.setContentDispositionFormData("attachment", downName);
                // 设置文件内容以流的形式来下载
                headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
                // 用springmvc 提供的下载方式
                ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK);
                return responseEntity;
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

}

2. 配置后端代码 ( 来实现文档的下载 )

2.1配置(controller层) 后端代码
    /**
     * 下载文档
     */
    @ResponseBody
    @RequestMapping("/downloadDocument")
public ResponseEntity<byte[]> downloadDocument(Integer id, HttpServletRequest request) {
        //获得该doc对象
        Doc doc = docService.getById(id);
        //用文件下载工具类 下载文件
        ResponseEntity<byte[]> responseEntity = FileDownLoadUtils.FileDownLoad(id, doc, request);
        return responseEntity;
    }

3. 配置前端代码 ( 来实现文档的下载 )

3.1配置配置(.jsp页面中) 前端代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<html>
<head>
    <meta charset="utf-8">
    <title>人事管理系统</title>
    <!-- jq -->
    <script src="../js/jquery-3.1.1.min.js"></script>

    <!-- bootstrap -->
    <link href="../css/bootstrap.min.css" rel="stylesheet">
    <script src="../js/bootstrap.min.js"></script>

    <!-- 分页插件 -->
    <link href="../css/bootstrap-table.min.css" rel="stylesheet">
    <script src="../js/bootstrap-table.js"></script>
    <script src="../js/bootstrap-table-locale-all.min.js"></script>

    <!--layer -->
    <link href="../js/layer/theme/default/layer.css" rel="stylesheet">
    <style type="text/css">
        .panel {
            margin-left: -48px;
            width: 1145px;
        }

        .col-sm-12 {
            margin-left: -60px;
        }

        thead {
            background: #428bca;
            color: white;
        }
    </style>
</head>
<body>
<div class="container" style="margin-top: 5px">
    <div class="row">
        <!--!查询区 -->
        <div class="panel panel-default">
            <div class="panel-heading"
                 style="background-color: #428bca; color: white">查询条件</div>
            <div class="panel-body form-group" style="margin-bottom: 0px;">
                <label class="col-sm-2 control-label"
                       style="text-align: right; margin-top: 5px">文档标题:</label>
                <div class="col-sm-2">
                    <input type="text" class="form-control" name="name" id="search_docname" />
                </div>
                <div class="col-sm-1 col-sm-offset-4">
                    <button class="btn btn-primary" class="search" type="button" id="search_btn" style="background-color: #0767C8">搜索</button>
                </div>
            </div>
        </div>

        <div id="toolbar" class="btn-group">
            <%--<button id="btn_edit" type="button" class="btn btn-primary" >--%>
            <%--<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>修改--%>
            <%--</button>--%>
            <button id="btn_delete" type="button" class="btn btn-danger"
                    style="margin-left: 10px">
                <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>批量删除
            </button>
        </div>
        <!-- 表格 -->
        <div class="col-sm-12">
            <table class="table table-striped table-bordered table-hover"
                   id="table"></table>
        </div>
    </div>
</div>
<script src="../js/layer/layer.js"></script>
<script type="text/javascript">

    //获取选中的所有行的id
    function getIds() {
        return $.map($("#table").bootstrapTable('getSelections'), function (row) {
            return row.id;
        })
    }

    /**
     * 批量删除文档
     */
    $("#btn_delete").click(function () {
        var ids = getIds();
        if (ids.length < 1) {
            layer.alert('请选择至少一个文档!', {
                skin: 'layui-layer-lan'
                , closeBtn: 0
            })
        } else {
            layer.confirm('确定删除这些文档吗??', {
                btn: ['是的', '按错了'] //可以无限个按钮
            }, function () {
                //确定按钮的回调函数
                var url = "/doc/removeDocuments";
                $.ajax({
                    url: url,
                    data: "ids="+ids,
                    type: "post",
                    dataType: "json",
                    success:function(result){
                        if(result.code==200){
                            alert("删除成功!");
                            $("#table").bootstrapTable("refresh", {url: '/doc/page'});
                            layer.closeAll("dialog");
                        }else{
                            alert("系统异常!");
                        }
                    },
                    error: function () {
                        $("#table").bootstrapTable("refresh", {url: '/doc/page'});
                        layer.closeAll("dialog");
                    }
                })
            })
        }
    });

   	    /**
         * 删除文档  
         */
    function deleteone(id) {
        layer.confirm('确定删除这个文档吗??', {
            btn: ['是的', '按错了'] //可以无限个按钮
        }, function () {
            //确定按钮的回调函数
            $.getJSON("/doc/removeDoc/"+id,function (result) {
                //alert(JSON.stringify(result));
                if(result.code==200){
                    alert("删除成功!");
                    //window.location.reload();
                    $("#table").bootstrapTable("refresh", {url: '/doc/page'});
                    layer.closeAll("dialog");
                }else{
                    alert("系统异常!");
                }
            });
        });
    }


    class BstpTable {
        constructor(obj) {
            this.obj = obj;
        }

         /**
         *  异步分页  
         */
        inint() {
            //---先销毁表格 ---
            this.obj.bootstrapTable('destroy');
            //---初始化表格,动态从服务器加载数据---
            this.obj.bootstrapTable({
                //【发出请求的基础信息】
                url: '/doc/page',
                method: 'post',
                contentType: "application/x-www-form-urlencoded",//必须有
                //【查询设置】
                /* queryParamsType的默认值为 'limit' ,在默认情况下 传给服务端的参数为:offset,limit,sort
                                  设置为 ''  在这种情况下传给服务器的参数为:pageSize,pageNumber */
                queryParamsType: '',
                queryParams: function queryParams(params) {
                    //自定义传递的参数
                    var param = {
                        pageNumber: params.pageNumber,
                        pageSize: params.pageSize,
                        title: $("#search_docname").val()  //进行异步分页 模糊查询的条件
                    };
                    return param;
                },

                //【其它设置】
                locale: 'zh-CN',//中文支持
                pagination: true,//是否开启分页(*)
                striped: true,
                pageNumber: 1,//初始化加载第一页,默认第一页
                pageSize: 5,//每页的记录行数(*)
                pageList: [5, 10, 15],//可供选择的每页的行数(*)
                sidePagination: "server", //分页方式:client客户端分页,server服务端分页(*)
                showRefresh: true,//刷新按钮
                showToggle: true,//卡片视图
                toolbar: '#toolbar',//工具栏

                //【样式设置】
                height: 384,
                //【设置列】
                columns: [
                    {
                        title: '全选',
                        field: 'select',
                        //复选框
                        checkbox: true,
                        width: 25,
                        align: 'center',
                        valign: 'middle'
                    },
                    {field: 'title', title: '标题'},
                    {field: 'createDate', title: '创建时间'},
                    {field: 'users.username', title: '创建人'},
                    {field: 'remark', title: '描述'},
                    {
                        field: 'tool', title: '操作', align: 'center',
                        formatter: function (value, row, index) {
                            var element = "<button  data-id='" + row.id + "' οnclick='deleteone(" + row.id + ")' class='btn btn-danger btn-sm'>删除</button> ";
                            return element;
                        }
                    },
                    {
                        field: 'download', title: '下载', align: 'center',
                        formatter: function (value, row, index) {
                            var element = "<a href='/doc/downloadDocument?id="+row.id+"'><img class='btn btn-success btn-sm' src='../images/download_icon.png' /></a>";
                            return element;
                        }
                    }
                ]
            })
        }
    }

    //初始化表格
    var bstpTable = new BstpTable($("table"));
    bstpTable.inint({})

    //查询按钮的逻辑
    $("#search_btn").click(function () {
        $("#table").bootstrapTable("refresh", {url: '/doc/page'})
    })

</script>
</body>
</html>
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
一、引言 本文档旨在为基于SSM框架的软件下载中心系统提供详细的需求分析,包括系统的功能需求、性能需求、可靠性需求、安全需求等方面,以确保系统能够满足用户的需求。 二、背景介绍 随着互联网的发展,软件下载已经成为人们获取软件的主要途径之一。然而,当前的软件下载网站并没有提供足够的安全性和便利性。因此,本项目旨在搭建一个基于SSM框架的软件下载中心系统,提供更加安全、便捷的软件下载服务。 三、系统需求 1. 功能需求: (1) 用户注册和登录:用户可以通过注册账号并登录系统,以便于进行软件下载和管理。 (2) 软件上传下载:用户可以上传自己的软件,并可以下载其他用户上传的软件。 (3) 软件分类和搜索:系统支持对软件进行分类和搜索,以方便用户查找需要的软件。 (4) 软件评论和评分:用户可以对下载的软件进行评论和评分,以方便其他用户进行参考。 (5) 软件推荐:系统可以根据用户的下载历史和评分情况,推荐符合用户需求的软件。 (6) 用户管理:管理员可以对用户进行管理,包括账号信息、下载历史等。 (7) 软件管理:管理员可以对软件进行管理,包括软件上传审核、软件信息管理等。 2. 性能需求: (1) 响应时间:系统应该在用户进行操作时保持良好的响应时间,不超过3秒。 (2) 并发性能:系统应该支持多个用户同时进行操作,不影响系统的正常运行。 (3) 数据库性能:系统应该具有良好的数据库性能,能够处理大量数据。 3. 可靠性需求: (1) 系统稳定性:系统应该具有良好的稳定性,能够长期稳定运行,不出现崩溃等情况。 (2) 数据安全性:系统应该具有良好的数据安全性,能够保护用户的个人信息和上传的软件数据。 (3) 备份恢复:系统应该具有备份和恢复功能,以便于在出现故障时能够快速恢复数据。 4. 安全需求: (1) 账号安全性:系统应该具有良好的账号安全性,包括密码加密、防止暴力破解等功能。 (2) 数据传输安全性:系统应该具有良好的数据传输安全性,包括数据加密、防止中间人攻击等功能。 (3) 防止恶意软件:系统应该具有防止上传恶意软件的功能,保证用户下载的软件安全可靠。 四、总结 本文档详细描述了基于SSM框架的软件下载中心系统的需求分析,包括功能需求、性能需求、可靠性需求和安全需求等方面。本文档为系统的设计和开发提供了重要参考,有助于确保系统能够满足用户的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值