运行第一个python程序

    技术2022-07-17  61

    在你开始前

    为了充分利用本教程,您需要:

    下载WebSphere MQ版本6.0的免费试用版。 下载Rational Application Developer版本6.0的免费试用版。

    关于本教程

    在本教程中,您将逐步学习如何安装和配置WebSphere MQ和Rational Application Developer来开发JMS应用程序。 提供了示例应用程序以及使用已安装的产品运行这些应用程序的说明。

    目标

    安装和配置IBM工具以创建JMS开发环境。 在该环境中配置并运行JMS程序。

    先决条件

    本教程适用于需要了解如何使用WebSphere MQ和Rational Application Developer编写和测试JMS程序的Java程序员。 假定您具有Java的中级知识和JMS的入门知识。

    系统要求

    本教程中的说明适用于Windows环境,尽管精通其他操作系统的读者也可以将其改编为在其操作系统中使用。

    可通过以下链接找到本教程中使用的产品的系统要求:

    WebSphere MQ Rational Application Developer

    企业消息传递系统

    企业消息系统,有时也称为面向消息的中间件 (MOM),长期以来一直是应用程序集成的重要工具。 它们提供了一种灵活的,松散耦合的方式,可在应用程序之间交换信息。 MOM充当中介,使用存储和转发机制在应用程序之间传递数据(消息)。 应用程序不直接相互通信,而是与MOM通信,后者根据需要路由消息。 在当今的计算环境中,MOM着重于服务和面向服务的体系结构(SOA),作为这种体系结构的连接层起着至关重要的作用。 IBM WebSphere MQ是历史悠久的企业消息传递系统,并且是该市场的领导者。

    Java消息服务

    过去,每个MOM供应商通常都提供一个专有的应用程序编程接口(API),以与其产品一起使用。 例如,当第三方供应商想要使用消息传递将其应用程序与企业资源计划(ERP),供应链管理(SCM)或其他应用程序集成时,他们必须在其应用程序中编写单独且不同的消息传递组件,以及用于ERP或SCM或其他系统的单独且不同的适配器,以利用其客户已安装的MOM。 随着MOM供应商数量的增加,这引起了开发和维护的麻烦。

    Java消息服务(JMS)提供了一种标准的,可移植的方式,供Java程序员访问MOM产品。 JMS可移植性的关键是将API定义为一组接口。 MOM供应商提供了为他们的特定产品实现这些接口的提供程序。 此外,可通过Java命名和目录接口(JNDI)访问JMS资源,从而提供更多的可移植性和抽象性。 Java程序员使用JMS从JNDI检索称为被管理对象的JMS资源,并通过标准JMS接口访问它们,从而使他们不必了解底层消息系统的详细信息。 WebSphere MQ具有内置的JMS提供程序。

    Rational Application Developer

    IBM Rational Application Developer(应用程序开发者)是IBM针对Java 2平台企业版(J2EE)开发的最新集成开发环境(IDE)。 尽管Application Developer支持其他供应商的运行时环境,但它是在Eclipse平台上构建的,并且经过优化以开发可在WebSphere平台上运行的应用程序。 Application Developer随附的WebSphere Application Server V6集成测试环境提供了内置的JMS提供程序,即服务集成总线(SIB)。 您可以使用此SIB来测试JMS应用程序,而无需安装单独的企业消息传递系统。

    安装软件

    让我们来看看一些动手的东西! 在本节中,您将逐步完成安装本教程所需的软件的步骤。

    安装WebSphere MQ

    下载WebSphere MQ V6的试用版。 (请参阅相关主题中的链接。) 将下载的文件WMQv600Trial-x86_win.zip解压缩到系统上的文件夹中。 从将下载的文件提取到的文件夹中启动MQLaunch.exe。 单击左侧导航栏上的软件需求 ,然后单击WebSphere Eclipse Platform 3.0.1旁边的+ 。 (请参见图1 )。
    图1. WebSphere MQ软件需求
    单击CD-ROM以安装WebSphere Eclipse Platform。 在此安装过程中接受所有默认设置。 安装WebSphere Eclipse Platform后,单击左侧导航栏上的“ 网络配置 ”。 选择“ 否”单选按钮。 单击左侧导航栏上的WebSphere MQ安装 。 单击启动IBM WebSphere MQ安装程序 。 接受许可协议条款后,选择“ 自定义”作为安装类型。 单击下一步 。 您需要更改默认安装文件夹,因此请点击更改 。 在文件夹名称:字段中输入C:\WSMQ 。 (请参见图2。 )
    图2. WebSphere MQ目标文件夹
    单击确定 。 接受所有其他默认设置以完成安装。 WebSphere MQ安装完成后,将启动Prepare WebSphere MQ向导。 单击下一步 。 接受所有默认值。 (请勿设置默认配置。) 在“准备WebSphere MQ向导”的最后一个屏幕上,取消选中所有选项,然后单击“ 完成” 。

    安装必需的WebSphere MQ SupportPacs

    SupportPacs构成了一个资料库,是WebSphere MQ产品系列的补充。 对于本教程,我们将使用SupportPac MS0N-现有JMS Admin工具的GUI版本。 该SupportPac提供了用于管理JMS管理对象的图形用户界面。 该SupportPac需要另外两个SupportPacs才能正常工作。

    ME01:WebSphere MQ Initial Context Factory,在WebSphere MQ中提供JNDI功能 MS0B:PCF的Java类,提供对可编程命令格式命令的支持(PCF是用于以编程方式管理WebSphere MQ的API。)

    SupportPacs由包含JAR文件和文档的.zip文件组成。 您将需要这些JAR文件来设置JMS管理的对象并在以后运行示例程序。

    下载的SupportPac MS0N -现有的JMS管理工具的GUI版本(请参阅相关信息中的链接。) SupportPac MS0N的下载页面还具有下载SupportPacs ME01和MS0B的链接。 下载完三个文件(ms0n.zip,me01.zip和ms0b.zip)后,将每个文件解压缩到名为MQTools的文件夹中。 (我将MQTools文件夹放在Windows桌面上,但可以将其放在适合您的位置。)

    安装Rational Application Developer

    下载Rational Application Developer V6的试用版(请参阅参考资料中的链接)。 将以下每个文件下载到系统上的同一文件夹中: 第1部分-extractor.exe 第2部分-C81N0ML.bin 第5部分-C81N3ML.bin 第6部分-C81N4ML.bin 下载完所有四个文件后,启动extractor.exe将安装映像解压缩到系统上的目录中。 提取程序将提供安装映像的默认位置。 您可以将其更改为适合您的任何目录。 出现提示时选择以下功能: 核心安装文件 WebSphere Application Server V6.0集成测试环境 IBM代理控制器 创建安装映像后,选中复选框立即启动安装向导 ,然后单击完成 。 在Rational Software Development Platform启动板上,单击Install Rational Application Developer V6.0 Trial 。 安装程序启动后,请接受许可协议。 将安装目录更改为C:\RAD (请参见图3 )。
    图3. Application Developer安装目录
    接受所有其他默认设置以完成安装。 当安装程序指示成功安装Application Developer时,单击Next 。 确保已选中“ 启动代理控制器安装”复选框,然后单击“ 完成” 。 启动代理控制器安装程序时,请接受所有默认值,直到出现Java Runtime对话框。 输入C:\RAD\eclipse\jre\bin\java.exe作为Java运行时文件的位置。 (参见图4。 )
    图4. Java运行时文件位置
    接受所有其他默认设置以完成安装。

    现在,您已经安装了所有软件。 在下一节中,您将安装示例代码。

    安装示例代码

    下载示例代码文件i-mqrad1code.zip。 (请参阅下载以获取链接)。 将此文件解压缩到系统上的文件夹中。 在我的系统上,我将其解压缩到Windows桌面上名为mq6rad6_1的文件夹中。 此文件夹中有两个文件:MQP2P.zip和EMQP2P.zip。 从开始菜单启动Application Developer。 当提示您提供工作空间时,输入C:\workspace 。 (参见图5。 )
    图5.工作区位置
    单击确定 。 Application Developer启动后,通过单击“ 欢迎”旁边的X关闭“欢迎”屏幕。 通过从主菜单中选择Window ,然后选择Open Perspective> Java来切换到Java透视图。 从主菜单中,选择“ 文件”>“导入” 。 选择Project Interchange作为导入源,然后单击Next 。 在“ 从zip文件:”字段中,输入先前提取的MQP2P.zip文件的位置。 (参见图6。 )
    图6.项目交换zip文件的位置
    选中MQP2P项目旁边的复选框,然后单击完成 。

    查看示例代码

    在继续之前,让我们详细看一下代码。 -已导入的类的三ConnectionPanel , QSenderUI和QReceiverUI 。 使用标准的抽象窗口工具包(AWT)工具为程序提供用户界面。 (因为这些类中没有JMS代码,所以我们不需要花任何时间来研究它们。)

    QSender类

    带有JMS代码的第一类是QSender 。 QSenderUI使用QSenderUI来将消息发送到队列。 此类中的三个方法包含JMS代码: setConnection() , setQueue()和sendMessage() 。 setConnection() ,如清单1所示。

    清单1. QSender类中包含JMS的三个方法
    public void setConnection(String connectionName) throws JMSException, NamingException, Throwable { try { close(); QueueConnectionFactory factory = (QueueConnectionFactory) getInitContext().lookup(connectionName); connection = factory.createQueueConnection(); session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); } catch (Throwable e) { setExceptionMessage(e); throw e; } }

    此方法将JNDI名称空间中可用的QueueConnectionFactory的名称作为输入。 此类的方法close()的调用可确保关闭所有QueueSender , QueueSession和QueueConnection对象。 然后,通过JNDI进行查找,以检索名称作为connectionName参数传入的QueueConnectionFactory 。 一旦QueueConnectionFactory已被检索,它被用来创建一个QueueConnection ,其又用于创建QueueSession 。

    请注意,在此方法以及所有其他方法(包含我们将要查看的JMS代码)中,所有代码都是基于JMS接口的-到处都没有特定于WebSphere MQ的代码。

    接下来,检查清单2所示的setQueue() 。 当在用户界面中输入Queue的JNDI名称时, QSenderUI将调用此方法。

    清单2.检查setQueue()
    public void setQueue(String queueName) throws JMSException, NamingException, Throwable { try { if (connection != null) connection.stop(); if (sender != null) sender.close(); Queue queue = (Queue) getInitContext().lookup(queueName); sender = session.createSender(queue); sender.setDeliveryMode(DeliveryMode.NON_PERSISTENT); sender.setPriority(4); sender.setTimeToLive(0); connection.start(); } catch (Throwable e) { setExceptionMessage(e); throw e; } }

    首先,如果需要,停止QueueConnection并关闭QueueSender 。 然后,使用queueName参数从JNDI中检索Queue对象。 接下来,创建一个QueueSender以将消息发送到Queue ,并设置QueueSender属性。 最后,启动QueueConnection ,以允许访问消息传递系统。

    我们在QSender介绍的最后一个方法是sendMessage() ,如清单3所示。 通过QueueSender对象将消息发送到Queue时,将调用此方法。

    清单3. sendMessage()
    public void sendMessage(String text) throws JMSException, Throwable { if (sender != null) { try { TextMessage message = session.createTextMessage(text); sender.send(message); } catch (Throwable e) { setExceptionMessage(e); throw e; } } }

    QueueSession对象用于使用text参数创建TextMessage ,然后QueueSender对象用于发送消息。

    QReceiver类

    现在,看看QReceiver类。 它还包含setConnection()和setQueue()方法。 因为setConnection()方法是相同的,在QSender ,我会在这里跳过。 下面是setQueue()方法,如清单4所示。

    清单4. setQueue()
    public void setQueue(String queueName) throws JMSException, NamingException, Throwable { try { if (connection != null) connection.stop(); if (receiver != null) receiver.close(); Queue queue = (Queue) getInitContext().lookup(queueName); receiver = session.createReceiver(queue); receiver.setMessageListener(this); connection.start(); } catch (Throwable e) { setExceptionMessage(e); throw e; } }

    在明显的差异setQueue()这里方法和setQueue()在方法QSender是一个QueueReceiver创建,而不是一个QueueSender 。 但是还有一件事要看。 注意setMessageListener()调用。 QReceiver类是javax.jms.MessageListener接口的实现。 通过在QueueReceiver设置MessageListener ,将在队列中接收到的消息异步传递到MessageListener对象。 这允许MessageListener在消息到达时对其进行处理,并且接收者不必在Queue查询新消息。

    MessageListener接口定义了一种方法onMessage() 。 因为QReceiver类实现了该接口,所以它具有onMessage()方法,如清单5所示。

    清单5. setQueue()
    public void onMessage(Message message) { String msgText = null; try { msgText = ((TextMessage) message).getText(); } catch (Throwable e) { setExceptionMessage(e); msgText = getExceptionMessage(); } finally { setMessage(msgText); } }

    每当消息到达正在侦听的Queue时,JMS都会调用此方法。 在此,消息的文本用于设置QReceiver对象的message属性。

    QSender和QReceiver类的其他方法相当不言自明,并负责JNDI访问,绑定属性和异常处理。

    配置WebSphere MQ运行时环境

    在运行示例程序之前,您需要配置运行时环境以提供WebSphere MQ队列管理器和JMS管理的对象。

    创建一个队列管理器

    从“开始”菜单启动WebSphere MQ Explorer。 在左侧的导航器视图中,右键单击队列管理器,然后选择新建>队列管理器 。 在“ 队列管理器名称:”字段中,输入Ender 。 选中将其设置为默认队列管理器复选框。 在“死信队列:”字段中,键入SYSTEM.DEAD.LETTER.QUEUE (大小写很重要)。 “创建队列管理器”对话框应该类似于图7 。
    图7.创建队列管理器对话框
    点击完成 。 关闭WebSphere MQ资源管理器。

    创建JMS管理的对象

    您将使用SupportPac MS0N提供的JMS Admin GUI创建JMS管理的对象。 结合使用此工具和SupportPac ME01提供的JNDI支持,可以让您直接在WebSphere MQ中创建JMS管理的对象,而WebSphere MQ提供JNDI工具,而无需单独的JNDI服务器。 您可以从Application Developer中运行JMS Admin GUI。

    导入JMS管理员GUI

    首先,您需要设置一个Java项目,其中包括JMS Admin GUI JAR文件。

    从主菜单中,选择“ 文件”>“新建”>“项目” 。 选择Java项目 ,然后单击Next 。 在项目名称:字段中,输入JMSAdminGUI 。 单击下一步 。 单击库选项卡。 单击添加外部JAR 。 导航到您将SupportPac下载提取到的MQTools文件夹。 选择jmsadmingui.jar文件。 (请参见图8。 )
    图8.选择jmsadmingui.jar
    单击打开 ,然后单击完成 。

    运行JMS Admin GUI

    现在,您可以运行该工具并创建JMS管理的对象。

    在程序包资源管理器中,依次展开JMSAdminGUI,jmsadmingui.jar和com.ibm.mq.jms.admin。 右键单击JMSAdminGUI.class,然后选择运行>运行 。 (参见图9。 )
    图9.运行JMSAdminGUI.class
    在“ 配置”列表中选择“ Java应用程序 ”。 点击新建 。 确保Run对话框如图10所示 。
    图10. JMSAdminGUI运行配置
    WebSphere MQ使用Java本机接口(JNI)为其所部署的特定操作系统调用本机代码。 为了确保此代码可用于Java Runtime Environment(JRE),并且还可以使用JRE本机代码,您需要将sun.boot.library.path系统变量设置为指向适当的文件夹。 单击参数选项卡。 在VM参数文本区域中,输入-Dsun.boot.library.path=C:\RAD\eclipse\jre\bin;C:\WSMQ\Java\lib 。 确保在开头包含连字符,并全部输入,且不包含空格或回车符。 JMS Admin GUI取决于SupportPacs随附的类以及WebSphere MQ Java库随附的类。 您需要设置运行时类路径以确保这些类可用。 单击类路径选项卡。 单击“ Classpath:”列表中的“ Bootstrap项 ”。 单击添加外部JARS 。 导航到MQTools文件夹,然后在其中选择三个JAR文件。 (使用Ctrl +单击选择多个文件。) com.ibm.mq.pcf.jar jmsadmingui.jar mqcontext.jar JAR选择对话框应类似于图11 。
    图11. MQTools JAR选择
    点击打开 。 再次单击添加外部JARS 。 导航到C:\ WSMQ \ Java \ lib并选择以下JAR文件: com.ibm.mq.jar com.ibm.mqjms.jar 连接器.jar dhbcore.jar jms.jar JAR选择对话框应类似于图12 。
    图12. WSMQ \ Java \ lib JAR选择
    点击打开 。 点击运行 。 点击创建新的配置文件单选按钮,然后点击确定 。 在文件名字段中输入WMQ ,然后单击创建 。 在提供者URL字段中输入 Ender 。 在“ 初始上下文工厂”下拉列表中选择com.ibm.mq.jms.context.WMQInitialContextFactory 。 您的“ JNDI配置”对话框应如图13所示 。
    图13.“ JNDI配置”对话框
    单击确定 。 从主菜单中,选择“ 对象”>“新建”>“队列” 。 在“ 对象名称:”字段中键入EnderQ ,然后单击“ 确定” 。 退出JMS Admin GUI。

    使用WebSphere MQ运行样本程序

    现在,您可以运行示例程序了。 与JMS Admin GUI一样,您需要设置VM参数和类路径以确保正确配置程序

    运行QReceiverUI

    在MQP2P项目中右键单击QReceiverUI ,然后选择Run> Run 。 在“ 配置”列表中选择“ Java应用程序 ”。 点击新建 。 确保“运行”对话框如图14所示 。
    图14. QReceiverUI运行配置
    单击参数选项卡。 在“ VM参数”文本区域中,键入以下参数,每个参数之间用空格分隔。 -Djava.naming.factory.initial=com.ibm.mq.jms.context.WMQInitialContextFactory -Djava.naming.provider.url=Ender -Dsun.boot.library.path=C:\RAD\eclipse\jre\bin;C:\WSMQ\Java\lib 除了参数之间的空格外,不应有其他空格或回车符。 确保在每个参数之前包括连字符。 参数将在VM参数文本区域中自动换行。 只要您不键入空格(参数之间的空格除外)或回车,就可以了。 单击类路径选项卡。 单击“ 类路径”列表中的“ 引导程序条目 ”。 单击添加外部JARS 。 导航到MQTools文件夹,然后选择以下JAR文件: com.ibm.mq.pcf.jar mqcontext.jar 点击打开 。 再次单击添加外部JARS 。 导航到C:\ WSMQ \ Java \ lib并选择以下JAR文件: com.ibm.mq.jar com.ibm.mqjms.jar 连接器.jar dhbcore.jar jms.jar 点击打开 。 点击运行 。 在“ 连接”字段中键入Ender ,然后按Enter或单击“ 设置” 。 在“ 队列”字段中键入EnderQ ,然后按Enter或单击“ 设置” 。

    运行QSenderUI

    要为QSenderUI创建配置,您可以复制QReceiverUI配置,然后更改配置名称和主类。

    返回到应用程序开发人员。 从主菜单中,选择运行>运行 。 在“ 配置”列表中右键单击QReceiverUI ,然后选择“ 复制” 。 将QReceiverUI(1)重命名为QSenderUI 。 将Main class字段更改为com.ibm.qbda.mq.p2p.QSenderUI 。 点击应用 。 确保运行对话框如图15所示 。
    图15. QSenderUI运行配置
    点击运行 。 在“ 连接”字段中键入Ender ,然后按Enter或单击“ 设置” 。 在Queue:字段中输入 EnderQ并按Enter或单击Set 。

    测试程序

    使“队列发送者”和“队列接收器”窗口均可见。 在“队列发件人”的“ 消息”字段中键入文本,然后按Enter或单击“ 设置” 。 您应该看到消息文本出现在“队列接收器”窗口中。 完成后,通过单击右上角的X关闭两个窗口。

    配置WebSphere集成测试环境

    如简介中所述,Application Developer附带的WebSphere Application Server V6集成测试环境提供了内置的JMS提供程序。 在本部分中,您将配置队列和JMS管理的对象,以便可以在测试环境中运行示例程序的版本。

    创建服务总线和队列

    从主菜单中,选择“ 窗口”>“打开透视图”>“ J2EE” 。 选择窗口底部的“ 服务器”视图。 右键单击WebSphere Application Server V6.0,然后选择启动 。 等待服务器的状态更改为已启动。 右键单击服务器,然后选择“运行管理控制台” 。 出现控制台时,使用任何用户ID登录。 从左侧的导航栏中单击服务集成 。 单击“ 总线” 。 点击新建 。 在名称字段中输入BeanBus 。 单击确定 。 从“ 总线”列表中单击BeanBus 。 从其他属性列表中单击总线成员 。 参见图16 。
    图16.总线的其他属性
    点击添加 。 单击下一步 ,然后单击完成 。 点击保存在页面的顶部,然后点击保存 。 单击页面顶部的BeanBus链接。 (参见图17。 )
    图17.总线成员
    单击附加属性列表目的地 。 点击新建 。 选择“ 队列”单选按钮。 单击下一步 。 在“ 标识符”字段中键入BeanQ 。 单击下一步 。 再次单击下一步 ,然后单击完成 。 点击保存在页面的顶部,点击保存 。

    创建JMS管理的对象

    在左侧导航栏上,单击资源> JMS提供者>默认消息 。 (参见图18。 )
    图18.默认消息导航选择
    单击“ 连接工厂”列表中的“ JMS队列连接 工厂 ”。 点击新建 。 在名称字段中输入BeanQCF 。 在JNDI名称字段中输入jms/BeanQCF 。 从总线名称下拉列表中选择BeanBus 。 单击确定 。 单击左侧导航栏上的默认消息 。 从“ 目标”列表中单击“ JMS队列 ”。 点击新建 。 在名称字段中输入MyBeanQ 。 在“ JNDI名称”字段中输入jms/MyBeanQ 。 从总线名称下拉列表中选择BeanBus 。 从队列名称下拉列表中选择BeanQ 。 单击确定 。 点击保存在页面的顶部,然后点击保存 。 关闭管理控制台。 在“ 服务器”视图中右键单击WebSphere Application Server V6.0 ,然后选择重新启动>启动 。

    使用WebSphere Test Environment运行样本程序

    在编写桌面应用程序以连接到应用程序服务器时,最好将该应用程序打包为企业应用程序的应用程序客户端模块。 这样可以确保连接到服务器所需的所有资源均可用。

    在本节中,您将导入将示例程序重新打包为应用程序客户端的项目。 完成此操作后,您可以运行程序以使用测试环境的内置消息传递。

    导入重新打包的示例程序

    从主菜单中,选择“ 文件”>“导入” 。 选择Project Interchange作为导入源,然后单击Next 。 在“ 从zip文件中”字段中,输入先前从示例代码下载文件中提取的EMQP2P.zip文件的位置。 单击全选 。 点击完成 。

    如果查看应用程序客户端项目,您将看到每个项目都有一个带有main()方法的Main类。 EQSender中Main类的main()方法调用QSenderUI.main() 。 同样,EQReceiver中Main类的main()方法调用QReceiverUI.main() 。

    运行EQReceiver

    右键单击EQReceiver,然后选择运行>运行 。 在“ 配置”列表中选择WebSphere V6.0 Application Client 。 点击新建 。 将名称字段更改为EQReceiver 。 点击运行 。 在“ 连接”字段中键入jms/BeanQCF ,然后按Enter或单击“ 设置” 。 在Queue字段中输入 jms/MyBeanQ ,然后按Enter或单击Set 。

    运行EQSender

    返回Application Developer,右键单击EQSender并选择Run> Run 。 在“ 配置”列表中选择WebSphere V6.0 Application Client 。 点击新建 。 将名称字段更改为EQSender 。 点击运行 。 在Connection:字段中输入 jms/BeanQCF ,然后按Enter或单击Set 。 在Queue字段中输入 jms/MyBeanQ ,然后按Enter或单击Set 。

    测试程序

    使“队列发送者”和“队列接收器”窗口均可见。 在“队列发件人”的“ 消息:”字段中键入文本,然后按Enter或单击“ 设置” 。 您应该看到消息文本出现在“队列接收器”窗口中。 完成后,通过单击右上角的X关闭两个窗口。 关闭Application Developer之前,请停止服务器测试环境。

    摘要

    现在,您已经下载并安装了用于开发,配置和测试JMS程序的IBM最新工具:WebSphere MQ和Rational Application Developer。 您还运行了一些示例程序来演示这些工具如何协同工作以为JMS开发提供完整的环境。

    在下一个教程中,您将研究JMS发布-订阅程序。 您还将查看其他一些WebSphere MQ配置,这些配置可以使您的程序更加灵活。


    翻译自: https://www.ibm.com/developerworks/websphere/tutorials/i-mqrad1/i-mqrad1.html

    相关资源:Learning Python Application Development
    Processed: 0.010, SQL: 9