服务端
1.首先在pom导入依赖包
<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>
2.建立WebService接口
package com.sinqi.webService;
import javax.jws.WebService;
@WebService(name="DemoService" , // 暴露的服务名
targetNamespace = "http://webService.sinqi.com" //命名空间,设置为接口的包名倒写(默认是本类包名倒写)
)
public interface DemoService {
//做两个测试的接口,一个带参数,一个不带参数。
public String sayHello(String user);
public String sayBye();
}
3.建立WebService接口的实现类
package com.sinqi.webService;
import java.util.Date;
import javax.jws.WebService;
@WebService(serviceName="DemoService" , //与接口的服务名一致
targetNamespace="http://webService.sinqi.com", // 与接口空间 命名一致
endpointInterface="com.sinqi.webService.DemoService" // 接口地址
)
public class DemoServiceImpl implements DemoService {
@Override
public String sayHello(String user) {
// TODO Auto-generated method stub
return user+",现在时间:"+"("+new Date()+")";
}
@Override
public String sayBye() {
// TODO Auto-generated method stub
return "haha---BayBay";
}
}
4.建立config类
package com.sinqi.config;
import javax.xml.ws.Endpoint;
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 com.sinqi.Interceptor.AuthInterceptor;
import com.sinqi.webService.DemoServiceImpl;
@Configuration
public class Cxfconfig {
@Bean
public ServletRegistrationBean dispatcherServlet1() {
// 这个方法名报错了,查了一下解决办法就是改个名,随便加个1就行了。
//接口路径,可根据实际情况自定义
return new ServletRegistrationBean(new CXFServlet(),"/demo/*");
}
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
// 此方法为每一个接口的实现类都创建一个
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(springBus(), new DemoServiceImpl());
endpoint.getInInterceptors().add(new AuthInterceptor()) ; //// 添加自己的拦截器,做认证之前可以先注掉。
endpoint.publish("/api");
return endpoint;
}
}
至此接口服务端已经可以运行了

5.建立一个拦截器
package com.sinqi.Interceptor;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.NodeList;
public class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
Logger logger = LoggerFactory.getLogger(this.getClass());
private SAAJInInterceptor saa = new SAAJInInterceptor();
private static final String USERNAME="root";
private static final String PASSWORD="admin";
public AuthInterceptor() {
super(Phase.PRE_PROTOCOL);
// TODO Auto-generated constructor stub
getAfter().add(SAAJInInterceptor.class.getName());
}
@Override
public void handleMessage(SoapMessage arg0) throws Fault {
// TODO Auto-generated method stub
SOAPMessage soap = arg0.getContent(SOAPMessage.class);
String userName = null ;
String passWord = null ;
if(soap == null ) {
saa.handleMessage(arg0);
soap=arg0.getContent(SOAPMessage.class);
}
SOAPHeader header = null ;
try {
header=soap.getSOAPHeader();
} catch (SOAPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(header==null){
throw new Fault(new IllegalAccessException("找不到Header,无法验证用户信息"));
}
NodeList username = header.getElementsByTagName("username");
NodeList password = header.getElementsByTagName("password");
userName = username.item(0).getTextContent().trim();
passWord = password.item(0).getTextContent().trim();
if(!(userName.equals(USERNAME)&& passWord.equals(PASSWORD))) {
SOAPException soapExc = new SOAPException("认证失败");
logger.debug("用户认证信息错误");
throw new Fault(soapExc);
}
}
}
然后不要忘记把config里的拦截器注释取消。
客户端
1.建立客户端的拦截器类通过服务端的拦截器
package com.sinqi.client;
import java.util.List;
import javax.xml.namespace.QName;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class LoginInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
private String USERNAME="root";
private String PASSWORD = "admin";
public LoginInterceptor(String username,String password) {
super(Phase.PREPARE_SEND);
this.USERNAME=username;
this.PASSWORD=password ;
// TODO Auto-generated constructor stub
}
@Override
public void handleMessage(SoapMessage message) throws Fault {
// TODO Auto-generated method stub
List<Header> headers = message.getHeaders();
Document doc = DOMUtils.createDocument();
Element auth = doc.createElementNS("http://serve.my.com","DemoService"); // DemoService:命名空间
Element username = doc.createElement("username");
Element password = doc.createElement("password");
username.setTextContent(this.USERNAME);
password.setTextContent(this.PASSWORD);
auth.appendChild(username);
auth.appendChild(password);
headers.add(0, new Header(new QName("identification"), auth));
}
}
2.客户端测试类
package com.sinqi.client;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import com.sinqi.webService.DemoService;
public class CxfClient {
public static void main(String[] args) {
CxfClient.main2();
}
///方式1:使用代理类工厂,需要拿到对方的接口
public static void main1() {
try {
//接口地址
String address = "http://localhost:8082/demo/api?wsdl" ;
//代理工厂
JaxWsProxyFactoryBean jwpfb = new JaxWsProxyFactoryBean();
//设置代理地址
jwpfb.setAddress(address);
//添加拦截器认证
jwpfb.getOutInterceptors().add(new LoginInterceptor("root", "admin"));
//设置接口类型
jwpfb.setServiceClass(DemoService.class);
//创建一个代理接口实现
DemoService ds = (DemoService) jwpfb.create();
String user = "我是世界之王!!!!" ;
String result = ds.sayHello(user);
System.out.println(result);
String res2 = ds.sayBye();
System.out.println(res2);
}catch (Exception e) {
e.printStackTrace();
}
}
////动态调用方式
public static void main2() {
// 创建动态用户
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("http://localhost:8082/demo/api?wsdl");
// 需要密码的情况需要加上用户名密码
LoginInterceptor loginInt = new LoginInterceptor("root", "admin");
client.getOutInterceptors().add(loginInt);
Object[] objects = new Object[0];
try {
objects = client.invoke("sayHello", "世界之王");
System.out.println(objects[0]);
objects = client.invoke("sayBye", "");
System.out.println(objects[0]);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
本文详细介绍如何使用Spring Boot和Apache CXF构建WebService服务端与客户端,包括依赖配置、接口定义及其实现、配置类编写等步骤,并实现了基本的认证拦截。
1898

被折叠的 条评论
为什么被折叠?



