vue+springboot整合jpa实现图文上传

前端部分,我使用了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之后,可以看到数据库中也添加进了相应数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值