SpringMVC中@PathVariable的使用和REST风格
1、@PathVariable
参数像作为参数应该怎么使用呢?可以使用@PathVariable注解,此注解就是提供了对占位符URL的支持,就是将URL中占位符参数绑定到控制器处理方法的参数中。
演示:
//value中的hello是访问路径
@RequestMapping(value = "/hello/{name}")
public String hello(@PathVariable("name") String name) {
System.out.println(name);
System.out.println("成功!");
return "hello";//返回一个名为hello的页面
}
访问:访问时,在hello后面加上/name=,就是将URL中占位符参数绑定到控制器处理方法的参数中。
- 注意:
- value中的{name}必须和(@PathVariable(“name”)中的name名称一致。
- URL中占位符参数绑定到控制器处理方法的参数中。访问时,必须带有指定的参数,不然将会报错。
2、REST风格
-
REST即表述性状态传递(英文:Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。它是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。
-
在三种主流的Web服务实现方案中,因为REST模式的Web服务与复杂的SOAP和XML-RPC对比来讲明显的更加简洁,越来越多的web服务开始采用REST风格设计和实现。例如,Amazon.com提供接近REST风格的Web服务进行图书查找;雅虎提供的Web服务也是REST风格的。
REST,翻译过来叫做表现层状态转化,是目前最流行的一个互联网软件架构,它架构清晰,符合标准,易于理解,扩展方便。
表现层(Representation):把资源具体呈现出来的形式,因此叫做表现层。
资源(Resource):网络上的一个具体信息,文本,图片,音频,视频都可以称之为资源,如果想要访问到互联网上的某一个资源,那么就必须要使用一个URL来唯一性的获取改资源,也可以这么说,URL是每一个资源的唯一标识符。
状态转化(State Transfer):当客户端发出一个请求的时候,就代表客户端跟服务端的一次交互过程,HTTP是一种无状态协议,即所有的状态都保存在服务器端,因此,客户端如果想要操作服务器,必须通过某些手段,让服务器的状态发生转化,而这种转化是建立在表现层的,这就是名字的由来。
理解:
我们在获取资源的时候就是进行增删改查的操作,如果是原来的架构风格,需要发送四个请求,分别是:
语句 | 路径 |
---|---|
查询 | localhost:8080/query?id=1 |
增加 | localhost:8080/insert |
删除 | localhost:8080/delete?id=1 |
更新 | localhost:8080/update?id=1 |
按照此方式发送请求的时候比较麻烦,需要定义多种请求,而在HTTP协议中,有不同的发送请求的方式,分别是GET、POST、PUT、DELETE等,我们如果能让不同的请求方式表示不同的请求类型就可以简化我们的查询
请求方式 | 路径 |
---|---|
GET:获取资源 | /book/1 |
POST:新建资源 | /book |
PUT:更新资源 | /book/1 |
DELETE:删除资源 | /book/1 |
要实现上述方式进行访问,就是要将URL中占位符参数绑定到控制器处理方法的参数中 占位符参数绑定到控制器处理方法的参数中。此时,我们以可用到注解@PathVariable进行绑定,但是,存在一个问题。
我们在发送请求的时候只能发送post或者get,没有办法发送put和delete请求,那么应该如何处理呢?
下面开始进入代码环节:
-
导入pom.xml依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>mashibing_springmvc_01</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.3.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.3.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.3.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet/jsp-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> </dependencies> </project>
导包:不需要过多解释,直接导入即可
-
配置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"> <servlet> <!--前端控制器--> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <!--配置启动参数--> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </init-param> <!--服务器启动时加载--> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!--设置编码格式--> <filter> <filter-name>encoding</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>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--此过滤器完成请求方式的转换,将post请求转换为put或者delete,没有配置该过滤器,将会报错--> <filter> <filter-name>hidden</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>hidden</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
注意:不能忘记配置HiddenHttpMethodFilter过滤器。该过滤器的作用是将post请求转换为put或delete请求。
-
创建并配置applictionContext.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.mvn"></context:component-scan> <!--添加mvc注解支持--> <mvc:annotation-driven></mvc:annotation-driven> <!--添加视图解析器--> <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--前缀--> <property name="prefix" value="/WEB-INF/page/"></property> <!-- 后缀 --> <property name="suffix" value=".jsp"/> </bean> </beans>
-
创建restcontroller类,模拟数据库的增删改查
package com.mvn.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class restcontroller { //POST请求,模拟数据库的曾 @RequestMapping(value = "/user",method = RequestMethod.POST) public String add() { System.out.println("添加"); return "success"; } //DELETE请求,模拟数据库的删 @RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE) public String delete(@PathVariable("id") Integer id) { System.out.println("删除:" + id); return "success"; } //PUT请求,模拟数据库的改 @RequestMapping(value = "/user/{id}", method = RequestMethod.PUT) public String update(@PathVariable("id") Integer id) { System.out.println("更新:" + id); return "success"; } //GET请求,模拟数据库的查 @RequestMapping(value = "/user/{id}", method = RequestMethod.GET) public String query(@PathVariable("id") Integer id) { System.out.println("查询:" + id); return "success"; } }
-
编写rest.jsp,用于发出请求
<%-- Created by IntelliJ IDEA. User: Lenovo Date: 2021/3/21 Time: 15:52 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <!--获取访问的URL路径--> <% pageContext.setAttribute("ctp",request.getContextPath()); %> <body> <form action="${ctp}/user" method="post"> <input type="submit" value="增加"> </form> <form action="${ctp}/user/1" method="post"> <input name="_method" value="delete" type="hidden"> <input type="submit" value="删除"> </form> <form action="${ctp}/user/2" method="post"> <input name="_method" value="put" type="hidden"> <input type="submit" value="修改"> </form> <a href="${ctp}/user/1">查询</a><br/> </body> </html>
注意:
-
访问路径是一个坑,很容易出错,记得java获取请求路径,写入访问url中;
<!--获取访问的URL路径--> <% pageContext.setAttribute("ctp",request.getContextPath()); %>
-
隐藏域中,除了put可以修改,其他都是固定的,不能是随意修改。
<input name="_method" value="put" type="hidden">
-
-
在WEB-INF目录下创建page文件夹。在文件夹中编写success,jsp文件,以便跳转
-
启动服务器,运行
**注意:**只支持tomcat7.0一下,否则会报错。
3、总结
-
@PathVariable的作用是:URL中占位符参数绑定到控制器处理方法的参数中,方便我请求路径的编写。
-
访问路径必须和PathVariable属性值一致
(value = "/hello/{name}") public String hello(@PathVariable("name") String name)
-
由于浏览器表单只支持 GET 和 POST 请求,为了实现 DELETE 和 PUT 请求,Spring 为我们提供了一个过滤器HiddenHttpMethodFilter,记得在web.xml中添加。
<!--此过滤器完成请求方式的转换,将post请求转换为put或者delete,没有配置该过滤器,将会报错--> <filter> <filter-name>hidden</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>hidden</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
-
表单中添加隐藏域
<input name="_method" value="put" type="hidden">
其中除了put可以改,其他不能修改。
-
使用tomcat7及以下版本。