繁体   English   中英

如何在调用时设置可选的 RequestBody 字段而不将其删除?

[英]How can I set an optional RequestBody field without it being deleted when I make the call?

我在 spring-boot 中有一个小程序,它通过带有 @RequestBody 的 get 调用返回一条包含所有规格的消息(以我的汽车为例)

public class CarsRequest implements Serializable {
    private String name;
    private String plate ;
    private  String price;
}

我希望能够确保如果一个字段设置为 null,它仍然可以找到具有值的其他字段的相关消息,在我的例子中,我想把“名称”字段放在RequestBody,是否可以这样做? 我试过设置

    public CarsResponse getCars(@RequestBody (required = false) CarsRequest request) throws IOException {
           //some code 

   }

但是当我 go 执行获取时,它在获取时完全删除了 null 字段,因此无法执行

只需从 function 中删除@RequestBody注释并保持原样

public CarsResponse getCars(CarsRequest request) throws IOException {
           //some code 

}

现在所有字段都将转换为查询参数并且都是可选的,因为按照惯例查询参数是可选的

public class CarsRequest implements Serializable {
    private String name;
    private String plate ;
    private  String price;
}

像这样打电话

GET /someEndpoint?name=<value>&plate=null

但是,如果您想强制某些参数,请使用javax.annotations或自己应用验证。

EDIT: As asked in comment, if you are accepting JSON as parameter body then you can do one thing, you can accept it as String and then convert json to object inside function body

public CarsResponse getCars(@RequestParam(required = false) String request) throws IOException {
           ObjectMapper mapper = new ObjectMapper();
           CarRequest request = mapper.readValue(request,CarRequest.class);
          // other code

}

并称它为这样

GET /someEndpoint?request="{ \"name\" : null, \"plate\": \"someValue\" }"

编辑2:

如果您想继续发送 json 并将其转换为 object,您可以再做一件事,您可以声明一个类似这样的活页夹

// Some controller class
class SomeController {
   @Autowired
   ObjectMapper mapper;
   
   // Ommited methods here
   
    @GetMapping("/carRequest")
    public ResponseEntity<String> testBinder(@RequestParam CarRequest request) {
        return ResponseEntity.ok("{\"success\": \"" + request.name+ "\"}");
    }

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(CarRequest.class, new CarRequestEditor(mapper));
    }

    static class CarRequestEditor extends PropertyEditorSupport {

        private ObjectMapper objectMapper;

        public CarRequestEditor(ObjectMapper objectMapper) {
            this.objectMapper = objectMapper;
        }

        @Override
        public void setAsText(String text) throws IllegalArgumentException 
        {
            if (StringUtils.isEmpty(text)) {
                setValue(new CarRequest());
            } else {
                try {
                    setValue(objectMapper.readValue(text, CarRequest.class));
                } catch (JsonProcessingException e) {
                    throw new IllegalArgumentException(e);
                }
            }
        }
    }
   
}

请注意,客户端需要发送这样编码的 json URL

http://localhost:8180/carRequest?request=%7B%22name%22%3"test"%7D

嗨,您正在使用 @RequestBody (required = false) CarsRequest,这意味着您的 CarsRequest object 本身是可选的,而不是您可以使用

@NotEmpty 
private String plate ;
@NotEmpty
private  String price;

您可以通过将单个字段设为 Optional 来使其成为Optional字段,在您的情况下为Optional<String> 如果该字段没有出现在请求正文中,则Optional将为空。

public class CarsRequest implements Serializable {
    private String name;
    private String plate;
    private Optional<String> price;
}

暂无
暂无

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

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