先後端分離跨服務器文件上傳-Java SpringMVC版

 近來工做上不上特別忙,加上對後臺java瞭解一點,因此就抽時間,寫了一個java版本的先後端分離的跨服務器文件上傳功能,包括先後端代碼。css

 須要購買阿里雲產品和服務的,點擊此連接領取優惠券紅包,優惠購買哦,領取後一個月內有效: https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=fp9ccf07html

1、Tomcat服務器部分

一、Tomcat服務器

單獨複製一份Tomcat,用來做爲文件服務器前端

1.1 web.xml文件:

須要在該Tomcat的conf目錄下的web.xml文件的大概100行添加以下幾行(紅框內部分):java

1.2 server.xml文件:

須要在該Tomcat的conf目錄下的server.xml文件作一些端口的修改jquery

1.3 Tomcat下創建文件夾

在該Tomcat的/webapps/ROOT目錄下建立一個upload目錄,用來存放上傳的文件web

1.4 啓動Tomcat服務器

以上三步作完後,就能夠啓動Tomcat服務器了,在Tomcat的bin目錄下執行 startup.sh 腳本ajax

2、java部分

2.1 jar包

除了其餘的jar包之外,還須要如下幾個jar包spring

commons-io-1.3.2.jar數據庫

commons-fileupload-1.2.1.jarapache

jersey-client-1.18.1.jar

jersey-core-1.18.1.jar

jersey-common

2.2 配置文件

2.2.1 spring-mvc.xml文件添加以下部分:

<!-- 上傳文件 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  <!--最大上傳尺寸  5M -->
   <property name="maxUploadSize" value="5242880"/>
</bean>

2.2.2 config.properties 文件添加以下部分:

#文件服務器地址
uploadHost=http://172.16.5.102:8090/
#上傳的文件保存的目錄 imgPath = upload/

2.3 java文件

2.3.1 Upload.java

package com.lin.utils;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;


/**
 * 上傳文件工具類
 * @author libo
 */
public class Upload {
    
    /**
     * 上傳文件
     * @param request
     * @param response
     * @param serverPath    服務器地址:(http://172.16.5.102:8090/)
     * @param path             文件路徑(不包含服務器地址:upload/)
     * @return
     */
    public static String upload(Client client, MultipartFile file, HttpServletRequest request,HttpServletResponse response, String serverPath, String path){
        // 文件名稱生成策略(UUID uuid = UUID.randomUUID())
        Date d = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        String formatDate = format.format(d);
        String str = "";
        for(int i=0 ;i <5; i++){
            int n = (int)(Math.random()*90)+10;
            str += n;
        }
        // 獲取文件的擴展名
        String extension = FilenameUtils.getExtension(file.getOriginalFilename());
        // 文件名
        String fileName = formatDate + str + "." + extension;
        //相對路徑
        String relaPath = path + fileName;
        
        String a = serverPath + path.substring(0, path.lastIndexOf("/"));
        File file2 = new File(a);
        if(!file2.exists()){
            boolean mkdirs = file2.mkdirs();
            System.out.println(mkdirs);
        }
        
        // 另外一臺tomcat的URL(真實路徑)
        String realPath = serverPath + relaPath;
        // 設置請求路徑
        WebResource resource = client.resource(realPath);

        // 發送開始post get put(基於put提交)
        try {
            resource.put(String.class, file.getBytes());
            return fileName+";"+relaPath+";"+realPath;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }
    
    /**
     * 刪除文件
     * @param filePath(文件完整地址:http://172.16.5.102:8090/upload/1234.jpg)
     * @return
     */
    public static String delete(String filePath){
        try {
            Client client = new Client();
            WebResource resource = client.resource(filePath);
            resource.delete();
            return "y";
        } catch (Exception e) {
            e.printStackTrace();
            return "n";
        }
    }
}

 

2.3.2 controller層

package com.lin.controller;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.VelocityConfigurerBeanDefinitionParser;

import com.lin.domain.data.ResData;
import com.lin.domain.data.ResListData;
import com.lin.domain.error.Error;
import com.lin.domain.sysUser.SysUser;
import com.lin.domain.sysUser.SysUserWithDep;
import com.lin.service.SysUserService;
import com.lin.utils.Aes;
import com.lin.utils.DateTimeUtils;
import com.lin.utils.ResponseUtils;
import com.lin.utils.Upload;
import com.lin.utils.Utils;
import com.sun.jersey.api.client.Client;

import net.sf.json.JSONObject;

/**
 * 後臺用戶-controller
 * @author libo
 */
@Controller
@RequestMapping("/sysUser")
public class SysUserController {

