基于SpringBoot的圖片上傳與顯示(付源碼)

Demo地址

https://github.com/HelloSummer5/FileUploadDemo

效果圖預覽

圖片上傳Demo效果圖

思路

  • 一般情況下都是將用戶上傳的圖片放到服務器的某個文件夾中,然后將圖片在服務器中的路徑存入數(shù)據(jù)庫昏名。本Demo也是這樣做的涮雷。
  • 由于用戶自己保存的圖片文件名可能跟其他用戶同名造成沖突,因此本Demo選擇了使用UUID來生成隨機的文件名解決沖突轻局。
  • 但是本Demo不涉及任何有關數(shù)據(jù)庫的操作洪鸭,便于演示样刷,就用原來的文件名。

步驟

pom相關依賴

  • 基于Spring boot當然是繼承了spring boot這不用多說
  • 具體依賴卿嘲,主要是FreeMarker相關依賴為了展現(xiàn)頁面颂斜,習慣用JSP也可以添加JSP的依賴,只是為了展示頁面拾枣,這個不重要沃疮。
<dependencies>
 <!--FreeMarker模板視圖依賴-->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-freemarker</artifactId>
       </dependency>

       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>

       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-test</artifactId>
           <scope>test</scope>
       </dependency>
   </dependencies>

application.properties相關配置

  • 除了視圖模板相關的配置,重點是要配置一下文件上傳的內(nèi)存大小和文件上傳路徑
server.port=8102

### FreeMarker 配置
spring.freemarker.allow-request-override=false
#Enable template caching.啟用模板緩存梅肤。
spring.freemarker.cache=false
spring.freemarker.check-template-location=true
spring.freemarker.charset=UTF-8
spring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=false
spring.freemarker.expose-session-attributes=false
spring.freemarker.expose-spring-macro-helpers=false
#設置面板后綴
spring.freemarker.suffix=.ftl

# 設置單個文件最大內(nèi)存
multipart.maxFileSize=50Mb
# 設置所有文件最大內(nèi)存
multipart.maxRequestSize=50Mb
# 自定義文件上傳路徑
web.upload-path=E:/Develop/Files/Photos/

生成文件名

  • 不準備生成文件名的可以略過此步驟
package com.wu.demo.fileupload.demo.util;

public class FileNameUtils {

    /**
     * 獲取文件后綴
     * @param fileName
     * @return
     */
    public static String getSuffix(String fileName){
        return fileName.substring(fileName.lastIndexOf("."));
    }

    /**
     * 生成新的文件名
     * @param fileOriginName 源文件名
     * @return
     */
    public static String getFileName(String fileOriginName){
        return UUIDUtils.getUUID() + FileNameUtils.getSuffix(fileOriginName);
    }

}


import java.util.UUID;

/**
 * 生成文件名
 */
public class UUIDUtils {

    public static String getUUID(){
        return UUID.randomUUID().toString().replace("-", "");
    }

}

文件上傳工具類

package com.wu.demo.fileupload.demo.util;

import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

/**
 * 文件上傳工具包
 */
public class FileUtils {

    /**
     *
     * @param file 文件
     * @param path 文件存放路徑
     * @param fileName 源文件名
     * @return
     */
    public static boolean upload(MultipartFile file, String path, String fileName){
    
        // 生成新的文件名
        //String realPath = path + "/" + FileNameUtils.getFileName(fileName);

        //使用原文件名
        String realPath = path + "/" + fileName;

        File dest = new File(realPath);

        //判斷文件父目錄是否存在
        if(!dest.getParentFile().exists()){
            dest.getParentFile().mkdir();
        }

        try {
            //保存文件
            file.transferTo(dest);
            return true;
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        }

    }
}

Controller

package com.wu.demo.fileupload.demo.controller;

import com.wu.demo.fileupload.demo.util.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.Map;

@Controller
public class TestController {

    private final ResourceLoader resourceLoader;

