简体   繁体   English

在春季处理空的RequestBody

[英]Handle empty RequestBody in Spring

I'm currently developing an application using Spring Boot and I have an API endpoint(POST method with @RequestBody) that performs different kind of operation based on request parameters. 我目前正在开发使用Spring启动一个应用程序,我有一个执行基于请求参数的不同类型的操作的API端点(POST方法与@RequestBody)。 For example, if I receive object like this: 例如,如果我收到的对象是这样的:

{
"field1":["value1"],
"field2":["value2"]
}

I need to do some transformations based on field1 , field2 . 我需要基于field1field2进行一些转换。 So, when I send object like this: 因此,当我发送这样的对象时:

{}

Jackson converts JSON obj to my model, but because this obj is empty, all fields in Model setting to null . 杰克逊转换JSON OBJ到我的模型,但由于这种obj是空的,在模型的所有字段设置为null。 So, does Spring contain some methods to avoid this? 因此,没有春天包含一些方法来避免这种情况?

Do thing like this: 做这样的事情:

if(allFieldsAreEmpty(requestObj)){
 throw new RuntimeException("All fields are empty.");    
 }

PS Models classes generated by Swagger and I can`t modify it. 通过扬鞭生成的PS模式类和我不能老是修改。

You can implement "org.springframework.validation.Validator" according to your models and validation you want to perform. 您可以根据模型和要执行的验证来实现“ org.springframework.validation.Validator”。 And you can use InitBinder in your controller to validate request object. 您可以在控制器中使用InitBinder来验证请求对象。 Below is an example which I used one of my project: 下面是我使用我的项目之一的示例:

@Component(value = "fromToDateValidator")
public class FromToDateValidator implements Validator {

    @Override
    public boolean supports(Class<?> clazz) {
        return (InventorySearchRequestByDate.class.equals(clazz) || OrderRequestDetails.class.equals(clazz));
    }

    @Override
    public void validate(Object target, Errors errors) {
        if (!errors.hasErrors()) {
            Date fromDate = null;
            Date toDate = null;
            if (target instanceof InventorySearchRequestByDate) {
                fromDate = ((InventorySearchRequestByDate) target).getFromDate();
                toDate = ((InventorySearchRequestByDate) target).getToDate();
            } else if (target instanceof OrderRequestDetails) {
                fromDate = ((OrderRequestDetails) target).getFromDate();
                toDate = ((OrderRequestDetails) target).getToDate();
            }
            if (fromDate.compareTo(toDate) > 0) {
                errors.rejectValue("toDate", null, "To Date is prior to From Date");
            }
        }
    }
}

So, supports method take class parameter which check whether the class validation is applicable to the model or not. 因此,支持使用带类参数的方法来检查类验证是否适用于模型。 So like in my example I have to check for the InventorySearchRequestByDate request object or OrderRequestDetails request object, So I performed check according to date. 因此,就像在我的示例中一样,我必须检查InventorySearchRequestByDate请求对象或OrderRequestDetails请求对象,因此我根据日期执行了检查。

Now in the validate method contains core logic for validating the model and adding the errors. 现在,validate方法中包含用于验证模型和添加错误的核心逻辑。

You can bind this validator in your controller like below and use it: 您可以像下面那样在控制器中绑定此验证器并使用它:

@RestController
public class ItemInventoryController extends BaseController {

    @Autowired
    @Qualifier("fromToDateValidator")
    private Validator fromToDateValidator;

    @Autowired
    private ItemInventoryService itemInventoryService;

    @InitBinder
    private void initBinder(WebDataBinder binder) {
        binder.addValidators(fromToDateValidator);
    }

    @RequestMapping(value = WebServiceEndPoints.INVENTORY_AVAILABILITY_BY_DATE, method = RequestMethod.POST)
    public Map<String, Set<ItemDetails>> getAvailableItems(@RequestBody @Validated InventorySearchRequestByDate
                                                       inventorySearchRequestByDate, BindingResult bindingResult) throws InvalidFieldException {
        validRequest(bindingResult);
        return itemInventoryService.searchItemsByDateAvailablity(inventorySearchRequestByDate.getFromDate()
                , inventorySearchRequestByDate.getToDate());
    }

    public void validRequest(BindingResult bindingResult) throws InvalidFieldException {
        if (bindingResult.hasErrors()) {
            throw new InvalidFieldException(bindingResult.getFieldErrors());
        }
    }

}

So above code validate the model and throw exception body according to your global handlers. 因此,以上代码根据您的全局处理程序验证模型并抛出异常主体。

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

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