当前请求不是多部分请求 Spring Boot 和 Postman(上传 json 文件加上额外字段)字段、上传、部分、不是

2023-09-08 08:51:03 作者:忘了我也不错

我在尝试为我的请求上传 json 文件和额外的 id 或 dto 对象时收到此 Current request is not a multipart request 错误,因为这也是填充我的数据库所必需的.

当我只发送 json 文件时,一切都上传得很好,但现在我已将 id 字段添加到相关方法和 Postman 中,如果我收到此消息并努力调试和修复它可以得到任何帮助.

七个开源的 Spring Boot 前后端分离项目,一定要收藏

这些是涉及的部分:

@Controller@RequestMapping("/api/gatling-tool/json")公共类 StatsJsonController {@自动连线StatsJsonService 文件服务;@PostMapping(值 = "/import")公共响应实体<响应消息>uploadFile(@RequestParam("file") MultipartFile 文件,@RequestBody CategoryQueryDto categoryQueryDto) {字符串消息=";UUID id = categoryQueryDto.getId();如果(StatsJsonHelper.hasJsonFormat(文件)){尝试 {fileService.save(文件,id);message = "上传文件成功:"+ 文件.getOriginalFilename();返回 ResponseEntity.status(HttpStatus.OK).body(new ResponseMessage(message));} 捕捉(异常 e){message = 无法上传文件:"+ file.getOriginalFilename() + "!";返回 ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ResponseMessage(message));}}message = "请上传一个 json 文件!";返回 ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseMessage(message));}}@服务公共类 StatsJsonService {@自动连线StatsJsonRepository 存储库;公共无效保存(MultipartFile 文件,UUID id){StatsEntity statsEntity = StatsJsonHelper.jsonToStats(file, id);存储库.保存(statsEntity);}}公共类 StatsJsonHelper {公共静态字符串类型=应用程序/json";公共静态布尔 hasJsonFormat(MultipartFile 文件){if (!TYPE.equals(file.getContentType())) {返回假;}返回真;}公共静态 StatsEntity jsonToStats(MultipartFile 文件,UUID id) {尝试 {Gson gson = 新 Gson();文件 myFile = convertMultiPartToFile(file);BufferedReader br = new BufferedReader(new FileReader(myFile));统计 stats = gson.fromJson(br, Stats.class);StatsEntity statsEntity = new StatsEntity();statsEntity.setGroup1Count(stats.stats.group1.count);statsEntity.setGroup1Name(stats.stats.group1.name);statsEntity.setGroup1Percentage(stats.stats.group1.percentage);statsEntity.setId(id);返回统计实体;} 捕捉(IOException e){throw new RuntimeException("解析 json 文件失败:" + e.getMessage());}}

非常感谢.

即使我将这部分从 application/json 更改为 multiform/data,同样的错误仍然存​​在.

public static String TYPE = "multiform/data";

解决方案

我在控制器中尝试了几个组合.

为我工作的那个看起来像这样.基本上我们必须将两个参数作为 @RequestParam 传递.

 @PostMapping("/import")公共响应实体<对象>uploadFile(@RequestParam("file") MultipartFile 文件,@RequestParam String id) {返回空值;}

我知道你想通过 CategoryQueryDto 作为 @RequestBody 但它似乎在多部分请求 @RequestParam@RequestBody 似乎不能一起工作.

所以你 IMO 你可以在这里做两件事:-

如上设计控制器,只需将 id 作为字符串发送到请求中,然后直接在 fileService.save(file, id); 中使用.

如果你仍然想使用 CategoryQueryDto 你可以发送这个 {"id":"adbshdb"} 然后转换成 CategoryQueryDto 使用对象映射器.

这就是你的控制器的样子 -

 @PostMapping("/import")公共响应实体<对象>uploadFile(@RequestParam("file") MultipartFile 文件,@RequestParam String categoryQueryDtoString) 抛出 JsonProcessingException {ObjectMapper objectMapper = new ObjectMapper();CategoryQueryDto categoryQueryDto = objectMapper.readValue(categoryQueryDtoString, CategoryQueryDto.class);//做你的文件相关的东西返回 ResponseEntity.ok().body(file.getOriginalFilename());}

这就是您可以使用 postman/ARC 发送请求的方式 -

PS:不要忘记像这样设置 Content-Type 标头 -

I'm getting this Current request is not a multipart request error when trying to upload a json file and an extra id or dto object for my request, since this is also required to populate my database.

When I am sending only the json file, everything is being uploaded fine, but now I've added the id field to the related methods and Postman, I'm getting this message and struggling to debug and fix it, if I can get any help please.

These are the pieces involved:

@Controller
@RequestMapping("/api/gatling-tool/json")
public class StatsJsonController {

@Autowired
StatsJsonService fileService;

@PostMapping(value = "/import")
public ResponseEntity<ResponseMessage> uploadFile(@RequestParam("file") MultipartFile file, @RequestBody CategoryQueryDto categoryQueryDto) {
    String message = "";

    UUID id = categoryQueryDto.getId();

    if (StatsJsonHelper.hasJsonFormat(file)) {
        try {
            fileService.save(file, id);

            message = "Uploaded the file successfully: " + file.getOriginalFilename();
            return ResponseEntity.status(HttpStatus.OK).body(new ResponseMessage(message));
        } catch (Exception e) {
            message = "Could not upload the file: " + file.getOriginalFilename() + "!";
            return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ResponseMessage(message));
        }
    }

    message = "Please upload a json file!";
    return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseMessage(message));
}

}




