在上一课中我们学习了如何在@Controller
中创建@RequestMapping
(或者相应的简写)来处理不同的URL请求。但是在Web应用中URL通常不是一成不变的,例如微博两个不同用户的个人主页对应两个不同的URL: http://weibo.com/user1
,http://weibo.com/user2
。我们不可能对于每一个用户都编写一个被@RequestMapping
注解的方法来处理其请求,也就是说,对于相同模式的URL(例如不同的用户的主页,它们仅仅是URL中的某一部分不同,为它们各自的用户名,我们说它们具有相同的模式)。
我们可以在@RequestMapping
注解里用{}
来表明它的变量部分,例如:
这里{username}
就是我们定义的变量规则,username
是变量的名字。那么这个URL路由可以匹配下列任意URL并进行处理:
/users/tianmaying
/users/ricky
/users/tmy1234
需要注意的是,在默认情况下,变量中不可以包含URL的分隔符
/
(Slash),例如上述路由不能匹配/users/tianmaying/ricky
,即使你认为tianmaying/ricky
是一个存在的用户名
在路由中定义变量规则后,通常我们需要在处理方法(也就是@RequestMapping
注解的方法)中获取这个URL变量的具体值,并根据这个值(例如用户名)做相应的操作,Spring MVC提供的@PathVariable
可以帮助我们:
@GetMapping("/users/{username}")
public String userProfile(@PathVariable String username) {
return String.format("user %s", username);
}
在上述例子中,当@Controller
处理HTTP请求时,userProfile
的参数username
会被自动设置为URL中的对应变量username
(同名赋值)的值,例如当HTTP请求为:/users/tianmaying
,URL变量username
的值tianmaying
会被赋给函数参数username
,函数的返回值自然也就是:String.format("user %s", username);
,即user tianmaying
。
在默认情况下,Spring会对
@PathVariable
注解的变量进行自动赋值,当然你也可以指定@PathVariable
使用哪一个URL中的变量:
@GetMapping("/users/{username}") public String userProfile(@PathVariable("username") String user) { return String.format("user %s", user); }
这时,由于注解
String user
的@PathVariable
的参数值为username
,所以仍然会将URL变量username
的值赋给变量user
可以定义URL路由,其中包含多个URL变量:
@GetMapping("/users/{username}/blogs/{blogId}")
public String getUserBlog(@PathVariable String username, @PathVariable int blogId) {
//具体实现,略
}
这种情况下,Spring能够根据名字自动赋值对应的函数参数值,当然也可以在@PathVariable
中显式地表明具体的URL变量值。
在默认情况下,
@PathVariable
注解的参数可以是一些基本的简单类型:int
,long
,Date
,String
等,Spring能够根据URL变量的具体值以及函数参数的类型来进行转换,例如/users/tianmaying/blogs/12
,会将tianmaying
赋值给String变量username
,而12
赋值给int
变量blogId
很多时候,我们需要对URL变量进行更加精确的定义,例如——用户名只可能包含小写字母、数字和下划线,我们希望:
/users/tianmaying
是一个合法的URL/users/#$$*#*#*
则不是一个合法的URL除了简单地定义{username}
变量,还可以定义正则表达式进行更精确的控制,定义语法是:{变量名:正则表达式}
[a-z0-9_]+
是一个正则表达式,表示只能包含小写字母、数字和下划线。如此设置URL变量规则后,不合法的URL则不会被处理,直接由Spring MVC框架返回404 Not Found
。
每一篇博客文章都会有一个自己独有的标识符(identity,也就是我们常说的ID),那么我们会这样设计URL:
@GetMapping("/blogs/{blogId}")
@ResponseBody
public String getBlog(@PathVariable int blogId) {
Blog blog = blogService.findBlog(blogId);
if (blog == null) {
//异常处理,一般来说是抛出404错误
}
return blog.getTitle();
}
这里假设Blog的ID是int
类型,例如:
/blogs/1
/blogs/12
blogService
则是封装的博客的业务逻辑,例如根据ID获取博客内容、添加博客、删除博客等。在这个函数中我们只是简单把博客标题返回,那么浏览器中只会显示标题文字。在以后的学习中,我们会使用模板渲染技术显示更加美观、信息更多的博客页面。
@RequestMapping
注解中定义URL变量规则@RequestMapping
注解的方法中获取URL变量——@PathVariable
@PathVariable
指定URL变量名URL处理是Web中最基本的部分,虽然看似容易,但在遇到具体场景时仍然有许多值得思考的地方:
/
且变长的变量规则呢?参考官方文档@RequestMapping
的params
和headers
参数可以帮助我们,参考官方文档
登录发表评论 登录 注册
我猜你userService和blogService没有用@Autowired自动注入吧
@GetMapping("/{username}[a-z0-9_]+")
@ResponseBody
public List<Blog> blogList(@PathVariable String user) {
User theUser = userService.findByName(user);
List<Blog> list = blogService.findBlogs(theUser);
return list;
}
请问怎么改呢
url去掉users也不行,能帮忙看下哪里错了吗,无法根据用户获取博客
可以获取用户,但是根据用户获取博客列表报空指针异常,帮忙看下哈.
```
User user = userService.findByName(username);
List<Blog> blogs = blogService.findBlogs(user);
```
1个测试已通过,1个测试未通过(共花费2117ms)
第三章的代码这个错误怎么解决?
现在还没有开设直播课,付费的服务包括:
付费之后是在线直播课吗?