一文掌握Spring MVC REST风格开发

1,215 阅读6分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第21天,点击查看活动详情

REST风格简介

REST(Respresentational State Transfer),表现形式状态转换。REST是一种软件架构风格设计风格,通过url路径的方式和请求方式的配合进行参数传递以及完成不同的CRUD操作,使不同的请求方式和不同的操作进行了一个匹配统一。

可能这样说,小伙伴们不能理解,简单来说就是与传统请求方式不同的另一种请求方式。

我们举个简单的例子来说明下。

传统风格的请求方式:

http://localhost/getProducts

http://localhost/getProduct?id=7

传统风格的请求方式通过路径名来区分我们的操作,例如:getProducts表示的是查询所有商品信息,addProduct表示添加商品信息。而如果需要路径传参则是在路径后面加上?参数1=参数值&参数2=参数值

REST风格的请求方式:

http://localhost/products

http://localhost/products/7

关于REST风格的请求方式,我们先来看看它的请求路径。products可以表示新增商品信息和查询所有商品信息,而products/id可以表示查询该id的商品信息、删除该id的还是商品信息、修改该id的商品信息。

是不是很疑惑,同样的请求路径怎么能表示出多种操作呢?REST风格的请求方式使用同样的请求路径的时候怎么区分是执行了哪种操作呢?

其实REST风格并不是通过请求路径来区分操作的,而是通过请求方法的不同来区分不同的操作。

常用的REST风格请求方法

请求方法执行操作
POST用于新建资源
DELETE用于删除资源
PUT用于更新资源
GET用于获取资源

POST、DELETE、PUT、GET四种请求方法分别对应增、删、改、查四种不同的操作。所以即使请求路径名相同也能知道我们执行的是什么操作。

REST风格开发的优点

根据上面举的例子,我们可以对比传统风格和REST风格,首先,显而易见的第一个优点就是更加的简便。其次,传统风格根据路径名就能大概知道我们是要进行什么操作,而REST风格是通过路径+请求方法来进行操作的,所以光看路径名我们无法得知进行了什么操作,这就是第二个优点,这样隐藏了资源访问的行为,相对来说比传统的方式更加安全。

REST风格代码实现

我们前面讲了这么多现在来用代码演示下REST风格,我们这里为了简单的演示,所有的操作并不关联数据库进行。

用于新建资源

在Products类中创建addProducts方法,用于新建资源请求。

@RequestMapping(value = "/products",method = RequestMethod.POST)
@ResponseBody
public String addProducts(){
    System.out.println("新增商品");
    return "addProducts";
}

在Postman中请求,注意对应的请求方法。

微信截图_20221019220243.png

请求成功,查看打印信息。

新增商品

这样我们就是用REST风格成功的发送了新增请求。

用于删除资源

@RequestMapping(value = "/products/{id}",method = RequestMethod.DELETE)
@ResponseBody
public String deleteProducts(Integer id){
    System.out.println("删除id为"+id+"商品");
    return "deleteProducts";
}

这里注意我们写的是/{id},这样才能接收到传递过来的参数。

然后Postman发送DELETE请求。

微信截图_20221019220623.png 这里Postman传参也是直接/id即可,不再使用之前问号传参的格式了。请求成功后,我们查看打印信息。

删除id为null商品

这里打印信息就有问题了,我们明明有获取id,为什么打印出来是个null呢?这是因为我们没有指定参数从路径中来获取所以参数没有获取到。我们在deleteProducts方法参数列表的参数前面加上@PathVariable注解即可获取到我们REST风格路径中传递的参数。

修改后:

@RequestMapping(value = "/products/{id}",method = RequestMethod.DELETE)
@ResponseBody
public String deleteProducts(@PathVariable Integer id){
    System.out.println("删除id为"+id+"商品");
    return "deleteProducts";
}

重新使用Postman发送DELETE请求。我们再来查看打印信息。

删除id为7商品

这次就能成功的获取到参数了。

用于更新资源

@RequestMapping(value = "/products/{id}",method = RequestMethod.PUT)
@ResponseBody
public String updateProducts(@PathVariable Integer id){
    System.out.println("修改id为"+id+"商品信息");
    return "updateProducts";
}

使用Postman发送PUT请求,查看打印信息。

修改id为7商品信息

修改请求成功。

用于获取资源

@RequestMapping(value = "/products",method = RequestMethod.GET)
@ResponseBody
public String getProducts(){
    System.out.println("查询商品列表");
    return "getProducts";
}

@RequestMapping(value = "/products/{id}",method = RequestMethod.GET)
@ResponseBody
public String getProduct(@PathVariable Integer id){
    System.out.println("查询id为"+id+"商品");
    return "getProduct by id";
}

这里有两个方法,一个是查询全部的商品列表,一个是根据id来查询商品。也跟上面的基本相同。

使用Postman发送GET请求。

微信截图_20221019221816.png

微信截图_20221019221826.png

查看打印信息。

查询id为7商品
查询商品列表

查询成功。

REST风格开发代码简化

通过我们上面的案例,我们实现了使用REST风格来请求并传递获取参数。但是看着上面的代码,每个方法前面都加上了@RequestMapping@ResponseBody注解,这样重复的地方就很多,所以我们需要整合代码达到简化开发的目的。

首先,我们的@ResponseBody注解每个方法都有,就可以放到类层面上。

然后,@RequestMapping注解每个方法也都有,也可以放到类层面上,但是有的方法带参数,并且请求方法也不同,这个问题我们怎么解决呢?这就要用到我们的一些新注解了。POST、DELETE、PUT、GET四种请求方式对应的注解分别是@PostMapping``@DeleteMapping``@PutMapping``@GetMapping,对于带参数的请求,我们可以在对应请求方法的注解中加上参数即可。

我们现在已经简化了不少地方,那还有没有地方可以简化呢?

我们类层面上有@Controller注解和@ResponseBody注解,其实有一个注解可以替代这两个注解——@RestController。这样我们就完成了REST风格开发代码简化。我们来看下简化后的代码。

微信截图_20221019224234.png

总结

关于REST风格开发,我们这里知识点比较多,学习到的新注解也比较多。不同的地方多看几次,也可以多多交流。希望喜欢的小伙伴们多多支持,你们的支持就是我更新的动力。