Webservice详解

什么是Webservice

WebService是一个SOA(面向服务的编程)的架构,它是不依赖于语言,不依赖于平台,可以实现不同的语言间的相互调用,通过Internet进行基于Http协议的网络应用间的交互。 其实WebService并不是什么神秘的东西,它就是一个可以远程调用的类,或者说是组件,把你本地的功能开放出去共别人调用。

HttpClient和WebService的区别

二者都是调用对方服务接口,区别在于:

  1. HttpClient用来调用服务,它是模拟一个浏览器,发送Http的请求,服务器会返回请求的一个响应结果,Httpclient然后把响应的结果取出来。HttpClinet相当于一个客户端,使用Http协议调用系统中的方法或者接口。
  2. webService是使用soap协议而不是Http协议。

什么是soap协议

SOAP 是基于 XML 的简易协议,可使应用程序在 HTTP 之上进行信息交换。或者更简单地说:SOAP 是用于访问网络服务的协议。

SOAP 消息实列:

<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">

<soap:Header>
  ...
  ...
</soap:Header>

<soap:Body>
  ...
  ...
  <soap:Fault>
    ...
    ...
  </soap:Fault>
</soap:Body>

</soap:Envelope>

xml元素详解:https://www.runoob.com/soap/soap-intro.html

SpringBoot使用CXF集成WebService

添加依赖

       <!--cxf-->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>3.1.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>3.1.6</version>
        </dependency>

        <!--axis-->
        <dependency>
            <groupId>org.apache.axis</groupId>
            <artifactId>axis</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.axis</groupId>
            <artifactId>axis-jaxrpc</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>commons-discovery</groupId>
            <artifactId>commons-discovery</artifactId>
            <version>0.2</version>
        </dependency>

创建服务端接口

@WebService(name = "DemoWebService", // 暴露服务名称
        targetNamespace = "http://service.webservicedemo.example.com"// 命名空间,一般是接口的包名倒序
)
public interface  DemoWebService {

    String sayHello(String message);

}

服务端接口实现

@WebService(
        serviceName = "DemoService", // 与接口中指定的name一致
        targetNamespace = "http://service.webservicedemo.example.com", // 与接口中的命名空间一致,一般是接口的包名倒
        endpointInterface = "com.example.webservicedemo.service.DemoWebService" // 接口地址
)
public class DemoWebServiceImpl implements DemoWebService {
    @Override
    public String sayHello(String message) {
        return message+",现在时间:"+"("+new Date()+")";
    }
}

CXF配置

@Configuration
public class CxfConfig {

    @Bean
    public ServletRegistrationBean createServletRegistrationBean() {
        return new ServletRegistrationBean(new CXFServlet(),"/demo/*");
    }

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

    @Bean
    public DemoWebService demoService() {
        return new DemoWebServiceImpl();
    }

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

}

启动SpringBoot服务

输入http://localhost:8090/demo/api?wsdl即可

使用单元测试模拟客户端

方式一 使用cxf模拟请求

@SpringBootTest
class WebServiceDemoApplicationTests {

    @Test
    void contextLoads1() {

        //创建动态客户端
        JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance();
        Client client = factory.createClient("http://localhost:8090/demo/api?wsdl");
        // 需要密码的情况需要加上用户名和密码
        //client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME,PASS_WORD));
        HTTPConduit conduit = (HTTPConduit) client.getConduit();
        HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
        httpClientPolicy.setConnectionTimeout(2000);  //连接超时
        httpClientPolicy.setAllowChunking(false);    //取消块编码
        httpClientPolicy.setReceiveTimeout(120000);     //响应超时
        conduit.setClient(httpClientPolicy);
        //client.getOutInterceptors().addAll(interceptors);//设置拦截器
        try{
            Object[] objects = new Object[0];
            // invoke("方法名",参数1,参数2,参数3....);
            objects = client.invoke("sayHello", "xxx");
            System.out.println("返回数据:" + objects[0]);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

运行结果

方式二 使用axis模拟请求

@SpringBootTest
class WebServiceDemoApplicationTests {

    @Test
    void contextLoads2() throws ServiceException, RemoteException, MalformedURLException {
        Service service = new Service();
        Call call = (Call) service.createCall();

        call.setTargetEndpointAddress(new URL("http://localhost:8090/demo/api?wsdl"));
        call.setOperationName(new QName("http://service.webservicedemo.example.com","sayHello"));


//        call.setUseSOAPAction(true);
//        call.setSOAPActionURI("http://service.webservicedemo.example.com"+"sayHello");
        call.addParameter(new QName("http://service.webservicedemo.example.com", "message"), XMLType.XSD_STRING, ParameterMode.IN);
        call.setReturnType(XMLType.XSD_STRING);
        call.setTimeout(10000);
        call.setEncodingStyle("utf-8");
        //设置命名空间和需要调用的方法名

        Object invoke = call.invoke(new Object[]{"xxx"});
        System.out.println(invoke.toString());

    }
}

运行时,会报一个元素错误

意外的元素 (uri:&quot;http://service.webservicedemo.example.com&quot;, local:&quot;message&quot;)。所需元素为&lt;{}message&gt; 

需要暴露服务端的接口以及参数。

@WebService(name = "DemoWebService", // 暴露服务名称
        targetNamespace = "http://service.webservicedemo.example.com"// 命名空间,一般是接口的包名倒序
)
public interface  DemoWebService {
    //暴露接口 参数
    @WebMethod
    String sayHello(@WebParam(name = "message",targetNamespace = "http://service.webservicedemo.example.com") String message);

}

运行结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

答 案

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值