各种参数注解遇到缺失、类型错、JSON 坏时分别返回什么?集合怎么传?不带注解的参数怎么处理?对象绑定有什么坑?这篇在 Spring Boot 4.0.8 的 Spring MVC 7.0.9 上用一组请求逐个验证。
GET /p1?q=hi → 200 p1 q=hi GET /p1 → 400 MissingServletRequestParameterException: Required request parameter 'q' for method parameter type String is not present GET /p2 → 200 p2 q=null GET /p3 → 200 p3 q=dft GET /p3?q= → 200 p3 q=dft GET /p4?n=7 → 200 p4 n=Optional[7] GET /p4 → 200 p4 n=Optional.empty GET /p5?n=abc → 400 MethodArgumentTypeMismatchException: Method parameter 'n': Failed to convert value of type 'java.lang.String' to required type 'int'; For input string: "abc" GET /p5 → 400 MissingServletRequestParameterException: Required request parameter 'n' for method parameter type int is not present GET /p9?flag=yes → 200 p9 flag=true GET /p9?flag=on → 200 p9 flag=true GET /p9?flag=maybe → 400 MethodArgumentTypeMismatchException: Method parameter 'flag': Failed to convert value of type 'java.lang.String' to required type 'boolean'; Invalid boolean value [maybe]
必需、可选、默认值、Optional;缺失和类型转换失败都是 400。
GET /p6?a=1&a=2 → 200 p6 a=[1, 2]
GET /p6?a=1,2 → 200 p6 a=[1, 2]
GET /p7?x=1&y=2&x=3 → 200 p7 all={x=1, y=2}
GET /p8?implicit=a&num=5 → 200 p8 implicit=a,num=5
GET /p8?implicit=a → 500 IllegalStateException: Optional int parameter 'num' is present but cannot be translated into a null value due to being declared as a primitive type. Consider declaring it as object wrapper for the cor
GET /x1/12 → 200 x1 id=12
GET /x1/abc → 400 MethodArgumentTypeMismatchException: Method parameter 'id': Failed to convert value of type 'java.lang.String' to required type 'int'; For input string: "abc"重复参数和逗号分隔都能进 List;不带注解的 int 缺失是 500。
GET /h1 → 400 MissingRequestHeaderException: Required request header 'X-Id' for method parameter type String is not present GET /h1 → 200 h1 id=7,sid=abc GET /x2 → 200 x2 method=GET,locale=zh_CN,principal=null
@RequestHeader、@CookieValue 和 Servlet 相关的类型可以直接作为参数。
POST /b1 [{"name":"ann","age":30}] → 200 b1 User[name=ann, age=30]
POST /b1 [{"name":"ann","age":"x"}] → 400 HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `int` from String "x": not a valid `int` value
POST /b1 [{bad json] → 400 HttpMessageNotReadableException: JSON parse error: Unexpected character ('b' (code 98)): was expecting double-quote to start property name
POST /b1 → 400 HttpMessageNotReadableException: Required request body is missing: java.lang.String demo.Main.b1(User)
POST /b1 [{"name":"ann","age":30,"extra":1}] → 200 b1 User[name=ann, age=30]
POST /b2 → 200 b2 null
POST /b3?q=z [raw text] → 200 b3 raw=raw text,q=zJSON 错误、空 body 都是 400,未知字段默认被忽略。
POST /m1 [name=ann&age=30&tags=a&tags=b] → 200 m1 Form(name=ann,age=30,tags=[a, b]) POST /m1?name=q&age=9 → 200 m1 Form(name=q,age=9,tags=null) POST /m1 [name=ann&age=x] → 400 MethodArgumentNotValidException: Validation failed for argument [0] in java.lang.String demo.Main.m1(Form): [Field error in object 'form' on field 'age': rejected value [x]; codes [typeMismatch.form.a POST /m1 [name=ann&nope=1] → 200 m1 Form(name=ann,age=0,tags=null) POST /m3 [name=ann&age=30] → 200 m3 FormPub(name=null,age=0) POST /m2?extra=e [name=bob&age=1] → 200 m2 Form(name=bob,age=1,tags=null),extra=e
需要 setter;只有 public 字段的对象会静默绑不上。