SpringBoot-URL路由:@Controller和@RequestMapping
SpringBoot定义URL处理方法:@Controller和@RequestMapping
@Controller标注的类表示的是一个处理HTTP请求的控制器(即MVC中的C),该类中所有被@RequestMapping标注的方法都会用来处理对应URL的请求。
在SpringMVC框架中,使用@RequsetMapping标注可以将URL与处理方法绑定起来,例如:
@RestController
public class HelloworldRestController {
@RequestMapping("/")
public String helloworld(){
return "hello world";
}
@RequestMapping("/hello")
@ResponseBody
public String hello(){
return "fpc";
}
}
HelloworldRestController类被@Controller标注,其中的两个方法都被@RequestMapping标注,当应用程序运行后,在浏览器中访问:localhost:8089,请求会被SpringMVC框架分发到hellworld()方法进行处理。同理输入localhost:8089/hello会交给hello()方法处理。
@ResponseBody标注表示处理函数直接将函数的返回值传到浏览器端显示。
运行结果:
输入localhost:8089:

输入loalhost:8089/hello:

@RequestMapping标注类
@RequestMapping标注同样可以加在类上:
@RestController
@RequestMapping("/index")
public class HelloworldRestController {
@RequestMapping("/")
public String helloworld(){
return "hello world";
}
@RequestMapping("/hello")
@ResponseBody
public String hello(){
return "fpc";
}
}
hello()方法绑定的URL路径是/index/hello
运行结果:
如果直接访问:localhost:8089/hello:

如果访问:localhost:8089/index/hello:

提示:每一个类都可以包含一个或者多个@RequestMapping标注的方法,通常我们会将业务逻辑相近的URL放在同一个Controller中处理。
@RequestMapping的简写形式
在web应用中常用的HTTP方法有四种:
- PUT方法用来添加资源
- GET方法用来获取已有的资源
- POST方法用来对资源进行状态转换
- DELETE方法用来删除已有的资源
这四个方法可以对应到CRUD操作(Create,Read,Update和Delete)比如博客的创建操作,按照REST风格设计URL就应该使用PUT方法,读取博客使用GET方法,更新博客使用POST方法,删除博客使用DELETE方法。
每一个Web请求都是属于其中一种,在SpringMVC中如果不特殊指定的话,默认是GET请求。
比如@RequestMapping("/")和@RequestMapping("/hello")和对应的Web请求是:
- GET /
- GET /hello
实际上@RequestMapping("/")是@RequestMapping("/",method = RequestMethod.GET)的简写,即可以通过method属性,设置请求的HTTP方法。
比如PUT /hello请求,对应@RequestMapping("/hello",method = RequestMethod.PUT)
Spring MVC最新的版本中提供了一种更加简洁的配置HTTP方式,增加了四个标注:
- PutMapping
- GetMapping
- PostMapping
- DeleteMapping
基于新的标注@RequestMapping("/hello",method = RequestMethod.PUT) 可以简写成@PutMapping("/hello"),@RequestMapping("/hello")和@GetMapping("/hello")等价。
返回HTML
在之前所有的Controller方法中,返回值字符串被直接传送到浏览器端并显示给用户。但是为了能够呈现更加丰富,美观的页面,我们需要将HTML代码返回给浏览器,浏览器在进行页面的渲染显示,一种很直观的方法是在处理请求的方法中,直接返回HTML代码:
@RequestMapping("/blog")
public String blog(){
return "<html><head><title>Title</title></head><body><h2>This is a blog</h2><p>This is content of the blog.</p></body></html>";
}
运行结果:浏览器地址栏输入:localhost:8089/blog:

显然,这样做的问题在于一个复杂的页面的HTML代码往往也非常复杂,并且内嵌在Java代码中十分不利于维护。
更好的做法是将页面的HTML代码卸载模板文件中,然后读取该文件并返回。Spring天然支持这种非常常见的场景,需要现在pom.xml引入Thymelea依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
将HTML文本保存在:src/main/webapp/pages/blog.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>This is title</h1>
<p>This is Content.</p>
</body>
</html>
Controller中可以去掉@ResponseBody标注(表示不是直接返回字符串,而是返回渲染的HTML模板,并将URL处理函数设置为刚刚保存在pages/文件夹中的文件名(不需要扩展名:))
运行结果并没有出现返回blog.html页面,而是返回了"blog"字符串在浏览器中显示出来:
造成这种现象的原因是:如果类是用@RestController修饰的出现这种情况很正常,如果想要返回页面可以将@RestController改为@Controller
package springboot; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; @Controller
//@RequestMapping("/index")
public class HelloworldRestController {
@RequestMapping("/")
public String helloworld(){
return "hello world";
}
@RequestMapping("/hello")
@ResponseBody
public String hello(){
return "fpc";
} @RequestMapping("/blog")
public String blog(){
return "blog";
}
}
继续运行项目:又出现问题了,报错信息为:
org.xml.sax.SAXParseException: 元素类型 "meta" 必须由匹配的结束标记 "</meta>" 终止。
报错的原因是blog.html代码中,meta元素没有封闭:

