简体   繁体   English

使用@RequestParam 参数在 Post 方法中映射多个值(多部分数据 + json)

[英]Mapping multiple values (multipart data + json) in Post method with @RequestParam arguments

I need to upload from Post request MultipartFile and map a class from json.我需要从 Post 请求 MultipartFile 上传并从 json 映射一个类。 My controller code looks like this:我的控制器代码如下所示:

 @PostMapping(value = API_FILE_DIRECT_ENDPOINT,
            consumes = {MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = MediaType.APPLICATION_JSON_VALUE)
    FileDto create( @RequestParam("file") @NotNull MultipartFile multipartFile,
                   @PathVariable(  IbsAttachmentServiceApi.FILE_TYPE_KEY) String type,
                    @RequestParam("dto") @NotNull ApplyingFileDto applyingFileDto){
    
    FileDto result= process(applyingFileDto, multipartFile);
    
    return result;
    }

when I'm trying to query it from Postman, like this当我尝试从 Postman 查询时,像这样

在此处输入图片说明

but it gives me an error但它给了我一个错误

"Failed to convert value of type 'java.lang.String' to required type 'com.domain.ibs.attachment.model.ApplyingFileDto'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'com.domain.ibs.attachment.model.ApplyingFileDto': no matching editors or conversion strategy found"

So it doesn't map ApplyingFileDto class, only if I change it to String, and convert by ObjectMapper explicitly, then it works所以它不会映射 ApplyingFileDto 类,只有当我将它更改为 String,并通过 ObjectMapper 显式转换时,它才会工作

@RequestParam("dto") @NotNull String applyingFileDto) ...
ApplyingFileDto mappedDto = objectMapper.readValue(applyingFileDto, ApplyingFileDto.class);

Is there is any way to configure editor to map it after @RequestParam ?有没有办法配置编辑器在 @RequestParam 之后映射它?

like the error says.就像错误所说的那样。 You're trying to convert a String value to an ApplyingFileDto Object.您正在尝试将 String 值转换为 ApplyingFileDto 对象。 The following method to pass objects to a service is to use the @RequestBody annotation.以下将对象传递给服务的方法是使用 @RequestBody 注释。 I think that should solve your problem.我认为这应该可以解决您的问题。 Give it a try.试一试。

It can be because you are unnecessarily including @RequestParam in the controller method.这可能是因为您在控制器方法中不必要地包含了 @RequestParam。 You should use @RequestBody你应该使用@RequestBody

But before that, Make sure the attributes received as request parameters have perfect getters and setters (eg for attribute bot - setBot) on the object to be mapped.但在此之前,请确保作为请求参数接收的属性在要映射的对象上具有完美的 getter 和 setter(例如,对于属性 bot - setBot)。

Add the object as a parameter in the controller method, but do not annotate with @RequestParam.将对象作为参数添加到控制器方法中,但不要使用@RequestParam 进行注释。 The setter method of the target object will be called for each matching request parameter.将为每个匹配的请求参数调用目标对象的 setter 方法。

Example -例子 -

@PostMapping()
FileDto create(@RequestBody DTO dto) {

}

您有@RequestParam但 dto 不在您的参数中,而是在正文选项卡中

I've found the solution for the answer.我找到了答案的解决方案。 It is needed to add @RequestPart annotation instead @RequestParam like this需要像这样添加@RequestPart 注释而不是@RequestParam

 @PostMapping(value = API_FILE_DIRECT_ENDPOINT,
            consumes = {MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = MediaType.APPLICATION_JSON_VALUE)
    FileDto create( @RequestParam("file") @NotNull MultipartFile multipartFile,
                   @PathVariable(  IbsAttachmentServiceApi.FILE_TYPE_KEY) String type,
                    @RequestPart("dto") @NotNull ApplyingFileDto applyingFileDto){
    
   FileDto result= process(applyingFileDto, multipartFile);
    
    return result;
    }

then reason for is in different type of converters.那么原因在于不同类型的转换器。 It is mentioned here 这里提到

Note that @RequestParam annotation can also be used to associate the part of a "multipart/form-data" request with a method argument supporting the same method argument types.请注意,@RequestParam 注释还可用于将“multipart/form-data”请求的一部分与支持相同方法参数类型的方法参数相关联。 The main difference is that when the method argument is not a String or raw MultipartFile / Part, @RequestParam relies on type conversion via a registered Converter or PropertyEditor while RequestPart relies on HttpMessageConverters taking into consideration the 'Content-Type' header of the request part.主要区别在于,当方法参数不是 String 或原始 MultipartFile / Part 时,@RequestParam 依赖于通过注册的 Converter 或 PropertyEditor 进行类型转换,而 RequestPart 依赖于 HttpMessageConverters,同时考虑了请求部分的“Content-Type”标头. RequestParam is likely to be used with name-value form fields while RequestPart is likely to be used with parts containing more complex content eg JSON, XML). RequestParam 可能与名称-值表单字段一起使用,而 RequestPart 可能与包含更复杂内容的部分(例如 JSON、XML)一起使用。

also this example is very useful 这个例子也非常有用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM