继续更新学习进度

为了不让过去走的弯路白走,所以自己一定要记录下这一路的“风景”。在之前我们实现了Delphi调用EJB,但是我们一直用的都是Delphi自己给我们生成的WSDL Importer,在接口文件中有根据wsdl分析得出的EJB方法,接下来问题就来了,如果我们每一次发布一个EJB工程,就需要每一次都Import一下,这样一来就十分不方便,所以为了改进,我们将所有EJB的方法都放在一个方法中,这个方法有两个参数,第一个参数代表第几个方法,也可以是方法名字,第二个参数是方法要传递到参数。这样做的好处有两点:1、我们可以不用改接口文件,同样在wsdl中就只有一个方法,比起有一大堆方法,这样加载起来更加迅速2、当别人通过浏览器看wsdl时也不知道我们写了什么方法,防止有人闲的无聊对服务器进行捣乱。。。然而对于第二个参数的传递我们有了实现好的约定,用字符串来传递并且用特定的分隔符将传进去的参数分隔开,在EJB中进行判断,然后将相应的参数存到相应的变量中,所以说这样一来对于参数的顺序有都变得随意,稍微简化了客户端的操作,当然函数返回的参数值是String类型。

接下来让我们来看下Importer生成的单元中系统给的代码。我的EJB中有两个方法DBConnection和UpdateInfo

 <textarea readonly="readonly" name="code" class="Delphi"> 
unit DBConnection1;

interface

uses Soap.InvokeRegistry, Soap.SOAPHTTPClient, System.Types, Soap.XSBuiltIns;

const
  IS_OPTN = $0001;
  IS_UNQL = $0008;


type
  //系统自动生成代码。。。
  
  DBConnection = interface(IInvokable)
  ['{7846D3B7-919A-4FF5-4D9A-446678551BF4}']//GUID,128位数字通过算法结合网卡MAC地址和电脑自带的时钟把数字转化成左边的一串东东
    function  GetDataSet(const arg0: string): string; stdcall;
    procedure UpdateInfo(const arg0: string); stdcall;
  end;

function GetDBConnection(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): DBConnection;
//这是系统给我们的用于接口实例化的函数,我们可以传URL或者是WSDL

implementation
  uses System.SysUtils;

function GetDBConnection(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): DBConnection;
const
  defWSDL = 'http://localhost:8080/GetData/DBConnection?wsdl';
  defURL  = 'http://localhost:8080/GetData/DBConnection';
  defSvc  = 'DBConnectionService';
  defPrt  = 'DBConnectionPort';
var
  RIO: THTTPRIO;
begin
  Result := nil;//因为我们在用WSDLImport的时候给了wsdl所以当我们再次接口实例化的时候如果传的部分参数是空,程序就会用一开始给的wsdl
  if (Addr = '') then
  begin
    if UseWSDL then
      Addr := defWSDL
    else
      Addr := defURL;
  end;
  if HTTPRIO = nil then
    RIO := THTTPRIO.Create(nil)
  else
    RIO := HTTPRIO;
  try
    Result := (RIO as DBConnection);
    if UseWSDL then
    begin
      RIO.WSDLLocation := Addr;
      RIO.Service := defSvc;
      RIO.Port := defPrt;
    end else
      RIO.URL := Addr;
  finally
    if (Result = nil) and (HTTPRIO = nil) then
      RIO.Free;
  end;
end;

//以下是程序运行时这个单元的初始化代码
initialization
  { DBConnection }
  InvRegistry.RegisterInterface(TypeInfo(DBConnection), 'http://getdata/', 'UTF-8');//其中<span style="font-family: Arial, Helvetica, sans-serif;">http://getdata/是我们EJB工程的目录,包的名字,为了我们每个人编写的方法可以一起用,多以我们把EJB的工程和包的名字作了约定,这样我们需要调用别人的方法时,只需要在接口实例化的时候把他的IP传过去就好了(因为EJB中的方法也约定好的就一个并且名字也一样)</span>

  InvRegistry.RegisterDefaultSOAPAction(TypeInfo(DBConnection), '');
  InvRegistry.RegisterInvokeOptions(TypeInfo(DBConnection), ioDocument);//其中ioDocument是由我们EJB代码决定的,@SOAPBinding(use = SOAPBinding.Use.LITERAL,style = SOAPBinding.Style.DOCUMENT)我选择的是DOCUMENT
  { DBConnection.GetDataSet }
  InvRegistry.RegisterMethodInfo(TypeInfo(DBConnection), 'GetDataSet', '',
                                 '[ReturnName="return"]', IS_OPTN or IS_UNQL);//在类加工厂注册函数和方法、这样才能实例化接口对象
  InvRegistry.RegisterParamInfo(TypeInfo(DBConnection), 'GetDataSet', 'arg0', '',
                                '', IS_UNQL);
  InvRegistry.RegisterParamInfo(TypeInfo(DBConnection), 'GetDataSet', 'return', '',
                                '', IS_UNQL);
  { DBConnection.UpdateInfo }
  InvRegistry.RegisterParamInfo(TypeInfo(DBConnection), 'UpdateInfo', 'arg0', '',
                                '', IS_UNQL);

end.
</textarea>

Ps.在这里补充下关于GUID的相关小知识,因为GUID的使用有IID(接口标识),CLSID(class标识),而本质都是GUID,用于区分不同人编写的东西。

对于JBOSS我们也有了一些新的发现,在SessionBean开始我们写的import带入包,实际上只是在编译的时候可以不出语法错误,而真正的包引入还是依赖于JBOSS的模块。我们发现,当在开头写了import org.apache.xerces.impl.dv.util.Base64;但是在启动JBOSS时还是会报错说找不到类,而后我们在META-INF的MANIFEST中添加了依赖关系Dependencies: org.jdom,org.apache.xerces,JBOSS便不再报错。对此我们猜测在开始时部署了相应的jar包并没有真正的加载进来,也许JBOSS为了提高效率,采用动态加载模块,另外,我们这个Dependencies后跟的是module.xml的模块名字,加入我们把JBOSS的org.apache中文件夹xerces改成tom,把module.xml中模块名字也改成tom,我们还是能找到jar包,因为一个模块对应着一个jar包,而import后的关系是类关系,模块部署的名字是和它不同,只是平常我们建文件夹时的层次和名字和引入类的关系一致。

最后要总结下最近关于向数据库中存图片的过程,首先在本地加载图片,得到图的流(流相当于二进制字节数组+对数组的一些操作),而后对流按照Base64码制进行编码,之后再对生成的字符串进行压缩,压缩之后再次变成二进制,接着Base64编码,然后作为参数传过去就好了,在EJB方法中反着来一遍就好了,因为WebService只认可见字符,转换成Base64码制是必须的。另外关于BLOB类型的插入也需要先一条空的而后在Update。具体方法来自以下http://ligaosong.iteye.com/blog/1072719

FINAL---->老师说要把编程看成乐趣,自己大一并没有做到,现在是时候动手敲写代码啦!2016年3月7日差4分钟第二天

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值