rest spring

这是关于使用Spring 3.1和Spring Security 3.1和基于Java的配置来建立安全的RESTful Web Service的系列文章的第五篇。 上一篇文章介绍了RESTful服务HATEOAS的可发现性的概念,然后介绍了一些由测试驱动的实际方案。 本文将重点介绍可发现性的实际实现以及使用Spring 3.1在REST服务中满足HATEOAS约束的情况。

通过事件使可发现性脱钩

可发现性作为Web层的一个单独方面或关注点 ,应与处理HTTP请求的控制器分离。 为此,Controller将触发所有需要对HTTP响应进行其他操作的操作的事件:

@RequestMapping( value = "admin/foo/{id}",method = RequestMethod.GET )
@ResponseBody
public Foo get( @PathVariable( "id" ) Long id, HttpServletRequest request, HttpServletResponse response ){Foo resourceById = RestPreconditions.checkNotNull( this.service.getById( id ) );this.eventPublisher.publishEvent( new SingleResourceRetrieved( this, request, response ) );return resourceById;
}
@RequestMapping( value = "admin/foo",method = RequestMethod.POST )
@ResponseStatus( HttpStatus.CREATED )
public void create( @RequestBody Foo resource, HttpServletRequest request, HttpServletResponse response ){RestPreconditions.checkNotNullFromRequest( resource );Long idOfCreatedResource = this.service.create( resource );this.eventPublisher.publishEvent( new ResourceCreated( this, request, response, idOfCreatedResource ) );
}

然后,可以由任意数量的解耦侦听器来处理这些事件,每个侦听器都专注于其自身的特定情况,并且朝满足整体HATEOAS约束的方向发展。

同样,侦听器应该是调用堆栈中的最后一个对象,不需要直接访问它们; 因此,它们不是公开的。

使新创建资源的URI可被发现

如前一篇文章所述,创建新资源的操作应在响应的Location HTTP标头中返回该资源的URI。 :

@Component
class ResourceCreatedDiscoverabilityListener implements ApplicationListener< ResourceCreated >{@Overridepublic void onApplicationEvent( ResourceCreated resourceCreatedEvent ){Preconditions.checkNotNull( resourceCreatedEvent );HttpServletRequest request = resourceCreatedEvent.getRequest();HttpServletResponse response = resourceCreatedEvent.getResponse();long idOfNewResource = resourceCreatedEvent.getIdOfNewResource();this.addLinkHeaderOnResourceCreation( request, response, idOfNewResource );}void addLinkHeaderOnResourceCreation( HttpServletRequest request, HttpServletResponse response, long idOfNewResource ){String requestUrl = request.getRequestURL().toString();URI uri = new UriTemplate( "{requestUrl}/{idOfNewResource}" ).expand( requestUrl, idOfNewResource );response.setHeader( HttpHeaders.LOCATION, uri.toASCIIString() );}
}

不幸的是,即使在Spring 3.1中,处理低级别的请求和响应对象也是不可避免的,因为仍在努力提供用于指定Location的一流支持。

获取单一资源

检索单个资源应允许客户端发现URI以获取该特定类型的所有资源:

@Component
class SingleResourceRetrievedDiscoverabilityListener implements ApplicationListener< SingleResourceRetrieved >{@Overridepublic void onApplicationEvent( SingleResourceRetrieved resourceRetrievedEvent ){Preconditions.checkNotNull( resourceRetrievedEvent );HttpServletRequest request = resourceRetrievedEvent.getRequest();HttpServletResponse response = resourceRetrievedEvent.getResponse();this.addLinkHeaderOnSingleResourceRetrieval( request, response );}void addLinkHeaderOnSingleResourceRetrieval( HttpServletRequest request, HttpServletResponse response ){StringBuffer requestURL = request.getRequestURL();int positionOfLastSlash = requestURL.lastIndexOf( "/" );String uriForResourceCreation = requestURL.substring( 0, positionOfLastSlash );String linkHeaderValue = RESTURLUtil.createLinkHeader( uriForResourceCreation, "collection" );response.addHeader( LINK_HEADER, linkHeaderValue );}
}

请注意,链接关系的语义使用了“ 集合 ”关系类型,该类型以多种微格式指定和使用,但尚未标准化。

