用cxf+spring开发web service

骑猪看日落 2022-08-07 00:24 280阅读 0赞

环境:
cxf-2.1.3,jdk6,jboss7.0.2,spring3.0.6

用cxf+spring开发web service程序很简单,不过有一些集成问题要注意。在此把这几天发现的一些总结一下,最后有一个遗留的问题

1、关于bean的声明

要发布或者要调用的web service接口,需要用@WebService注解声明。不过要注意的是,@WebService注解不会把类声明为spring的bean

可以声明为bean的方式有以下4个:


@Component

写了一个类来证明这一点:


Xml代码 复制代码 收藏代码spinner.gif

1. <?xml version=”1.0” encoding=”UTF-8”?>
2.
3.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.

22.
23.
25.
26.
29.
30.


<?xml version=”1.0” encoding=”UTF-8”?>











  1. <jaxws:endpoint id="helloWorld" address="/HelloWorld"
  2. implementor="#helloWorldImpl" />
  3. <jaxws:client id="remedy"
  4. serviceClass="com.huawei.remedy.webservice.RemedyWebServiceCM"
  5. address="http://10.78.229.199:8080/remedy/webservice/RemedyWebService" />
  6. </beans>

Java代码 复制代码 收藏代码spinner.gif

  1. protected void doGet(HttpServletRequest request,
  2. HttpServletResponse response) throws ServletException, IOException {
  3. ServletContext context = request.getServletContext();
  4. WebApplicationContext wc = WebApplicationContextUtils
  5. .getWebApplicationContext(context);
  6. String[] beans = wc.getBeanDefinitionNames();
  7. for (String beanName : beans) {
  8. System.out.println(beanName);
  9. }
  10. RemedyWebServiceCM remedy = (RemedyWebServiceCM) wc.getBean(“remedy”);
  11. AcknowledgeRequest message = new AcknowledgeRequest();
  12. remedy.acknowledge(message);
  13. }

    protected void doGet(HttpServletRequest request,

    1. HttpServletResponse response) throws ServletException, IOException {
    2. ServletContext context = request.getServletContext();
    3. WebApplicationContext wc = WebApplicationContextUtils
    4. .getWebApplicationContext(context);
    5. String[] beans = wc.getBeanDefinitionNames();
    6. for (String beanName : beans) {
    7. System.out.println(beanName);
    8. }
    9. RemedyWebServiceCM remedy = (RemedyWebServiceCM) wc.getBean("remedy");
    10. AcknowledgeRequest message = new AcknowledgeRequest();
    11. remedy.acknowledge(message);
    12. }

在控制台可以看到以下几个bean:
20:02:24,120 INFO [stdout] (http—0.0.0.0-8888-2) helloWorldImpl
20:02:24,120 INFO [stdout] (http—0.0.0.0-8888-2) helloWorld
20:02:24,120 INFO [stdout] (http—0.0.0.0-8888-2) remedy

以上3个bean,就分别是由生成的

2、如果要在的实现类中注入bean的话,要注意:

错误的写法:

Xml代码 复制代码 收藏代码spinner.gif

  1. <jaxws:endpoint id=”helloWorld” address=”/HelloWorld”
  2. implementor=”com.huawei.framework.webservice.HelloWorldImpl” />

用这种写法,虽然HelloWorldImpl类已经被声明成bean了,但是注入是失败的

准确来说,在spring容器中存在有HelloWorldImpl对应的bean,并且相关的依赖也已经注入了。但是cxf框架得到的HelloWorldImpl,与上述的bean不是同一个对象,这个HelloWorldImpl对象可能是用反射或者其他机制创建出来的,没有任何组件被注入

正确的写法:

Xml代码 复制代码 收藏代码spinner.gif

  1. <jaxws:endpoint id=”helloWorld” address=”/HelloWorld”
  2. implementor=”#helloWorldImpl” />

在implementor属性中,用#beanName,这样的话,cxf框架得到的HelloWorldImpl,就是spring容器持有的那个bean。当然这有个前提,就是系统中已经存在这个bean。用或者@Component都是OK的,这里支持注解

3、上面说的是,比较简单。但是就比较麻烦

我目前感觉,声明的bean,没办法在别的bean里用@Autowired注入,只能用的方式来注入

Java代码 复制代码 收藏代码spinner.gif

  1. @WebService
  2. public interface RemedyWebServiceCM {
  3. RemedyResponse acknowledge(AcknowledgeRequest arg0);
  4. RemedyResponse close(CloseRequest arg0);
  5. RemedyResponse notify(NotifyRequest arg0);
  6. }

    @WebService
    public interface RemedyWebServiceCM {

    1. RemedyResponse acknowledge(AcknowledgeRequest arg0);
    2. RemedyResponse close(CloseRequest arg0);
    3. RemedyResponse notify(NotifyRequest arg0);

    }

