.NET HTTP处理器与手持应用通信

服务器端模块包括一个.NETHTTP处理器、一组包含业务逻辑和数据访问代码的类库,以及一个作为知识库应用程序文章存储库的SQL Server数据库

创建HTTP处理器

HTTP处理器的任务是从手持设备发出的HTTP请求中提取信息,确定需要执行的操作类型,并要求业务逻辑层执行这些操作。它还将业务逻辑层生成的结果附加到HTTP响应中,并将其发送到手持应用程序。

为了使手持应用程序和处理器能够相互通信,所有手持应用程序可能发送的命令都需要在处理器中定义,就像在手持设备中定义的那样:

private const int CMD_SEARCH_ARTICLES = 1; private const int CMD_GET_ARTICLES_BY_TAG = 2; private const int CMD_GET_TAG_COUNTS = 3;

每个请求参数的键也需要定义:

private const string KEY_COMMAND = "cmd"; private const string KEY_SEARCH_PHRASE = "sp"; private const string KEY_TAG = "tg";

KEY_SEARCH_PHRASE标识当请求搜索现有文章时携带搜索短语的请求参数。KEY_TAG标识当请求检索给定标签的文章时携带标签名称的参数。

确定要执行的操作是检查标记有KEY_COMMAND键的请求参数:

string commandString = request.Form[KEY_COMMAND]; if (!int.TryParse(commandString, out currentCommand)) { // 如果没有收到数字命令,则退出。 return; } articlesServer = Shared.GetArticlesServer(context); switch (currentCommand) { case CMD_SEARCH_ARTICLES: string searchPhrase = request.Params[KEY_SEARCH_PHRASE]; responseString = SearchArticles(searchPhrase); break; case CMD_GET_ARTICLES_BY_TAG: string tag = request.Params[KEY_TAG]; responseString = GetArticlesForTag(tag); break; case CMD_GET_TAG_COUNTS: responseString = GetTagCounts(); break; default: return; }

使用业务逻辑服务

今天不会详细介绍业务逻辑和数据访问层的构建,因为它们已经在文章《端到端ExtJS应用程序》系列中介绍过了。值得一提的是,这些层支持将文章存储在文件中或SQL Server数据库中。今天文章的代码下载默认使用基于文件的存储,但可以通过运行包含的SQL脚本来安装数据库,并通过更改Web应用程序的配置文件将业务层指向它。

在HTTP处理器中,SearchArticles()、GetArticlesForTag()和GetTagCounts()简单地将请求转发到业务逻辑层:

private string SearchArticles(string searchPhrase) { Debug.Assert(searchPhrase != null); if (null == searchPhrase) { ExceptionPolicy.HandleException(new ArgumentNullException("searchPhrase"), Shared.KB_EXCEPTION_PLCY); } string result = string.Empty; try { List articles = articlesServer.GetArticlesForSearchPhrase(searchPhrase); if (null == articles) return string.Empty; result = SerializeArticlesList(articles); } catch (Exception ex) { ExceptionPolicy.HandleException(ex, Shared.KB_EXCEPTION_PLCY); } return result; }

在业务逻辑结果传递给处理器后,需要根据在编写手持代码时建立的格式约定来序列化结果。例如,这是将文章列表转换为字符串的例程,该字符串将作为HTTP响应的一部分发送到手持设备:

private string SerializeArticlesList(List articles) { Debug.Assert(articles != null); if (null == articles) { ExceptionPolicy.HandleException(new ArgumentNullException("articles"), Shared.KB_EXCEPTION_PLCY); } StringBuilder sb = new StringBuilder(""); string body; foreach (IArticle article in articles) { // 解码文章正文中的HTML字符。 body = HttpUtility.HtmlDecode(HttpUtility.UrlDecode(article.Body)); // 删除HTML字符 // (使用的手持设备上的RichTextField尚不能显示HTML。) body = Regex.Replace(body, @"<(.|\n)*?>", string.Empty); sb.Append(string.Format("{0}^~^{1}^~^{2}^~^{3}^~^", article.Id.ToString(), article.Title, article.DateCreated.ToShortDateString(), article.Author)); sb.Append(string.Format("{0}^~^{1}~^~", article.Tags, body)); } return sb.ToString(); }

是否注意到在上述代码中,还删除了文章正文中的HTML字符?必须这样做,因为在手持设备上用于显示文章正文的字段尚不能渲染HTML。

现在剩下的就是将数据发送到手持设备:

response.ContentType = "text/plain"; int contentLength = response.Output.Encoding.GetByteCount(responseString); response.AppendHeader("content-length", contentLength.ToString()); response.Write(responseString); response.End();

知道服务器端代码的介绍非常快。鼓励下载代码并查看所有细节。此外,阅读《端到端ExtJS应用程序》文章可以让更深入地了解业务逻辑和数据访问层。

从手持应用程序发起请求并接收数据

让回到设备端代码,并准备将其连接到HTTP处理器。将做的第一件事是停止使用MockHTTPTransport实例,开始使用KbHTTPTransport。而MockHTTPTransport只是模拟HTTP请求,允许在设备上测试所有渲染逻辑,KbHTTPTransport是真正的交易。这是在文章屏幕或标签屏幕上的使用方式:

private void sendHttpRequest(String[] keys, String[] values) { articlesList.set(null); // 在下载时显示"No Articles"。 String url = DataStore.getAppServerUrl(); // 确保可以创建一个http请求。 // 如果应用程序服务器URL未设置,则无法进行任何http请求。 if (null == url || url.length() == 0) { Dialog.alert(resources.getString(KnowledgeBaseResource.ERR_INVALID_APP_SERVER_URL)); return; } statusDlg.show(); byte[] requestContents = TransportUtils.createPostData(keys, values); KbHTTPTransport transport = new KbHTTPTransport(); transport.setHTTPTransportListener(this); transport.send(KbHTTPTransport.REQ_METHOD_POST, url, requestContents); }

此时,所有部分都已就绪,将使用BlackBerry模拟器和MDS模拟器使用真实数据测试应用程序。在启动两个模拟器后,将检查选项屏幕,确保指向的是HTTP处理器的正确URL。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485