SpringBootRESTful实战

了解Restful是什么,基本概念及风格;

能使用SpringBoot实现一套基础的Restful风格接口;

利用Swagger生成清晰的接口文档。

什么是REST

摘自百科的定义:REST即表述性状态转移(英文:RepresentationalStateTransfer,简称REST)是RoyFielding博士(HTTP规范主要贡献者)在2000年的论文中提出来的一种软件架构风格。是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。

通俗点说,REST就是一组架构约束准则;在这些准则中,有不少是利用了现有的WEB标准能力。而最终的目的则是简化当前业务层的设计及开发工作。

关键要点

理解Restful风格需要理解以下几点:

资源

资源的表述

资源表述(Representation)指的则是资源的外在表现形式比如一个帖子,可以通过HTML格式展现,也可以通过XML、JSON等格式输出到客户端。

状态转移

在HTTP访问过程中,资源的状态发生变化。这里会涉及到以下的几个动词:

对于不同的访问方法,服务器会产生对应的行为并促使资源状态产生转换。

关于无状态

Restful是无状态的设计,这点意味着交互过程中的请求应该能包含所有需要的信息,而不需要依赖于已有的上下文。然而JavaEE中存在一些违背的做法,比如Cookie中设置JSESSIONID,在多次请求间传递该值作为会话唯一标识,这标识着服务端必须保存着这些会话状态数据。

PlayFramework框架实现了无状态的Session,其将会话数据经过加密编码并置入Cookie中,这样客户端的请求将直接携带上全部的信息,是无状态的请求**,这点非常有利于服务端的可扩展性。

接下来,我们利用SpringBoot来实现一个Restful风格的样例。

说明基于PetStore(宠物店)的案例,实现对某顾客(Customer)名下的宠物(Pet)的增删改查。

Customer

