1、想做一個小的商城系統,里面有個商家模塊,我用layui.table顯示的,但是當我想把圖片加進去時才發現對於相對路徑和絕對路徑的理解不夠,進過研究終於搞出來了,不多說直接上代碼。
2、首先要了解springboot內置tomcat和外置tomcat里面的虛擬路徑的配置。
內置tomcat虛擬路徑的配置有兩種:
第一種:直接在application.properties中配置,配置方法如下:
# 默認值為/** spring.mvc.static-path-pattern=/** # 默認值為 classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,\ classpath:/static/, classpath:/public/,file:D:/var/uploaded_files/
第二種方法:新建一個config類,我建的是StaticMvcConfigurerAdapter配置方法,該方法需要實現WebMvcConfigurerAdapter類
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class StaticMvcConfigurerAdapter extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); // 指明瀏覽器標簽頁上標題的小圖標 // registry.addResourceHandler("/favicon.ico").addResourceLocations("classpath:/static/images/favicon.ico"); // super.addResourceHandlers(registry); registry.addResourceHandler("/uploaded_files/**").addResourceLocations("file:/var/uploaded_files/"); } }
上述兩種方法選一種即可
外置tomcat的配置:
https://www.cnblogs.com/hglibin/p/10392078.html
這里就不多說了
3、layui頁面
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>商家信息管理</title> <link rel="stylesheet" th:href="@{/layui/css/layui.css}"> </head> <style> .layui-table-cell{ display:table-cell; vertical-align: middle; } </style> <body> <blockquote class="layui-elem-quote role_search"> <div class="layui-inline"> <div class="layui-input-inline"> <input id="keyword" type="text" value="" placeholder="請輸入類別名稱" class="layui-input search_input"> </div> <a class="layui-btn search_btn" onclick="query()"><i class="layui-icon layui-icon-search"></i></a> </div> <div class="layui-inline"> <a class="layui-btn layui-btn-normal newsAdd_btn" onclick="openDialog()"> <i class="layui-icon layui-icon-add-circle-fine"></i>新增商家</a> </div> </blockquote> <table class="layui-hide" id="business" lay-filter="tools"></table> <script type="text/html" id="tools"> <a class="layui-btn layui-btn-xs" lay-event="edit"><i class="layui-icon layui-icon-edit"></i></a> <a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del"><i class="layui-icon layui-icon-delete"></i></a> </script> <script type="text/html" id="barDemo"> <a class="layui-btn layui-btn-xs" lay-event="find" onclick="openProduct()">商品信息</a> </script> <script type="text/html" id="imgTpl"> <img src="{{ d.picture }}"> <!--<div><img src="{{d.picture}}"></div>--> </script> <script th:src="@{layui/layui.js}"></script> <script th:src="@{jquery-1.11.3.js}"></script> <script th:src="@{/biz/business_detail.js}"></script> </body> </html>
business_detail.js
var table; var layer; layui.use(['layer', 'table', 'element'], function () { table = layui.table; layer = layui.layer; // 執行一個 table 實例 table.render({ elem: '#business', height: 472, url: 'business_list', page: true, // 開啟分頁 limits: [10, 20], limit: 10, cols: [[ // 表頭 { fixed: 'left', type: 'checkbox' }, { field: 'shopId', title: '商家編號', width: 160, align: 'center' }, { field: 'name', title: '商家名稱', width: 160, align: 'center' }, { field: 'introduction', title: '商家介紹', width: 300, align: 'center' }, { field: 'picture', title: '商家圖片', templet: '<div><img src="{{d.picture}}"></div>', width: 160, align: 'center' }, { title: '詳情', width: 160, align: 'center', toolbar: '#barDemo' }, { title: '操作', width: 160, align: 'center', toolbar: '#tools' } ]] });
這里點擊上傳圖片之后,返回滿足layui格式的json數據,然后通過回調函數把url地址賦值達到預覽效果,代碼如下
//html代碼
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>商家信息</title>
<link rel="stylesheet" th:href="@{/layui/css/layui.css}">
</head>
<body>
<form class="layui-form" th:object="${business}" id="businessFrm" method="post" enctype="multipart/form-data">
<input type="hidden" name="shopId" id="shopId" th:value="*{shopId}"/>
<div class="layui-form-item" style="margin-top: 20px;">
<label class="layui-form-label">商家名稱:</label>
<div class="layui-input-block">
<input type="text" name="name" id="name" th:value="*{name}"
style="width: 200px;" placeholder="請輸入商家名稱" class="layui-input" lay-verify="required">
</div>
</div>
<div class="layui-form-item" style="margin-top: 20px;">
<label class="layui-form-label">商家簡介:</label>
<div class="layui-input-block">
<input type="text" name="Introduction" id="Introduction" th:value="*{introduction}"
style="width: 200px;" placeholder="請輸入商家簡介" class="layui-input" lay-verify="required">
</div>
</div>
<div class="layui-form-item" style="margin-top: 20px;">
<label class="layui-form-label">商家圖片:</label>
<div class="layui-upload">
<button type="button" class="layui-btn" id="test1">上傳圖片</button>
<input type="hidden" id="img_url" name="picture"/>
<div class="layui-upload-list">
<img class="layui-upload-img" name="picture" id="picture" th:value="*{picture}">
<p id="demoText"></p>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit="" lay-filter="*">確認</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
<script th:src="@{/layui/layui.js}"></script>
<script th:src="@{/jquery-1.11.3.js}"></script>
<script th:src="@{/biz/business_view.js}"></script>
</body>
</html>
html和js兩個要分開,這里我寫到一起了
//business_view.js代碼
layui.use(['form', 'layer','upload'], function () { var form = layui.form; var layer = layui.layer; var $ = layui.jquery ,upload = layui.upload; // 添加驗證規則 form.verify({ name: function (value, item) { value = value.trim(); if (value.length < 0) { return "請輸入商家名稱"; } } }); var uploadInst = upload.render({ elem: '#test1' ,url: '/upload' ,before: function(obj){ files = obj.pushFile(); //將每次選擇的文件追加到文件隊列 //預讀本地文件示例,不支持ie8 obj.preview(function(index, picture, result){//回調函數達到預覽效果 $('#picture').attr('src', result); //圖片鏈接(base64) }); } ,done: function(res){ //如果上傳失敗 if(res.code > 0){ return layer.msg('上傳失敗'); } //上傳成功 layer.msg(res.msg); // alert("上傳成功"+res.msg); document.getElementById("img_url").value = res.data.src; // document.getElementById("picture").value = res.data.src(); /*if(res.code==0){ $('.layui-upload-list').html('<img class="layui-upload-list" style="width:80px;height:100px" src="'+res.src+'" id="demo1"> <p id="demoText"></p>'); $('.layui-btn').css({"margin-left":"104px","width":"90px","margin-top":"6px"}); $('.layui-btn').text("重新上傳"); return layer.msg(res.msg,{time:700}); }*/ } ,error: function(){ //演示失敗狀態,並實現重傳 var demoText = $('#demoText'); demoText.html('<span style="color: #FF5722;">上傳失敗</span> <a class="layui-btn layui-btn-mini demo-reload">重試</a>'); demoText.find('.demo-reload').on('click', function(){ uploadInst.upload(); }); } }); form.on('submit(*)', function (data) { layer.alert(JSON.stringify(data.field), { title: '最終的提交信息' }) var index = layer.msg('提交中,請稍候', {icon: 16, time: false, shade: 0.8}); var context = data.field; var url = "/saveOrUpdate"; $.ajax({ type: 'POST', url: "/saveOrUpdate", data: context, dataType: "text", success: function (data) { var index = parent.layer.getFrameIndex(window.name); //獲取窗口索引 parent.layer.close(index); // 關閉layer if (data == 0) { parent.layer.msg("操作成功", {icon: 6}); parent.table.reload('business', { page: { curr: 1 // 重新從第1頁開始 }, where: { 'keyword': $("#keyword").val() } }); } else { parent.layer.msg("操作失敗", {icon: 5}); } }, error: function () { parent.layer.msg("操作失敗", {icon: 5}); } }); return false; }); });
controller層photoUpload.controller
import com.alibaba.fastjson.JSONObject; import org.springframework.beans.factory.annotation.Autowired; 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 javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.UUID; @Controller public class photoUpload { @Autowired private BusinessDao businessDao; @ResponseBody @RequestMapping("/upload") public JSONObject uploadaaa(MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws IllegalStateException, IOException{ JSONObject res = new JSONObject(); JSONObject resUrl = new JSONObject(); //String path = request.getSession().getServletContext().getRealPath("upload"); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");//設置日期格式 HH:mm:ss String date = df.format(new Date());// new Date()為獲取當前系統時間,也可使用當前時間戳 String path = "D:/var/uploaded_files/"; UUID uuid=UUID.randomUUID(); String originalFilename = file.getOriginalFilename(); // String fileName = uuid.toString() + originalFilename; String extendName = originalFilename.substring(originalFilename.lastIndexOf("."), originalFilename.length()); String fileName = uuid.toString() + extendName; File dir = new File(path+fileName); File filepath = new File(path); System.out.println("路徑=="+filepath.getParentFile()); if(!filepath.getParentFile().exists()){ filepath.getParentFile().mkdirs(); }else{ System.out.println(filepath.getParentFile()); } // if(!filepath.exists()) { file.transferTo(dir); //獲得當前項目所在路徑 String pathRoot=request.getSession().getServletContext().getRealPath(""); System.out.println("當前項目所在路徑:"+pathRoot); String sqlFile = "http://localhost:8003/"+fileName; Business business =new Business(); business.setPicture(sqlFile); businessDao.save(business); // } resUrl.put("src", sqlFile); res.put("code", 0); res.put("msg", "上傳成功"); res.put("data", resUrl); String str=""; str = "{\"code\": 0,\"msg\": \"\",\"data\": {\"src\":\"" +dir + "\"}}"; return res; /*Map<String, String> map = new HashMap<>(); map.put("filePath", path); map.put("fileName", fileName); Map<String, Object> result = new HashMap<>(); result.put("code", 0); result.put("msg", "上傳成功"); result.put("count", 1); result.put("data", map); return result;*/ } //@RequestParam(required=false)MultipartFile file 表示圖片接受可為空 @ResponseBody @RequestMapping(value = "/saveOrUpdate",method = RequestMethod.POST) public Integer saveOrUpdate (@RequestParam("shopId") int shopId, @RequestParam("Introduction") String Introduction, @RequestParam("picture") String picture, // @RequestParam("file") String file, MultipartFile file, HttpServletRequest request){ JSONObject res = new JSONObject(); JSONObject resUrl = new JSONObject(); try { String pictureFile = file.getOriginalFilename(); Business business =new Business(); business.setPicture(picture); // business.setBusinessid(bussinessid); business.setIntroduction(Introduction); business.setShopId(shopId); businessDao.save(business); } catch (Exception e) { e.printStackTrace(); /*res.put("code", 500); res.put("msg", "服務器內部錯誤"); res.put("count", 0); res.put("data", new ArrayList()); return res;*/ } /* res.put("count", 10); res.put("code", 0); res.put("msg", "上傳成功"); res.put("data", new ArrayList());*/ return 0; } }
實體類:Business
import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import java.util.Objects; @Entity public class Business { private int shopId; private Integer businessid; private String name; private String picture; private String introduction; @Id @Column(name = "shop_id", nullable = false) public int getShopId() { return shopId; } public void setShopId(int shopId) { this.shopId = shopId; } @Basic @Column(name = "businessid", nullable = true) public Integer getBusinessid() { return businessid; } public void setBusinessid(Integer businessid) { this.businessid = businessid; } @Basic @Column(name = "name", nullable = true, length = 128) public String getName() { return name; } public void setName(String name) { this.name = name; } @Basic @Column(name = "picture", nullable = true, length = 255) public String getPicture() { return picture; } public void setPicture(String picture) { this.picture = picture; } @Basic @Column(name = "Introduction", nullable = true, length = 255) public String getIntroduction() { return introduction; } public void setIntroduction(String introduction) { this.introduction = introduction; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Business business = (Business) o; return shopId == business.shopId && Objects.equals(businessid, business.businessid) && Objects.equals(name, business.name) && Objects.equals(picture, business.picture) && Objects.equals(introduction, business.introduction); } @Override public int hashCode() { return Objects.hash(shopId, businessid, name, picture, introduction); } }
Dao層
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.stereotype.Repository; @Repository public interface BusinessDao extends JpaRepository<Business, Integer>, JpaSpecificationExecutor<Business> { /*@Query(value="select * from business where bus_id=?",nativeQuery=true) Business findAllByBusIdA(int bus_id); @Query(value="select * from business",nativeQuery=true) List<Business> findAll(Specification<Business> specification); */ /*@Query(value="select * from business",nativeQuery=true) List<Business> findAll();*/ }
好了到這里就完成了,最后附上界面