    @Resource
    private SysUserService sysUserService;
    
    @Value(value="${imgPath}")    //後臺圖片保存地址
    private String imgPath;
    
    @Value(value="${uploadHost}")
    private String uploadHost;    //項目host路徑    
    
    /**
     * 後臺用戶登錄功能
     * @return
     * @throws IOException 
     */
    @ResponseBody
    @RequestMapping(value="/login.do", method=RequestMethod.POST)
    public void login(HttpServletRequest req, HttpServletResponse res, 
            @RequestParam(required=true) String loginEmail, 
            @RequestParam(required=true) String loginPwd) throws IOException{
        //代碼省略
    }

/** * 根據id查詢用戶信息(包括部門信息) * @param req * @param res * @param id * @throws IOException */ @ResponseBody @RequestMapping(value="/getSysUser.do", method=RequestMethod.GET) public void getSysUser(HttpServletRequest req, HttpServletResponse res, @RequestParam(required=true) Integer id) throws IOException{   //代碼省略 } /** * 更新後臺用戶信息 * @param req * @param res * @throws IOException */ @ResponseBody @RequestMapping(value="/updateSysUser.do" ,method=RequestMethod.POST) public void updateSysUser(HttpServletRequest req, HttpServletResponse res) throws IOException{ //代碼省略 } /** * 添加用戶 * @param req * @param res * @throws IOException */ @ResponseBody @RequestMapping(value="/addSysUser.do", method=RequestMethod.POST) public void addSysUser(HttpServletRequest req, HttpServletResponse res) throws IOException { //代碼省略 }


/** * 上傳用戶頭像 * @param request * @param response */ @ResponseBody @RequestMapping(value="uploadSysHeadImg.do", method=RequestMethod.POST) public void uploadSysHeadImg(HttpServletRequest request,HttpServletResponse response){ JSONObject jo = new JSONObject(); try { MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext()); MultipartHttpServletRequest Murequest = resolver.resolveMultipart(request); Map<String, MultipartFile> files = Murequest.getFileMap();//獲得文件map對象
       // 實例化一個jersey Client client = new Client(); List<String> fileNameList = new ArrayList<>(); List<String> relaPathList = new ArrayList<>(); List<String> realPathList = new ArrayList<>(); for(MultipartFile pic: files.values()){ String uploadInfo = Upload.upload(client, pic, request, response, uploadHost, imgPath);
                if(!"".equals(uploadInfo)){    //上傳成功
                    String[] infoList = uploadInfo.split(";");
                    fileNameList.add(infoList[0]);    //文件名
                    relaPathList.add(infoList[1]);    //相對路徑
                    realPathList.add(infoList[2]);    //真實完整路徑
                }else{    //上傳失敗
                    fileNameList.add("");
                    relaPathList.add("");
                    realPathList.add("");
                } } jo.put(
"success", 1); jo.put("error", null); jo.put("fileNameList", fileNameList); jo.put("relaPathList", relaPathList); jo.put("realPathList", realPathList); }catch (Exception e) { jo.put("success", 0); jo.put("error", "上傳失敗"); } ResponseUtils.renderJson(response, jo.toString()); } }

其餘的java文件省略,而後運行java項目

 

3、前端部分

3.1 index1-cropper圖片剪切上傳

<!DOCTYPE html>
<html>
<head>
    <title>index1-cropper圖片剪切上傳</title>
    <meta charset="utf-8"/>
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <link rel="stylesheet" href="lib/cropper/dist/cropper.min.css" />
</head>
<body>

<!-- accept="image/*,camera":表示容許調用相冊和攝像頭,capture="camera":表示直接打開攝像頭-->
<!--<input id="btn1" type="file" accept="image/*,camera" capture="camera" style="opacity: 0;"/>-->
<input id="btn1" type="file" accept="image/*,camera" style="opacity: 0;"/>

