BlackBerry 应用程序开发者指南 第一卷:基础--附录:MDS服务参考
作者:Confach 发表于2006-04-28 21:53
版权信息:可以任意转载, 转载时请务必以超链接形式标明文章原始出处 和作者信息.
http://www.cnblogs.com/confach/articles/387923.html
B
附录:MDS服务参考
HTTP请求 HTTP响应 HTTPS支持 编码转化器 创建编码转化器 编译和安装编码转化器 |
HTTP请求[1]
一个客户端建立一个连接,并且发送一个HTTP请求消息到服务器.服务器然后发送一个响应消息,这个消息通常包含了请求的资源.
<method> <resource_path><version> Header1: value1 Header2: value2 Header3: value3 <optional message> |
HTTP请求变量 |
描述 |
method |
方法名,指定了一个动作,例如GET,HEAD或POST.常用的方法是GET,它从服务器请求一个资源. |
resource_path |
指向请求资源的路径,它是URL中的一部分,在主机名后面出现.它也称为请求URL(Request URL). |
version |
你正在运行的HTTP版本,标记为”HTTP /x.x”.BES支持1.0和1.1版本. |
Header |
提供了关于请求的或在消息体里发送的对象的信息. |
optional message |
HTTP消息可以包含数据.在一个请求里,它是发送到服务器的用户类型的数据,或上传的文件.当一个对象伴随着此消息时,请求通常也包含定义它属性的消息头. |
HTTP响应
在HTTP请求消息的接收之上,服务器发送一个响应消息,它通常包含了请求的资源.
<HTTP version><status_code><reason> Header1: value1 Header2: value2 Header3: value3 <message> |
HTTP响应变量 |
描述 |
HTTP_version |
正在运行的HTTP版本,标记为”HTTP /x.x”.BES支持1.0和1.1版本. |
status_code |
状态码的数值,它反映了客户端提出的请求的结果。例如,200(OK)说明了传输成功,404(Not Found)说明了请求的URL没有找到。 |
reason |
reason是和状态码相关的文本消息。 |
Header |
消息头提供了响应的信息,也提供了消息体中正在发送的对象的信息。 |
message |
HTTP消息必须包含数据。在一个响应消息里,它提供了客户端请求的的内容。此响应也包含了定义它的属性的消息头。 |
Push请求响应状态码
为push请求连接服务,BlackBerry MDS返回2种响应码:
l PAP(Push Access Protocal)响应码。
l RIM Push响应码。
注:访问www.wapforum.org获得更多关于PAP响应码的信息。
RIM Push请求响应码
RIM Push请求响应码 |
描述 |
解释 |
200 |
OK |
请求成功完成。 |
400 |
任何其他的错误。 |
|
403 |
访问控制错误,或者未知的邮件地址或特定的BlackBerry PIN。 |
服务器接收了请求,但是不能响应。 |
503 |
服务器忙,服务不可用。 |
当前,服务器不能管理请求,因为暂时的负载或服务器正在维护。 |
HTTPS支持
如果你的应用程序通过Internet访问服务器,为了提过其他的验证和安全,在TLS上建立一个安全的HTTP(HTTPS)连接。
HTTPS认证(Certificate)管理
当BlackBerry设备以代理模式请求一个HTTPS连接时,BlackBerry MDS服务为BlackBerry设备建立一个SSL连接。系统管理员配置MDS服务,要么允许连接到未信任的服务器,要么是限制访问信任的服务器,这个配置仅适用代理模式下的连接。在end-to-end模式里,BlackBerry设备建立一个SSL连接。
在BlackBerry管理器里,系统管理员编辑MDS服务属性,并且设置TLS和HTTP选项,为获得更多信息,参看BES管理指南。
注:在MDS服务模拟器里,通过设置rimpublic.property文件来允许或拒绝访问未信任的服务器。设置application.handler.https.allowUntrustedServer参数为true或false。参看177页的“配置BlackBerry MDS模拟器”获得更多信息。
如果MDS服务包含认证,MDS服务将信任一个服务器。
使用keytool安装一个认证
1. 保存认证。
2.将认证文件拷贝到MDS服务所在计算机上的C:\Java\j2re1.4.2\lib\security文件夹。
3. 为了将认证导入到键存储里,请使用keytool,它可以在JRE bin文件夹下找到,例如C:\Java\j2re1.4.2\bin.例如,输入:
keytool -import -file <cert_filename> -keystore cacerts
访问http://java.sun.com/j2se/1.3/docs/tooldocs/win32/keytool.html 获得更多关于keytool的信息。
编码转化器
BlackBerry MDS支持插件的Java应用程序,称为编码转化器,它处理BlackBerry设备发送和接收的数据。
MDS服务提供下列缺省的编码转化:
编码转化名 |
描述 |
WML>WMLC |
将.wml(Wireless Markup Lanuage)转化为一个压缩的格式。 |
WMLScript>WMLScriptC |
将MIDlet应用程序为BlackBerry格式。 |
JAD>COD :XML>WBXML |
将xml文件转化为下面的WAP二进制XML(.wbxml) MIME类型:application/vnd.wap.wbxml.. |
SVG >PME |
将可svg(Scalable Vector Graphics)转化为BlackBerry设备支持的pme(Plazmic Media Engine)二进制格式. |
图像编码转化 |
将下列图像的文件类型转化为png文件:
|
注:图像编码转化器将先前的图像格式转化为下面的.PNG MIME类型:image/vnd.rim.png.
你也可以编写自己的编码转化器完成客户化数据的处理.例如,如果你的应用程序正在和服务器交换数据,而服务器不是为BlackBerry设备设计的,并且发送到服务器端的数据对BlackBerry设备来说没有合适的格式.那么你可能编写一个编码转化器.
一个编码器可能改变数据格式或删除冗余信息来降低网络流量,并且支持BlackBerry设备上的简单应用程序.例如,你可以编写一个编码转化器将HTML内容转化为WML.
数据转化处理
如果你专门编写一个服务器端的应用程序支持一个BlackBerry设备上客户应用程序,编码转化器就不需要了.你可以设计一个服务器应用程序一合适的格式输出数据.
在发送数据到BES之前,你也可以将数据处理作为一单独的服务器端进程的一部分.
编码转化器API
主要的编码转化器类 |
描述 |
HttpContentTranscoder |
此类提供方法来控制HTTP请求和响应的内容和属性. |
HttpContentTranscoderException |
本异常的抛出说明编码转化工程不成功. BlackBerry设备将把本异常作为IOException抛出. |
HttpHeader |
本类提供方法对HTTP请求和响应的消息头进行操作. |
HttpParameter |
本类代表了HTTP查询参数.它提供获取和设置参数名和值. |
HttpRequest |
本类扩展了HttpTransmission类,它代表了一个包含头,参数和内容的HTTP请求. |
HttpResponse |
本类扩展了HttpTransmission类,它代表了一个包含头,参数和内容的HTTP响应. |
HttpTransmission |
本类提供获取和设置内容,头,以及HTTP请求和响应的参数. |
参看API参考获得更多信息.
创建一个HTTP内容编码转化器
为了创建一个HTTP内容编码转化器来全面控制HTTP请求与响应内容,扩展HttpContentTranscoder类.本编码转化器也可以修改,增加,或删除HTTP请求与响应属性.
编码转化器必须在net.rim.protocal.http.content.tanscoder.<name>包里定义,在这里,<name>是映射文件中使用的编码转化器的标志符.它的类名必须是Transcoder.
编码转化器的位置要么在httpcontenttranscoder文件指定,要么由应用程序指定.
处理HTTP内容编码转化器异常
任何由编码转化器抛出的异常将作为IOException被发送到应用程序.相关具体的消息也拷贝到IOException中.
注:为代替抛出一个异常到HTTP连接处理器,一个编码转化器也可能发送一个HTTP响应到一个应用程序,这表明发生了一个内部的服务器错误.
选择编码转化器
当BlackBerry设备请求内容时,MDS服务决定客户端请求的内容类型和服务器响应的内容类型的比较是否需要一个编码转化器.如果类型不一样,MDS服务检查httpcontenttranscoder.property文件来决定一个编码转化器是否可用来转化内容.
BlackBerry设备发送的HTTP请求里,x-rim-transcode-content头指定了MDS优化服务转化内容的输入格式.如果内容遇见以下情形,MDS数据优化服务将转化内容:
l 由x-rim-transcode-content头指定的输入格式也HTTP请求的Accept头中指定,此HTTP请求是MDS服务发送到服务器的请求.
l Web服务器响应一个内容类型,或者输出类型,它和BlackBerry设备接受的类型不同.
l httpcontenttranscoder.property文件包含了一个编码转化器,此编码转化器可以将Web服务器发送到MDS服务的内容转化为BlackBerry设备可接受的类型.
为了判断当push内容时一个编码转化器是否需要,MDS服务检查内容类型(content-type)和服务器端应用程序的x-rim-transcode-content头.如果2者相同,MDS数据优化服务将头文件指定的内容转为为BlackBerry可以显示的格式.
httpcontenttranscoder.property文件将输入的格式转化为一个给出的编码转化器.在下面的例子中, httpcontenttranscoder.property文件将.wml输入格式转化为.wbxml或.wmlc.
content-type: text/vnd.wap.wml
x-rim-transcode-content: text/vnd.wap.wml
你也可以创建定制的编码转化器来重新格式化或者转化应用程序请求的数据.例如,有愧乐意编写一个编码转化器将HTML内容转为为WML.参看196也的”创建编码转化器”获得更多信息.
HTTP请求
MDS服务使用MIME类型决定附加到一个服务器HTTP响应的内容格式是否和BlackBerry设备请求的内容格式相匹配.
MDS服务测试一列可用的编码转化器,并且扩展Accept头.例如,如果一个请求接受WML的MIME类型和一个编码转化器存在的HTML-to-WML,将HTML加到Accept头.参看195页的”映射编码转化器”获得更多信息.
在HTTP请求里,应用程序可以包含2个头来控制它接收的内容的类型:
l Accept头
l Content-Transcoder头.
头 |
描述 |
Accept |
在HTTP请求的Accept头里,应用程序列出它从内容服务器接收的MIME类型.例如,如果应用程序可以接收WML或XML格式的内容,它在HTTP请求里发送如下的消息头: Accept:text/wml,text/xml 缺省的,当Accept头列出了不止一个MIME类型,MDS服务将从左到右分配引用,在这里列出的第一个MIME类型假设为优先的. 应用程序页可以将质量因子(Quality factor)赋值给MIME类型来表明优先权.质量因子范围时0(最低优先权)到1(最高优先权),例如,下面的头表明了编译的WML(WMLC)是优先的,但是WML是可接受的. Accept:text/vnd.wap.wml;q=0.5, application/vnd.wap.wmlc;q=1 |
Content-Transcoder |
Content-Transcoder头是一个BlackBerry头,在内容返回到BlackBerry设备之前,它允许应用程序指定一个应用到任何内容的特定编码转化器.使用Content-Transcoder头覆写MDS服务运用的缺省处理来选择一个编码转化器. |
HTTP响应
内容服务器产生一个包含一个Content-Type头的HTTP响应.. Content-Type头描述了一个特定数据包的MIME类型.例如,当内容服务器一HTML格式返回内容时,HTTP响应包含一个值为text/html的Content-Type头.
MDS服务将应用程序的请求和内容服务器的响应进行比较.下面的部分将描述MDS服务如何决定什么时候转化内容:
响应类型 |
描述 |
不需要编码转化 |
应用程序发送一个请求获取WML格式的内容.请求包含以下的头: Accept:text/vnd.wap.wml 在它的响应里,内容服务器发送以下的头: Content-Type:text/vnd.wap.wml 因为服务器返回的内容类型与BlackBerry请求类型相符,MDS服务不需要任何转化.它将内容毫无变化的转发给BlackBerry设备. |
需要编码转化 |
应用程序发动一个请求获取内容.请求包含一下内容: Accept: text/vnd.wap.wml; q=0.5, application/vnd.wap.wmlc; q=1 此消息头表明应用程序接受WML或者编译的WML格式(WMLC)的内容. 在它的响应中,内容服务器发送下面的头: Content-Type: text/vnd.wap.wml 因为服务器返回的内容类型与BlackBerry请求类型不符,MDS服务搜索一个可以将MIME类型(WML)转化为优先的MIME类型(WMLC)的可用编码转化器. 如果一个适合的编码转化器不可用,MDS服务将WML内容毫无变化的转发给BlackBerry设备,因为初始请求表明BlackBerry设备应用程序接受WML内容. |
每个编码转化器都实现了一个方法创建一个哈希表,此哈希表映射作为来自内容服务器的输入,编码转化器接受的格式,以及作为输出编码转化器创建的格式.
在启动时,将自BlackBerry设备的HTTP请求转发之前,MDS服务使用哈希表修改Accept头域.例如,一个BlackBerry设备应用程序使用下面的Accept头发送一个HTTP请求:
Accept: application/vnd.wap.wmlc, text/vnd.wap.wmlscriptc
在审查编码转化器映射表之后,MDS数据优化服务加入下面的项到Accept头里:
application/vnd.wap.wmlscript, text/wml, and text/vnd.wap.wml
Accept: application/vnd.wap.wmlc, text/vnd.wap.wmlscriptc, application/vnd.wap.wmlscript, text/wml, text/vnd.wap.wml
这个扩展的Accept头现在列出了所有内容服务器可以提供的MIME类型.
映射编码转化器
httpcontenttranscoder.property文件在你的BlackBerry JDE 安装目录的MDS\config子目录下.它指定了MDS数据优化服务如何管理应用程序与内容服务器之间的多种内容类型的交换.
下面是httpcontenttranscoder.property的一个实例:
text/vnd.wap.wml->application/vnd.wap.wmlc:vnd.wap.wml
text/vnd.wap.wml->application/vnd.wap.wbxml:vnd.wap.wml
text/vnd.wap.wmlscript->application/vnd.wap.wmlscriptc:wmls
text/html->application/vnd.rim.html.filtered:html
text/vnd.wap.wml:vnd.wap.wml
text/vnd.sun.j2me.app-descriptor->application/vnd.rim.cod:vnd.rim.cod
default:pass
每个入口使用了下面的格式:
<InputType> [-> <OutputType>]: <Action>
在这里:
l InputType>是内容服务器可用的MIME类型,或者default.
l OutputType>是BlackBerry设备请求的MIME类型.
l Action>是下列值之一:
n 编码转化器包名,如vnd.wap.wml
n Pass:在没有改变下发送数据.
n Discard:放弃数据,不发送它.
下面几节解释在httpcontenttranscoder.property文件里可能的输入格式:
格式1
当服务器端可用的格式和BlackBerry设备请求的格式不同时,下面格式的入口指定了MDS完成的动作.
InputType -> OutputType:Transcoder OR RSV
例如,应用程序请求text/wml,但是内容服务器只有text/xml.MDS服务找到下面的MIME类型入口:
Text/xml -> Text/wml : vnd.wap.wml
根据本入口,MDS服务必须使用vnd.wap.wml编码转化器将XML内容转化为WML.
格式2
当服务器发送一个给定类型的内容,不考虑BlackBerry设备请求的内容, ,下面格式的入口指定了MDS完成的动作.
InputType:Transcoder OR RSV
例如,如果服务器仅有WML内容(text/vnd.wap.xml), .MDS服务找到下面的MIME类型入口:
text/vnd.wap.wml: vnd.wap.wml
根据本入口,MDS服务必须使用vnd.wap.wml编码转化器将XML内容转化为WML.
缺省的入口
如果MDS服务不能为一个特定的MIME类型:
default : Transcoder or RSV
找到一个入口,一个缺省的入口指定了MDS服务完成的缺省动作.
例如,如果MDS服务不能为defualt:pass缺省入口的内容找到一个入口,MDS服务将内容毫无变化的转发给BlackBerry设备.
创建编码转化器
将HTML标记和内容转化为大写
遵循编码转化器包层次结构(hierarchy)
在net.rim.protocol.http.content.transcoder.<transcoder name>包里定义HTTP内容转化器.所有HTTP内容编码转化器必须在Transcoder包层次结构里定义.
package net.rim.protocol.http.content.transcoder.uppercasehtm |
扩展HTTPContentTranscoder
一个编码转化器的类名必须为Transcoder.它扩展了HttpContentTranscoder类.
在本例中, 一个公共类Transcoder定义了HTTP内容编码转化器.
public class Transcoder extends HttpContentTranscoder { ... } |
定义HTTP头
为HTTP头定义常数以及编码转化器加到这些头的字符串.
private static final String CONTENTTYPE_HEADER_NAME = "Content-Type"; private static final String CONTENTLENGTH_HEADER_NAME = "Content-Length"; private static final String ACCEPT_HEADER_NAME = "Accept"; // Add this line to the Accept header field if it exists when // the BlackBerry device issues an HTTP request. private static final String ACCEPTLINE= "text/html"; // This line identifies the output content type that this transcoder produces. private static final String OUTPUT_TYPE= "text/UPPERCASEHTML"; |
创建一个输入和输出类型的映射
getMapOfOutputToAcceptLine()的实现创建了一个编码转化器输入和输出类型之间的映射.
随着启动,MDS服务使用映射修改Accept消息头域.MDS服务发送一个HTTP请求中修改的头到一个HTTP服务器.
public HashMap getMapOfOutputToAcceptLine() { HashMap mapping = new HashMap(); mapping.put(OUTPUT_TYPE, ACCEPTLINE); return mapping; } |
设置连接URL
当BlackBerr设备请求一个打开的HTTP连接时,定义一个方法设置连接URL.
public void setURL(URL newURL) { url = newURL; } |
定义BlackBerry设备的请求处理
在MDS服务将BlackBerry设备请求转发到目标服务器之前,transcodeDevice(HttpRequest)的实现定义了任何对这些请求的处理.下面的例子不需要处理:
一个应用程序可以使用一个称为Content-Transcoder的HTTP头请求一个指定的编码转化器,
public void transcodeDevice(HttpRequest request) throws HttpContentTranscoderException { // Implementation. } |
定义BlackBerry设备的响应处理
在MDS服务将BlackBerry设备响应转发到目标服务器之前, transcodeDevice(HttpResponse)的实现定义了任何对这些响应的处理.下面的例子不需要处理:
public void transcodeDevice(HttpResponse response) throws HttpContentTranscoderException { // Implementation. } |
定义服务器的请求处理
在MDS服务将它转发到BlackBerry设备之前, transcodeServer(HttpRequest)的实现定义了任何对内容服务器请求的处理需求.
public void transcodeServer(HttpRequest request) throws HttpContentTranscoderException { try { // Retrieve the request content, which, in this case, is in HTML. byte[] requestContent = request.getContent(); if (requestContent != null) { // Convert the content to String object. String requestContentAsString = new String(requestContent).toUpperCase(); // Convert the requestContentAsString to bytes again. requestContent = requestContentAsString.getBytes(); } else { // Send an HTML message to indicate that the server // is not responding with appropriate content. StringBuffer sb = new StringBuffer(); sb.append("<HTML>\n"); sb.append("<HEAD>\n"); sb.append("<TITLE> UPPERCASEHTML TRANSCODER</title>\n"); sb.append("</HEAD>\n"); sb.append("<BODY>\n"); sb.append("SERVER IS NOT PUSHING APPROPRIATE CONTENT\n"); sb.append("</BODY\n"); sb.append("</HTML>\n"); requestContent = sb.toString().getBytes(); } request.setContent(requestContent); // Update the Content-Length HttpHeader contentLengthHeader = request.getHeader(CONTENTLENGTH_HEADER_NAME); if (contentLengthHeader != null) { contentLengthHeader.setValue("" + requestContent.length); } else { // The server did not send the Content-Length. // No update is needed. } // Update the Content-Type. HttpHeader contentTypeHeader = request.getHeader(CONTENTTYPE_HEADER_NAME); if (contentTypeHeader != null) { contentTypeHeader.setValue(OUTPUT_TYPE); } else { // Add the Content Type here if the server does not specify one. request.putHeader(new HttpHeader( CONTENTTYPE_HEADER_NAME, OUTPUT_TYPE)); } } catch (Throwable t) { throw new HttpContentTranscoderException(t.toString()); } } |
定义服务器的响应处理
在MDS服务将它转发到BlackBerry设备之前, transcodeServer(HttpResponse)的实现定义了包含来自于内容服务器的内容服务器响应的任何处理需求.如果响应不包含任何内容,MDS服务将响应毫无变化的转发给BlackBerry设备.
public void transcodeServer(HttpResponse response) throws HttpContentTranscoderException { try { // Retrieve the response content, which in this case is in HTML. byte[] responseContent = response.getContent(); if (responseContent != null) { // Convert the content to String object. String responseContentAsString = new String(responseContent).toUpperCase(); // Convert the responseContentAsString to bytes again. responseContent = responseContentAsString.getBytes(); } else { // No response is received from the server. StringBuffer sb = new StringBuffer(); sb.append("<HTML>\n"); sb.append("<HEAD>\n"); sb.append("<TITLE> UPPERCASEHTML TRANSCODER </title>\n"); sb.append("</HEAD>\n"); sb.append("<BODY>\n"); sb.append("SERVER IS NOT RESPONDING\n"); sb.append("</BODY\n"); sb.append("</HTML>\n"); responseContent = sb.toString().getBytes(); } response.setContent(responseContent); // Update the Content-Length. HttpHeader contentLengthHeader = response.getHeader(CONTENTLENGTH_HEADER_NAME); if (contentLengthHeader != null) { contentLengthHeader.setValue("" + responseContent.length); } else { // Server did not send Content-Length so no update is required. } // Update the Content-Type. HttpHeader contentTypeHeader = response.getHeader(CONTENTTYPE_HEADER_NAME); if (contentTypeHeader != null) { contentTypeHeader.setValue(OUTPUT_TYPE); } else { // Add the Content Type here. response.putHeader(new HttpHeader(CONTENTTYPE_HEADER_NAME, OUTPUT_TYPE)); } } catch (Throwable t) { throw new HttpContentTranscoderException(t.toString()); } } |
编译和安装编码转化器
1. 编译编码转化器的类文件,在类路径里包含bmds.jar.
2. 为编译编码转化器创建一个jar文件.
3. 以下面的任一方式安装编码转化器.jar文件
l BES:将一个编码转化器.jar文件加到JRE的lib\jar目录下.此.jar文件必须可访问Java VM.
l 模拟器:将一个编码转化器.jar文件加到BlackBerry JDE的MDS\classpath目录下.
4. 打开httpcontenttranscoderslist.property文件,此文件在BlackBerry JDE安装目录的MDS\Config子目录下.
5. 为了指定何时使用编码转化器,加入一个或多个入口,.例如,为了使用uppercasehtml编码转化器将HTML内容转化为大写的HTML,加入下面的入口:
text/html -> text/UPPERCASEHTML : uppercasehtml
6. 保存属性文件.
7. 重启MDS服务或BlackBerry MDS模拟器.
[1]其实就是HTTP协议。译者注。