虽然REST架构是Roy Fielding(他也是HTTP和URI规范的主要作者之一)在一篇论文中描述的,没有被官方指定相关的标准,但在REST服务大行其道的今天,其实已经成为事实的开发选型过程中的首选。
REST服务能够大行其道,有一定原因在里头。对系统层级关系的减负之类我们本次不表,单说对团队角色职责清晰化带来的影响,比如,交互采用JSON串,这样就可以很方便的通过js技术以最少的编码量来使用,这样一来,使原来前后端界限不明的前端页面从后端开发同学这里完全释放出来。UI端与API端已经从职业的角度划分开来。因此,REST服务的到来使前端开发同学与后端开发同学的精力能够更加聚焦,更加专注于处理自己擅长的工作。
为确保服务通信安全,通常会使用https服务。但问题也跟随来了,对于https方式的rest服务,如何集成到我们系统服务中来。如果直接还是使用默认的http方式集成进来,那https提供的证书怎么支持,下面我们将说明如何在访问https方式的rest服务时,将相关的证书信息一并处理,确保对接业务的正常执行。
spring提供了一个模板 org.springframework.web.client.RestTemplate 用来在服务端进行REST服务的对接工作。RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。
调用RestTemplate的默认构造函数,RestTemplate对象在底层通过使用java.net包下的实现创建HTTP 请求,可以通过使用ClientHttpRequestFactory指定不同的HTTP请求方式。
ClientHttpRequestFactory接口主要提供了两种实现方式
- 一种是SimpleClientHttpRequestFactory,使用J2SE提供的方式(既java.net包提供的方式)创建底层的Http请求连接。
- 一种方式是使用HttpComponentsClientHttpRequestFactory方式,底层使用HttpClient访问远程的Http服务,使用HttpClient可以配置连接池和证书等信息。
有了这些常识的预热,接下来的做法就很好办了,为方便集成过程中的使用,我们把通过HttpComponentsClientHttpRequestFactory类构建RestTemplate过程整理为一个工具类:
/** * Danlley Wei (mailto://danlley@126.com) * Copyright (c) 2005-2017 All Rights Reserved. */ package com.myteay.restful.mapper; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.ssl.SSLContextBuilder; import org.apache.log4j.Logger; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; /** * HttpClient证书处理工具类 * * @author danlley(danlley@126.com) * @version $Id: HttpClientUtils.java, v 0.1 2017年4月22日 下午8:40:55 danlley(danlley@126.com) Exp $ */ public class HttpClientUtils { /** 日志 */ private static final Logger logger = Logger.getLogger(HttpClientUtils.class); private static final HttpClientUtils _instance = new HttpClientUtils(); public static HttpClientUtils getInstance() { return _instance; } /** * 初始化证书支持的CloseableHttpClient * * @return CloseableHttpClient * @throws KeyStoreException 证书存储异常 * @throws NoSuchAlgorithmException 算法异常 * @throws KeyManagementException 证书管理异常 */ public static CloseableHttpClient acceptsUntrustedCertsHttpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException { //不做任何处理,默认相信所有证书 SSLContext sslContext = new SSLContextBuilder() .loadTrustMaterial(null, new TrustStrategy() { public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { return true; } }).build(); //将对证书的认可配置加入上下文 HttpClientBuilder b = HttpClientBuilder.create(); b.setSSLContext(sslContext); //对HostName不做校验 HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE; //注册请求方式 SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier); Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder .<ConnectionSocketFactory> create() .register("http", PlainConnectionSocketFactory.getSocketFactory()) .register("https", sslSocketFactory).build(); //将请求方式加入连接管理器(支持多线程) PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager( socketFactoryRegistry); connMgr.setMaxTotal(200); connMgr.setDefaultMaxPerRoute(100); b.setConnectionManager(connMgr); return b.build(); } /** * 构建RestTemplate实例 * * @return RestTemplate */ public static RestTemplate buildRestTemplate() { CloseableHttpClient httpClient = null; try { httpClient = acceptsUntrustedCertsHttpClient(); } catch (KeyManagementException e) { logger.error("证书关键字异常:" + e.getMessage(), e); } catch (KeyStoreException e) { logger.error("证书存储异常:" + e.getMessage(), e); } catch (NoSuchAlgorithmException e) { logger.error("算法执行异常:" + e.getMessage(), e); } return new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpClient)); } /** * 请求指定地址的restful服务 * * @param url * @param obj * @return */ public Object postRestfulService(String url, Object obj) { if (obj == null) { logger.warn("入参对象不可用,不做请求。 obj is null!"); return null; } RestTemplate template = buildRestTemplate(); return template.postForObject(url, obj, obj.getClass()); } }
接下来编写使用代码:
@RequestMapping(value = "/greet", method = { RequestMethod.POST }) public ApplicationModel greeting(@RequestBody ApplicationModel model, HttpServletRequest request, HttpServletResponse response) { logger.warn("------------------->model=" + model); Object quote = HttpClientUtils.getInstance() .postRestfulService("https://192.168.56.102:8080/greet", model); logger.warn("++++++++++++++++ read from server quote: " + quote); return (ApplicationModel) quote; }
执行结果如下:
2017-04-22 21:59:56.195 WARN 27752 --- [nio-8080-exec-4] c.m.r.service.impl.RestfulController : ------------------->model=ApplicationModel[keyModel=ObjectModel[id=test,content=danlley-55---],key=my,value=alipay] 2017-04-22 21:59:56.592 WARN 27752 --- [nio-8080-exec-4] c.m.r.service.impl.RestfulController : ++++++++++++++++ read from server quote: ApplicationModel[keyModel=ObjectModel[id=test,content=danlley-55---],key=my,value=alipay]
相关推荐
spring与wink集成开发rest服务,包括说明文档、源码、可执行文件
它可用于实现任何种类的REST式系统,而不仅仅是REST式Web服务。 Restlet项目受到Servlet API、JSP(Java Server Pages)、HttpURLConnection及Struts等Web开发技术的影响。该项目的主要目标是:在提供同等功能的同时...
activiti入门六(集成新版activitimodeler与rest服务).pdf
具有Spring集成的简单REST服务器 以下是创建不同类型的Jersey项目的方法: 创建一个示例Jersey 2.3.1项目,该项目生成一个可以在Web容器(Tomcat / Jetty)中运行的.war: mvn archetype:generate -...
springboot集成mybatis源码,包含自定义端口,自定义属性获取,访问文件,提供rest接口等内容。适合初学者学习参考。
您想通过一个新的、有用的SOAP客户端将您的体验提升到一个新的水平,并以前所未有的方式改进您的REST服务吗? Boomerang在这里为您提供。 Boomerang比其他SOAP客户端快很多,生成具有默认值的SOAP请求,并与REST...
本人在前辈《从MVC到前后端分离(REST-个人也认为是目前比较流行和比较好的方式)》一文的基础上,实现了一个基于Spring的符合REST风格的完整Demo,具有MVC分层结构并实现前后端分离,该项目体现了一个具有REST风格...
蓝凌标准产品V15.0管理员手册-RestService服务管理
GraphQL通常用于将应用程序与REST API集成。 使用此指令可以让您创建REST集成,而无需创建任何解析器
基于 REST 的Web 服务日益成为后端企业服务集成的首选,因为它比SOAP 更加简单。这篇文章介绍了一 个简单的可扩展框架,将Java 业务服务作为类REST 服务。它详细描述了设计细节,并探讨了各种可扩展性方法。
perso, 个人邮件服务器到REST服务器 个人邮件个人邮件服务器是邮件邮件邮箱的一个小的自包含的REST服务器。它包括可以配置的header 索引和爬网。个人在测试或者临时站点上使用以快速访问邮箱( 例如通过集成测试框架...
本文档用于描Spring+Jersey框架的搭建Rest服务的过程及其注意事项。主要介绍环境配置、Spring框架配置、Jersey与Spring的集成配置,以及前端Ajax的调用Demo。
基于REST风格的RBAC模型研究,主要就是针对REST集合的权限管理的开发.
而对于前端提供服务则使用rest协议。前端应用面临许多rest服务,为了解决调用的统一,所以需要一个网关系统。为什么自己写对于api网关,现在已有框架可以解决该类问题,但是基于java语言开源的没有(除了zuul,也有...
参考《Visual C# 2010从入门到精通》((英)夏普著,周靖译)一书第29章,将SOAP和REST服务集成到一个解决方案中。代码比较简单,适合入门的人参考。
rest-java, 在Java和 spring 和 Jersey 中构建rest服务 JAVA REST应用程序示例网页项目演示如何使用:Jersey jax rsSpring IntegrationSpring Data HibernateGroovy集成测试OAuth速度 Java邮件Fac
Apache CXF配置REST服务,集成到Spring当中。
angular-dashboard-seed, 带有 nodejs REST后端集成的Angular 仪表板样例应用程序 angular-dashboard-seed使用最新的Angular 最佳实践构建 nodejs REST集成的Angular 仪表板样例应用程序。这个种子是一个模板的免费...
一体化骆驼座如何通过HTTP与两个服务进行互通的示例: 其中之一是集成服务,该服务使用Camel和... 第二个是外部独立的Rest服务,该服务基于CXF JAX-RS,打包为WAR存档+交付以在带有端口9094的Jetty服务器上启动。
整合服务测试方案:检查流行和开放式REST API服务要求: 使用任何面向对象的语言使用REST Assured进行API交互使用自动化模式,例如PageObject ,数据驱动的测试等。 提供代码并明确说明如何运行说明如何运行: 执行...