延申第一章:WebService初探

webService

引言

WebService 是一个SOA的架构,它是不依赖语言,不依赖平台,可以实现不同语言间的相互调用,通过Internet进行基于Http协议的网络应用间的交互,Webservice可以让你的网站使用其他网站的资源。

实例

服务端

  • 导入依赖
 <!--webservice-->
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web-services</artifactId>
 </dependency>
 <!--CXF webservice-->
 <dependency>
     <groupId>org.apache.cxf</groupId>
     <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
     <version>3.2.7</version>
 </dependency>
 <dependency>
     <groupId>org.apache.cxf</groupId>
     <artifactId>cxf-rt-transports-http</artifactId>
     <version>3.2.7</version>
 </dependency>
 <dependency>
     <groupId>org.hibernate.validator</groupId>
     <artifactId>hibernate-validator</artifactId>
 </dependency>
  • 创建服务接口以及实现类
@WebService(name="ServerServiceDemo",targetNamespace = "http://server.webservice.example.com")
public interface SeverServiceDemo {

    String demoService(@WebParam String data);

}
@Component
@WebService(name="ServerServiceDemo",targetNamespace = "http://server.webservice.example.com")
public class ServerServiceImpl implements SeverServiceDemo{

    @Override
    public String demoService(@WebParam String data) {
        if(null==data || "".equals(data.trim())){
            return "传入参数为空";
        }
        return "调用成功";
    }
}

上述代码各注解的意思:

  • webservice 注解表明是一个webservice服务。
    • name:对外发布的服务名,对应<wsdl:portType name=“XXXX”></wsdl:portType>
    • targetNameSpace:命名空间
    • endpointInterface:服务接口全路径
    • serviceName
    • portName
  • WebMethod 表示暴露的服务方法,这里有接口
    • operationName :接口的方法名
    • action
    • exclude:默认为false,用于组织将某一继承方法公开为webservice服务
  • WebResult 表示方法的返回值
    • name:返回值的名称
    • partName
    • targetNameSpace
    • header:默认为false
  • WebParam
    • name:接口的参数
    • partname:
    • targetNameSpace:
    • header:默认为false
    • model

接口发布类

@Configuration
public class WebServiceConfig {
   // private Bus bus;
    @Autowired
    private SeverServiceDemo severServiceDemo;
    /*@Bean
    public ServletRegistrationBean disServlet(){
        return new ServletRegistrationBean(new CXFServlet() , "/webservice/*");
    }*/

    /*public WebServiceConfig(Bus bus,SeverServiceDemo severServiceDemo) {
        this.bus = bus;
        this.severServiceDemo=severServiceDemo;
    }*/

    @Bean(name = Bus.DEFAULT_BUS_ID)
    public SpringBus springBus() {
        return new SpringBus();
    }

    @Bean
    public Endpoint endpoint(){
        EndpointImpl endpoint = new EndpointImpl(springBus(), severServiceDemo);
        endpoint.publish("/demo/service");
        return endpoint;
    }

}

启动服务,

创建客户端,CXF的client调用

引入与服务端一样的依赖。

写个controller实现

@RestController
public class TestMain {
    public static void invokeMain(){
        // 创建动态客户端
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
        Client client = dcf.createClient("http://localhost:8080/services/ws/api?wsdl");
        // 需要密码的情况需要加上用户名和密码
        // client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME, PASS_WORD));
        Object[] objects = new Object[0];
        try {
            // invoke("方法名",参数1,参数2,参数3....);
            //这里注意如果是复杂参数的话,要保证复杂参数可以序列化
            objects = client.invoke("demoService", "hello world");
            System.out.println("返回数据:" + objects[0]);
        } catch (java.lang.Exception e) {
            e.printStackTrace();
        }

    }
    @RequestMapping("/invoke/test")
    public String invokeController(){
        this.invokeService_2();
        return "测试完毕";
    }
}

创建客户端,Axis的Call调用

public static void invokeAxis(){
        try{
            String endpoint="http://localhost:8080/services/ws/api";
            Service service = new Service();
            Call call = (Call) service.createCall();
            call.setTargetEndpointAddress(endpoint);
            String data="hello world";
            call.setOperationName(new QName("http://server.webservice.example.com","demoService"));
            call.addParameter("data", null, javax.xml.rpc.ParameterMode.IN);
            call.setReturnClass(String.class);
            String invoke = (String) call.invoke(new Object[]{ data });
            System.out.println("调用结束:"+invoke);
        } catch (ServiceException | RemoteException e) {
            e.printStackTrace();
        }
    }

之前出现了很多地址不对应的问题,其中听信了网上方法上也要加targetnamespace的模板,然后踩坑了,其中删了就行了,

然后我看还有百度上一些参数问题,一般都是不对应的问题,要在webParam上添加name属性,其次,最好使用

image-20201224161331850也可以起到一定的解除bug的效果。

posted @ 2020-12-24 16:17  且I听  阅读(92)  评论(0)    收藏  举报