你可以直接封闭meta元素:
<meta charset="UTF-8"/>
也可修改SpringBoot的配置文件application.properties:
spring.thymeleaf.mode=LEGACYHTML5
SpringBoot的配置文件通常在/resource根目录下,以application.properties命名,没有这个文件则创建一个。
另外为了保证Thymeleaf能够正确识别HTML5,还需要添加Maven依赖到pom.xml:
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.22</version>
</dependency>
再次运行程序:

注意:在编写HTML代码时,请务必保证每一个标签都是闭合的,容易忽略的标签包括<meta/>,<link/>,<br/><hr/>,<img/>,<input/>等等
但是在HTML5中,有些标签并不要求闭合,Thymeleaf遇到这样的HTML文件会报错。为了支持HTML5,你可以在SpringBoot配置文件中增加一行配置:如上面的过程。
静态资源处理
在编写HTML代码的过程中,我们会遇到几类外部静态资源:
- CSS文件:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"/> - JavaScript文件:
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> - 图像:
<img src="http://assets0.tianmaying.com/img/appicon/ios.png"/>
这些外部资源都是通过HTTP协议访问得到--也就是说,当我们用浏览器打开我们编写的HTML页面(无论是通过本地文件直接打开,还是访问SpringBoot服务器),在获取页面内容本身之外,还需要向外部服务器(例如maxcdn.bootstrapcdn.com)发起HTTP请求以获取我们需要的CSS/JavaScript资源。
但是在我们开发过程中,如果某个时刻不能访问Internet,那我们的页面也就无法正确地展现出它应有的样式。另一方面,除了使用第三方库,我们自己还会编写大量的CSS/JavaScript文件,这就要求我们必须有一种很快的方式能够在修改后立马在本地看到结果。
本地资源文件组织
首先我们抛开本地HTTP服务器,简单来看在本地编写一个HTML文件以及使用CSS资源,那么我们可以这样组织项目结构:
.
├── index.html
├── css
└── style.css
└── js
└── main.js
在index.html文件中你可以这样引用它们:
<link rel="stylesheet" href="css/style.css"/>
<script src="js/main.js"></script>
css/style.css和js/main.js都是使用相对路径描述。
服务器中的静态资源文件
如果需要将index.html放在服务器中呢?index.html位于templates目录下,通过http://localhost:8089/可以访问首页内容,但是CSS和JavaScript外部资源呢?因为我们的HTTP服务器根本没有处理它们,所以不可能通过类似http://localhost:8089/css/style.css这样的方式来访问他们使得我们的页面正确显示。
默认情况下,SpringBoot会将类路径上的/static/目录的内容Serve起来,意思就是对静态资源的请求,都会返回/static/目录中对应路径的文件内容,于是我们可以这样组织文件目录结构来处理静态资源(以下是src/main/resources 目录结构,这个目录经过编译后被添加到类路径上)
├── static
├── css
└── style.css
└── js
└── main.js
└── templates
└── index.html
这样,当我们经过以上布局,重启应用后,就可以通过访问http://localhost:8089/css/style.css和http://localhost:8089/js/main.js来获取CSS和JavaScript资源了。
在HTML中引入资源
最后我们将静态资源引入到HTML页面中,我们往往需要一种介于相对路径(css/style.css)和绝对路径(http://localhost:8089/css/style.css)之间的资源访问方式--context路径:
<link rel="stylesheet" href="/css/style.css"/>
<script src="/js/main.js"></script>
这里只是简单的在相对路径URL的最前面加上了/,但是意义和相对路径就完全不同了,此时服务器会将其视为访问当前host中的“绝对路径”,也就是自动在这个路径前面加上协议,主机名,端口(都是当前服务器的相同信息),那么无论我们访问的是当前网站下的任何路径,它都会给出统一的结果,从而正确引用到外部资源。
SpringBoot-URL路由:@Controller和@RequestMapping的更多相关文章
- Java开发学习心得(二):Mybatis和Url路由
目录 Java开发学习心得(二):Mybatis和Url路由 1.3 Mybatis 2 URL路由 2.1 @RequestMapping 2.2 @PathVariable 2.3 不同的请求类型 ...
- SpringBoot 中常用注解@Controller/@RestController/@RequestMapping的区别
SpringBoot中常用注解@Controller/@RestController/@RequestMapping的区别 @Controller 处理http请求 @Controller //@Re ...
- SpringBoot 中常用注解@Controller/@RestController/@RequestMapping介绍
原文 SpringBoot 中常用注解 @Controller/@RestController/@RequestMapping介绍 @Controller 处理http请求 @Controller / ...
- Netty URL路由方案探讨
最近在用Netty做开发,需要提供一个http web server,供调用方调用.采用Netty本身提供的HttpServerCodec handler进行Http协议的解析,但是需要自己提供路由. ...
- 《Entity Framework 6 Recipes》中文翻译系列 (21) -----第四章 ASP.NET MVC中使用实体框架之在页面中创建查询和使用ASP.NET URL路由过虑
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 4.2. 构建一个搜索查询 搜索数据是几乎所有应用的一个基本功能.它一般是动态的,因 ...
- ASP.NET MVC 多语言实现——URL路由
考虑实现一个完整的基于asp.net mvc的多语言解决方案,从路由到model再到view最后到数据库设计(先挖好坑,后面看能填多少). 我所见过的多语言做得最好的网站莫过于微软的msdn了,就先从 ...
- 004_URL 路由 - URL 路由
在Web Form 情况下,每一个 ASPX页面既是一个文件,又是一个队请求自包含的响应.而在 MVC 情况下,请求是由控制器类中的动作方法处理的,而且与硬盘上的文件没有一对一的相互关系. ASP.N ...
- MVC的URL路由规则
MVC的URL路由规则 Routing的作用:它首先是获取到View传过来的请求,并解析Url请求中Controller和Action以及数据,其次他将识别出来的数据传递给Controller的Act ...
- ASP.NET MVC 的URL路由介绍
在这个教程中,向你介绍每个ASP.NET MVC一个重要的特点叫做URL路由.URL路由模块是负责映射从浏览器请求到特定的控制器动作. 在教程的第一部分,你将学习标准路由表如何映射到控制器的动作.在教 ...
随机推荐
- svn提示out of date
你需要先update一下,应该会有一个冲突标志,你查看一下历史日志,找到是谁在你之前进行了提交,和他商议一下如何合并你们两个人的修改,然后在你本地处理后,标记“冲突已解决”,最后再次commit
- 1.1.18 zabbix监控NFS
1.1.1 zabbix监控NFS 第一步创建脚本: 添加执行权限 chmod +x cat /server/scripts/nfs_check.sh [root@web02 scripts]# ...
- 无偏估计(Unbiased Estimator)
无偏估计是参数的样本估计量的期望值等于参数的真实值. 一个简单的例子(https://www.zhihu.com/question/22983179/answer/23470969): 比如我要对某个 ...
- Abstract可以将子类的共性最大限度的抽取出来,放在父类中,以提高程序的简洁性
Abstract可以将子类的共性最大限度的抽取出来,放在父类中,以提高程序的简洁性. Abstract虽然不能生成对象,但是可以声明,作为编译时类型,但不能作为运行时类型. Final和abstrac ...
- 关于 AfxSocketInit()
一般来说 WASAtarup() 是应用程序调用的Windows Sockets dll的第一个函数,在调用任何Winsock Api之前,必须调用WSAStartup()进行初始化,最后调用WSAC ...
- STL容器:deque双端队列学习
所谓deque,是"double-ended queue"的缩写; 它是一种动态数组形式,可以向两端发展,在尾部和头部插入元素非常迅速; 在中间插入元素比较费时,因为需要移动其它元 ...
- shell 中各种符号的含义
http://yesjavame.iteye.com/blog/1062405 http://blog.csdn.net/taiyang1987912/article/details/39551385
- Python爬虫(五)
源码: import requests from lxml import etree from my_mysql import MysqlConnect mc = MysqlConnect(','ho ...
- 三、Gradle初级教程——Gradle除了签名打包还能配置jar包
1.gradle概念 构建工具,Groovy,Java. 2.gradle配置jar包,和libs文件夹导入jar包的区别 到此,还是这种方法导入JAR包比较方便.每次更新JAR包,只需要修改版本号就 ...
- mac java环境
1.java运行环境jre:http://www.java.com/zh_CN/ 2.jdk:http://www.oracle.com/technetwork/java/javase/downloa ...