Restful API设计(Java web Spring MVC 版)
来源:互联网 发布:ct重建算法 编辑:程序博客网 时间:2024/06/08 14:13
关于Restful API 设计的Java SpringMVC的介绍主要分为两部分,先介绍Restful API的基础知识,然后介绍如何在Java web项目中的Spring MVC中使用。
一:关于Restful API相关知识
Restful API 对于HTTP动作的约定
Restful API是目前比较成熟的一套互联网应用程序的API设计理论,它遵循统一接口原则,包含了一组预定义的操作,比如,常用的HTTP动词包括以下五个:
GET:查询操作(可以重复操作)对应MySQL的SELECT语句;
POST:添加操作,对应MySQL的CREATE语句;
PUT:更新操作(客户端提供改变后的完整资源),对应MySQL的UPDATE语句;
PATCH:更新操作(客户端提供改变的属性),对应MySQL的UPDATE语句;
DELETE:删除操作,对应MySQL的DELETE语句。
Restful API对接口的域名规定(两种方法)
方法一:对于部署的API应该在专用的域名之下,比如:https://api.example.com(推荐)
方法二:如果确定API很简单,不会进一步扩展,可以考虑放在主域名下:https://example.om/api/
Restful API 对于版本号的约定(两种方法)
方法一:将API的版本号放入URL中:https://api.example.com/v1/
方法二:将版本号放在HTTP头信息中,但不如放入URL方便和直观。Github采用此法。
Restful API 对于URL的约定
在Restful 架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表名相对应。一般来说,数据库中的表都是同种记录的“集合”(collection),所以API中的名词也可以使用复数。
URL的设计规则如下:
/模块/资源/{标识}/集合1/….
比如:
/user/{uid}/friends -> 好友列表
/user/{uid}/followers -> 关注者列表
再举个栗子:
与秒杀相关的操作的接口:
GET /seckill/list 秒杀列表
GET /seckill/{id}/detail 详情页
GET /seckill/time/now 系统时间
POST /seckill/{id}/exposer 暴露秒杀
POST /seckill/{id}/{md5}/execution 执行秒杀
不友好的设计如下:
POST /seckill/execute/{seckillId} (不友好,execute是动词)
GET /seckill/delete/{id} (不友好,应该用DELETE提交,可改为如下:)
DELETE /seckill/{id}/delete (友好)
二、Restful API 在Spring MVC中的实现
Spring中的@RequestMapping注解,分析如下:
@RequestMapping注解的特点如下:
(1)支持标准的URL
(2)Ant风格URL(即?和**等字符)
(3)带{×××}占位符的URL
例如:
/user/*/creation
匹配: /user/aaa/creation、/user/bbb/creation等URL。
/user/**/creation
匹配: /user/creation、/user/aaa/bbb/creation等URL。
/user/{userId}
匹配: /user/123、/user/abc等URL。
/company/{campanyId}/user/{userId}/detail
匹配:/company/123/user/323/detail等的URL
SpringMVC中的具体配置如下:
(1)web.xml文件的内容
<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_3_1.xsd" version="3.1"> <!-- 修改Servlet 版本为3.1 --> <!-- 配置DispatcherServlet--> <servlet> <servlet-name>seckill-dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 配置springMVC配置需要加载的配置文件 spring-dao.xml,spring-service.xml,spring-web.xml Mybatis -> spring -> springMVC --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/spring-*.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>seckill-dispatcher</servlet-name> <!-- *.do 是非常丑陋的,默认匹配所有请求--> <url-pattern>/</url-pattern> </servlet-mapping></web-app>
注意:上述的DispatcherServlet对应的seckill-dispatcher将所有的请求(这里配置为”/”),都会进行handlemapping,即去控制器中去找对于的路径,因此需要配置一个对静态的资源默认的Servlet,因此有如下配置文件。
(2)spring-web.xml 中配置对静态的资源默认的Servlet
<?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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 配置springMVC --> <!-- 1:开启SpringMVC注解模式 --> <!-- (1)自动注册DefaultAnnotationHandlerMapping, AnnotationMethodHandlerAdapter (2)提供一系列:数据绑定,数字和日期的format @NumberFormat, @DataTimeFormat,xml,json默认读写支持. --> <mvc:annotation-driven /> <!-- 2、servlet-mapping 映射路径:"/" --> <!-- 静态资源默认servlet配置 1、加入对静态资源的处理:js,gif,png 2、允许使用“/”做整体映射 --> <!-- <mvc:default-servlet-handler />--> <!-- 3:配置jsp 显示ViewResolver --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> <!-- 4:扫描web相关的bean --> <context:component-scan base-package="org.seckill.web" /></beans>(3)Java 秒杀 SeckillController控制器Restful 接口设计
@Controller@RequestMapping("/seckill") // url:/模块/{id}/细分 /seckill/listpublic class SeckillController { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private SeckillService seckillService; @RequestMapping(value="/list", method = RequestMethod.GET) public String list(Model model){ //获取列表页 List<Seckill> list = seckillService.getSeckillList(); model.addAttribute("list", list); // list.jsp + model = ModelAndView return "list"; //WEB-INF/jsp/list.jsp } @RequestMapping(value = "/{seckillId}/detail", method = RequestMethod.GET) public String detail(@PathVariable("seckillId") Long seckillId, Model model){ if(seckillId == null){ return "redirect:/seckill/list"; } Seckill seckill = seckillService.getById(seckillId); if(seckill == null){ return "forward:/seckill/list"; } model.addAttribute("seckill", seckill); return "detail"; } @RequestMapping(value="/{seckillId}/exposer", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) @ResponseBody public SeckillResult<Exposer> exposer(Long seckillId){ SeckillResult<Exposer> result; try{ Exposer exposer = seckillService.exposeSeckillUrl(seckillId); result = new SeckillResult<Exposer>(true, exposer); }catch (Exception e){ logger.error(e.getMessage(), e); result = new SeckillResult<Exposer>(false, e.getMessage()); } return result; } @RequestMapping(value = "/{seckillId}/{md5}/execution", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) public SeckillResult<SeckillExecution> execute(@PathVariable("seckillId") Long seckillId, @PathVariable("md5") String md5, @CookieValue(value = "killPhone", required = false) Long phone){ //SpringMVC valid if(phone == null){ return new SeckillResult<SeckillExecution>(false, "未注册"); } SeckillResult<SeckillExecution> result; try { SeckillExecution execution = seckillService.executeSeckill(seckillId, phone, md5); return new SeckillResult<SeckillExecution>(true, execution); }catch (RepeatKillException e){ SeckillExecution execution = new SeckillExecution(seckillId, SeckillStateEnum.REPEAT_KILL); return new SeckillResult<SeckillExecution>(false, execution); }catch (SeckillCloseException e){ SeckillExecution execution = new SeckillExecution(seckillId, SeckillStateEnum.END); return new SeckillResult<SeckillExecution>(false, execution); }catch (Exception e){ logger.error(e.getMessage(), e); SeckillExecution execution = new SeckillExecution(seckillId, SeckillStateEnum.INNER_ERROR); return new SeckillResult<SeckillExecution>(false, execution); } } @RequestMapping(value = "/time/now", method = RequestMethod.GET) @ResponseBody public SeckillResult<Long> time(){ Date now = new Date(); return new SeckillResult(true, now.getTime()); }}
- Restful API设计(Java web Spring MVC 版)
- Spring MVC RESTFul Web Services
- Spring Web MVC实现Restful Web Service
- Spring Web MVC实现Restful Web Service
- 使用Spring MVC写RESTFUL API
- RESTful api接口开发与Spring MVC
- Spring Web MVC Restful API 优化之路 (1) - 参数构建优化
- Spring mvc实现RESTful Web 服务Demo
- Spring MVC中发布Restful Web服务
- Spring MVC 4 RESTFul Web Services CRUD例子(带源码)【这才是restful,超经典】
- Spring MVC 4 RESTFul Web Services CRUD例子(带源码)【这才是restful,超经典】
- Spring MVC 4 RESTFul Web Services CRUD例子(带源码)【这才是restful,超经典】
- Spring security实战(3)-----使用Spring MVC编写RestFul API
- spring mvc restful java.lang.Stackoverflowerror
- Apache HttpClient调用Spring3 MVC Restful Web API演示
- Spring MVC中使用 Swagger2 构建Restful API
- Spring MVC中使用 Swagger2 构建Restful API
- 【实践笔记】Spring MVC中Restful API使用 Swagger2 构建
- HDU
- 反射
- 51nod 1049 最大子段和
- spark-troubleshooting-OOM
- Qt设置应用程序图标
- Restful API设计(Java web Spring MVC 版)
- Junit单元测试
- 基于Dubbo的分布式系统架构(一):安装ZooKeeper注册中心(单机版)
- SAS中字符串连接符与连接函数
- Eclipse插件推荐
- **XML**:
- 485. Max Consecutive Ones
- 字典树 模板
- SAS中变量命名规则