Vue使用axios提交POJO数据(含文件)到后端

该代码示例展示了如何使用Vue.js组件创建一个前端页面,用于输入商品的基本信息如名称、价格、库存等,并通过axios与后端接口进行交互。用户可以选择商品图片,选择是否推荐和作为广告,以及商品分类。提交时,数据会以multipart/form-data格式发送到后端,后端处理文件上传和商品信息存储。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前端页面

前端代码:GoodBaseSetting.vue

<template>
    <div>
        <el-container class="content-row">
            <div class="input-tip">
                商品名称:
            </div>
            <div class="input-field">
                <el-input v-model="queryParams.gname"></el-input>
            </div>
        </el-container>
        <el-container class="content-row">
            <div class="input-tip">
                商品原价:
            </div>
            <div class="input-field">
                <el-input v-model="queryParams.goprice"></el-input>
            </div>
        </el-container>
        <el-container class="content-row">
            <div class="input-tip">
                商品折扣价:
            </div>
            <div class="input-field">
                <el-input v-model="queryParams.grprice"></el-input>
            </div>
        </el-container>
        <el-container class="content-row">
            <div class="input-tip">
                库存数量:
            </div>
            <div class="input-field">
                <el-input v-model="queryParams.gstore"></el-input>
            </div>
        </el-container>
        <el-container class="content-row">
            <div class="input-tip">
                商品封面:
            </div>
                <el-upload
                name="fileName" 
                :auto-upload="false"
                :limit="1" 
                :on-change="handleChange"
                :file-list="fileList"
                list-type="picture-card">
                    <i class="el-icon-plus"></i>
                </el-upload>
        </el-container> 
        
        <el-container class="content-row">
            <div class="input-tip">
                是否推荐:
            </div>
            <div class="input-field">
                <el-radio-group v-model="queryParams.isRecommend">
                    <el-radio label="1">是</el-radio>
                    <el-radio label="0">否</el-radio>
                </el-radio-group>
            </div>
        </el-container>
        
        <el-container class="content-row">
            <div class="input-tip">
                是否广告:
            </div>
            <div class="input-field">
                <el-radio-group v-model="queryParams.isAdvertisement">
                    <el-radio label="1">是</el-radio>
                    <el-radio label="0">否</el-radio>
                </el-radio-group>
            </div>
        </el-container>

        <el-container class="content-row">
            <div class="input-tip">
                商品分类:
            </div>
            <div class="input-field">
                <el-select v-model="queryParams.goodstype_id">
                    <el-option v-for="item in categoryList" 
                        :key="item.id" :label="item.typename" :value="item.id">
                    </el-option>
                </el-select>
            </div>
            <div style="margin-top:6px">
                <el-button type="primary" size="mini" round @click="addCategory">添加分类</el-button>
            </div>
        </el-container>
        <el-container class="content-row">
            <el-button type="success" plain @click="submit">提交</el-button>
            <div style="margin-left:40px"></div>
            <el-button type="warning" plain @click="cancel">取消</el-button>
        </el-container>
    </div>

</template>


<script>
import axios from 'axios'
import {ElMessage} from 'element-plus'

export default{
    data(){
        return {
            queryParams:{
                gname:"",
                goprice:0,
                grprice:0,
                gstore:0,
                gpicture:"",
                isAdvertisement:0,
                isRecommend:0,
                goodstype_id:0
            },
            categoryList:[
                {
                    id:1231,
                    typename:"男装",
                },
            ],
        }
    },
    mounted(){
        let baseURL='http://localhost:8888';

        axios.get(baseURL+"/type/showAllTypes")
        .then(successResponse=>{
            this.categoryList=successResponse.data;
    
        }).catch(failResponse=>{
            alert("响应异常");
        })
    },
    methods:{
        //通过onchanne触发方法获得文件列表
        handleChange(file, fileList) { 
            this.queryParams.gpicture=fileList[0].raw.name;
            this.queryParams.fileName=fileList[0].raw;
        },
        
        cancel(){
            this.$router.go(-1)
        },
        submit(){
            ElMessage({
                type:'success',
                message:'设置商品基本属性: '+JSON.stringify(this.queryParams)
            })

            if(this.queryParams.gname=="" || this.queryParams.gpicture==""){
                alert("商品名称或图片为空,请重新输入!")
            }
            else{

                let formData=new FormData();
               
                for(var key in this.queryParams){
                    formData.append(key.toString(), this.queryParams[key]);
                }

                let config={
                    headers:{'Content-Type':'multipart/form-data'}
                };

    
                let baseURL='http://localhost:8888/goods/addGoods';
           
                axios.post(baseURL, formData, config)
                .then(successResponse => {
                    if (successResponse.data === "no") {
                        ElMessage({
                            message:'添加商品失败',
                            type:'error',
                            duration:3000
                        });
                    }else{
                        ElMessage({
                            message:'添加商品成功!',
                            type:'success',
                            duration:3000
                        });
                    }
                })
                .catch(failResponse => {
                    ElMessage({
                        message:'响应异常',
                        type:'error',
                        duration:3000
                    });
                })
            }


        },
        addCategory(){
            this.$router.push({name:'GoodCategory'})
        }
    }
}
</script>

