前端部分,我使用了element-ui组件库中的el-upload,其中一些参数及含义官网都有,可以去官网自行查看
思路:先将文件传到后台服务器,
然后后台服务器上传至本地,并返回地址,
前端接收图片保存的地址信息,
再将此信息作为表单数据连同其他数据一起传递并保存至数据库
前端代码:
<template>
<div>
<el-form :model="hotelform" ref="hotelformRef">
<el-form-item label="酒店名称" :label-width="formLabelWidth">
<el-input v-model="hotelform.name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="酒店类型" :label-width="formLabelWidth">
<el-select v-model="hotelform.type" placeholder="请选择酒店类型">
<el-option label="经济型" value="经济型"></el-option>
<el-option label="标准型" value="标准型"></el-option>
<el-option label="豪华型" value="豪华型"></el-option>
</el-select>
</el-form-item>
<el-form-item label="酒店位置" :label-width="formLabelWidth">
<el-input id="myInput" aria-placeholder="请输入位置或自动定位" v-model="hotelform.address"></el-input>
</el-form-item>
<el-form-item label="详情概览" :label-width="formLabelWidth">
<el-input type="textarea" v-model="hotelform.info"></el-input>
</el-form-item>
<el-form-item label="住店须知" :label-width="formLabelWidth">
<el-input type="textarea" v-model="hotelform.warning"></el-input>
</el-form-item>
<el-form-item label="酒店图片" :label-width="formLabelWidth">
<el-upload
ref="hotelImgFile"
action="http://localhost:8099/hotel/upload"
list-type="picture-card"
multiple
:on-preview="handleImgPreview"
:on-remove="handleImgRemove"
:on-success="handleImgSuccess" >
<i class="el-icon-plus"></i>
</el-upload>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="warning">取 消</el-button>
<el-button type="primary" @click="hotelAddSubmit()">确 定</el-button>
</div>
</div>
</template>
<script>
const funcOptions = ['WiFi','停车位','行李寄存','淋浴室'];
export default {
data() {
return {
formLabelWidth: '120px',//表单Label宽度
hotelform:{
//酒店功能与全选相关
func:funcOptions,
checkAll: true,
checkedFuncs: ['WiFi', '停车位'],
isIndeterminate: true,
},
}
},
methods: {
//全选
handleCheckAllChange(val) {
if(this.hotelform.checkAll){
this.hotelform.checkedFuncs = funcOptions;
}
else{
this.hotelform.checkedFuncs =[];
}
this.hotelform.checkedFuncs = val ? funcOptions : [];
this.hotelform.isIndeterminate = false;
},
handleCheckedFuncChange(val) {
let checkedCount = value.length;
this.hotelform.checkAll = checkedCount === this.hotelform.func.length;
this.hotelform.isIndeterminate = checkedCount > 0 && checkedCount < this.hotelform.func.length;
this.hotelform.checkedFuncs = val;
},
//图片移除
handleImgRemove(file, fileList) {
console.log(file, fileList);
},
//图片上传成功时的钩子函数
handleImgSuccess(res,file){
// console.log(file);
// console.log(this.hotelform);
// //取到图片文件,通过ref关联
let myFile = this.$refs.hotelImgFile;
// // console.log(myFile);
// // console.log(myFile.file-list)
// // let file = document.getElementById("hotelimgs").files;
// // console.log(file);
// var file = myFile.files[0];
// //let file = myFile.files.item(0);
// //let file = myFile.uploadFiles;
let formData = new FormData();
//
formData.append("file",file);//这里的name应该与后台获取的MultipartFile参数名一致
// formData.append("hotel_name",this.hotelform.name);
// formData.append("hotel_type",this.hotelform.type);
// formData.append("hotel_address",this.hotelform.address);
// // formData.append("hotel_func",this.hotelform.checkedFuncs);
// formData.append("hotel_info",this.hotelform.info);
// console.log(formData)
// axios({
// method:'post',
// url:'/hotel/upload',
// data:formData,
// headers:{
// 'Content-Type':'multipart/form-data'
// }
// }).then((res)=>{
// console.log("then");
// console.log(res.data);
// console.log(res);
// })
// this.$message({
// type:'info',
// message:'图片上传成功',
// duration:6000
// });
//注意,当直接使用<input type="file">进行文件选择时,才需要这些操作,而我用的el-upload组件有直接封装的一些参数及方法,因此可以不用这些操作
if(file.response.data!=null){
this.hotelform.img = file.response.data;//将返回的文件储存路径赋值给img,方便后面提交表单时将此处获取的信息作为表单数据提交到数据库
alert(this.hotelform.img);
}
else {
alert("发生错误")
}
},
handleImgPreview(file) {
console.log(file);
},
//提交酒店添加表单
hotelAddSubmit(){
let formData = new FormData();
//formData.append可以直接添加之前未声明的字段,这里的name与数据库中的字段名对应
formData.append("hotel_name",this.hotelform.name);
formData.append("hotel_type",this.hotelform.type);
formData.append("hotel_address",this.hotelform.address);
// formData.append("hotel_func",this.hotelform.checkedFuncs);
formData.append("hotel_info",this.hotelform.info);
formData.append("hotel_img",this.hotelform.img);
this.$http.post('/hotel/save',formData).then(result => {
console.log(formData.getAll("hotel_name"));
console.log(result);
// if(result.body.success){
// //保存成功
// this.$message({
// type:'success',
// message:result.body.message,
// duration:6000
// })
// }
})
}
}
}
</script>
<style scoped>
</style>
由于我调用了el-upload的一些方法,里面的文件通过myFile.files[0]获取,结果一直报错,后来才发现原来可以直接通过其参数来获取,还让我找了一天的bug,哭了
后台
emmm…DAO,Pojo这些层的代码和普通一样,这里就不详细讲了,简单贴一下,主要讲一下配置文件及Controller层
实体层
/pojo/Hotel.java
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
@Data
public class Hotel {
@Id
private int hotel_id;
private String hotel_name;
private String hotel_type;
private String hotel_area;
private String hotel_address;
private String hotel_func;
private Float hotel_grade;
private String hotel_info;
private String hotel_img;
private String hotel_video;
}
dao/HotelDAO.java
import com.example.hotelapi.pojo.Hotel;
import org.springframework.data.jpa.repository.JpaRepository;
public interface HotelDAO extends JpaRepository<Hotel,Integer> {
}
result/CommonResult
public class CommonResult<T> {
private long code;
private String message;
private T data;
protected CommonResult() {
}
protected CommonResult(long code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
/**
* 成功返回结果
*
* @param data 获取的数据
*/
public static <T> CommonResult<T> success(T data) {
return new CommonResult<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);
}
/**
* 成功返回结果
*
* @param data 获取的数据
* @param message 提示信息
*/
public static <T> CommonResult<T> success(T data, String message) {
return new CommonResult<T>(ResultCode.SUCCESS.getCode(), message, data);
}
/**
* 失败返回结果
*
* @param errorCode 错误码
*/
public static <T> CommonResult<T> failed(IErrorCode errorCode) {
return new CommonResult<T>(errorCode.getCode(), errorCode.getMessage(), null);
}
/**
* 失败返回结果
*
* @param message 提示信息
*/
public static <T> CommonResult<T> failed(String message) {
return new CommonResult<T>(ResultCode.FAILED.getCode(), message, null);
}
/**
* 失败返回结果
*/
public static <T> CommonResult<T> failed() {
return failed(ResultCode.FAILED);
}
/**
* 参数验证失败返回结果
*/
public static <T> CommonResult<T> validateFailed() {
return failed(ResultCode.VALIDATE_FAILED);
}
/**
* 参数验证失败返回结果
*
* @param message 提示信息
*/
public static <T> CommonResult<T> validateFailed(String message) {
return new CommonResult<T>(ResultCode.VALIDATE_FAILED.getCode(), message, null);
}
/**
* 未登录返回结果
*/
public static <T> CommonResult<T> unauthorized(T data) {
return new CommonResult<T>(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data);
}
/**
* 未授权返回结果
*/
public static <T> CommonResult<T> forbidden(T data) {
return new CommonResult<T>(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage(), data);
}
public long getCode() {
return code;
}
public void setCode(long code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
详细讲配置文件及Controller
application.properties文件新增以下内容
#指定图片文件上传到本地的目录,新建一个文件夹用于存放
upload.dir=D:/fileResource/images
HotelController.java
import com.example.hotelapi.Service.HotelService;
import com.example.hotelapi.dao.HotelDAO;
import com.example.hotelapi.pojo.Hotel;
import com.example.hotelapi.result.CommonResult;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
//import org.springframework.util.Base64Utils;
//import org.springframework.util.Base64Utils;
//@RestController表示该类下所有返回值默认以json格式进行返回
@RestController
@RequestMapping("/hotel")
public class HotelController {
@Autowired
private HotelDAO hotelDAO;
@Autowired
private HotelService hotelService;
//文件的真实位置,将配置文件中的目录注入过来
// 我之前少写了右花括号,导致一直报错500,系统找不到文件路径,后来是直接把路径直接写到这里才发现的错误
@Value("${upload.dir}")
private String realPath;
@GetMapping("/hotellist")
public List<Hotel> hotels(){
return hotelDAO.findAll();
}
// @PostMapping("/hoteladd/fenmian")
// public JSONObject hotelvideo(@RequestParam(value="file",required = false)MultipartFile file,Hotel hotel)throws IOException{
// JSONObject res = new JSONObject();
// JSONObject resUrl = new JSONObject();
// String filename = UUID.randomUUID().toString().replaceAll("-","");
// String ext = FilenameUtils.getExtension(file.getOriginalFilename());
// String newFileName = filename + "." + ext;
// file.transferTo(new File(realPath, newFileName));
// resUrl.put("src", "/pic/"+newFileName);
// res.put("msg", "");
// res.put("code", 0);
// res.put("data", resUrl);
// return res;
// }
// @PostMapping("/hoteladd")
// @ResponseBody
// public JSONObject hotelimages(@RequestParam(value = "file", required = false) MultipartFile[] file) throws IOException {
// JSONObject res = new JSONObject();
// JSONObject resUrl = new JSONObject();
// List<String> imageurls=new ArrayList<>();
// for (MultipartFile files:file){
// String filename = UUID.randomUUID().toString().replaceAll("-", "");
// String ext = FilenameUtils.getExtension(files.getOriginalFilename());
// String newFileName = filename + "." + ext;
// files.transferTo(new File(realPath, newFileName));
// imageurls.add("/pic/"+newFileName);
// res.put("msg", "");
// res.put("code", 0);
// }
// resUrl.put("src", imageurls);
// res.put("data", resUrl);
// return res;
// }
@PostMapping("/upload")
public CommonResult upload(MultipartFile file, Hotel hotel)throws IOException {
//System.out.println(file.getOriginalFilename());
// System.out.println(hotel);
//注:我原来写了try{}catch{},没有直接提示异常信息,而是在打印返回数据时才看到控制台中提示404信息,但却能添加文件,虽然文件已经添加成功,但还是提示系统找不到文件路径
try {
//文件上传,需要在配置文件application.properties中指定目录
//获取文件的扩展名
// String extension = FilenameUtils.getExtension(file.getOriginalFilename());
System.out.println(file);
String originalFilename = file.getOriginalFilename();
String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
System.out.println(file.getOriginalFilename());
String newFileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + extension;//设置图片信息,Base64编码处理,应该先处理再进行上传,不然会报错找不到文件路径
hotel.setHotel_img(Base64Utils.encodeToString(file.getBytes()));
//文件上传
File destFile = new File(realPath, newFileName);
//destFile.createNewFile();
file.transferTo(destFile);
设置图片信息,Base64编码处理
//hotel.setHotel_img(Base64Utils.encodeToString(file.getBytes()));
//保存hotel对象
// hotelDAO.save(hotel);
System.out.println(hotel.getHotel_img());
return CommonResult.success(hotel.getHotel_img(),"保存成功");
}catch (Exception e){
e.printStackTrace();
return CommonResult.failed("发生未知错误");
}
//return "ok";
}
@PostMapping("/save")
public CommonResult save(Hotel hotel){
// System.out.println(hotel);
if(StringUtils.isNotBlank(hotel.getHotel_name())){
// try {
System.out.println(hotel);
hotelDAO.save(hotel);
return CommonResult.success(hotel, "添加成功");
// }catch (Exception e){
// e.printStackTrace();
// }
}
return CommonResult.failed("发生未知错误");
}
}
之后,即可在前面配置的d:/fileReasource/images下看到后台上传到本地的图片信息了,通过/save之后,可以看到数据库中也添加进了相应数据