servicecomb-java-chassis icon indicating copy to clipboard operation
servicecomb-java-chassis copied to clipboard

@RequestBody 传空,不能拦截,会将空对象传导到controller。

Open hypggg opened this issue 2 years ago • 5 comments

接口已经定义body体不能为空,但body请求体 什么也不传,参数校验拦截不了。 parameters: - in: "body" name: "xxx " required: true servicecomb版本 2.7.4 期待报4XX错误 。

hypggg avatar Sep 21 '22 09:09 hypggg

可以贴一下接口定义吗?

liubao68 avatar Sep 22 '22 12:09 liubao68

xxMethod (@Valid XXXQueryReq XXXQueryReq) 就是普通的post请求,生成的接口就是这样的

hypggg avatar Oct 11 '22 11:10 hypggg

Can you please provided a minimize demo?

shoothzj avatar Oct 11 '22 12:10 shoothzj

`@RestController @RequestMapping(value = {"/v3"}, produces = {"application/json;charset=UTF-8"}) @Validated public class TestRequestBodyDemoController { private static final CMLogger logger = CMLoggerFactory.getLogger(TestRequestBodyDemoController.class);

@RequestMapping(value = {"/test_requestbody"}, produces = {"application/json"}, method = {RequestMethod.POST})
public ResponseEntity<User> showMonthUsages(@Valid @RequestBody User requestbody) {
    logger.info("requestbody is {}", requestbody);
    return new ResponseEntity<>(requestbody, HttpStatus.OK);
}

}` 这个是一个简单的案例,请求体为空,不拦截

weinihaom avatar Oct 12 '22 08:10 weinihaom

2022-10-12 08:32:48,002Z+0000|INFO|group0-1-thread-2|||||TID: N/A|..controller.TestRequestBodyDemoController.showMonthUsages(TestRequestBodyDemoController.java:29)|requestbody is null 2022-10-12 08:32:48,002Z+0000|INFO|group0-1-thread-2|||||TID: N/A|...interceptor.aspect.LogAspect.doInterceptor(LogAspect.java:56)|===TestRequestBodyDemoController.showMonthUsages success! cost time: 0ms 2022-10-12 08:32:48,003Z+0000|INFO|transport-vert.x-eventloop-thread-10|||||TID: N/A||0:0:0:0:0:0:0:1 - - Wed, 12 Oct 2022 08:32:48 UTC "POST /v3/test_requestbody HTTP/1.1" 200 0 2

This is a test log, which should not be entered into the business method body.

weinihaom avatar Oct 12 '22 08:10 weinihaom

我通过POSTMan调用是在body中输入一个null,会出现你这种情况,能把User的定义也贴一下吗

yanghao605 avatar Oct 20 '22 03:10 yanghao605

可以搭配@NotNull使用

yanghao605 avatar Oct 20 '22 06:10 yanghao605

搭配@NotNull使用,没有效果,还是会进入业务层

weinihaom avatar Oct 26 '22 02:10 weinihaom

可以用来@NotNull使用 这个试过没有用

weinihaom avatar Oct 26 '22 02:10 weinihaom

我通过POSTMan调用是在body中输入一个null,会出现这种情况,可以把用户的定义也贴一下吗

public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    @Valid
    @NotNull
    private String name;

    @Valid
    @NotNull
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

weinihaom avatar Oct 26 '22 02:10 weinihaom

你直接在接口的参数声明上加一个@NotNull showMonthUsages(@RequestBody @Valid @NotNull School requestbody)

yanghao605 avatar Oct 26 '22 07:10 yanghao605

我在2.6.0版本的chassis中在对象中使用@NotNull注解的时候,是把servicecomb中的hibernate-validator以及jakarta.validation-api排除,使用spring-boot-starter-validation,jakarta.validation-api 3.0 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> <version>2.6.7</version> </dependency> <dependency> <groupId>jakarta.validation</groupId> <artifactId>jakarta.validation-api</artifactId> <version>3.0.0</version> </dependency>

yanghao605 avatar Oct 26 '22 08:10 yanghao605

servicecomb版本 2.1.5版本是没有问题的,对比新版本。发现是VertxServerRequestToHttpServletRequest这个类的ServletInputStream getInputStream()方法修改导致的

weinihaom avatar Oct 27 '22 09:10 weinihaom

你直接在接口的参数声明上加一个@NotNull showMonthUsages(@requestbody @Valid @NotNull School requestbody)

OK

weinihaom avatar Oct 27 '22 11:10 weinihaom

servicecomb版本 2.1.5版本是没有问题的,对比新版本。发现是VertxServerRequestToHttpServletRequest这个类的ServletInputStream getInputStream()方法修改导致的

Rest on Servelt应该用不到这个转换类吧

yanghao605 avatar Oct 29 '22 02:10 yanghao605

showMonthUsages(@Requestbody @Valid @NotNull School requestbody) 应该是正确的用法, 关闭问题。

liubao68 avatar Oct 29 '22 14:10 liubao68

showMonthUsages(@Requestbody @Valid @NotNull School requestbody) 应该是正确的用法, 关闭问题。 @Requestbody注解,就已经包含了非空的意思。再加一个@NotNull显得累赘。而且不兼容之前的版本,升级serviceComb需要开发者手动去给每个接口,手动增加一个@NotNull注解。这非常不合理

weinihaom avatar Nov 01 '22 03:11 weinihaom

servicecomb版本 2.1.5版本是没有问题的,对比新版本。发现是VertxServerRequestToHttpServletRequest这个类的ServletInputStream getInputStream()方法修改导致的

Rest on Servelt应该用不到这个转换类吧

本地debug是会的

weinihaom avatar Nov 01 '22 03:11 weinihaom

@requestbody注解,就已经包含了非空的意思 这个直观理解上不是很对。 body 参数还是允许传空。

liubao68 avatar Nov 01 '22 06:11 liubao68

@requestbody注解,就已经包含了非空的意思 这个直观理解上不是很对。 body 参数还是允许传空。

@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RequestBody {

/**
 * Whether body content is required.
 * <p>Default is {@code true}, leading to an exception thrown in case
 * there is no body content. Switch this to {@code false} if you prefer
 * {@code null} to be passed when the body content is {@code null}.
 * @since 3.2
 */
boolean required() default true;

} 您看一下这个required(), 这个标明了请求体是否可以为空

weinihaom avatar Nov 01 '22 07:11 weinihaom

不填,默认是不可以为空

weinihaom avatar Nov 01 '22 07:11 weinihaom

I add a fix https://github.com/apache/servicecomb-java-chassis/pull/3447.

liubao68 avatar Nov 02 '22 01:11 liubao68