优缺点
有点:跨语言、跨平台
缺点:性能差
服务端代码
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<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>
接口类
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.WebServiceProvider;
@WebService(name = "TestService", // 暴露服务名称
targetNamespace = "server.webservice.Bag.admin.com"// 命名空间,一般是接口的包名倒序
)
public interface TestService {
@WebMethod
public String sendMessage(@WebParam(name = "username") String username);
@WebMethod
public boolean getFlag(@WebParam(name = "username") String username);
}
- @WebMethod :operationName属性是方法名,客户端访问时需要用到,区分大小写
接口实现类
import com.admin.Bag.webservice.server.TestService;
import org.springframework.stereotype.Component;
import javax.jws.WebService;
@WebService(serviceName = "TestService", // 与接口中指定的name一致
targetNamespace = "server.webservice.Bag.admin.com", // 与接口中的命名空间一致,一般是接口的包名倒
endpointInterface = "com.admin.Bag.webservice.server.TestService"// 接口地址
)
@Component
public class TestServiceImpl implements TestService {
@Override
public String sendMessage(String username) {
return "=====Hello! " + username + "=====";
}
@Override
public boolean getFlag(String username) {
//
return true;
}
}
webservice配置文件
package com.webservice;
import com.webservice.impl.TestServiceImpl;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.xml.ws.Endpoint;
@Configuration
public class CxfConfig {
@Autowired
private TestService testService;
@Bean
public ServletRegistrationBean disServlet() {
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new CXFServlet(), "/webService/*");
return servletRegistrationBean;
}
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(springBus(), testService); // 如果服务中有用到spring容器中的对象,必须用注入进来的对象
endpoint.publish("/TestService");
return endpoint;
}
}
启动项目,访问时路径为项目根目录加上ServletRegistrationBean的配置的拦截路径,加上@WebService的值,http://localhost:8080/webService/TestService?wsdl
或者直接访问http://localhost:8080/webService可以看到有哪些暴露服务
客户端访问时会用到targetNamespace 属性的值加上@WebMethod注解的operationName属性值,如果operationName不填默认为所在方法名
客户端开发
依赖
<!-- 进行jaxes 服务开发 -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.0.1</version>
</dependency>
<!-- 内置jetty web服务器 -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.0.1</version>
</dependency>
测试
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
public class WebserviceTest {
public static void main(String[] args) throws Exception{
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("http://localhost:8080/webService/TestService?wsdl");
//client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME, PASS_WORD));
Object[] objects;
// invoke("方法名",参数1,参数2,参数3....);
objects = client.invoke("sendMessage", "1111");
System.out.println(objects[0].toString());
}
}
开发中要注意的
- springboot版本2.3.2
- 接口和实现类的@WebService的targetNamespace 属性一定要有值且一致,一开始我注释掉,虽然用soupUI可以访问,但是用客户端代码访问报
No operation was found with the name
was not recognized. (Does it exist in service WSDL?)
此异常是因为客户端和服务端的命名空间和方法名不一致
转载:https://blog.csdn.net/qq_43842093/article/details/123076587