    @Autowired
    public TestController(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    @Value("${web.upload-path}")
    private String path;

    /**
     * 跳轉到文件上傳頁面
     * @return
     */
    @RequestMapping("test")
    public String toUpload(){
        return "test";
    }

    /**
     *
     * @param file 要上傳的文件
     * @return
     */
    @RequestMapping("fileUpload")
    public String upload(@RequestParam("fileName") MultipartFile file, Map<String, Object> map){

        // 要上傳的目標文件存放路徑
        String localPath = "E:/Develop/Files/Photos";
        // 上傳成功或者失敗的提示
        String msg = "";

        if (FileUtils.upload(file, localPath, file.getOriginalFilename())){
            // 上傳成功司蔬,給出頁面提示
            msg = "上傳成功!";
        }else {
            msg = "上傳失斠毯俊啼!";

        }

        // 顯示圖片
        map.put("msg", msg);
        map.put("fileName", file.getOriginalFilename());

        return "forward:/test";
    }

    /**
     * 顯示單張圖片
     * @return
     */
    @RequestMapping("show")
    public ResponseEntity showPhotos(String fileName){

        try {
            // 由于是讀取本機的文件,file是一定要加上的左医, path是在application配置文件中的路徑
            return ResponseEntity.ok(resourceLoader.getResource("file:" + path + fileName));
        } catch (Exception e) {
            return ResponseEntity.notFound().build();
        }
    }

}

頁面

  • 頁面主要是from表單和下面的 <img src="/show?fileName=${fileName}" /> 授帕,其余都是細節(jié)。
<!DOCTYPE html>
<head>
    <meta charset="UTF-8" />
    <title>圖片上傳Demo</title>
</head>
<body>
<h1 >圖片上傳Demo</h1>
<form action="fileUpload" method="post" enctype="multipart/form-data">
    <p>選擇文件: <input type="file" name="fileName"/></p>
    <p><input type="submit" value="提交"/></p>
</form>
<#--判斷是否上傳文件-->
<#if msg??>
    <span>${msg}</span><br>
<#else >
    <span>${msg!("文件未上傳")}</span><br>
</#if>
<#--顯示圖片浮梢,一定要在img中的src發(fā)請求給controller跛十,否則直接跳轉是亂碼-->
<#if fileName??>
<img src="/show?fileName=${fileName}" style="width: 200px"/>
<#else>
<img src="/show" style="width: 100px"/>
</#if>
</body>
</html>

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市秕硝,隨后出現(xiàn)的幾起案子芥映,更是在濱河造成了極大的恐慌,老刑警劉巖远豺,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奈偏,死亡現(xiàn)場離奇詭異,居然都是意外死亡躯护,警方通過查閱死者的電腦和手機惊来,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來榛做,“玉大人唁盏,你說我怎么就攤上這事〖烀校” “怎么了厘擂?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長锰瘸。 經(jīng)常有香客問我刽严,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任舞萄,我火速辦了婚禮眨补,結果婚禮上,老公的妹妹穿的比我還像新娘倒脓。我一直安慰自己撑螺,他們只是感情好,可當我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布崎弃。 她就那樣靜靜地躺著甘晤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪饲做。 梳的紋絲不亂的頭發(fā)上线婚,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天,我揣著相機與錄音盆均,去河邊找鬼塞弊。 笑死,一個胖子當著我的面吹牛泪姨,可吹牛的內(nèi)容都是我干的游沿。 我是一名探鬼主播,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼肮砾,長吁一口氣:“原來是場噩夢啊……” “哼奏候!你這毒婦竟也來了?” 一聲冷哼從身側響起唇敞,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎咒彤,沒想到半個月后疆柔,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡镶柱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年旷档,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片歇拆。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡鞋屈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出故觅,到底是詐尸還是另有隱情厂庇,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布输吏,位于F島的核電站权旷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏贯溅。R本人自食惡果不足惜拄氯,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一躲查、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧译柏,春花似錦镣煮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至黔衡,卻和暖如春蚓聘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盟劫。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工夜牡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人侣签。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓塘装,卻偏偏與公主長得像,于是被迫代替她去往敵國和親影所。 傳聞我的和親對象是個殘疾皇子蹦肴,可洞房花燭夜當晚...
    茶點故事閱讀 44,947評論 2 355

推薦閱讀更多精彩內(nèi)容