@Service
public class StatsJsonService {

@Autowired
StatsJsonRepository repository;

public void save(MultipartFile file, UUID id) {
    StatsEntity statsEntity = StatsJsonHelper.jsonToStats(file, id);
    repository.save(statsEntity);
}

}


public class StatsJsonHelper {

public static String TYPE = "application/json";

public static boolean hasJsonFormat(MultipartFile file) {

    if (!TYPE.equals(file.getContentType())) {
        return false;
    }

    return true;
}

public static StatsEntity jsonToStats(MultipartFile file, UUID id) {

    try {
        Gson gson = new Gson();

        File myFile = convertMultiPartToFile(file);

        BufferedReader br = new BufferedReader(new FileReader(myFile));

        Stats stats = gson.fromJson(br, Stats.class);
         StatsEntity statsEntity = new StatsEntity();
        
        statsEntity.setGroup1Count(stats.stats.group1.count);
        statsEntity.setGroup1Name(stats.stats.group1.name);
        statsEntity.setGroup1Percentage(stats.stats.group1.percentage);


        statsEntity.setId(id);

        return statsEntity;

    } catch (IOException e) {
        throw new RuntimeException("fail to parse json file: " + e.getMessage());
    }
}

Thank you very much.

https://github.com/francislainy/gatling_tool_backend/pull/3/files

UPDATE

Added changes as per @dextertron's answers (getting a 415 unsupported media type error)

@PostMapping(value = "/import")
public ResponseEntity<ResponseMessage> uploadFile(@RequestParam("file") MultipartFile file, @RequestBody CategoryQueryDto categoryQueryDto) {

The same error persists even if I change this part from application/json to multiform/data as well.

public static String TYPE = "multiform/data";

解决方案

I tried with couple of combinations in controller.

The one Worked for me looks something like this. Basically we will have to pass both arguments as @RequestParam.

    @PostMapping("/import")
    public ResponseEntity<Object> uploadFile(@RequestParam("file") MultipartFile file, @RequestParam String id) {
        return null;
    }

I know you wanted to pass CategoryQueryDto as @RequestBody But it seems in multipart request @RequestParam and @RequestBody doesn't seem to work together.

So you IMO you can do 2 things here :-

Design the controller as above and just send the id as string in request and use that in fileService.save(file, id); directly.

If you still want to use CategoryQueryDto you can send this {"id":"adbshdb"} and then convert it to CategoryQueryDto using object mapper.

This is how your controller will look like -

    @PostMapping("/import")
    public ResponseEntity<Object> uploadFile(@RequestParam("file") MultipartFile file, @RequestParam String categoryQueryDtoString) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        CategoryQueryDto categoryQueryDto = objectMapper.readValue(categoryQueryDtoString, CategoryQueryDto.class);
// Do your file related stuff
        return ResponseEntity.ok().body(file.getOriginalFilename());
    }

And this is how you can send request using postman/ARC -

PS: Dont forget to set Content-Type header like so -