出于可发现性的目的, Link头是最常用的HTTP头之一。 因此,需要一些简单的实用程序来简化在服务器上创建其值并避免引入第三方库的情况。

从根本上发现

根是RESTful Web服务中的入口点–它是客户端首次使用API​​时与之联系的对象。 如果要始终考虑并实施HATEOAS约束,那么这是一个起点。 到目前为止,必须从根目录中发现系统的大多数主要URI,这一事实不足为奇。

这是从根本上提供可发现性的示例控制器方法:

@RequestMapping( value = "admin",method = RequestMethod.GET )
@ResponseStatus( value = HttpStatus.NO_CONTENT )
public void adminRoot( HttpServletRequest request, final response ){String rootUri = request.getRequestURL().toString();URI fooUri = new UriTemplate( "{rootUri}/{resource}" ).expand( rootUri, "foo" );String linkToFoo = RESTURIUtil.createLinkHeader( fooUri.toASCIIString(), REL_COLLECTION );response.addHeader( HttpConstants.LINK_HEADER, linkToFoo );
}

当然,这是该概念的说明,可以在该系列的概念证明RESTful服务的上下文中阅读。 在更复杂的系统中,会有更多的链接,每个链接都有自己的语义,这些语义由链接关系的类型定义。

可发现性与更改URI无关

与可发现性相关的最常见陷阱之一是一种误解,即由于URI现在是可发现的,因此它们可能会发生变化 。 但是,事实并非如此,这是有充分理由的:首先,这不是Web的工作方式–客户将URI加为书签,并希望它们将来能够正常工作。 其次,客户端不必浏览API就可以直接到达某个状态。

取而代之的是,RESTful Web服务的所有URI都应被视为即兴URI ,而URI 不变 。 相反,可以使用API​​的版本控制来解决URI重组的问题。

可发现性警告

正如前几篇文章中的某些讨论所指出的那样,可发现性的首要目标是最大限度地减少文档使用或不使用文档,并让客户通过获得的响应来学习和理解如何使用API​​。 实际上,这不应该被视为遥不可及的理想-这是我们如何使用每个新网页的方式- 没有任何文档 。 因此,如果该概念在REST上下文中存在更多问题,那么它必须是技术实施问题,而不是是否可能的问题。

话虽这么说,从技术上讲,我们离一个完整的解决方案还差得很远–规范和框架支持仍在不断发展,因此,可能必须做出一些折衷。 但是,这些都是妥协,应视为妥协。

结论

本文介绍了在具有Spring MVC的RESTful服务的上下文中实现可发现性的某些特征,并从根本上涉及了可发现性的概念。 在接下来的文章中,我将重点介绍自定义链接关系和Atom发布协议。 同时,检查github项目 。

参考:我们的JCG合作伙伴 Eugen Paraschiv在baeldung博客上的第5部分 Spring的REST服务发现性 。

相关文章 :

  • 使用Spring 3.1和基于Java的配置引导Web应用程序,第1部分
  • 使用Spring 3.1和基于Java的配置构建RESTful Web服务,第2部分
  • 使用Spring Security 3.1保护RESTful Web服务,第3部分
  • RESTful Web服务可发现性,第4部分
  • 使用Spring Security 3.1的RESTful服务进行基本身份验证和摘要身份验证,第6部分
  • Spring&Quartz集成自定义注释
  • Spring MVC拦截器示例
  • 在运行时交换出Spring Bean配置

翻译自: https://www.javacodegeeks.com/2011/12/rest-service-discoverability-with.html

rest spring

