SpringBoot實現(xiàn)上傳圖片功能

1:首先在項目的pom文件中添加兩個依賴
<!-- 文件上傳組件 -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>
<!-- 圖片處理類 -->
<dependency>
    <groupId>net.coobird</groupId>
    <artifactId>thumbnailator</artifactId>
    <version>0.4.8</version>
</dependency>
2:resource中添加 file-message.properties 配置文件
file-message.properties.png

配置文件內(nèi)容如下

#文件壓縮大小(大于4兆壓縮)
message.fileSize=4194304
#圖片保存路徑
message.upPath=D:\\MyProjectName\\UploadData\\images
#壓縮比例
message.scaleRatio=0.20f
#圖片類型
message.imageType=png,jpg,jpeg
3:新建 MessageProperties 類,對應(yīng) file-message.properties 配置文件
@Component
@ConfigurationProperties(prefix="message")
@PropertySource("classpath:file-message.properties")
public class MessageProperties {

    private long fileSize;  //壓縮大小

    private double scaleRatio; //壓縮比例

    private String upPath; //保存路徑

    private String imageType; //圖片類型
    
    public long getFileSize() {
        return fileSize;
    }

    public void setFileSize(long fileSize) {
        this.fileSize = fileSize;
    }

    public double getScaleRatio() {
        return scaleRatio;
    }

    public void setScaleRatio(double scaleRatio) {
        this.scaleRatio = scaleRatio;
    }

    public String getUpPath() {
        return upPath;
    }

    public void setUpPath(String upPath) {
        this.upPath = upPath;
    }

    public String getImageType() {
        return imageType;
    }

    public void setImageType(String imageType) {
        this.imageType = imageType;
    }

}

@PropertySource("classpath:file-message.properties")對應(yīng)第二步配置文件的名稱

當(dāng)然也可以不新建 file-message.properties 文件衅金, file-message.properties 文件里的內(nèi)容可以直接寫在 application.properties 配置文件中耳幢,那MessageProperties 類就應(yīng)該按下面這種寫法:

@Component
public class MessageProperties {

    @Value("${fileSize}")
    private long fileSize;  //壓縮大小

    @Value("${scaleRatio}")
    private double scaleRatio; //壓縮比例

    @Value("${MDDIMG_LOCATION}")
    private String upPath; //保存路徑

    @Value("${imageType}")
    private String imageType; //圖片類型
    
    ...

}
4:service層接口
public interface FileUpAndDownService {

    Map<String, Object> uploadPicture(MultipartFile file) throws ServiceException;

}
5:service層接口實現(xiàn)
@Service
public class FileUpAndDownServiceImpl implements FileUpAndDownService {

    @Autowired
    private MessageProperties config; //用來獲取file-message.properties配置文件中的信息

    @Override
    public Map<String, Object> uploadPicture(MultipartFile file) throws ServiceException {
        try {
            Map<String, Object> resMap = new HashMap<>();
            String[] IMAGE_TYPE = config.getImageType().split(",");
            String path = null;
            boolean flag = false;
            for (String type : IMAGE_TYPE) {
                if (StringUtils.endsWithIgnoreCase(file.getOriginalFilename(), type)) {
                    flag = true;
                    break;
                }
            }
            if (flag) {
                resMap.put("result", IStatusMessage.SystemStatus.SUCCESS.getMessage());
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                // 獲得文件類型
                String fileType = file.getContentType();
                // 獲得文件后綴名稱
                String imageName = fileType.substring(fileType.indexOf("/") + 1);
                // 原名稱
                String oldFileName = file.getOriginalFilename();
                // 新名稱
                String newFileName = uuid + "." + imageName;
                // 年月日文件夾
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                String basedir = sdf.format(new Date());
                // 進(jìn)行壓縮(大于4M)
                if (file.getSize() > config.getFileSize()) {
                    // 重新生成
                    String newUUID = UUID.randomUUID().toString().replaceAll("-", "");
                    newFileName = newUUID + "." + imageName;
                    path = config.getUpPath() + "/" + basedir + "/" + newUUID + "." + imageName;
                    // 如果目錄不存在則創(chuàng)建目錄
                    File oldFile = new File(path);
                    if (!oldFile.exists()) {
                        oldFile.mkdirs();
                    }
                    file.transferTo(oldFile);
                    // 壓縮圖片
                    Thumbnails.of(oldFile).scale(config.getScaleRatio()).toFile(path);
                    // 顯示路徑
                    resMap.put("path", "/" + basedir + "/" + newUUID + "." + imageName);
                } else {
                    path = config.getUpPath() + "/" + basedir + "/" + uuid + "." + imageName;
                    // 如果目錄不存在則創(chuàng)建目錄
                    File uploadFile = new File(path);
                    if (!uploadFile.exists()) {
                        uploadFile.mkdirs();
                    }
                    file.transferTo(uploadFile);
                    // 顯示路徑
                    resMap.put("path", "/" + basedir + "/" + uuid + "." + imageName);
                }
                resMap.put("oldFileName", oldFileName);
                resMap.put("newFileName", newFileName);
                resMap.put("fileSize", file.getSize());
            } else {
                resMap.put("result", "圖片格式不正確,支持png|jpg|jpeg");
            }
            return resMap;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(e.getMessage());
        }
    }
}
6:Controller層的實現(xiàn)
@Controller
@RequestMapping("/upload")
public class FileUploadController {

