java抽奖项目-奖品上传中传递参数类型的错误

目录

问题导入:

测试后端接口代码:

[使用CreatePrizeParam类来接收param参数,前端应该传递 application\json 字符串。](#使用CreatePrizeParam类来接收param参数,前端应该传递 application\json 字符串。)

postman发起http请求成功,后端失败。

网页显示创建奖品失败:undefined

一、不设定param参数后面的Content-Type

二、在postman上的Content-Type上强制application/json

[三、后端使用String 来接收参数,再使用Jacakson工具转化为对应类](#三、后端使用String 来接收参数,再使用Jacakson工具转化为对应类)

最后总结:


问题导入:

测试后端接口代码:

使用CreatePrizeParam类来接收param参数,前端应该传递 application\json 字符串。
java 复制代码
/**
     * 创建奖品
     * RequestParam:用于接收表单数据的 multipart/form-data
     *
     * @param param
     * @param prizePic
     * @return
     */
    @RequestMapping("/prize/create")
    public CommonResult<Long> createPrize(@Valid @RequestPart("param") CreatePrizeParam param,
                                          @RequestPart("prizePic") MultipartFile prizePic) {
        log.info("createPrize CreatePrizeParam:{}",
                JacksonUtil.writerValueAsString(param));
        return CommonResult.success(prizeService.createPrize(param, prizePic));
    }
postman发起http请求成功,后端失败。
网页显示创建奖品失败:undefined

一、不设定param参数后面的Content-Type

使用postman来测试,因为浏览器无法设置单个参数的 Content-Type。在 form-data 表单中把param参数使用json字符串格式构造完成,prizePic 传递成功。

发起请求之后:http请求成功,但是显示 Content-Type 的类型为 application/octet-stream 类型导致请求失败,后端报错信息,也是显示 Content-Type 类型错误。

java 复制代码
12:16:41 [http-nio-8080-exec-1] ERROR c.e.l.c.h.GlobalExceptionAdvice - 服务异常: org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'application/octet-stream' is not supported

浏览器中项目前端页面显示创建奖品失败:undefind 未定义,后端服务器错误信息和上面的服务器异常一样。

java 复制代码
12:16:41 [http-nio-8080-exec-1] ERROR c.e.l.c.h.GlobalExceptionAdvice - 服务异常: org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'application/octet-stream' is not supported

二、在postman上的Content-Type上强制application/json

在 postman 上的 Content-Type 上强制 application/json 传递成功。因为 prizePic 是一个文件,所以不能设定它的类型为application/json

所以我们就确定了是 param 参数传递的时候 Content-Type 的问题。

三、后端使用String 来接收参数,再使用Jacakson工具转化为对应类

但是浏览器无法这样只给param参数设置 Content-Type 类型为 application/json 所以对前端很不友好。所以我们修改后端接口,让接收 json 字符串自动构造成对象的修改为 String 类型来接收一个字符串。

这样就可以让 form-data 中不设定param的 Content-Type 类型,让它默认为 application/octet-stream 后端接收到 json 字符串,之后通过这个字符串来构造成 CreatePrizeParam 对象了。

  • 这是后端代码
java 复制代码
/**
     * 创建奖品
     * RequestParam:用于接收表单数据的 multipart/form-data
     *
     * @param param
     * @param prizePic
     * @return
     */
    @RequestMapping("/prize/create")
    public CommonResult<Long> createPrize(@Valid @RequestPart("param") String param,
                                          @RequestPart("prizePic") MultipartFile prizePic) {
        log.info("createPrize CreatePrizeParam:{}",
                param);
        CreatePrizeParam param1 = JacksonUtil.readValue(param, CreatePrizeParam.class);
        return CommonResult.success(prizeService.createPrize(param1, prizePic));
    }
  • 使用postman 测试成功
  • 浏览器页面也成功

最后总结:

我使用的是SpringBoot4.1.0 ,在奖品创建的时候param 在postman 上把json 字符串构造成功后,在返回类型Content-type这一栏里面需要加上application\json 这个类型,但是浏览器不支持这种写法

解决方案:1.psotman 可以使用,但是在param 传参数的一栏中的 Content-Type 这个填上 application\json表示这一栏返回的是json

2.后端修改,把CreatePrizeParam param 类换成字符串来接收参数,接收到字符串后使用jacksong 工具转化为CreatePrizeParam 传递给Service层来保证正常。

java 复制代码
package com.example.lotterysystem.controller;

import com.example.lotterysystem.common.pojo.CommonResult;
import com.example.lotterysystem.common.utils.JacksonUtil;
import com.example.lotterysystem.controller.param.CreatePrizeParam;
import com.example.lotterysystem.service.PictureService;
import com.example.lotterysystem.service.PrizeService;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@RestController
//@Slf4j
public class PrizeController {

    private static final Logger log = (Logger) LoggerFactory.getLogger(PrizeController.class);
//    private static final Logger logger = LoggerFactory.getLogger(PrizeController.class);
    @Autowired
    private PictureService pictureService;
    @Resource(name = "prizeServiceImpl")
    private PrizeService prizeService;

    @RequestMapping("/pic/upload")
    public String uploadPic(MultipartFile file) {
        return pictureService.savePicture(file);
    }

    /**
     * 创建奖品
     * RequestParam:用于接收表单数据的 multipart/form-data
     *
     * @param param
     * @param prizePic
     * @return
     */
    @RequestMapping("/prize/create")
    public CommonResult<Long> createPrize(@Valid @RequestPart("param") String param,
                                          @RequestPart("prizePic") MultipartFile prizePic) {
        log.info("createPrize CreatePrizeParam:{}",
                param);
        CreatePrizeParam param1 = JacksonUtil.readValue(param, CreatePrizeParam.class);
        return CommonResult.success(prizeService.createPrize(param1, prizePic));
    }

}
相关推荐
RuoyiOffice11 分钟前
Spring AI+Vue3 企业知识库设计:让每个答案有依据,让每份资料守住权限
java·spring boot·vue3·rag·企业知识库·spring ai·ruoyi office
卢锡荣44 分钟前
乐得瑞Type-c接口产品描述
c语言·开发语言
晴天的雨.99244 分钟前
【C++】模板进阶
开发语言·c++·算法
倔强的石头1061 小时前
【Linux指南】进程通信系列(二):匿名管道 —— pipe 的本质、fork 继承与四种读写规则
java·linux·运维
调试优选官1 小时前
2026年IoT物联网开发赛道年度榜单深度解析:D-coding物联网系统定制与源码交付能力专项解读
java·物联网·struts·iot·开发经验
木井巳1 小时前
【动态规划】三步问题
java·算法·leetcode·动态规划·推荐算法
小张成长计划..1 小时前
【Linux】25:线程概念和控制
java·linux·jvm
蛋蛋的就会顺顺的10 小时前
hot100 p0——栈,贪心算法,动态规划
java·前端·javascript·算法·leetcode·力扣
需要82611 小时前
Spring Bean 生命周期:从实例化到销毁的完整钩子
java·后端·spring
小 黄 鸡11 小时前
HashMap 面试必会知识点详解(JDK 8)
java·面试·职场和发展