我用的springboot版本的是2.1.3
org.springframework.boot
spring-boot-starter-parent
2.1.3.RELEASE
org.apache.cxf
cxf-spring-boot-starter-jaxws
3.2.5
2.服务端声明接口
@WebService(name = "CommonService", // 暴露服务名称
targetNamespace = "http://webservice.leftso.com/"// 命名空间,一般是接口的包名倒序
)
public interface CommonService {
@WebMethod
@WebResult(name = "String", targetNamespace = "")
public String sayHello(@WebParam(name = "userName") String name);
}
3.接口实现类
@WebService(serviceName = "CommonService", // 与接口中指定的name一致
targetNamespace = "http://webservice.leftso.com/", // 与接口中的命名空间一致,一般是接口的包名倒
endpointInterface = "com.ljw.CommonService"// 接口地址
)
@Component
public class CommonServiceImp implements CommonService {
public String sayHello(String name) {
return "hello:::"+name;
}
}
4.webserivce配置类
@Configuration
public class CXFConfig {
@Autowired
private Bus bus;
@Autowired
CommonService commonService;
//一定要有
@Bean
public ServletRegistrationBean cxfServlet(){
return new ServletRegistrationBean(new CXFServlet(),"/services/*");
}
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(bus, commonService);
endpoint.publish("/CommonService");
endpoint.getInInterceptors().add(new ClientLoginInterceptor());
endpoint.getInInterceptors().add(new AuthInterceptor());
return endpoint;
}
}
5.服务端针对客户端请求时需要密码认证
/**
* 发布服务端,定义拦截器用户用户验证
*/
public class AuthInterceptor extends AbstractPhaseInterceptor {
private static final Logger logger = LoggerFactory.getLogger(AuthInterceptor.class);
private SAAJInInterceptor saa = new SAAJInInterceptor();
private static final String USER_NAME = "admin";
private static final String USER_PASSWORD = "123456";
public AuthInterceptor() {
super(Phase.PRE_PROTOCOL);
getAfter().add(SAAJInInterceptor.class.getName());
}
@Override
public void handleMessage(SoapMessage message) throws Fault {
SOAPMessage mess = message.getContent(SOAPMessage.class);
if(mess==null){
saa.handleMessage(message);
mess=message.getContent(SOAPMessage.class);
}
SOAPHeader header =null;
try {
header = mess.getSOAPHeader();
} catch (SOAPException e) {
logger.error("getSOAPheader error:{}",e.getMessage(),e);
e.printStackTrace();
}
if(header==null){
throw new Fault(new IllegalAccessException("找不到Header,无法验证用户信息"));
}
NodeList username = header.getElementsByTagName("username");
NodeList password = header.getElementsByTagName("password");
if(username.getLength()<1){
throw new Fault(new IllegalAccessException("找不到Header,无法验证用户信息"));
}
if(password.getLength()<1){
throw new Fault(new IllegalAccessException("找不到Header,无法验证用户信息"));
}
String userName = username.item(0).getTextContent().trim();
String passWord = password.item(0).getTextContent().trim();
if(USER_NAME.equals(userName)&&USER_PASSWORD.equals(passWord)){
logger.debug("admin auth success");
}else {
SOAPException soapException = new SOAPException("认证错误");
logger.debug("admin auth failed");
throw new Fault(soapException);
}
}
}
6.客户端请求时认证
public class ClientLoginInterceptor extends AbstractPhaseInterceptor {
private String username;
private String password;
public ClientLoginInterceptor() {
super(Phase.PREPARE_SEND);
}
public ClientLoginInterceptor(String username, String password) {
//super();
super(Phase.PREPARE_SEND);
this.username = username;
this.password = password;
}
@Override
public void handleMessage(SoapMessage soap) throws Fault {
List headers = soap.getHeaders();
Document doc = DOMUtils.createDocument();
Element auth = doc.createElement("authrity");
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("timamaes"), auth));
}
}
7.客户端测试调用
public class CxfClient {
private static String USER_NAME="admin";
private static String PASS_WORD="123456";
public static void main(String[] args) {
//cl1();
System.out.println("---------------调用时加入用户名,密码认证--------------");
cl2();
}
/**
* 方式1.代理类工厂的方式,需要拿到对方的接口
*/
public static void cl1() {
try {
// 接口地址
String address = "http://localhost:9090/services/CommonService?wsdl";
// 代理工厂
JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
// 设置代理地址
jaxWsProxyFactoryBean.setAddress(address);
// 设置接口类型
jaxWsProxyFactoryBean.setServiceClass(CommonService.class);
// 创建一个代理接口实现
CommonService cs = (CommonService) jaxWsProxyFactoryBean.create();
// 数据准备
String userName = "你好你好你好";
// 调用代理接口的方法调用并返回结果
String result = cs.sayHello(userName);
System.out.println("返回结果:" + result);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 动态调用方式
*/
public static void cl2() {
// 创建动态客户端
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("http://localhost:9090/services/CommonService?wsdl");
// 需要密码的情况需要加上用户名和密码
client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME, PASS_WORD));
Object[] objects = new Object[0];
try {
// invoke("方法名",参数1,参数2,参数3....);
objects = client.invoke("sayHello", "你好你好你好你好");
System.out.println("返回数据:" + objects[0]);
} catch (java.lang.Exception e) {
e.printStackTrace();
}
}
}
你成功了!!!