publicclassCustomer{

privateStringname;

publicCustomer(){

super();

}

publicCustomer(Stringname){

this.name=name;

publicStringgetName(){

returnname;

publicvoidsetName(Stringname){

Customer只包含一个name属性,我们假定这是唯一的标志。

Pet

publicclassPet{

privateStringpetId;

privateStringtype;

privateStringdescription;

publicStringgetPetId(){

returnpetId;

publicvoidsetPetId(StringpetId){

this.petId=petId;

publicStringgetType(){

returntype;

publicvoidsetType(Stringtype){

this.type=type;

publicStringgetDescription(){

returndescription;

publicvoidsetDescription(Stringdescription){

this.description=description;

Pet包含了以下几个属性

基于Restful的原则,我们定义了以下的一组URL:

接下来实现一个PetManager类,用于模拟在内存中对Pet数据进行增删改查代码如下:

@Component

publicclassPetManager{

privatestaticMapcustomers=newConcurrentHashMap();

privatestaticMap>pets=newConcurrentHashMap>();

@PostConstruct

publicvoidinit(){

for(StringcustomerName:customerNames){

customers.put(customerName,newCustomer(customerName));

/**

*获取customer

*

*@paramcustomer

*@return

*/

publicCustomergetCustomer(Stringcustomer){

if(StringUtils.isEmpty(customer)){

returnnull;

returncustomers.get(customer);

*获取customer名下的pet列表

publicListgetPets(Stringcustomer){

returnCollections.emptyList();

if(!pets.containsKey(customer)){

returnpets.get(customer).values().stream().collect(Collectors.toList());

*获取某个pet

*@parampetId

publicPetgetPet(Stringcustomer,StringpetId){

if(StringUtils.isEmpty(customer)||StringUtils.isEmpty(petId)){

returnpets.get(customer).get(petId);

*删除pet

publicbooleanremovePet(Stringcustomer,StringpetId){

returnfalse;

returnpets.get(customer).remove(petId)!=null;

*添加pet

*@parampet

publicPetaddPet(Stringcustomer,Petpet){

if(StringUtils.isEmpty(customer)||pet==null){

MapcustomerPets=null;

customerPets=newLinkedHashMap();

Mapprevious=pets.putIfAbsent(customer,customerPets);

//已经存在

if(previous!=null){

customerPets=previous;

}else{

customerPets=pets.get(customer);

if(pet.getPetId()==null){

pet.setPetId(UUID.randomUUID().toString());

customerPets.put(pet.getPetId(),pet);

returnpet;

*更新某个pet

*@parampetPojo

publicPetupdatePet(Stringcustomer,PetpetPojo){

if(StringUtils.isEmpty(customer)||petPojo==null){

if(petPojo.getPetId()==null){

Petpet=getPet(customer,petPojo.getPetId());

pet.setType(petPojo.getType());

pet.setName(petPojo.getName());

pet.setDescription(petPojo.getDescription());

SpringBoot提供了@RestController,用于快速定义一个Restful风格的Controller类@RestController=@ResponseBody+@Controller

@RestController

publicclassRestApiController{

@Autowired

privatePetManagerdataManager;

*添加宠物

@PostMapping

publicResponseEntityaddPet(@PathVariableStringcustomer,@RequestBodyPetpet){

validateCustomer(customer);

PetnewPet=dataManager.addPet(customer,pet);

//返回201.created

if(newPet!=null){

.buildAndExpand(newPet.getPetId()).toUri();

returnResponseEntity.created(location).build();

//返回204.noContent

returnResponseEntity.noContent().build();

*获取宠物列表

@GetMapping

@ResponseBody

publicListlistPets(@PathVariableStringcustomer){

Listpets=dataManager.getPets(customer);

returnpets;

*获取某个宠物

publicPetgetPet(@PathVariableStringcustomer,@PathVariableStringpetId){

validatePet(customer,petId);

Petpet=dataManager.getPet(customer,petId);

*更新宠物信息

publicResponseEntityupdatePet(@PathVariableStringcustomer,@PathVariableStringpetId,@RequestBodyPetpet){

pet.setPetId(petId);

PetpetObject=dataManager.updatePet(customer,pet);

if(petObject!=null){

returnResponseEntity.ok(petObject);

*删除某个宠物

publicResponseEntityremovePet(@PathVariableStringcustomer,@PathVariableStringpetId){

dataManager.removePet(customer,petId);

returnResponseEntity.ok().build();

上述代码中已经实现了完整的增删改查语义。在Restful风格的API接口定义中,往往会引用HTTP状态码用于表示不同的结果,比如一些错误的状态类型。

这里我们对Customer、Pet进行存在性校验,若资源不存在返回404_NotFound。

*校验customer是否存在

privatevoidvalidateCustomer(Stringcustomer){

if(dataManager.getCustomer(customer)==null){

*校验pet是否存在

privatevoidvalidatePet(Stringcustomer,StringpetId){

if(dataManager.getPet(customer,petId)==null){

自定义异常拦截

*自定义异常,及拦截逻辑

*@authoratp

publicstaticclassObjectNotFoundExceptionextendsRuntimeException{

publicObjectNotFoundException(Stringmsg){

super(msg);

@ExceptionHandler(ObjectNotFoundException.class)

@ResponseStatus(HttpStatus.NOT_FOUND)

publicStringobjectNotFoundExceptionHandler(ObjectNotFoundExceptionex){

returnex.getMessage();

{

返回示例

201created

Content-Length→0

Date→Mon,09Jul201805:15:01GMT

200OK

Content-Type→application/json;charset=UTF-8

Date→Mon,09Jul201805:23:27GMT

Transfer-Encoding→chunked

[

},

]

Date→Mon,09Jul201805:25:24GMT

Date→Mon,09Jul201805:31:28GMT

Date→Mon,09Jul201805:32:51GMT

关于Swagger

Swagger是目前非常流行的一个API设计开发框架(基于OpenApi),可用于API的设计、管理、代码生成以及Mock测试等。

目前Swagger的应用非常广,其涵盖的开源模块也比较多,这里将使用swagger-ui实现API在线DOC的生成。

引入依赖

io.springfox

springfox-swagger2

2.7.0

springfox-swagger-ui

定义API配置

@EnableSwagger2

@Configuration

publicclassSwaggerConfig{

privatebooleanenabled;

ApiInfoapiInfo(){

returnnewApiInfoBuilder().

.version(VERSION)

.build();

@Bean

publicDocketcustomImplementation(){

returnnewDocket(DocumentationType.SWAGGER_2).select()

.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))

THE END
1.狗狗去宠物店洗澡,刚开始我就说明了狗狗会咬人,咬了店员,需要怎么解决...被狗咬了,当事人可以与动物饲养人协商解决索赔问题,如果达成一致意见的,当事人可以自信履行协议,如果...https://www.lawtime.cn/wenda/q_42492969.html
2.[宠物详情页描述模板]图片免费下载宠物详情页描述模板素材千图网为您找到1000张宠物详情页描述模板相关素材,千图网还提供宠物详情页描述模板图片,宠物详情页描述模板素材, 宠物详情页描述模板模板等免费下载服务,千图网是国内专业创意营销服务交易平台,一站式解决企业营销数字化、协同化,实现营销转化效果增长!https://m.58pic.com/tupian/chongwuxiangqingyemiaoshumoban.html
3.宠才网官网(PetHr.com)宠才网-原宠物人才网(Pethr.com)专注于宠物招聘,中国宠物人才网站,是宠物医院招聘、宠物店招聘和宠物医生、训犬师、实习生、饲养员、医师、宠物美容师招聘求职理想选择!https://www.pethr.com/
4.补习系列(5)springbootrestful应用实战基于PetStore(宠物店) 的案例,实现对某顾客(Customer)名下的宠物(Pet)的增删改查。 1. 实体定义 Customer public class Customer { private String name; public Customer() { super(); } public Customer(String name) { super(); this.name = name; } public String getName() { return name; } pu...https://www.imooc.com/article/50217
1.关于宠物店作文300字,想当宠物店老板的梦想从这里起航关于宠物店的300字作文(11篇) 在日常学习、工作和生活中,每个人都不可避免地要接触或使用作文。人们借助构图可以达到文化交流的目的。相信很多人都会觉得写论文很难。以下是小编搜集的一篇关于宠物店的300字作文,供大家参考。希望可以帮助到有需要的朋友。 https://xkyczp.com/detail/200225.html
2....为宠物医院建立一个猫的数据库用于描述宠物猫包括猫的行为习惯名字年...这篇博客是一个关于Python编程的实战练习,涉及创建宠物店类,其中包括宠物列表,以及宠物猫和宠物狗两个子类。宠物店类提供展示店内宠物信息的方法。宠物猫类具有吃鱼、撒娇和叫(喵)的功能,而宠物狗类则能吃骨头、拆家和叫(汪)。示例代码展示了这些类和方法的具体实现。 https://blog.csdn.net/hello_miemie/article/details/114368435
3.宠物商店创业计划书(精选10篇)(1)宠物用品自身风险;宠物用品行业是国内新兴行业,随着人们生活水平的提高、知识素养程度的提升,宠物越来越受到人们的欢迎,随着而来的就是巨大的宠物用品市场,所以该风险在长期内将会非常小,反而却有利于本项目的实施。 (2)货源不稳定;本店通过考察、洽谈,已确定几家大规模的宠物用品生产商,可从他们厂直接进货,且可...https://www.yjbys.com/chuangye/ziliao/chuangyejihuashu/632154.html
4....结果是细小病毒细小病毒是一星期死亡说明了在宠物店里它就已经得病...详细描述(遇到的问题、发生经过、想要得到怎样的帮助):我买了一只狗然后养到第四天死亡,第三天的时候我带它去医院检查结果是细小病毒 细小病毒是一星期死亡说明了在宠物店里它就已经得病了我打电话给这个店长他就说他的狗都是没有问题的然后就一直不接我电话了我应该怎么办...https://www.66law.cn/question/16884222.aspx
5.宠物店的氛围声音淘声网一家宠物店的氛围与主导的鱼缸声音和蟋蟀在背景中与人们在背景中谈话。https://www.tosound.com/sound/sound-4VgJoXer
6.创业策划书(15篇)最近几年的宠物市场越来越热,我们身边的宠物食品、用品店,宠物美容店在几年之内增加了很多,超市里与宠物食品、宠物用品有关的产品也由原来的一个货架,扩展成为一排货架,小区周围的'小型超市也增加了宠物食品、用品的货架,各大主流网站也开辟了宠物论坛,()到处可以了解到关于宠物的各种信息,宠物成了居民生活中的一部...https://www.pinda.com/zhichang/cehuashu/109248.html
7.(营业中)宠物店转让宠物店生活服务商铺转让商铺详细描述 因个人原因,没有多余精力去管理,转让经营中宠物店一家。地址隆尧县最繁华商业圈,周围临近县城各个高档小区,有幼儿园,培训机构,商业街,生活广场,人流密集,顾客稳定,消费力强。交通便利,停车方便。 整体转让,包括进货渠道,接受即可盈利。在各个地图都有商家认证。 上下两层,面积197平,房租、水电加起来,...https://www.shangpu5.com/zhuanrang/show-10465.html
8.下列关于胸锁乳突肌的位置描述,正确的是?【单选题】服务器的部署是网络规划的重要环节。某单位网络拓扑结构如图5-5所示,需要部署VOD服务器、Web服务器、邮件服务器,此外还需要部署流量监控服务器对单位内部网络流量进行监控。VOD服务器应部署在位置(1),Web服务器应部署在位置(2),流量监控服务器应部署在位置(3)。上述服务器中,流出流量最大的是(...https://www.shuashuati.com/ti/088d6bb3549a43d69f8af7a3a2ff70dd.html?fm=bde26c83d1f9778e6493b934044b5c3ebf
9.请用java代码对宠物进行类描述java创建一个宠物类请用java代码对宠物进行类描述 java创建一个宠物类 文章目录 1.使用继承 1.1 设计类图 1.2 类代码 1.2.1 Pet类代码 1.2.2 Dog类代码 1.2.3 Penguin类代码 1.3 第一阶段总结 2.抽象类 3 改进代码,实现宠物店功能 3.1 实现效果 3.2 实现代码 本节我们将实现一个小的宠物店系统,可以领养小狗和企鹅。https://blog.51cto.com/u_14402/8920847
10.关于犬主粮评价语之前在宠物店里买过这个牌子的狗粮,我家狗子们爱吃,这次在网上看到有活动就买了,狗子们抢着吃呢~而且发货特别快,上一袋刚吃完这一袋正好接上 一键复制 中文字数:63 替同事买的狗粮,很大一袋,还送了小包装的,同事说狗狗吃了不拉肚子,价格又划算,很满意! http://www.tool168.cn/pingjia/pingyu/id/1246.html
11.关于宠物猫“五月”在猫研所成华动物医院就诊的情况说明一、关于猫咪“五月”的基本情况 “五月”,英短银渐层,三月龄,体重0.98kg。据主人自述,于5月23日花费1000余元从宠物店购买而得,卖家打过第一针疫苗后买回家。但无任何免疫及体检证明。 主人接猫回家后,猫咪开始出现流泪、精神萎靡等症状,因此一直未注射第二针疫苗。而在疫苗未注射完全的情况下,主人多次带猫咪外...https://www.douban.com/group/topic/234864945/?start=0&_i=0235308Yk0kQeI
12.男孩凌晨救下30只宠物狗!店主:送一只男孩见宠物店着火报警消防员安全转移约30只狗 6月11日凌晨4点多 苏州市119指挥中心 接到一名男孩报警称 位于工业园区的一家宠物店起火 有大量浓烟冒出图片 在接警员的询问下 男孩清晰地描述出现场情况和起火位置 苏安消防救援站十几名消防员 立即出动赶赴现场处置 ...https://content-static.cctvnews.cctv.com/snow-book/index.html?item_id=5260159321802033465
13.精幼儿园区域活动总结本学期,据幼儿的年龄特点,我班开设了益智乐园、科学区、表演区、娃娃家、建构区、图书区、创意美工区、小医院、宠物店、宝宝餐厅,坚持每天开展游戏活动,指导幼儿动手、动脑,积极地与材料相互作用。现将这段时间以来的活动情况作一简单总结。 一、材料的投放 ...https://www.jy135.com/huodongzongjie/1151364.html
14.地理的实习报告范文合集6篇(4)注重分析六条商业街各商业网点类型,描述其商业活动的功能、性质、集聚分散以及人流兴旺程度;对比六条商业街整理出它们之间的差异,并用简单直观的方式表现出来。 (5)把理论与实践相结合,做一份综合的人文地理实习调查报告,加深对人文地理学的学习。 四、关于桂林路商业圈 ...https://www.fwsir.com/Article/html/Article_20211014222350_1398153.html