如何在 Spring Boot 中正确使用表单数据参数?

问题描述 投票:0回答:2

我正在从 Google Guice 和 JAX-RS 迁移到 Spring Boot。 以前我的方法是这样的:

    @POST
    @Path("/generateTable")
    public ExportResult generateTable(@FormParam("content") TableParam tableParam,
                                                      @FormParam("panel") PanelParam panelParam,
                                                      @FormParam("entityData") EntityDataParam entityDataParam,
                                                      @FormParam("drillPath") TypoParam typoParam) 

现在我需要在 Spring Boot 中迁移这段代码。我已经在 Chrome DevTools 上查看了到达此端点的请求,并且在有效负载中它具有表单数据参数。

将代码重写到 Spring Boot 时,我意识到我无法将 @FormParam 替换为 @RequestParam,所以我拥有的一种解决方案是使用这个:

    @PostMapping("/generateTable")
    public ExportResult generateTable(@RequestBody MultiValueMap<String, String> formData) {

但是当使用这种方法时,我需要从 formData 哈希图中获取参数并手动将它们解析为适当的对象。有没有一种方法可以自动完成此操作,而无需我检查参数是否已传递以及其他参数是否已传递。 还有另一种方法,我在想是否可以创建一个包含请求中所有参数的自定义对象并使用 @RequestBody 自动解析它?

任何其他方法都会有很大帮助!

java spring spring-boot httprequest endpoint
2个回答
0
投票

实际上你可以限制内容类型并使用对象类来接受参数。

在控制器上:

@RestController
@RequestMapping("/test")
public class TestController {

    @PostMapping(value = "/form-data", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseEntity<Object> generateTable(FormDataDTO data){

        return ResponseEntity.ok(data);
    }

}

表单数据DTO:

@Data
public class FormDataDTO {

     private TinyDTO tiny;

     private TinyDTO mid;

     private TinyDTO height;

}

小DTO:

@Data
public class TinyDTO {

    private String str;

    private Integer num;

}

如何请求?你可以这样测试:

###
POST http://localhost:10001/test/form-data
Content-Type: multipart/form-data; boundary=boundary

--boundary
Content-Disposition: form-data; name="tiny.str"

aaaa
--boundary
Content-Disposition: form-data; name="tiny.num"

1
--boundary
Content-Disposition: form-data; name="mid.str"

mid
--boundary
Content-Disposition: form-data; name="mid.num"

99
--boundary
Content-Disposition: form-data; name="height.str"

height
--boundary
Content-Disposition: form-data; name="height.num"

-1
--boundary--

回复是:

{
    "tiny": {
        "str": "aaaa",
        "num": 1
    },
    "mid": {
        "str": "mid",
        "num": 99
    },
    "height": {
        "str": "height",
        "num": -1
    }
}

0
投票

使用

@RequestParam
注释将 JAX-RS 请求重写到 Spring Boot MVC 非常简单。在你的情况下是这样的:

@PostMapping(path = "/generateTable", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public ResponseEntity<ExportResult> generateTable(@RequestParam("content") TableParam tableParam,
                      @RequestParam("panel") PanelParam panelParam,
                      @RequestParam("entityData") EntityDataParam entityDataParam,
                      @RequestParam("drillPath") TypoParam typoParam))

此外,您还需要提供从 String 到 Java 对象的转换器。您可以在现有类中识别必要的代码。它要么是带有单个 String 参数的构造函数,要么是名为

valueOf()
fromString()
的静态方法,或者是
ParamConverterProvider
的注册实现。

获取此代码并在 Spring 组件中实现

Converter<S, T>
接口。类似于下面的例子。它从 JSON 字符串构造一个 Customer 对象:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.convert.converter.Converter;
@Component
public class CustomerConverter implements Converter<String, Customer> {

    @Autowired
    private ObjectMapper mapper;

    @Override
    public Customer convert(String customer) {
        try {
            return mapper.readValue(customer, Customer.class);
        } catch (JsonProcessingException e) {
            throw new IllegalArgumentException(e);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.