我接触webservice的时间并不长,到现在为止只用过axis2做过开发,这是公司要求用的。
我先说说公司项目开发用了些什么东西: 前台用的是liferay+struts;  后台的webservice用的是axis2,还有spring+hibernate现在我说说,公司以前的webservice开发流程,我是刚刚进入公司不久,从头到尾做完的项目还没有,只是参与了一个快要完成的项目。
第一步:把 wsdl文件,services.xml文件,xsd文件都写好
第二步:写服务端,客户端代码,(没有用工具生成,全是手写的,老大要求的)
以上工作完成之后,打包发布,进行测试
是这样打包的:
把  wsdl文件,services.xml文件,xsd文件 打包成.aar文件到 axis2/web-inf/services下
把  服务端代码 打包成.jar文件  放到axis2/web-inf/lib 目录下
把  客户端代码 打成.jar文件,导出供前台调用这样咋一看来,好像是没有什么问题,但是时间长了,我觉得有好多地方都有些问题
比如:用了  spring,却没有用到spring 的依赖注入和事务处理,前台每次调用webservice的时候,都是硬生生把spring配置文件读出来,然后用getBean(str)方法取得业务类对象来调相应的方法,很明显这时Spring显得有点多余,不但没有带来好处,反而是降低了一定的性能(读取配置文件花的时间)。spring的其中一个好处就是面向接口编程,虽然之前的项目也有定义接口,但是由于没有运用依赖注入,所以,项目中定义的接口完全就是一个摆设,没有任何意义。因为getBean()取出来的就是实现类,而且配置文件中也没有进行必要的配置。还有其他一些小问题,我都找到了解决方法, 在这儿就不一一列举。现在我就是想把axis2 和  spring 集成起来,充分发挥 spring的强大功能。
有了这个想法之后,我就立即着手,在网上找了很久,都没有找到满意的答案,下了一个官方文档来看,也没怎么看明白,水平不限呀。网上关于这方面的文章和资料太少了如果有哪一位朋友做过或者是知道怎么集成的,我真诚的希望在这里能留下你宝贵的经验,万分感谢!!如有朋友愿意给予解答的,尽可能的详细,  如怎么样打包,文件的存放位置等等,谢谢!!

解决方案 »

  1.   

    前台每次调用webservice的时候,都是硬生生把spring配置文件读出来
    --------
    客户端怎么写的?前台怎么还会去获取spring中的bean?
      

  2.   

    你理解错了,我的意思是说,前台每调一次webservice,后台读配置文件
      

  3.   

    用 static 关键字可以解决重复读配置文件的问题,
    但是这不是问题的关键
      

  4.   

    你的困难是不是
    在服务端提供webservice的那个类里,无法得到业务层的xxxService对象?所以每次都要去读配置文件得到一个context,然后再调用
    context.getBean('xxxService'),然后调用xxxService的相关业务方法
    -----------------------------
    可以这样
    public class JaxRpcHelloWorld extends ServletEndpointSupport implements IHelloWorld{ 
    private IHelloWorld helloWorld; protected void onInit() throws ServiceException { 
    //在Spring容器中获取Bean的实例 
    helloWorld = (IHelloWorld) getApplicationContext().getBean( 
    "helloWorld"); 
    } public String getMessage(String name) throws RemoteException { 
    //执行Bean中的相同的方法 
    return helloWorld.getMessage(name); 


    然后配置
    <service name="HelloWorld" provider="java:RPC"> 
    <parameter name="className" 
    value="com.test.www.webservice.JaxRpcHelloWorld"/> 
    <parameter name="allowedMethods" value="*"/> 
    </service>
      

  5.   

    其实你的困难应该是在webservice的环境里不能得到applicationContext吧,所以每次都通过配置文件去创建。
    也可以用servlet在初始化时把applictionContext保存在一个静态变量
    public class GetBeanServlet extends HttpServlet
    { private static final long serialVersionUID = -7672417781132478273L;
    private static WebApplicationContext context;
        
        public void init() throws ServletException{
            context=WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
        }
        
        public static Object getBean(String id){
            Object bean = context.getBean(id);
            return bean;
        }
    }
    然后就可以每次调用 GetBeanServlet.getBean('xxxService')了
      

  6.   

    谢谢  这位朋友的回答,这个集成的问题我已经解决了,
    现在又发现了一个新的问题:--->AXIS2中OMElement和Java对象之间的转换
    问题是这么回事:由于项目中引入了 hibernate,所以由 Hibernate 自动生成的 JavaBean中有 Set 属性(数据库中的主外键关系导致的)
    这是student实体类,由Hibernate自动生成的  public class Student implements java.io.Serializable {
    private Integer stuNo;
    private String stuName;
    private Integer stuAge;
    private String stuSex;
    private Set scores = new HashSet(0);
            //省略 getters   setters
      }
    我将该类的一个对象转换成 axis2 的 OMElement 可以成功转换,如果这个对象的属性都没有值时,转换成OMElement 为   <root:example xmlns:root="root"><Student type="com.wgy.persistence.entity.Student"><scores type="java.util.HashSet"><empty>true</empty></scores><stuAge xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" /><stuName xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" /><stuNo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" /><stuSex xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" /></Student></root:example>但是如果将这个转换过后的OMElement 转换为 javaBean时,就会抛出   java.lang.IllegalArgumentException: argument type mismatch
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.axis2.databinding.utils.BeanUtil.deserialize(BeanUtil.java:457)
    at org.apache.axis2.databinding.utils.BeanUtil.processObject(BeanUtil.java:722)
    at com.wgy.util.TypeConverter.toBeObject(TypeConverter.java:152)
    at com.wgy.client.ClientTestCase.main(ClientTestCase.java:27)这个异常,经过我的测试,我发现问题在于这个  set 属性的转换,如果我把  set 属性换成List就可以成功转换,但是要换成List的话,就要修改Hibernate 映射文件
    由于在Hibernate 中 List 是有序集合,所以在数据库表中还得另外提供一列,用来存储 List 中元素的索引,这样就要修改数据库   BeanUtil.processObject(ele, cls, null, true,new DefaultObjectSupplier());执行这个方法时,抛出上面的非法参数异常 ,怎么来解决这个不能转换set 的问题呢?各位
      

  7.   

    我遇到的集成问题其实和楼主是一致的:Axis2官网上提供的集成方法只适用与,先用代码做interface,然后根据代码生成WSDL,发布其WebService。而通常情况下,WebService开发的场景是:大家约定好WSDL和Schema,然后根据WSDL生成客户端或者服务端代码 。这种情况下,要使用现有的WSDL和反转过来的Java代码,如何集成到Spring里,是个问题
     
      

  8.   

    楼主怎么解决的集成问题? 我现在使用SCA生成webservice,用注解方式注入dao但是实现方法里的dao为空
      

  9.   

    由于本身这个实现方法是逆向生成的,并不是由spring进行管理的,所以使用注入的模式并不能得到结果,需要通过其他方式进行获取,如
    WebApplicationContext context=ContextLoader.getCurrentWebApplicationContext();
    UserService userService = (UserService)context.getBean("userServiceImpl");
    然后再去调取userService中的方法
      

  10.   


    不知到楼主这个问题解决了没有,最近我们在项目中也遇到了这个问题,通过获取list,到客户端时可以得到list的大小,但不能读出list中的值,报类型不匹配的错误