    private static final Logger LOGGER = LoggerFactory.getLogger(FileUploadController.class);

    @Autowired
    private FileUpAndDownService fileUpAndDownService;

    @RequestMapping(value = "/setFileUpload", method = RequestMethod.POST)
    @ResponseBody
    public ResponseResult setFileUpload(@RequestParam(value = "file", required = false) MultipartFile file) {
        ResponseResult result = new ResponseResult();
        try {
            Map<String, Object> resultMap = upload(file);
            if (!IStatusMessage.SystemStatus.SUCCESS.getMessage().equals(resultMap.get("result"))) {
                result.setCode(IStatusMessage.SystemStatus.PARAM_ERROR.getCode());
                result.setMessage((String) resultMap.get("msg"));
                return result;
            }
            result.setData(resultMap);
        } catch (ServiceException e) {
            e.printStackTrace();
            LOGGER.error(">>>>>>圖片上傳異常考传,e={}", e.getMessage());
            result.setCode(IStatusMessage.SystemStatus.ERROR.getCode());
            result.setMessage(IStatusMessage.FILE_UPLOAD_ERROR);
        }
        return result;
    }

    private Map<String, Object> upload(MultipartFile file) throws ServiceException {
        Map<String, Object> returnMap = new HashMap<>();
        try {
            if (!file.isEmpty()) {
                Map<String, Object> picMap = fileUpAndDownService.uploadPicture(file);
                if (IStatusMessage.SystemStatus.SUCCESS.getMessage().equals(picMap.get("result"))) {
                    return picMap;
                } else {
                    returnMap.put("result", IStatusMessage.SystemStatus.ERROR.getMessage());
                    returnMap.put("msg", picMap.get("result"));
                }
            } else {
                LOGGER.info(">>>>>>上傳圖片為空文件");
                returnMap.put("result", IStatusMessage.SystemStatus.ERROR.getMessage());
                returnMap.put("msg", IStatusMessage.FILE_UPLOAD_NULL);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(IStatusMessage.FILE_UPLOAD_ERROR);
        }
        return returnMap;
    }
}

7:springboot項目中還需要添加下面一段代碼到Application啟動類中
@SpringBootApplication
//exclude表示自動配置時不包括Multipart配置
@EnableAutoConfiguration(exclude = {MultipartAutoConfiguration.class})
public class StartApplication {

    public static void main(String[] args) {
        ...
    }

    /**
     * 顯示聲明CommonsMultipartResolver為mutipartResolver
     */
    @Bean(name = "multipartResolver")
    public MultipartResolver multipartResolver() {
        CommonsMultipartResolver resolver = new CommonsMultipartResolver();
        //resolver.setDefaultEncoding("UTF-8");
        //resolveLazily屬性啟用是為了推遲文件解析,以在在UploadAction中捕獲文件大小異常
        resolver.setResolveLazily(true);
        resolver.setMaxInMemorySize(40960);
        resolver.setMaxUploadSize(3 * 1024 * 1024);//上傳文件大小 3M 3*1024*1024
        return resolver;
    }

}

頂部 @EnableAutoConfiguration(exclude = {MultipartAutoConfiguration.class}) 注解不要忘了
這兩段代碼不加的話奥邮,可能會造成圖片上傳成文件夾形式浇衬,上傳失敗峭范!

8:前端HTML界面,直接使用layui

HTML:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<link rel="stylesheet" href="/js/layui/css/layui.css"/>
<script type="text/javascript" src="/js/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="/js/layui/layui.js"></script>
<script type="text/javascript" src="/js/index.js"></script>

<button type="button" class="layui-btn" id="uploadBtn">
    <i class="layui-icon"></i>上傳
</button>

</body>
</html>

JS:

layui.use('upload', function () {
    var upload = layui.upload;
    //執(zhí)行實例
    var uploadInst = upload.render({
        elem: '#uploadBtn' //綁定元素
        , url: '/upload/setFileUpload' //上傳接口
        , multiple: true
        , before: function (obj) {
            //可設(shè)置回顯
            console.log(obj)
        }
        , done: function (res) {
            console.log(res);
            //上傳完畢回調(diào)
            if (res.code != 1000) {
                return layer.msg('上傳失敗');
            } else {
                return layer.msg('上傳成功');
            }
        }
        , error: function () {
            //請求異潮窦回調(diào)
        }
    });
});

上傳成功后會返回如下信息:

上傳成功.png

上傳失斏纯亍:

上傳失敗.png

ServiceException為自定義接口異常處理:

public class ServiceException extends Exception {

