IBM®Rational Team Concert™版本2.0提供了与工作项和服务器上存储的其他资源进行交互的API。 通过使用Java™客户端,可以轻松利用此API。 本文介绍了如何使用Apache HTTP客户端作为代码基础来使用面向资源的工作项API。 它涵盖了如何克服常见问题,例如证书处理和身份验证。 最后,本文解释了如何利用API进行多种操作,例如对Rational Team Concert运行查询并返回一组工作项。
图1中的图说明了该体系结构。
图1.体系结构

面向资源的工作项API
Rational Team Concert 2.0工作项和其他相关资源通过面向资源的工作项API公开。 该API遵守开放服务生命周期协作组织的变更管理规范(OSLC CM),其目的是根据HTTP方法,HTTP响应代码,MIME类型处理和资源格式定义一组基于HTTP的RESTful接口。
通过使用面向资源的工作项API,您可以使用标准的HTTP方法来获取,创建,修改,删除和查询工作项以及Rational Team Concert服务器上存储的其他资源。 这些是可以通过API执行的一些操作:
- 检索不同粒度级别的工作项(支持的格式为JavaScript Object Notation或JSON,XML,Atom和HTML)
- 更新工作项(通过修改JSON或XML表示形式并将其发布回服务器)
- 创建工作项(通过获取HTML创建对话框模块或通过将JSON或XML表示形式发布到工厂URL)
- 添加或删除链接
- 查询工作项(通过获取HTML选择器模块或通过创建全文查询和结构化查询)
可以通过多种方式和多种语言来利用该API。 本文重点介绍如何使用Apache HTTP Java客户端与API进行交互。
Apache HTTP客户端
核心Java包提供了使用HTTP的基本方法,但没有提供许多应用程序所需的灵活性和功能。 Apache HTTP客户端(HttpClient)通过提供功能丰富且功能齐全的Java包来添加额外的功能,以通过HTTP访问资源。
Apache HTTP客户端软件包旨在进行扩展,同时还支持基本HTTP协议。 HttpClient组件对于构建客户端应用程序(例如Web浏览器或REST客户端)的任何人都非常有用。
该软件包是用作构建Java客户端以与Rational Team Concert服务器进行交互的基础的明显选择。 客户端的Get和Post方法可用于轻松地将请求发送到Rational Team Concert Server REST API。 HttpClient还具有内置功能来存储cookie和处理证书,您将在以下各节的示例中使用这些功能。
证书处理
Rational Team Concert包含一个自签名证书,当服务器配置为使用安全套接字层(SSL)时,默认使用该证书。 这可能会导致Java客户端引发SSLPeerUnverifiedException。 如果您使用浏览器访问该网站,则将得到相同的警告。
如何以编程方式接受自签名证书
TrustManager接口的作用是验证对等方发送的SSL证书。 这包括检查证书的到期日期,验证签名以及确定是否应接受对等方提供的凭据。
- 要接受自签名证书,请创建一个新的TrustManager数组,其中包含一个实现X509信任管理器接口的TrustManager实例。
- 实现接口时,您的方法必须覆盖该接口的所有方法。 对于X509TrustManager接口,请重写代码清单1所示的三个方法。
清单1. TrustManager方法重写
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkclientTrusted(X509Certificate[] certs, String authType) {
// Leave blank to trust every client
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
// Leave blank to trust every server
}
}
};
- 为了确保Java客户端使用新的TrustManager,请创建一个新的SSLContext实例:
mySSLContext = SSLContext.getInstance("SSL");
- 接下来,使用新的TrustManager初始化SSLContext实例:
mySSLContext.init(null, trustAllCerts, new java.security.SecureRandom());
- 最后,您必须覆盖HttpsURLConnection的默认SSLSocketFactory,Apache HTTP客户端在发出请求时会使用该默认SSLSocketFactory:
HttpsURLConnection.setDefaultSSLSocketFactory(mySSLContext.getSocketFactory());
如果在发送第一个请求之前执行了此操作,则该会话的其余部分将接受所有证书。
重要:
此实现将自动接受它遇到的任何证书。 在某些情况下,这可能会引起一些安全问题,因此请谨慎使用。
认证方式
缺省情况下,Rational Team Concert安装在Apache Tomcat服务器上,但是也可以安装在IBM®WebSphere®Application Server上。 支持的认证机制将取决于使用哪个Web服务器来托管Rational Team Concert。 Apache Tomcat服务器使用基本身份验证; 而WebSphere Application Server支持基本认证和基于表单的认证。
HTTP客户端
- 首先,使用Apache HttpClient(4.0.1)库设置HTTP客户端。
- 创建DefaultHttpclient类的实例:
DefaultHttpclient httpclient = new DefaultHttpclient();
您将使用此客户机与Rational Team Concert服务器进行交互。
基本认证
创建HttpClient实例之后,下一步就是提供使用Rational Team Concert服务器进行身份验证所需的凭证。
- 通过创建CredentialsProvider实例来指定凭据:
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(
"host", AuthScope.ANY_PORT), new UsernamePasswordCredentials("username", "password"));
setCredentials方法将AuthScope类的实例作为其第一个参数,将UsernamePasswordCredentials类的实例作为其第二个参数。 您要连接的Rational Team Concert服务器的主机名和端口必须在AuthScope实例中定义。 UsernamePasswordCredentials实例将封装通过Rational Team Concert服务器进行认证所需的用户名和密码。
- 最后,将CredentialProvider绑定到客户端:
httpclient.setCredentialsProvider(credsProvider);
基于表单的身份验证
- 使用先前初始化的DefaultHttpClient,创建到服务器的连接以检索WebSphere Application Server请求URL。
- 要存储WebSphere Application Server请求URL,请设置cookie存储和本地HttpContext实例:
Httpclient httpclient = new DefaultHttpclient();
CookieStore cookieStore = new BasicCookieStore();
HttpContext localContext = new BasicHttpContext();
- 接下来,将cookie存储区绑定到HttpContext:
localContext.setAttribute(clientContext.COOKIE_STORE,cookieStore);
- 现在,构造一个HttpGet方法,并将URL传递给构造函数。 该URL包括您要连接的Rational Team Concert服务器的主机名和端口号,后跟路径/ jazz / authenticated / identity:
HttpGet httpGetID = new HttpGet("https://myRtcServer:9443/jazz/authenticated/identity");
- 要将WebSphere Application Server请求URL检索为cookie,请执行Get方法。 为此,请调用Http客户端的execute方法,并将Get方法和本地HttpContext实例作为参数传递。
- 由于此时未使用响应,因此必须关闭连接:
httpclient.execute(httpGetID, localContext);
httpGetID.abort();
- 要检查URL是否已存储在cookie存储中,请使用以下代码打印出存储中的每个cookie:
List<Cookie> cookies1 = cookieStore.getCookies();
for (Cookie cookie : cookies1) {
logger.info("\t"+cookie.getName()+" : "+cookie.getValue());
}
- 下一步是构造一个表单以传递给WebSphere Application Server j_security_check。 为此,请使用Apache HttpClient的“名称/值对”类:
List<NameValuePair> authFormParams = new ArrayList<NameValuePair>();
authFormParams.add(new BasicNameValuePair("j_username", "myUsername"));
authFormParams.add(new BasicNameValuePair("j_password", "myPassword"));
- 现在,构造一个URLEncodedFormEntity。 该实体由URL编码对的列表组成。 在这里,您可以使用它在HTTP Post请求中将用户名和密码传递给Rational Team Concert服务器:
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(authFormParams, "UTF-8");
HttpPost httpPostAuth = new HttpPost(
"https://myRtcServer:9443/jazz/authenticated/j_security_check");
httpPostAuth.setEntity(entity);
- 最后,执行Post方法以从WebSphere Application Server检索轻量级第三方认证(LTPA)令牌。 将本地上下文传递给execute方法,以便将LTPA令牌存储在定制cookie存储中。
httpclient.execute(httpPostAuth, localContext);
- 要检查LTPA令牌是否正确存储,请使用以下代码:
List<Cookie> cookies2 = cookieStore.getCookies();
for (Cookie cookie : cookies2) {
logger.info("\t"+cookie.getName()+" : "+cookie.getValue());
}
- 要维护经过身份验证的会话,请将本地HttpContext实例传递给您在代码中调用的每个httpclient.execute方法。
与工作项API交互
在将HttpClient配置为对Rational Team Concert服务器实例使用适当的认证协议之后,您可以利用工作项API。
- 如有必要,更改HttpContext实例:
- 如果使用基本身份验证,则必须创建一个HttpContext实例:
HttpContext localContext = new BasicHttpContext();
- 如果您使用的是基于表单的身份验证,请使用先前创建的本地HttpContext实例。
- 现在,设置对Rational Team Concert服务器的Get请求,并指定Accept标头。 在此示例中,我们正在访问根服务文档 :
HttpGet httpget = new HttpGet("https://myRtcServer:9443/jazz/rootservices");
httpget.setHeader("Accept", "text/xml");
接受请求标头用于指定哪些媒体类型适合于响应。
然后由客户端执行Get请求:
HttpResponse response = httpclient.execute(httpget, localContext);
响应被读入HttpEntity实例,其内容被读入IO流:
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
在读取流时,需要解析XML以识别和提取相关的资源URI。 URI引用由合格名称或QNames表示 。
对于每个要提取的资源,您必须知道元素和属性的名称空间URI和本地名称。
考虑例如:
<oslc_cm:cmServiceProviders
rdf:resource="https://myRtcServer:9443/jazz/oslc/workitems/catalog"/>
在该示例中:
-
QName
oslc_cm:cmServiceProviders
是元素。 -
QName
rdf:resource
是一个属性。 -
oslc_cm
和rdf
是前缀。 -
cmServiceProviders
和resource
是本地名称。
前缀用作速记符号。
QNames将命名空间URI映射到前缀,从而启用URI的缩写。 它们提供了一种更方便的方式来编写XML文档,因为URI引用可能很长,并且可能包含用于元素或属性命名的禁止字符。
前缀在XML文档的开头定义。 例如, oslc_cm
前缀定义为:
xmlns:oslc_cm="http://open-services.net/xmlns/cm/1.0/"
这意味着oslc_cm:cmServiceProviders
只是以下各项的简写形式:
http://open-services.net/xmlns/cm/1.0/cmServiceProviders
清单2将InputStream读入XMLInputStreamReader。 它查找开始元素,如果它与元素名称空间URI和本地名称匹配,则它将读取属性,以查找匹配项。 找到属性(在本例中为资源URI)后,将返回该属性。 然后可以将URI作为下一个Get请求输入到HttpClient中。
清单2.解析响应的示例代码
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
XMLStreamReader reader = inputFactory.createXMLStreamReader(stream);
Integer eventType;
String resource = null;
while(reader.hasNext()){
eventType = reader.next();
if(eventType.equals(XMLEvent.START_ELEMENT)) {
if(reader.getNamespaceURI().equals(element_namespaceUri)
&& reader.getLocalName().equals(element_localname)) {
for(int i = 0; i < reader.getAttributeCount(); i++){
if(reader.getAttributeNamespace(i).equals(attribute_namespaceUri)
&& reader.getAttributeLocalName(i).equals(attribute_localname))
{
resource = reader.getAttributeValue(i);
return resource;
}
}
}
}
}
stream.close();
reader.close();
return resource;
小费:
请注意, element_namespaceUri
, element_localname
, attribute_namespaceUri
和attribute_localname
是先前在属性文件中定义的字符串对象。
使用发现链方法
Rational Team Concert提供了一种无需依赖特定URL即可公开其资源和功能的机制。 这种机制称为发现链 。 它是访问Rational Team Concert服务的首选方法。
在Rational Team Concert中,根文档位于https:// <服务器>:<端口> / <app> / rootservices 并且不需要身份验证即可检索其中包含的ServiceProvider元素。
将请求发送到根服务URL时,返回的响应是资源描述框架(RDF)文档。
- 从根服务文档中,您可以检索变更管理目录URI。
- 该URI后面的文档包含ServiceProvider元素的列表,这些元素指向包含实际服务描述的文档。 您可以解析根服务文档,标识
oslc_cm:cmServiceProviders
元素,并提取rdf:resource
属性的值:
<oslc_cm:cmServiceProviders
rdf:resource="https://myRtcServer:9443/jazz/oslc/workitems/catalog"/>
- 可以将请求发送到此URI,以获取其后面的文档。
访问XML格式的目录文档需要进行身份验证 。 - 要提取服务URL,可以解析返回的文档以找到
oslc_disc:services
元素的rdf:resource
属性的值:
<oslc_disc:services rdf:resource=
"https://myRtcServer:9443/jazz/oslc/contexts/<genId>/workitems/services.xml"/>
- 最后,可以向此URI发出第三个请求以获取服务文档。 本文档包含以下对话框的链接:对话框模块,创建新工作项的工厂URL以及使您可以查询工作项的工作项集合URL。
图2显示了通过服务提供商目录从根服务文档到服务描述符的发现链。
图2.发现链流程

