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方法有四种:

  1. PUT方法用来添加资源
  2. GET方法用来获取已有的资源
  3. POST方法用来对资源进行状态转换
  4. DELETE方法用来删除已有的资源

这四个方法可以对应到CRUD操作(Create,Read,Update和Delete)比如博客的创建操作,按照REST风格设计URL就应该使用PUT方法,读取博客使用GET方法,更新博客使用POST方法,删除博客使用DELETE方法。

每一个Web请求都是属于其中一种,在SpringMVC中如果不特殊指定的话,默认是GET请求。

比如@RequestMapping("/")和@RequestMapping("/hello")和对应的Web请求是:

  1. GET /
  2. GET /hello

实际上@RequestMapping("/")是@RequestMapping("/",method = RequestMethod.GET)的简写,即可以通过method属性,设置请求的HTTP方法。

比如PUT /hello请求,对应@RequestMapping("/hello",method = RequestMethod.PUT)

Spring MVC最新的版本中提供了一种更加简洁的配置HTTP方式,增加了四个标注:

  1. PutMapping
  2. GetMapping
  3. PostMapping
  4. 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的更多相关文章

  1. Java开发学习心得(二):Mybatis和Url路由

    目录 Java开发学习心得(二):Mybatis和Url路由 1.3 Mybatis 2 URL路由 2.1 @RequestMapping 2.2 @PathVariable 2.3 不同的请求类型 ...

  2. SpringBoot 中常用注解@Controller/@RestController/@RequestMapping的区别

    SpringBoot中常用注解@Controller/@RestController/@RequestMapping的区别 @Controller 处理http请求 @Controller //@Re ...

  3. SpringBoot 中常用注解@Controller/@RestController/@RequestMapping介绍

    原文 SpringBoot 中常用注解 @Controller/@RestController/@RequestMapping介绍 @Controller 处理http请求 @Controller / ...

  4. Netty URL路由方案探讨

    最近在用Netty做开发,需要提供一个http web server,供调用方调用.采用Netty本身提供的HttpServerCodec handler进行Http协议的解析,但是需要自己提供路由. ...

  5. 《Entity Framework 6 Recipes》中文翻译系列 (21) -----第四章 ASP.NET MVC中使用实体框架之在页面中创建查询和使用ASP.NET URL路由过虑

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 4.2. 构建一个搜索查询 搜索数据是几乎所有应用的一个基本功能.它一般是动态的,因 ...

  6. ASP.NET MVC 多语言实现——URL路由

    考虑实现一个完整的基于asp.net mvc的多语言解决方案,从路由到model再到view最后到数据库设计(先挖好坑,后面看能填多少). 我所见过的多语言做得最好的网站莫过于微软的msdn了,就先从 ...

  7. 004_URL 路由 - URL 路由

    在Web Form 情况下,每一个 ASPX页面既是一个文件,又是一个队请求自包含的响应.而在 MVC 情况下,请求是由控制器类中的动作方法处理的,而且与硬盘上的文件没有一对一的相互关系. ASP.N ...

  8. MVC的URL路由规则

    MVC的URL路由规则 Routing的作用:它首先是获取到View传过来的请求,并解析Url请求中Controller和Action以及数据,其次他将识别出来的数据传递给Controller的Act ...

  9. ASP.NET MVC 的URL路由介绍

    在这个教程中,向你介绍每个ASP.NET MVC一个重要的特点叫做URL路由.URL路由模块是负责映射从浏览器请求到特定的控制器动作. 在教程的第一部分,你将学习标准路由表如何映射到控制器的动作.在教 ...

随机推荐

  1. JQuery.getJSON 没反应

    Jquery是一个优秀的Javascrīpt框架,轻量级的js库,它兼容CSS3.jQuery使用户能更方便地处理HTML documents.events.实现动画效果,并且方便地为网站提供AJAX ...

  2. Spring Mvc中DispatcherServlet和Servlet的区别小结

    在web开发过程中开始接触的是servlet,用来处理用户请求.这几年随着spring 框架越来越成熟,几乎成了java web开发界的主流框架.既然这么受欢迎肯定有它的优点,spring框架在原来的 ...

  3. Keil的使用方法(汇总)

    推荐 分享一个大神的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到人工智能的队伍中来! http://www.captainbed.net/strongerhuang 软件的开发 ...

  4. SHLVL--shell终端深度

    参考:How And Why You Would Use The $SHLVL Variable SHLVL代表shell打开的深度,进程第一次打开shell时$SHLVL=1,然后在此shell中再 ...

  5. 缓存技术PK:选择Memcached还是Redis(转)

    [IT168 技术]要Memcached还是要Redis?在构建一款现代且由数据库驱动的Web应用程序并希望使其拥有更为出色的性能表现时,这个问题总会时不时出现.并给每一位开发人员带来困扰.在考虑对应 ...

  6. Entity Framework中的实体类添加复合主键

    使用Code First模式实现给实体类添加复合主键,代码如下: using System; using System.Collections.Generic; using System.Compon ...

  7. windows下端口占用解决方法-查看和杀死占用端口进程

    在Windows下启动程序时有时会遇到端口被占用的情况,由于一个端口同时只能运行一个进程,所以要想启动新的程序就要先把占用该端口的进程给kill掉,具体的命令分为以下三步, 以杀死占用了80端口的进程 ...

  8. 敏捷软件开发实践-Sprint Retrospective Meeting(转)

    介绍: 在敏捷开发模式中,Sprint Retrospective Meeting 也是一个必不可少的环节,它通常发生在每个Sprint的结尾,其主要作用是对于当前的迭代周期做一个阶段性的总结,包括好 ...

  9. centos7安装avahi

    sudo yum install avahi sudo yum install avahi-tools 转自: http://unix.stackexchange.com/questions/1829 ...

  10. hdu 2105:The Center of Gravity(计算几何,求三角形重心)

    The Center of Gravity Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...