Spring MVC中创建URL路由 由David发表在天码营
设计网站的URL
现代的Web站点都会设计一套拥有明确意义,方便用户记忆的URL,不论是域名还是路径,以天码营为例:
- http://tianmaying.com/courses 表示网站下所有的课程列表
- http://tianmaying.com/course/web-development 表示当前我们正在学习的这门课程
在HTML和CSS的学习中,我们创建了个人博客网站的基本页面,如果需要将他们放在Internet中让其他人可以访问,就必须为它们设计一套URL,现在假设我们的网站通过 http://localhost:8080/ 可以访问:
- http://localhost:8080/ 是网站首页,同时也应该对应当前的文章列表
- http://localhost:8080/posts/create ,创建新文章页面
- http://localhost:8080/posts/){id}/ ,显示某一篇文章页面
- http://localhost:8080/posts/){id}/edit ,编辑某一篇文章页面
定义URL处理方法
在Spring WebMVC框架中,使用@RequestMapping
注解可以将URL与处理方法绑定起来,例如:
@Controller
public class IndexController {
@RequestMapping("/")
@ResponseBody
public String index() {
return "index";
}
@RequestMapping("/hello")
@ResponseBody
public String hello() {
return "hello";
}
}
IndexController
类中的两个方法都被@RequestMapping
注解,当应用程序运行后,在浏览器中访问[http://localhost:8080/](http://localhost:8080/)
,请求会被Spring MVC框架分发到index()
方法进行处理。同理,[http://localhost:8080/hello](http://localhost:8080/hello)
会交给hello()
方法进行处理。
@ResponseBody
注解表示处理函数直接将函数的返回值传回到浏览器端显示。同时,不要忘记给IndexController
类加上@Controller
注解。
@RequestMapping
注解同样可以加在类上:
@Controller
@RequestMapping("/posts")
public class AppController {
@RequestMapping("/create")
public String create() {
return "mapping url is /posts/create";
}
}
create()
绑定的URL路径是/posts/create
。
::: note每一个类中都可以包含一个或多个@RequestMapping
注解的方法,通常我们会将业务逻辑相近的URL(例如上例中的文章列表、创建文章)放在同一个Controller中进行处理。:::
URL变量
在Web应用中URL通常不是一成不变的,例如微博两个不同用户的个人主页对应两个不同的URL: [http://weibo.com/user1](http://weibo.com/user1)
,[http://weibo.com/user2](http://weibo.com/user2)
。我们不可能对于每一个用户都编写一个被@RequestMapping
注解的方法来处理其请求,Spring MVC提供了一套机制来处理这种情况:
@RequestMapping("/users/{username}")
public String userProfile(@PathVariable("username") String username) {
return String.format("user %s", username);
}
@RequestMapping("/posts/{id}")
public String post(@PathVariable("id") int id) {
return String.format("post %d", id);
}
在上述例子中,URL中的变量可以用{variableName}
来表示,同时在方法的参数中加上@PathVariable("variableName")
,那么当请求被转发给该方法处理时,对应的URL中的变量会被自动赋值给被@PathVariable
注解的参数(能够自动根据参数类型赋值,例如上例中的int
)。
返回HTML
在之前所有的@RequestMapping
注解的方法中,返回值字符串都被直接传送到浏览器端并显示给用户。但是为了能够呈现更加丰富、美观的页面,我们需要将HTML代码返回给浏览器,浏览器再进行页面的渲染、显示。一种很直观的方法是在处理请求的方法中,直接返回HTML代码:
@RequestMapping("/posts/{id}")
public String post(@PathVariable("id") int id) {
return "<html><head><title>Title</title></head><body><h2>This is a Post</h2><p>This is content of the post."</p></body></html>;
}
显然,这样做的问题在于——一个复杂的页面HTML代码往往也非常复杂,并且嵌入在Java代码中十分不利于维护。
更好的做法是将页面的HTML代码写在模板文件中,然后读取该文件并返回。Spring天然支持这种非常常见的场景,需要先在pom.xml
引入Thymeleaf依赖(接下来的学习中会重点讲到):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
将HTML文本保存在src/main/resources/templates/post.html
下:
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>This is title</h1>
<p> This is Content</h2>
</body>
</html>
Controller
中可以去掉@ResponseBody
注解,并将URL处理函数的返回值设为刚刚保存在templates/
文件夹中的文件名(不需要扩展名):
@RequestMapping("/posts/{id}")
public String post(@PathVariable("id") int id) {
return "post";
}
Spring框架在发现返回值是"post"
后,就会去src/main/resources/templates/
目录下读取post.html
文件并将它的内容返回给浏览器。
在编写HTML代码时,请务必保证每一个标签都是闭合的,容易忽略的标签包括<meta/>
, <link/>
, <br/>
, <hr/>
,<img/>
, <input/>
等等
更多文章请访问天码营网站