@RequestParam
@RequestParam注解的原码
@Target({ElementType.PARAMETER}) // 只能作用于参数上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
// 定义参数名称,默认和名字一致
@AliasFor("name")
String value() default "";
// 定义参数名称,默认和名字一致
@AliasFor("value")
String name() default "";
// 默认必填,一旦加上该注解,前台必须传递此参数
boolean required() default true;
// 定义默认值
String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
关于@AliasFor注解说明:标识2个属性作用一致
在Spring的众多注解中,经常会发现很多注解的不同属性起着相同的作用,比如@RequestParam 的value属性和name属性,这就需要做一些基本的限制,比如value和path的值不能冲突,比如任意设置value或者设置path属性的值,都能够通过另一个属性来获取值等等。为了统一处理这些情况,Spring创建了@AliasFor标签。另外,@RequestMapping注解中也有应用。
注解使用示例
后台:
@RequestMapping("demo")
public String demo(Model model
// 走默认装配规则,参数名称和名字一致,选传
,String name
// 参数名称和名字默认一直,必传参数,不传报错
,@RequestParam String name0
// 通过value属性定义名称,必传参数,不传报错
,@RequestParam(value = "name1") String name1
// 通过name属性定义,非必传参数
,@RequestParam(name = "name2",required = false) String name2
// 通过value属性定义,必传参数,有默认值,可以不传自动赋值
,@RequestParam(value = "name3",defaultValue = "t3") String name3
// 自定义参数名字,不必加name或者value属性,必传
,@RequestParam("name444") String name4
){
System.out.println("name:"+name);
System.out.println("name0:"+name0);
System.out.println("name1:"+name1);
System.out.println("name2:"+name2);
System.out.println("name3:"+name3);
System.out.println("name4:"+name4);
return "hello";
}
请求连接:
/demo?name=t&name0=t0&name1=t1&name2=t2&name444=t44
控制台输出:
name:t
name0:t0
name1:t1
name2:t2
name3:t3
name4:t44
必传参数name1,不传会报400错误,如下:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Tue Apr 13 11:16:17 CST 2021
There was an unexpected error (type=Bad Request, status=400).
Required String parameter 'name1' is not present
org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'name1' is not present
at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:202)
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:113)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:126)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:166)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895
@PathVariable
@PathVariable注解的原码
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PathVariable {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
boolean required() default true;
}
注解使用示例
后台:
@RequestMapping(value={
"demo1/{name1}/{name2}/{name3}"
// 配合name3选传,此种场景应用较少,一般使用此注解均为必传参数
,"demo1/{name1}/{name2}"
})
public String demo1(Model model
//注意,没加注解,使用问号后追加参数请求
,String name
// 必传
,@PathVariable String name1
// 必传
,@PathVariable("name2") String name2
// 选传
,@PathVariable(value = "name3",required = false) String name3
){
System.out.println("name:"+name);
System.out.println("name1:"+name1);
System.out.println("name2:"+name2);
System.out.println("name3:"+name3);
return "hello";
}
请求连接:
/demo1/t1/t2?name=t0
/demo1/t1/t2/t3
/demo1/t1 ===> 404地址找不到
控制台输出:
/demo1/t1/t2?name=t0
/demo1/t1/t2/t3
/demo1/t1 ===> 404地址找不到
如果是使用注解@PathVariable必传的参数类型,不加参数会报404。
总结:实际场景中,可以使用@RequestParam和@PathVariable传递参数,搭配Spring Mvc默认的装配规则,合理使用可以满足复杂的请求需求。