<div>
    <div>上傳以前的圖片</div>
    <img id="face_image" style="width:50px;height:50px;border-radius: 25px;border: 1px solid #fff;"/>
    <div>上傳以後服務器的圖片</div>
    <img id="success_image" style="width:50px;height:50px;border-radius: 25px;border: 1px solid #fff;"/>
</div>
<div>
    <button id="upload_btn">上傳頭像</button>
    <button id="image_save">保存</button>
    <span></span>
</div>

<div class="upload-img" style="width:300px;height: 300px;">
    <img src=""/>
</div>

<script src="jquery.min.js"></script>
<script src="lib/cropper/dist/cropper.min.js"></script>
<script src="lib/canvas-toBlob/canvas-toBlob.js"></script>

<script>
    $(function() {
        //觸發input file
        $('#upload_btn').click(function() {
            console.log('模擬點擊。。。');
            $('#btn1').trigger('click');
        });

        //圖片上傳
        var $image = $('.upload-img > img');
        $image.cropper({
            viewMode: 1,
//            preview: '.img-preview', //不一樣尺寸預覽區
            aspectRatio: 1, //裁剪比例,NaN-自由選擇區域
            autoCropArea: 0.7, //初始裁剪區域佔圖片比例
            crop: function(data) { //裁剪操做回調
                console.log(data);
            }
        });
        var fileName; //選擇上傳的文件名
        $('#btn1').change(function(){
            var file = this.files[0];
            fileName = file.name;
            var reader = new FileReader();
            //reader回調,從新初始裁剪區
            reader.onload = function(){
                // 經過 reader.result 來訪問生成的 DataURL
                var url = reader.result;
                //選擇圖片後從新初始裁剪區
                $image.cropper('reset', true).cropper('replace', url);
            };
            reader.readAsDataURL(file);
        });

        /*
         * 上傳圖片
         */
        $('#image_save').click(function() {
            var type = $image.attr('src').split(';')[0].split(':')[1];

            var canVas = $image.cropper("getCroppedCanvas", {});
            //將裁剪的圖片加載到face_image
            $('#face_image').attr('src', canVas.toDataURL());
            canVas.toBlob(function(blob) {
                var formData = new FormData();
                formData.append("file", blob, fileName);
                http://172.16.5.102:9000/index1-cropper%E5%9B%BE%E7%89%87%E5%89%AA%E5%88%87%E4%B8%8A%E4%BC%A0.html
                $.ajax({
                    type: "POST",
                    url: 'http://172.16.5.102:8081/ssm_project/sysUser/uploadSysHeadImg.do',
                    data: formData,
                    contentType: false, //必須
                    processData: false, //必須
                    dataType: "json",
                    success: function(res){
                        //清空上傳文件的值
                        $('#btn1').val('');
                        $('#success_image').attr('src', res.realPathList[0]);
                    },
                    error : function() {
                        //清空上傳文件的值
                        $('#btn1').val('');
                    }
                });
            }, type);
        });

        //取消
        $("#image_cancel").click(function() {
            //清空上傳文件的值
            $(_pageId + inputFileId).val('');
        });
    });
</script>
</body>
</html>

效果圖:

 

3.2 index2-jquery-Form表單提交

<!DOCTYPE html>
<html lang="en">
<head>
    <!-- 選擇圖片後,就開始上傳 -->
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <title>index2-jquery-Form表單提交</title>
    <script src="jquery.min.js"></script>
    <script src="jquery.form.js"></script>
</head>
<body>
<img height="100" id="success_img"/>
<form id="jvForm" action="o_save.shtml" method="post" enctype="multipart/form-data">
    <!-- 保存圖片的相對路徑,方便提交給後臺,存到數據庫 -->
    <input type="hidden" name="" id="img_path"/>

    <input type="file" id="select_file" onchange="uploadPic()" name="pic12"/>
</form>