创建自定义查询
Rational Team Concert服务器中的每个工作空间都有一个简单查询URL,可用于创建定制查询。 可以使用发现链方法从服务发现文档中检索此URL。
- 要创建自定义查询,请将参数
?oslc_cm.query=[query]
附加到简单查询URL。 Jazz.net论坛中提供了可以查询的属性列表。 - 要在Java客户端中创建自定义查询,请以简单查询URL为基础构造一个新的URI。 然后使用一个名称值对列表来构造查询字符串:
URI baseURI = new URI("https://myRtcServer:9443/jazz/oslc/contexts/<genID>/workitems);
List<BasicNameValuePair> qparams = new ArrayList<BasicNameValuePair>();
- 接下来,将搜索参数添加到查询参数列表中。 在此示例中,查询将返回所有包含缩写“ RTC”的工作项。
qparams.add(new BasicNameValuePair("oslc_cm.query", "oslc_cm:searchTerms=\"RTC\""));
- 接下来,使用新的查询字符串重建URI:
queryURI = URIUtils.createURI(
baseURI.getScheme(), baseURI.getHost(), baseURI.getPort(), baseURI.getPath(),
URLEncodedUtils.format(qparams, "UTF-8"), null);
- 现在,使用查询URI构造HttpGet方法:
HttpGet httpGetMethod = new HttpGet(queryURI);
- 可以使用面向资源的工作项API支持的不同格式来检索内容。 在此示例中,我们通过设置Accept标头来检索OSLC更改请求XML格式的数据:
httpGetMethod.addHeader("Accept", "application/x-oslc-cm-change-request+xml");
- 记住要传入本地HttpContext实例以通过服务器进行身份验证 :
HttpResponse response = null;
// Pass local context as a parameter
try {
response = httpclient.execute(httpGetMethod, httpContext);
} catch (clientProtocolException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
由于响应是XML格式的,因此现在可以按照您想要的任何方式对其进行解析或处理。
检索存储的查询结果
在Rational Team Concert中,尚未通过发现链公开在查询编辑器中创建的查询。 但是,该功能超出了OSLC CM规范的范围。
HTTP客户端可以使用GET请求访问存储的查询结果。 存储的查询集合位于以下地址:
https://myRtcServer:9443/jazz/oslc/queries.xml
查询结果可以JSON,ATOM,XML和XHTML返回。 您可以通过将扩展名附加到请求URI来指定格式。
如果您知道商品ID,则可以使用以下URI直接访问查询:
https://myRtcServer:9443/jazz/oslc/queries/<itemId>
和以前一样,您可以通过添加扩展名在URI中指定格式。 例如,如果要指定XML,请使用以下请求:
https://myRtcServer:9443/jazz/oslc/queries/<itemId>.xml
要查看查询的结果集,请使用以下请求URL:
https://myRtcServer:9443/jazz/oslc/queries/<itemId>/rtc_cm:results
同样,您可以通过将扩展名附加到URI来指定要以XML格式查看结果:
https://myRtcServer:9443/jazz/oslc/queries/<itemId>/rtc_cm:results.xml
也可以指定在结果集中显示哪些属性。
例如,要仅显示查询返回的工作项的“创建日期”和“类型”属性,这将是URI:
https://myRtcServer:9443/jazz/oslc/queries
/<itemId>/rtc_cm:results.xml?oslc_cm.properties=dc:created,dc:type
该响应将返回工作项的集合,并且仅显示您指定的属性。
有关可以在请求中为其指定属性的所有可用工作项属性的列表,请参阅面向资源的工作项API文档的附录B。 (要查看附录B,需要Jazz.net用户ID和密码。免费注册。)
对于某些属性,该值将是URL。 在此示例中,您可以看到资源类型属性是URL:
<oslc_cm:ChangeRequest
rdf:resource="https://myRtcServer:9443/jazz/resource/itemOid/WorkItem/<genID>">
<dc:type rdf:resource="https://myRtcServer:9443 /jazz/oslc/types/<genID>/defect"/>
</oslc_cm:ChangeRequest>
要解析位置URL,可以将媒体类型指定为文本或XML。 例如:
https://myRtcServer:9443/jazz/resource/itemOid/Category/<genID>?_mediaType=text/xml
连接故障排除技巧
在对Rational Team Concert服务器的连接性问题进行故障排除时,线路日志记录可能非常有用。 您可以通过在集成开发环境(IDE)中指定以下虚拟机参数来启用线路日志记录:
-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog
-Dorg.apache.commons.logging.simplelog.showdatetime=true
-Dorg.apache.commons.logging.simplelog.log.org.apache.http=DEBUG
-Dorg.apache.commons.logging.simplelog.log.org.apache.http.wire=ERROR
-Dorg.apache.commons.logging.simplelog.log.org.apache.http.impl.conn=DEBUG
-Dorg.apache.commons.logging.simplelog.log.org.apache.http.impl.client=DEBUG
-Dorg.apache.commons.logging.simplelog.log.org.apache.http.client=DEBUG
摘要
本文介绍了如何处理来自Rational Team Concert 2.0服务器的自签名证书,概述了如何使用基本协议和基于表单的协议进行认证,并概述了如何开始与面向资源的工作项API进行交互。 。 我们希望这可以帮助您克服身份验证和连接到Rational Team Concert的最初障碍,以便您可以与Rational Team Concert资源高效地进行交互。
致谢
作者感谢Brian Parle向他们介绍了该主题,感谢Ronan Dalton鼓励和激励他们撰写本文,并感谢Patrick Streule和Jerh O'Connor的时间和对本文的回顾和帮助。