spring 如何在Sping Boot 中正确使用Form Data参数?

0vvn1miw  于 4个月前  发布在  Spring
关注(0)|答案(2)|浏览(82)

我正在从Google Guice和JAX-RS迁移到Sping Boot 。以前我看起来像这样的方法:

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

字符串
现在我需要在Sping Boot 中迁移此代码。我已经在Chrome DevTools上查看了到达此端点的请求,并且在有效负载中它具有表单数据参数。
在将代码重写到Sping Boot 时,我意识到我不能用@RequestParam替换@FormParam,所以我的一个解决方案是使用这个:

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


但是当使用这种方法时,我需要从formData散列表中获取参数,并手动将它们解析为相应的对象。有没有一种方法可以自动完成这一点,而无需我检查是否已传递参数以及其他参数。还有另一种方法,我在考虑是否可以创建一个包含请求中所有参数的自定义对象,并使用@ RequestBody自动解析?
任何其他方法都将有很大的帮助!

tgabmvqs

tgabmvqs1#

使用@RequestParam annotation将JAX-RS请求重写到Sping 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 String构造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);
        }
    }
}

knpiaxh1

knpiaxh12#

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

@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);
    }

}

字符串
FormDataDTO:

@Data
public class FormDataDTO {

     private TinyDTO tiny;

     private TinyDTO mid;

     private TinyDTO height;

}


TinyDTO:

@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
    }
}

相关问题