第4章 Web开发
4.1 Web开发简介
4.2 URL映射
4.3 参数传递
4.4 数据验证
4.5 拦截器
4.6 过滤器
4.7 Web配置
4.8 实战:实现优雅的数据返回
4.1 Web开发简介
4.1.1 Web入门
1. spring-boot-starter-web介绍
Spring Boot自带的spring-boot-starter-web组件为Web应用开发提供支持,它内嵌的Tomcat以及Spring MVC的以来使用起来非常方便。
Spring Boot创建Web应用非常简单,先创建一个普通的Spring Boot项目,然后修改pom.xml文件将spring-boot-starter-web组件加入项目就可以创建WEb应用。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
spring-boot-starter-web启动器主要包括web、webmvc、json、tomcat等基础依赖组件,作用是提供Web开发场景所需的所有底层依赖。
2. Web项目结构
Spring Boot的Web应用与Spring Boot应用基本没有区别,只是resources目录中多了static静态资源目录以及templates页面模板目录。Spring Boot Web项目结构如下图所示。
3. 实现简单的Web请求
Spring Boot不像传统的MVC框架那样必须继承某个基础类才能处理HTTP请求,只需要在类上声明@Controller注解,标注这是一个控制器,然后使用@RequestMapping注解把HTTP请求映射到对应的方法上即可。
@RequestMapping注解用于定义请求的路由地址,既可以作用在方法上,又可以作用在类上。
- 请求页面和数据:如果请求的是页面和数据,使用@Controller注解即可;
- 只是请求数据:如果只是请求数据,则可以使用@RestController注解,或者同时使用@Controller和@ResponseBody注解(@RestController 等价于 @Controller与@ResponseBody组合)。
下面演示“只是请求数据”的具体使用:
方式1:使用 @RestController 注解
package com.example.webproject.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello() {
return "hello, world";
}
}
方式2:使用 @Controller 注解
package com.example.webproject.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
@RequestMapping("/hello")
@ResponseBody
public String hello() {
return "hello, world";
}
}
启动项目,在浏览器中访问 http://localhost:8080/hello 地址,就可以看到页面返回“hello, world”。这说明一个简单的Web项目创建成功了。
4.1.2 @Controller 和 @RestController
1、@Controller 的用法
(1)请求页面和数据(@Controller)
Spring Boot 提供了@Controller注解主要用于页面和数据的返回。下面创建ThymeleafController响应前台页面请求。
pom.xml
<!--Spring Boot 集成 Thymeleaf模板引擎-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
application.properties(路径:src/main/resources/application.properties)
# 是否开启缓存,开发室可以设置为false,默认为true
spring.thymeleaf.cache=false
# 模板文件位置
spring.thymeleaf.prefix=classpath:/templates/
# 模板文件后缀
spring.thymeleaf.suffix=.html
# Content-Type 配置
spring.thymeleaf.servlet.content-type=text/html
# Mode 配置
spring.thymeleaf.mode=HTML
# Encoding 配置
spring.thymeleaf.encoding=UTF-8
index.html(路径:src/main/resources/templates/thymeleaf/index.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
Thymeleaf模板引擎
<h1 th:text="${name}">Hello Thymeleaf</h1>
</body>
</html>
ThymeleafController.java (路径:src/main/java/com/example/webproject/controller/ThymeleafController.java)
package com.example.webproject.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/thymeleaf")
public class ThymeleafController {
@RequestMapping("/index")
public String index(ModelMap map) {
map.addAttribute("name", "thymeleaf-index");
return "thymeleaf/index";
}
}
上面的示例请求 /user/index 地址,返回具体的 index 页面和 name=thymeleaf-index 的数据。在前端页面中通过 ${name} 参数获取后台返回的数据并显示在页面中。
(2)只是请求数据(@Controller和@ResponseBody组合)
在@Controller类中,如果只返回数据到前台页面,需要使用@ResponseBody注解,否则会报错。
HelloController.java
package com.example.webproject.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
@RequestMapping("/hello")
@ResponseBody
public String hello() {
return "hello, world";
}
}
2、@RestController 的用法
Spring Boot 提供的 @RestController 注解用于实现数据请求的处理。默认情况下, @RestController 注解会将返回的对象数据转换为JSON格式。
UserController.java
package com.example.webproject.controller;
import com.example.webproject.model.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
public class UserController {
@RequestMapping("/getUser")
public User getUser() {
User u = new User();
u.setName("zhangsan");
u.setAge(20);
u.setPassword("123456");
return u;
}
}
在上面的示例中,定义 /user/getUser 接口返回JSON格式的User数据。
3、@RestController 和 @Controller 的区别
(1)共同点:
@Controller 和 @RestController 注解都是表示该类是否可以处理HTTP请求,可以说 @RestController 是 @Controller 和 @ResponseBody 的结合体,是这两个注解合并使用的效果。
(2)区别:
- @Controller 标识当前类是 Spring MVC Controller 处理器,而 @RestController 则只负责数据返回。
- 如果使用 @RestController 注解,则 Controller 中的方法无法返回 Web 页面,配置的视图解析器 InternalResourceViewResolver 不起作用,返回的内容就是 Return 中的数据。
- 如果需要返回指定页面,则使用 @Controller 注解,并配合视图解析器返回页面和数据。如果需要返回 JSON、XML 或自定义内容到页面,则需要在对应的方法上加上 @ResponseBody 注解。
总之,在 Web 系统中使用 @Controller 较多,而在 Web API 中基本使用 @RestController 注解。
4.1.3 @RequestMapping
@RequestMapping 注解主要负责URL的路由映射。它可以添加在 Controller 类或者具体的方法上,如果添加在 Controller 类上,则这个 Controller 中的所有路由映射都将会加上此映射规则,如果添加在方法上,则支队当前方法生效。
@RequestMapping 注解包含很多属性参数来定义 HTTP 的请求映射规则。常用的属性参数如下:
- value:请求 URL 的路径,支持 URL 模板、正则表达式。
- method:HTTP 请求的方法。
- consumes:允许的媒体类型,如 consumes="application/json" 为 HTTP 的 Content-Type。
- produces:响应的媒体类型,如 produces="application/json" 为 HTTP 的 Accept 字段。
- params:请求参数。
- headers:请求头的值。
以上属性基本涵盖了一个 HTTP 请求的所有参数信息。其中,value 和 method 属性比较常用。
@RequestMapping 使用示例
定义接口:
package com.example.webproject.controller;
import com.example.webproject.model.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user2")
public class User2Controller {
@RequestMapping(value="/getUser", method= RequestMethod.GET, consumes = "application/json", produces = "application/json", params = {"key=123"}, headers = {"token"})
public User getUser() {
User u = new User();
u.setName("zhangsan");
u.setAge(20);
u.setPassword("123456");
return u;
}
}
调用接口:
4.1.4 @ResponseBody
@ResponseBody 注解主要用于定义数据的返回格式,作用在方法
上,默认使用 Jackson 序列化成 JSON 字符串后返回给客户端,如果是字符串,则直接返回。
在 Controller 中有时需要返回 JSON 格式的数据,如果想直接返回数据体而不是视图名,则需要在方法上使用 @ResponseBody。使用方式如下:
package com.example.webproject.controller;
import com.example.webproject.model.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/user")
public class UserController {
@ResponseBody
@RequestMapping("/getUser")
public User getUser() {
User u = new User();
u.setName("zhangsan");
u.setAge(20);
u.setPassword("123456");
return u;
}
}
在上面的示例中,请求 /user/getUser 时,返回 JSON 格式的 User 数据。
来源:《Spring Boot 从入门到实战》学习笔记