    public ServiceException() {
        super();
    }
    public ServiceException(String message){
        super(message);
    }   
    public ServiceException(Throwable throwable){
        super(throwable);
    }
    public ServiceException(String message ,Throwable throwable){
        super(message, throwable);
    }
}

IStatusMessage為自定義響應(yīng)狀態(tài)信息枚舉類:

public interface IStatusMessage {
    String getCode();
    String getMessage();

    enum SystemStatus implements IStatusMessage {

        SUCCESS("1000", "操作成功"), //請求成功
        ERROR("1001", "網(wǎng)絡(luò)異常,請稍后重試~"), 
        FILE_UPLOAD_NULL("1002","上傳圖片為空文件"), ;      //請求失敗
       
        private String code;
        private String message;

        SystemStatus(String code, String message) {
            this.code = code;
            this.message = message;
        }
        public String getCode() {
            return this.code;
        }
        public String getMessage() {
            return this.message;
        }
    }
}

ResponseResult前端響應(yīng)結(jié)果類:

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

public class ResponseResult implements Serializable {
    
    private static final long serialVersionUID = -148117940294941578L;
    
    private String code;
    private String message;
    private Object obj;
    
    private Map<String,Object> data; //默認(rèn)為hashMap,也可為對象

    public String getCode() {
        return code;
    }
    
    public ResponseResult() {
        this.code = IStatusMessage.SystemStatus.SUCCESS.getCode();
        this.message = IStatusMessage.SystemStatus.SUCCESS.getMessage();
    }
    
    public ResponseResult(IStatusMessage statusMessage){
        this.code = statusMessage.getCode();
        this.message = statusMessage.getMessage();
        
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getObj() {
        return obj;
    }

    public void setObj(Object obj) {
        this.obj = obj;
    }
    
    public Map<String,Object> getData() {
        return data;
    }
    public void setData(Map<String,Object> data) {
        this.data = data;
    }
    
    public void putData(String key,Object value){
        if( this. data == null ){
            this.data = new HashMap<String,Object>();
        } 
        this.data.put(key, value);
    }

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末菜秦,一起剝皮案震驚了整個濱河市甜害,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌球昨,老刑警劉巖尔店,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異主慰,居然都是意外死亡嚣州,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進(jìn)店門共螺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來该肴,“玉大人,你說我怎么就攤上這事藐不≡群澹” “怎么了?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵雏蛮,是天一觀的道長涎嚼。 經(jīng)常有香客問我,道長挑秉,這世上最難降的妖魔是什么法梯? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮犀概,結(jié)果婚禮上鹊汛,老公的妹妹穿的比我還像新娘。我一直安慰自己阱冶,他們只是感情好刁憋,可當(dāng)我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著木蹬,像睡著了一般至耻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上镊叁,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天尘颓,我揣著相機與錄音,去河邊找鬼晦譬。 笑死疤苹,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的敛腌。 我是一名探鬼主播卧土,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼惫皱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了尤莺?” 一聲冷哼從身側(cè)響起旅敷,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎颤霎,沒想到半個月后媳谁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡友酱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年晴音,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缔杉。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡锤躁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出壮吩,到底是詐尸還是另有隱情进苍,我是刑警寧澤,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布鸭叙,位于F島的核電站觉啊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏沈贝。R本人自食惡果不足惜杠人,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望宋下。 院中可真熱鬧嗡善,春花似錦、人聲如沸学歧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽枝笨。三九已至袁铐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間横浑,已是汗流浹背剔桨。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留徙融,地道東北人洒缀。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親树绩。 傳聞我的和親對象是個殘疾皇子萨脑,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,492評論 2 348

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