Java代码 复制代码 收藏代码spinner.gif

  1. public class HelloWorldImpl implements HelloWorld {
  2. private RemedyWebServiceCM remedy;
  3. public String sayHi(User theUser) {
  4. AcknowledgeRequest message = new AcknowledgeRequest();
  5. remedy.acknowledge(message);
  6. return “Hello “ + theUser.getName() + “ ,your age is “
  7. + theUser.getAge();
  8. }
  9. public void setRemedy(RemedyWebServiceCM remedy) {
  10. this.remedy = remedy;
  11. }
  12. }

    public class HelloWorldImpl implements HelloWorld {

    1. private RemedyWebServiceCM remedy;
    2. public String sayHi(User theUser) {
    3. AcknowledgeRequest message = new AcknowledgeRequest();
    4. remedy.acknowledge(message);
    5. return "Hello " + theUser.getName() + " ,your age is "
    6. + theUser.getAge();
    7. }
    8. public void setRemedy(RemedyWebServiceCM remedy) {
    9. this.remedy = remedy;
    10. }

    }

Xml代码 复制代码 收藏代码spinner.gif

  1. <?xml version=”1.0” encoding=”UTF-8”?>
  2. <beans xmlns=”http://www.springframework.org/schema/beans“
  3. xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance“ xmlns:jaxws=”http://cxf.apache.org/jaxws“
  4. xmlns:context=”http://www.springframework.org/schema/context“
  5. xsi:schemaLocation=”http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  7. http://www.springframework.org/schema/context
  8. http://www.springframework.org/schema/context/spring-context-3.0.xsd
  9. http://cxf.apache.org/jaxws
  10. http://cxf.apache.org/schemas/jaxws.xsd">
  11. <jaxws:endpoint id=”helloWorld” address=”/HelloWorld”
  12. implementor=”#helloWorldImpl” />
  13. <jaxws:client id=”remedy”
  14. serviceClass=”com.huawei.remedy.webservice.RemedyWebServiceCM”
  15. address=”http://10.78.229.199:8080/remedy/webservice/RemedyWebService“ />
  16. <?xml version=”1.0” encoding=”UTF-8”?>

















用这种的方式就可以

Java代码 复制代码 收藏代码spinner.gif

  1. @Controller
  2. public class HelloWorldImpl implements HelloWorld {
  3. @Autowired
  4. private RemedyWebServiceCM remedy;
  5. public String sayHi(User theUser) {
  6. AcknowledgeRequest message = new AcknowledgeRequest();
  7. remedy.acknowledge(message);
  8. return “Hello “ + theUser.getName() + “ ,your age is “
  9. + theUser.getAge();
  10. }
  11. }

    @Controller
    public class HelloWorldImpl implements HelloWorld {

    1. @Autowired
    2. private RemedyWebServiceCM remedy;
    3. public String sayHi(User theUser) {
    4. AcknowledgeRequest message = new AcknowledgeRequest();
    5. remedy.acknowledge(message);
    6. return "Hello " + theUser.getName() + " ,your age is "
    7. + theUser.getAge();
    8. }

    }

Xml代码 复制代码 收藏代码spinner.gif

  1. <?xml version=”1.0” encoding=”UTF-8”?>
  2. <beans xmlns=”http://www.springframework.org/schema/beans“
  3. xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance“ xmlns:jaxws=”http://cxf.apache.org/jaxws“
  4. xmlns:context=”http://www.springframework.org/schema/context“
  5. xsi:schemaLocation=”http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  7. http://www.springframework.org/schema/context
  8. http://www.springframework.org/schema/context/spring-context-3.0.xsd
  9. http://cxf.apache.org/jaxws
  10. http://cxf.apache.org/schemas/jaxws.xsd">
  11. <jaxws:endpoint id=”helloWorld” address=”/HelloWorld”
  12. implementor=”#helloWorldImpl” />
  13. <jaxws:client id=”remedy”
  14. serviceClass=”com.huawei.remedy.webservice.RemedyWebServiceCM”
  15. address=”http://10.78.229.199:8080/remedy/webservice/RemedyWebService“ />
  16. <?xml version=”1.0” encoding=”UTF-8”?>













用@Autowired加@Component的方式来做,就不行,报以下异常:

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.huawei.remedy.webservice.RemedyWebServiceCM com.huawei.framework.webservice.HelloWorldImpl.remedy; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.huawei.remedy.webservice.RemedyWebServiceCM] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508) [org.springframework.beans-3.0.6.RELEASE.jar:]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84) [org.springframework.beans-3.0.6.RELEASE.jar:]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285) [org.springframework.beans-3.0.6.RELEASE.jar:]
… 21 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.huawei.remedy.webservice.RemedyWebServiceCM] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:924) [org.springframework.beans-3.0.6.RELEASE.jar:]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:793) [org.springframework.beans-3.0.6.RELEASE.jar:]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707) [org.springframework.beans-3.0.6.RELEASE.jar:]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480) [org.springframework.beans-3.0.6.RELEASE.jar:]
… 23 more

说自动注入失败,因为找不到RemedyWebServiceCM类型的bean

试了很久,完全搞不定。也想不通是为啥,因为RemedyWebServiceCM这个类型的bean,明明已经用声明了,而且用配置文件的方式也是能搞定的

发表评论

表情:
评论列表 (有 0 条评论,280人围观)

还没有评论,来说两句吧...

相关阅读

    相关 使用Axis开发Web Service程序

    今天是感恩节,差点又要在公司加班了。好在Web Service程序并不是特别难搞,下午终于在eclipse下调通过了,正确产生了服务器端和客户端的Java代码,apache的东