1、POM.xml文件引入相关的依赖包
4.0.0 net.logcd springboot_wscxf 1.0.0 jar springboot_wscxf org.springframework.boot spring-boot-starter-parent 1.5.8.RELEASE UTF-8 UTF-8 1.7 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-web-services org.apache.cxf cxf-rt-frontend-jaxws 3.1.6 org.apache.cxf cxf-rt-transports-http 3.1.6 org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin
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{ 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 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{ 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 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]); } }