<script>
    //上傳圖片
    function uploadPic(){
        //定義參數
        var options = {
            url:"http://172.16.5.102:8081/ssm_project/sysUser/uploadSysHeadImg.do",
            type:"post",
            dataType:"json",
            success:function(res){
                $('#success_img').attr('src', res.realPathList[0]); //真實完整路徑
                $('#img_path').val(res.relaPathList[0]);    //相對路徑
            }
        };
        //jquery.form使用方式
        $("#jvForm").ajaxSubmit(options);
    }
</script>
</body>
</html>

效果圖:

 

 

3.3 index3-jquery-ajax提交

<!DOCTYPE html>
<html lang="en">
<head>
    <!-- 選擇圖片後,須要點擊提交按鈕,纔開始上傳,能夠不須要form標籤 -->
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <title>index3-jquery-ajax提交</title>
    <script src="jquery.min.js"></script>
</head>
<body>
<img id="success_img" height="100px">
<br>

<input type="file" id="upload_file">

<!-- 保存圖片的相對路徑,方便提交給後臺,存到數據庫 -->
<input type="hidden" name="" id="img_path"/>
<input type="button" id="uploadPicButton" value="上傳">

<div>
    <a href="" id="download" download=""></a>
</div>
<script>
    //上傳圖片
    $('#uploadPicButton').click(function () {
        var pic = $('#upload_file')[0].files[0];
        var fd = new FormData();
        fd.append('uploadFile', pic);
        $.ajax({
            url:"http://172.16.5.102:8081/ssm_project/sysUser/uploadSysHeadImg.do",
            type:"post",
            data: fd,   // Form數據
            cache: false,
            contentType: false,
            processData: false,
            success:function(res){
                $('#success_img').attr('src', res.realPathList[0]); //真實完整路徑
                $('#img_path').val(res.relaPathList[0]);    //相對路徑

                $('#download').html(res.fileNameList[0]);
                $('#download').attr('href', res.realPathList[0]);
                $('#download').attr('download', res.fileNameList[0]);
            }
        });
    })
</script>
</body>
</html>

效果圖:

 

 

 

3.4 index4-WebUploader多文件上傳

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <title>index4-WebUploader多文件上傳</title>
    <link rel="stylesheet" href="lib/webuploader/dist/webuploader.css">
    <script src="jquery.min.js"></script>
    <script src="lib/webuploader/dist/webuploader.js"></script>
    <style>
        .file-item {
            display: inline-block;
            text-align: center;
            font-size: 12px;
            margin: 10px;
        }
        .file-item .progress {
            position: relative;
            height: 6px;
            width: 100%;
            background-color: #ddd;
        }
        .file-item .progress span {
            position: absolute;
            left: 0;
            top: 0;
            width: 0%;
            height: 6px;
            background-color: dodgerblue;
        }
        .suc-img-item {
            display: inline-block;
            height: 100px;
            margin: 10px;
        }
    </style>
</head>
<body>

<h3>圖片上傳</h3>
<!--dom結構部分-->
<div id="uploader-demo">
    <h4>上傳前縮略圖</h4>
    <div id="fileList" class="uploader-list"></div>
    <div id="upInfo"></div>

    <h4>上傳後預覽圖</h4>
    <div id="successImgList">
            <!--<img class="suc-img-item" src="http://172.16.5.102:8090/upload/4337bd72-57d3-4d26-b94e-61193e9fe440.jpg">-->
            <!--<img class="suc-img-item" src="http://172.16.5.102:8090/upload/4337bd72-57d3-4d26-b94e-61193e9fe440.jpg">-->
    </div>

    <div id="filePicker">選擇文件</div>
