JavaWeb @PathVariable 设置路由变量的默认值
解决
如果我们遇到的问题相同,那你看完这段代码就可以知道解决方法。
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/user")
public class UserController {
@GetMapping(path = { "/{userId}", "/"})
public void user(@PathVariable(value = "userId", required = false) String uid) {
if (uid == null) {
uid = "默认的id值";
}
String id = uid; // 获取到值
// do something.
}
}
核心的两步:@RequestMapping
注解的path
属性值可以是字符串数组,即多个URL模式。@PathVariable
注解的required
属性表示该路由变量是否是必须的,需要设置为false
。
Intro
首先,依赖详情:org.springframework.spring-web:5.3.4
注解路径:org.springframework.web.bind.annotation.PathVariable
其次:HTTP 客户端向服务端传递参数的4种方式 SpringMVC的对应接收方式
设计RESTful风格的API如下get /api/user/{userId}
get /api/user/1001
表示获取id为1001的用户信息get /api/user/1003
表示获取id为1003的用户信息get /api/user/1004
表示获取id为1004的用户信息
如果接口的调用方(前段/或其他消费端)未传入userId,能否在服务的提供段设置默认值?即:get /api/user
后台会获取一个默认的用户信息(如id为1000的用户信息)
可以。
解决
V1
@RequestMapping(path = “/api/user/{userId}”)
public void user(@PathVariable(value = “userId”) String uid) {String id = uid; // 获取到值
// do something.
}
V1的缺点是: 只能处理 /api/user/xxx
这样的请求,而对于/api/user
这样的请求,他根本不处理(非己之责)
V2
@RequestMapping(path = { “/api/user/{userId}”, “/api/user”})
public void user(@PathVariable(value = “userId”, required = false) String uid) {if (uid == null) {
uid = "默认的id值";
}
String id = uid; // 获取到值
// do something.
}
首先,@RequestMapping
注解的path
属性是这样定义的:
@AliasFor("value")
String[] path() default { };
即可以设置请求映射规则为对多个path值进行拦截处理。
只改path还不够。
还需要修改@PathVariable
的required
属性为false
。
这样即使不传入这个路由变量。也可以被该方法拦截。
- V3
通常,在Controller类上使用注解@RequestMapping
指定基本路径,
而对于该控制器中的具体方法,可以使用以下几种指定了请求方法的、带有请求映射功能的注解去标记。
@PostMapping 增
@DeleteMapping 删
@PutMapping 改
@GetMapping 查
@PatchMapping 部分字段修改
修改后:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/user")
public class UserController {
@GetMapping(path = { "/{userId}", "/"})
public void user(@PathVariable(value = "userId", required = false) String uid) {
if (uid == null) {
uid = "默认的id值";
}
String id = uid; // 获取到值
// do something.
}
}
这样,当请求格式为get /api/user/xxx
或/api/user
时,都会进入该方法,执行一套逻辑。
相当于设置了路由变量{userId}
的默认值。
思考
对处于路由路径path末端的路由单节路由变量可设置默认值,
那么对于路由路径path中,中间部分的某节路由变量,能否也设置默认值?
@RequestMapping(path = { "/api/user/{userId}/profile", "/api/user/profile"})
public void profile(@PathVariable(value = "userId", required = false) String uid) {
System.out.println("拿到的路由变量:" + uid);
if (uid == null) {
uid = "默认的id值";
}
String id = uid;
}
经测试可以。
get /api/user/id2002/profile
可以返回userId为id2002的用户profile。get /api/user/profile
也可以返回一个userId为所设置默认值的用户profile。
源码
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
/** * Annotation which indicates that a method parameter should be bound to a URI template * variable. Supported for {@link RequestMapping} annotated handler methods. * * <p>If the method parameter is {@link java.util.Map Map<String, String>} * then the map is populated with all path variable names and values. * * @author Arjen Poutsma * @author Juergen Hoeller * @since 3.0 * @see RequestMapping * @see org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter */
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PathVariable {
/** * Alias for {@link #name}. */
@AliasFor("name")
String value() default "";
/** * The name of the path variable to bind to. * @since 4.3.3 */
@AliasFor("value")
String name() default "";
/** * Whether the path variable is required. * <p>Defaults to {@code true}, leading to an exception being thrown if the path * variable is missing in the incoming request. Switch this to {@code false} if * you prefer a {@code null} or Java 8 {@code java.util.Optional} in this case. * e.g. on a {@code ModelAttribute} method which serves for different requests. * @since 4.3.3 */
boolean required() default true;
}
可以看到@PathVariable
注解有三个属性值,其中name
和value
互为同义词/别名。required
就是我们利用到的属性。
还没有评论,来说两句吧...