rest spring_Spring的REST服务发现性,第5部分相关推荐

  1. Spring的REST服务发现性,第5部分

    这是有关使用Spring 3.1和Spring Security 3.1和基于Java的配置来建立安全的RESTful Web Service的系列文章的第五篇. 上一篇文章介绍了RESTful服务H ...

  2. restful web_RESTful Web服务可发现性,第4部分

    restful web 这是关于使用Spring 3.1和Spring Security 3.1和基于Java的配置来建立安全的RESTful Web Service的系列文章的第四篇 . 本文将重点 ...

  3. RESTful Web服务可发现性,第4部分

    这是有关使用Spring 3.1和Spring Security 3.1和基于Java的配置来建立安全的RESTful Web Service的系列文章的第四篇 . 本文将重点介绍REST API,H ...

  4. 服务发现存储仓库 etcd 使用简介

    目录 经典应用场景 场景一:服务发现(Service Discovery) 场景二:消息发布与订阅 场景三:负载均衡 场景四:分布式通知与协调 场景五:分布式锁 场景六:分布式队列 场景七:集群监控与 ...

  5. 服务发现 注册中心 consul 的介绍、部署和使用

    什么是服务发现 微服务的框架体系中,服务发现是不能不提的一个模块.我相信了解或者熟悉微服务的童鞋应该都知道它的重要性.这里我只是简单的提一下,毕竟这不是我们的重点.我们看下面的一幅图片: 图中,客户端 ...

  6. dubbo k8s 服务发现_服务化改造实践(二)| Dubbo + Kubernetes-阿里云开发者社区

    "没有最好的技术,只有最合适的技术."我想这句话也同样适用于微服务领域,没有最好的服务框架,只有最适合自己的服务改造.在Dubbo的未来规划中,除了保持自身技术上的领先性,关注性能 ...

  7. 谈服务发现的背景、架构以及落地方案

    http://www.infoq.com/cn/articles/background-architecture-and-solutions-of-service-discovery 在开始之前,我们 ...

  8. 微服务实践分享(3)服务发现

    1.为什么要服务发现[https://www.nginx.com/blog/service-discovery-in-a-microservices-architecture/] 2.选型 3.业界使 ...

  9. 服务发现框架选型,Consul还是Zookeeper还是etcd

    https://www.servercoder.com/2018/03/30/consul-vs-zookeeper-etcd/ 背景 本文并不介绍服务发现的基本原理.除了一致性算法之外,其他并没有太 ...

最新文章

  1. SAP SD基础知识之装运的组织单元(Organizational Units in Shipping)
  2. ROS学习(五):package.xml 文件
  3. LeetCode 1031. 两个非重叠子数组的最大和(一次遍历,要复习)*
  4. c语言中字符怎么表示6,6、C语言中的字符串
  5. CentOS Linux 系统镜像文件(M1 Mac虚拟机专用)
  6. NCBI数据上传(二):转录组测序(RNA-Seq)数据
  7. fileutils java_FileUtils类的应用实例教程
  8. 芝诺数解|「十一」千里姻缘一“线”牵—重庆网络婚恋分析报告
  9. opencv如何隐藏窗口-cvNameWindow创建窗口的时候会创建两个窗口,一个主窗口,一个子窗口。
  10. 【爬虫1】爬虫和反爬虫介绍
  11. yate工具的使用求教
  12. 公众号快速注册并认证小程序
  13. K线形态识别—三K线之买入型三日K线组合
  14. 行为识别:行人跌倒检测(含源码)
  15. 18. --plic--=--ply--=--pli--=--ple--=--plex--=--plo-- to fold 倍,重,折叠 (词19、20)
  16. DirectX 开启硬件加速
  17. 跨境电商平台有哪些?各国电商平台及品类概览
  18. js取小数点后两位 方法总结
  19. #2021暑假杭电多校8_1003.Ink on paper
  20. 大学计算机基础 教学要求,《大学计算机基础》课程教学大纲

热门文章

  1. 阅读器关闭时尝试调用Read无效时的解决方法
  2. Servlet使用适配器模式进行增删改查案例(BaseDaoUtilImpl.java)
  3. html5动画是什么,10个HTML5动画 让你忘掉Flash是啥(组图)
  4. 互换性与技术测量教材pdf_【检验】临床生物化学检验技术(第6版)人民卫生出版社【电子教材PDF】【人卫教材电子版】...
  5. nginx的日志文件配置
  6. 使用junit进行单元测试_使用JUnit对ADF应用程序进行单元测试
  7. spring 计划任务_与Spring的计划任务一起按时运行
  8. drools dmn_DMN 1.1 XML:从建模到使用Drools 7.0的自动化
  9. apache spark_如何将自定义数据源集成到Apache Spark中
  10. java关闭窗口函数_2016年将是Java终于拥有窗口函数的那一年!