一、在服务器端的WebSerivce服务发布
1、POM.xml文件引入相关的依赖包
class="xml" name="code">
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.logcd</groupId>
<artifactId>springboot_wscxf</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>springboot_wscxf</name>
<description></description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.7</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、定义服务
@WebService(targetNamespace="http://cxf.logcd.net")
@Service("helloService")
public class HelloService{
public String sayHello(String user, String userData) {
return "hello," + user+"! userData = "+userData;
}
}
3、定义访问权限验证的拦截器
/**
* 校验(用户名、密码)拦截器
*/
public class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
private Logger logger = Logger.getLogger(this.getClass());
private static final String USERNAME = "admin";
private static final String PASSWORD = "admin";
public AuthInterceptor() {
// 定义在哪个阶段进行拦截
super(Phase.PRE_PROTOCOL);
}
@Override
public void handleMessage(SoapMessage soapMessage) throws Fault {
List<Header> headers = null;
String username = null;
String password = null;
try {
headers = soapMessage.getHeaders();
} catch (Exception e) {
logger.error("getSOAPHeader error: {}", e);
}
if (headers == null) {
throw new Fault(new IllegalArgumentException("找不到Header,无法验证用户信息"));
}
// 获取用户名,密码
for (Header header : headers) {
SoapHeader soapHeader = (SoapHeader) header;
Element e = (Element) soapHeader.getObject();
NodeList usernameNode = e.getElementsByTagName("username");
NodeList pwdNode = e.getElementsByTagName("password");
username = usernameNode.item(0).getTextContent();
password = pwdNode.item(0).getTextContent();
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
throw new Fault(new IllegalArgumentException("用户信息为空"));
}
}
// 校验用户名密码
if (!(username.equals(USERNAME) && password.equals(PASSWORD))) {
SOAPException soapExc = new SOAPException("认证失败");
logger.info("用户认证信息错误");
throw new Fault(soapExc);
}
}
}
4、发布webserive服务
/**
* 配置并发布WebService
*/
@Configuration
public class WSCxfConfig {
@Bean
public ServletRegistrationBean dispatcherServlet() {
//接口访问的过滤路径
return new ServletRegistrationBean(new CXFServlet(), "/cxf/*");
}
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
@Bean
public HelloService helloService() {
return new HelloService();
}
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(springBus(), helloService());
endpoint.getInInterceptors().add(new AuthInterceptor());//添加校验拦截器
endpoint.publish("/helloService");
return endpoint;
}
}
5、SpringBoot应用启动
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
二、客户端测试调用WebService
1、调用WebSerivce时,设置帐号密码的拦截器
/**
* 调用时添加用户名密码信息
*/
public class LoginInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
private String namespace = "http://cxf.cdmcs.com";
private String username = "admin";
private String password = "admin";
public LoginInterceptor(String username, String password) {
// 设置在发送请求前阶段进行拦截
super(Phase.PREPARE_SEND);
this.username = username;
this.password = password;
}
@Override
public void handleMessage(SoapMessage soapMessage) throws Fault {
List<Header> headers = soapMessage.getHeaders();
Document doc = DOMUtils.createDocument();
Element auth = doc.createElementNS(namespace, "SecurityHeader");
Element UserName = doc.createElement("username");
Element UserPass = doc.createElement("password");
UserName.setTextContent(username);
UserPass.setTextContent(password);
auth.appendChild(UserName);
auth.appendChild(UserPass);
headers.add(0, new Header(new QName("SecurityHeader"), auth));
}
}
2、客户端调用测试
public class TestClientCXFWS {
/**
* 动态调用方式
* @throws Exception
*/
@Test
public void invokeHelloService_WS() throws Exception {
//WSDL路径
String wsUrl = "http://127.0.0.1:8080/cxf/helloService?wsdl";
String nameSpace = "http://cxf.logcd.net";
//方法名
String method = "sayHello";
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient(wsUrl);
//需要密码的情况需要加上用户名和密码
client.getOutInterceptors().add(new LoginInterceptor("admin","admin"));
Endpoint endpoint = client.getEndpoint();
//endpoint.getService().getName().getNamespaceURI()
QName opName = new QName(nameSpace, method);
BindingInfo bindingInfo = endpoint.getEndpointInfo().getBinding();
//如果命名空间不对,需要重新寻找operationName
if (bindingInfo.getOperation(opName) == null) {
for (BindingOperationInfo operationInfo : bindingInfo.getOperations()) {
if (method.equals(operationInfo.getName().getLocalPart())) {
opName = operationInfo.getName();
break;
}
}
}
Object[] params = new Object[] {"Lucy","{time:"+new Date().toString()+"}"};
Object[] retArr = client.invoke(opName, params);
System.out.println(retArr[0]);
}
}