</div>
<input type="button" id="btn" value="開始上傳">
<script>
//    // 圖片上傳demo
    $(function() {
        var $ = jQuery,
            $list = $('#fileList'),
            $successImgList = $('#successImgList'),
            ratio = window.devicePixelRatio || 1,  // 優化retina, 在retina下這個值是2 (window.devicePixelRatio是設備上物理像素和設備獨立像素(device-independent pixels (dips))的比例)
            thumbnailWidth = 50 * ratio,   // 縮略圖寬度
            thumbnailHeight = 50 * ratio,  // 縮略圖高度
            uploader;    // Web Uploader實例

        // 初始化WebUploader
        uploader = WebUploader.create({
            auto: false,   // 自動上傳
            swf:'../js/Uploader.swf',   // swf文件路徑
            server: 'http://172.16.5.102:8081/ssm_project/sysUser/uploadSysHeadImg.do',  // 文件接收服務端接口地址
            threads:'5',        //同時運行5個線程傳輸
            fileNumLimit:'10',  //文件總數量只能選擇10個

            // 選擇文件的按鈕,可選
            pick: {
                id:'#filePicker',  //選擇文件的按鈕
                multiple:true      //容許能夠同時選擇多個圖片
            },

            quality: 90,        // 圖片質量,只有type爲`image/jpeg`的時候纔有效
            compressSize: 0,     // 單位字節,若是圖片大小小於此值,不會採用壓縮
            crop: true,        //是否贊成剪切

            //限制傳輸文件類型,accept能夠不寫
            accept: {
                title: 'Images',    //描述
                extensions: 'gif,jpg,jpeg,bmp,png,mkv,mp4', //文件類型
                mimeTypes: '*/*'    //mime類型(*/* 能夠上傳全部類型)
            },

            compress: false,    //是否啓用壓縮
            resize: false,      //尺寸不改變
            duplicate: false   //是否容許重複上傳
        });


        // 當有文件添加進來的時候,建立img顯示縮略圖使用
        uploader.on('fileQueued', function(file) {
            var $li = $('<div id="' + file.id + '" class="file-item thumbnail">' +
                            '<img>' +
                            '<div class="info">' + file.name + '</div>' +
                            '<div class="progress"><span></span></div>' +
                        '</div>'),
                $img = $li.find('img');

            $list.append($li);    // $list爲容器jQuery實例

            // 建立縮略圖
            // 若是爲非圖片文件,能夠不用調用此方法。
            // thumbnailWidth x thumbnailHeight 爲 50 x 50
            uploader.makeThumb(file, function(error, src) {
                if (error) {
                    $img.replaceWith('<span>不能預覽</span>');
                    return;
                }
                $img.attr('src', src);
            }, thumbnailWidth, thumbnailHeight);
        });

        // 文件上傳過程當中建立進度條實時顯示。  uploadProgress事件:上傳過程當中觸發,攜帶上傳進度。 file:文件對象;percentage:傳輸進度 Nuber:類型
        uploader.on('uploadProgress', function(file, percentage){
            console.log(file);
            console.log(percentage);
            var $li = $('#'+file.id),
                $percent = $li.find('.progress span');

            // 避免重複建立
            if (!$percent.length) {
                $percent = $('<p class="progress"><span></span></p>').appendTo($li).find('span');
            }
            $percent.css('width', percentage * 100 + '%');
        });

        // 文件上傳成功時候觸發,給item添加成功class, 用樣式標記上傳成功。 file:文件對象,    response:服務器返回數據
        uploader.on('uploadSuccess', function(file,res) {
            $('#'+file.id).addClass('upload-state-done');
            $("#upInfo").html("<font color='red'>"+res._raw+"</font>");
            $successImgList.append('<img class="suc-img-item" src="'+res.realPathList[0]+'">');
        });

        // 文件上傳失敗                                file:文件對象 , code:出錯代碼
        uploader.on('uploadError', function(file,code) {
            var $li = $( '#'+file.id ),
                $error = $li.find('div.error');

            // 避免重複建立
            if(!$error.length) {
                $error = $('<div class="error"></div>').appendTo($li);
            }
            $error.text('上傳失敗!');
        });

        // 無論成功或者失敗,文件上傳完成時觸發。 file: 文件對象
        uploader.on('uploadComplete', function( file ) {
            $('#'+file.id ).find('.progress').remove();
        });

        //綁定提交事件
        $("#btn").click(function() {
            console.log("上傳...");
            uploader.upload();   //執行手動提交
            console.log("上傳成功");
        });

    });
</script>
</body>
</html>

效果圖:

 

4、查看文件服務器Tomcat下上傳的文件

 

 注:因爲我是一個前端開發人員,只對後臺java瞭解一點。若有更好的解決方案,但願你們一塊兒討論,共同進步。

相關文章
相關標籤/搜索