后端代码:Controller

  @CrossOrigin //跨域访问
    @RequestMapping("/addGoods")
    public String addGoods(Goods goods)
            throws IllegalStateException, IOException{
        System.out.println("goods:"+goods.toString());
        return goodsService.addGoods(goods);
    }

后端代码:ServiceImpl

  @Override
    public String addGoods(Goods goods) throws IllegalStateException, IOException {

        String act="add";

        MultipartFile myfile=goods.getFileName();
//        System.out.println("gpicture:"+goods.getGpicture()+", fileName:"+goods.getFileName());
        //如果选择了上传文件,将文件上传到指定的目录images
        if(!myfile.isEmpty()){
            //上传文件路径
            String path="H:\\JetBrains\\IntelliJ_IDEA\\JavaEE_Proj2022\\SpringBoot_Proj_2022\\" +
                    "spb_eBusiness\\src\\main\\resources\\static\\images";
            //获得上传文件原名
            String fileName=myfile.getOriginalFilename();
            //对文件重命名
            String fileNewName=MyUtil.getNewFileName(fileName);
            File filePath=new File(path+File.separator+fileNewName);
            //如果文件目录不存在,创建目录
            if(!filePath.getParentFile().exists())
                filePath.getParentFile().mkdirs();
            //将上传文件保存到一个目标文件中
            myfile.transferTo(filePath);
            //将重命名后的图片名存到goods对象中,添加时使用
            goods.setGpicture(fileNewName);
        }

        if("add".equals(act)){
            int n= goodsRepository.addGoods(goods);
            if(n>0) //成功
                return "ok";
            //失败
            return "no";
        }else{//修改
            int n= goodsRepository.updateGoods(goods);
            if(n>0) //成功
                return "ok";
            //失败
            return "no";
        }
    }

<think>好的,我现在需要帮助用户解决如何通过JavaScript将对象数组递到后端的问题。根据用户提供的引用内容,我需要整合这些信息,给出一个清晰的解决方案。 首先,用户提供的引用中提到了几种方法。引用[1]中的例子展示了如何通过axios发送包数组的对象,使用POST请求将整个对象发送到后端。引用[2]提到,当递复杂数组结构时,应该用对象包裹集合,例如使用Pojo{List<Object> list}的形式。引用[3]则指出后端可以使用@RequestBody注解配合工具类来接收数组。 接下来,我需要将这些方法转化为具体的步骤。首先,前端需要使用JavaScript(可能是Vue框架,因为示例中有this.axios和this.order)构建一个包对象数组的数据结构。然后,通过axios的POST请求发送这个数据。需要注意设置Content-Type为application/json,以便后端正确解析。 在后端部分,用户可能需要使用Spring Boot框架,因为引用中提到@RequestBody和JSONArray。后端控制器应该定义一个POJO类来接收数据,这个类包一个列表属性。例如,定义一个OrderWrapper类,其中有一个List<Order>类型的字段,这样前端递的对象数组就会被正确映射。 另外,用户可能遇到的问题是前端递的数据结构不正确,或者后端没有正确解析JSON数据。需要确保前端发送的数据格式与后端的接收结构一致,比如数据是否被正确包裹在对象中,数组的字段名是否匹配等。 可能还需要处理跨域问题,或者axios配置问题,比如是否使用了正确的URL和请求方法。此外,错误处理也是需要考虑的,比如网络请求失败时的回调处理。 最后,根据用户的要求,生成相关问题,可能涉及前端数据格式调整、后端接收方式、错误排查以及工具使用等方面的问题。</think>### JavaScript递对象数组到后端的实现方法 #### 1. 前端数据构造 需要将对象数组包裹在父对象中,确保数据结构符合后端接收要求。例如: ```javascript const postData = { orders: [ { userId: 1, items: ["A", "B"] }, { userId: 2, items: ["C", "D"] } ] }; ``` #### 2. 使用axios发送请求 ```javascript axios.post('http://localhost:8080/api/save', postData, { headers: { 'Content-Type': 'application/json' // 必须明确指定JSON格式[^2] } }).then(response => { console.log('提交成功'); }).catch(error => { console.error('请求失败:', error); }); ``` #### 3. 后端接收方式(Spring Boot示例) ```java @PostMapping("/api/save") public ResponseEntity<?> saveOrders(@RequestBody OrderWrapper wrapper) { List<Order> orders = wrapper.getOrders(); // 处理业务逻辑 return ResponseEntity.ok("保存成功"); } // 定义包装类 public class OrderWrapper { private List<Order> orders; // getter/setter省略 } ``` #### 4. 关键注意事项 - 数据结构验证:通过浏览器开发者工具的Network面板检查实际发送的JSON结构 - 字段名一致性:前端`orders`字段必须与后端包装类的属性名完全匹配[^1] - 嵌套数组处理:如果对象包多层数组,需要逐级定义对应的Java类[^3] #### 5. 常见问题排查 ```javascript // 调试输出示例 console.log("最终发送数据:", JSON.stringify(postData)); ``` 若遇到400错误,可检查: 1. 是否遗漏`@RequestBody`注解 2. 字段类型是否匹配(如数字/字符串类型混淆) 3. 日期格式是否符合`yyyy-MM-dd`等规范
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值