一、RESTful
REST(Representational State Transfer),表现层资源状态转移,是一种将请求参数变成请求路径的一种软件架构风格或软件设计风格。
具体说,就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。
它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源,PUT用来更新资源,DELETE用来删除资源。
REST风格提倡URL地址使用统一的风格设计,从前到后各个单词使用斜杠分开,不使用问号键值对方式携带请求参数,而是将要发送给服务器的数据作为URL地址的一部分,以保证整体风格的一致性。
代码演示
pom.xml依赖
<packaging>war</packaging>
<dependencies>
<!--SpringMVC-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.1</version>
</dependency>
<!--日志-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!--servletAPI-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--Spring与Thymeleaf整合-->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.12.RELEASE</version>
</dependency>
</dependencies>
(1)UserController.java
@Controller
public class UserController {
/**
* 使用RESTFul实现对用户信息的操作
* /user GET 查询所有用户信息
* /user/1 GET 根据id查询用户信息
* /user POST 添加用户信息
* /user/1 DELETE 根据id删除用户信息
* /user PUT 修改用户信息
*/
@RequestMapping(value = "/user",method = RequestMethod.GET)
public String getAllUSer(){
System.out.println("查询用户信息");
return "success";
}
@RequestMapping(value = "/user/{id}",method = RequestMethod.GET)
public String getUserById(){
System.out.println("根据id查询客户信息");
return "success";
}
@RequestMapping(value = "/user",method = RequestMethod.POST)
public String insertUser(String username,String password){
System.out.println("添加用户信息:"+username+","+password);
return "success";
}
@RequestMapping(value = "user",method = RequestMethod.PUT)
public String updateUser(String username,String password){
System.out.println("修改用户信息:"+username+","+password);
return "success";
}
}
(2)springMVC.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--配置包扫描组件-->
<context:component-scan base-package="com.jd.mvc.controller"/>
<!--配置视图解析器-->
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<!--视图前缀-->
<property name="prefix" value="/WEB-INF/templates/"/>
<!--视图后缀-->
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>
<!--配置SpringMVC的视图控制器-->
<mvc:view-controller path="/" view-name="index"></mvc:view-controller>
<mvc:view-controller path="/rest_test" view-name="rest_test"></mvc:view-controller>
<!--开启SpringMVC的注解驱动-->
<mvc:annotation-driven/>
</beans>
(3)web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">
<!--配置编码过滤器,在此之前不能获取任何的请求参数,只要获取请求参数,设置编码方式就无用-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!--设置请求的编码-->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<!--设置响应的编码-->
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<!--表示对所有的都进行编码,过滤器的执行顺序是根据<filter-mapping>的顺序执行的-->
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--配置HiddenHttpMethodFilter-->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--配置SpringMVC的前端控制器-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMVC.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
(4)rest_test.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a th:href="@{/user}">查询用户信息</a>
<a th:href="@{/user/1}">根据id查询用户信息</a>
<form th:action="@{/user}" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="添加">
</form>
<!--要想处理put和delete请求:(1)method设置为post;(2)传输一个请求参数为“_method”-->
<form th:action="@{/user}" method="post">
<!--该请求参数对客户无用,不需要看到,设置为hidden-->
<input type="hidden" name="_method" value="PUT">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="修改">
</form>
</body>
</html>
二、HttpMessageConverter
HttpMessageConverter(报文信息转换器):将请求报文转换为Java对象,或将Java对象转换为响应报文。
HttpMessageConverter提供了两个注解和两个类型:@PequestBody,@ResponseBody,RequestEntity,ResponseEntity
1.@RequestBody
@RequestBody可以获取请求体,需要在控制器方法设置一个形参,使用@RequestBody进行标识,当前请求的请求体就会为当前注解所标识的形参赋值。
@RequestMapping("/testRequestBody")
public String testRequestBody(@RequestBody String requestBody ){
System.out.println("requestBody : "+requestBody);
return "success";
}
<form th:action="@{testRequestBody}" method="post">
username:<input type="text" name="username"><br>
username:<input type="password" name="password"><br>
<input type="submit" value="测试@RequestBody"><br>
</form>
运行结果:
requestBody : username=admin&password=11111
2、RequestEntity
RequestEntity封装请求报文的一种类型,需要在控制器方法的形参中设置该类型的形参,当前请求的请求报文就会赋值给该形参,可以通过getHeaders()获取请求头信息,通过getBody()获取请求体信息。
@RequestMapping("/testRequestEntity")
public String testRequestEntity(RequestEntity<String> requestEntity){
System.out.println("------------------------------------------");
System.out.println("请求头:"+requestEntity.getHeaders());
System.out.println("请求体:"+requestEntity.getBody());
System.out.println("------------------------------------------");
return "success";
}
<form th:action="@{testRequestEntity}" method="post">
username:<input type="text" name="username"><br>
username:<input type="password" name="password"><br>
<input type="submit" value="测试RequestEntity"><br>
</form>
运行结果:
------------------------------------------
请求头:[host:"localhost:8080", connection:"keep-alive", content-length:"29", cache-control:"max-age=0", sec-ch-ua:""Chromium";v="94", "Google Chrome";v="94", ";Not A Brand";v="99"", sec-ch-ua-mobile:"?0", sec-ch-ua-platform:""Windows"", upgrade-insecure-requests:"1", origin:"http://localhost:8080", user-agent:"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36", accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", sec-fetch-site:"same-origin", sec-fetch-mode:"navigate", sec-fetch-user:"?1", sec-fetch-dest:"document", referer:"http://localhost:8080/", accept-encoding:"gzip, deflate, br", accept-language:"zh-CN,zh;q=0.9", Content-Type:"application/x-www-form-urlencoded;charset=UTF-8"]
请求体:username=admin&password=11111
------------------------------------------
3.@ResponseBody@ResponseBody用于标识一个控制器方法,可以将该方法的返回值直接作为响应报文的响应体响应到浏览器。
@RequestMapping("/testResponseBody")
@ResponseBody
public String testResponseBody() {
//返回值作为数据响应到浏览器,若没有@ResponseBody则表示响应的视图名
return "success";
}
<a th:href="@{/testResponseBody}">测试@ResponseBody响应浏览器数据</a><br>
3.SpringMVC处理json
步骤:
(1)导入jackson依赖
<!--jackson的依赖,实现@ResponseBody对Json数据的处理-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
</dependency>
(2)springMVC的配置文件中开启注解驱动
<!--开启SpringMVC的注解驱动-->
<mvc:annotation-driven/>
(3)在处理器方法上使用@ResponseBody标识
(4)在控制器方法中将Java对象直接返回
@RequestMapping("/testResponseUser")
@ResponseBody
public User testResponseUser(){
return new User(1001,"admin","123456","男");
}
<a th:href="@{/testResponseUser}">测试@ResponseBody响应浏览器数据User对象</a><br>
运行结果:
4.RestControlle注解
@RestController注解是springMVC提供的一个复合注解,标识在控制器的类上,就相当于为类添加了@Controller注解,并且为其中的每个方法添加了@ResponseBody注解
5.ResponseEntity
ResponseEntity用于控制器方法的返回值类型,该控制器方法的返回值就是响应到浏览器的响应报文