参照上一篇博文 基于HTTPS的webservice 的环境搭建step by step
完成所需环境之后,就可以开始接下来的著名项目HelloWorld了。
1. 建立一个helloworld的web项目
2. 创建SEI
package com.harvey.services;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
@WebService(targetNamespace="http://webservice.harvey.com")
public interface HelloWorldInf {
public String sayHello(@WebParam(name="name")String name);
}
通过@WebService注解将该接口声明为webservice
3. 创建SIB
package com.harvey.services;
import javax.jws.WebService;
@WebService(endpointInterface="com.harvey.services.HelloWorldInf",
targetNamespace="http://webservice.harvey.com")
public class HelloWorldImpl implements HelloWorldInf {
public String sayHello(String name) {
return "hello,"+name;
}
}
这个类功能虽然很强大,但是应该比较容易看懂,就是向调用者打招呼。
4. 建立鉴权的handler
package com.harvey.services;
import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
public class ServerPasswordCallback implements CallbackHandler {
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
String pw = pc.getPassword();
String idf = pc.getIdentifier();
if (!"harvey".equals(idf) || !"123456".equals(pw)) {
throw new SecurityException("鉴权失败!");
}
}
}
5. 通过spring整合
通过spring发布helloworld服务并为服务添加鉴权的handler.
在web.xml的配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
为了方便直接在src目录下建立applicationContext.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:cxf="http://cxf.apache.org/core"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="hello" class="com.harvey.services.HelloWorldImpl" />
<jaxws:endpoint id="helloworldservice"
endpointName="e:helloWorldPointName"
serviceName="s:helloworldservice"
implementor="#hello"
address="/helloworld"
xmlns:e="http://webservice.harvey.com/endponit"
xmlns:s="http://webservice.harvey.com/service">
<jaxws:inInterceptors>
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken" />
<entry key="passwordType"
value="PasswordText" />
<entry key="user" value="cxfServer" />
<entry key="passwordCallbackRef">
<ref bean="serverPasswordCallback" />
</entry>
</map>
</constructor-arg>
</bean>
</jaxws:inInterceptors>
</jaxws:endpoint>
<bean id="serverPasswordCallback" class="com.harvey.services.ServerPasswordCallback" />
</beans>
Server端的工作就这些了,结合我们在上一篇文章中提到的数字证书的环境,一个支持数字证书和鉴权的server端搭建完成了。
接下来我们在转到client端,看一下如何在client加入对数字证书以及鉴权的支持。
6. 创建client端的密码的handler
为了方便起见,我们不再为client独立创建功能,与service在同一项目下建立client端的回调类,为webservice的请求添加鉴权的头信息
import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
public class ClientPasswordCallback implements CallbackHandler {
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
pc.setPassword("123456");
pc.setIdentifier("Harvey");
}
}
7. 创建client的spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:cxf="http://cxf.apache.org/core"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:http="http://cxf.apache.org/transports/http/configuration"
xmlns:sec="http://cxf.apache.org/configuration/security"
xsi:schemaLocation="
http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="client" class="com.harvey.services.HelloWorldInf"
factory-bean="clientFactory" factory-method="create" />
<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="com.harvey.services.HelloWorldInf" />
<property name="address" value="https://localhost:8443/WebServiceDemo/services/helloworld" />
<property name="outInterceptors">
<list>
<ref bean="wss4jOut" />
</list>
</property>
</bean>
<bean id="wss4jOut" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken" />
<entry key="user" value="cxfClient" />
<entry key="passwordType" value="PasswordText" />
<entry key="passwordCallbackClass" value="com.harvey.services.ClientPasswordCallback" />
</map>
</constructor-arg>
</bean>
</beans>
8. 创建client端的测试类,并将上一篇 博文中生成的client.jks和truststore.jks添加到类目录下
package com.harvey.test;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.harvey.services.HelloWorldInf;
public class HelloWorldClient {
private final static String trustStore = "truststore.jks";
private final static String keyStore = "client.jks";
private final static String trustStorePass = "123456";
private final static String keyStorePass = "999999";
/**
* @param args
*/
public static void main(String[] args) throws Exception{
ApplicationContext context=new ClassPathXmlApplicationContext("client-bean.xml");
HelloWorldInf client = (HelloWorldInf)context.getBean("client");
Client proxy = ClientProxy.getClient(client);
HTTPConduit conduit = (HTTPConduit) proxy.getConduit();
TLSClientParameters tlsParams = conduit.getTlsClientParameters();
if (tlsParams == null) {
tlsParams = new TLSClientParameters();
}
tlsParams.setSecureSocketProtocol("SSL");
tlsParams.setKeyManagers(getKeyManagers());
tlsParams.setTrustManagers(getTrustManagers());
conduit.setTlsClientParameters(tlsParams);
String response = client.sayHello("han");
System.out.println(response);
}
private static TrustManager[] getTrustManagers() throws IOException {
try {
String alg = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory factory = TrustManagerFactory.getInstance(alg);
InputStream fp = HelloWorldClient.class.getResourceAsStream(trustStore);
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(fp, trustStorePass.toCharArray());
fp.close();
factory.init(ks);
TrustManager[] tms = factory.getTrustManagers();
return tms;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
}
return null;
}
private static KeyManager[] getKeyManagers() throws IOException {
try {
String alg = KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory factory = KeyManagerFactory.getInstance(alg);
InputStream fp = HelloWorldClient.class.getResourceAsStream(keyStore);
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(fp, keyStorePass.toCharArray());
fp.close();
factory.init(ks, keyStorePass.toCharArray());
KeyManager[] keyms = factory.getKeyManagers();
return keyms;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
}
return null;
}
}
9.现在就可以运行client端测试鉴权功能了。
本来想着认真解释一下代码,不过环境太吵,实在没法安静下来写,就算是抛砖引玉吧。
分享到:
相关推荐
在这个基于CXF的Web服务完整例子中,我们将深入探讨CXF的核心概念、配置、以及如何创建和调用Web服务。 1. **CXF框架介绍**:CXF,全称为"Code first eXtended Framework",最初由XFire项目发展而来,后与Apache ...
使用jdk1.6、cxf2.3和tomcat开发的一个关于验证码的webservice接口,主要实现对手机验证码的验证。
cxf WebService jar包
将CXF和Mybatis整合,可以创建一个基于Web服务的数据访问层。以下是整合步骤: 1. **创建服务接口**:定义一个Java接口,包含CRUD操作。 2. **创建服务实现**:实现该接口,并使用Mybatis的SqlSession执行SQL操作...
此"CXF Webservice Demo"是一个实例,展示了如何使用CXF来创建和消费Web服务。CXF允许开发者通过SOAP(简单对象访问协议)和RESTful(Representational State Transfer)接口进行通信,支持多种协议和绑定,如HTTP、...
实战Web+Service+with+CXF webservice快速入门 webservice快速入门
4. **Web服务**:理解SOAP协议,包括WSDL(Web Services Description Language)和XSD(XML Schema Definition),以及如何通过CXF实现基于SOAP的Web服务是非常重要的。 5. **集成**:如何将MyBatis的持久层操作与...
【CXF Webservice Demo】是基于Apache CXF框架的一个示例项目,用于演示如何使用CXF来创建和消费Web服务。Apache CXF是一个开源的Java框架,它允许开发者构建和集成Web服务,支持多种Web服务标准,如SOAP、RESTful ...
- **Spring-WS**:侧重于基于WSDL的第一类公民,而CXF支持更广泛的Web服务标准和协议。 6. **最佳实践** - **模块化设计**:将服务接口和实现分离,提高代码可维护性。 - **利用注解**:使用JAX-WS或JAX-RS注解...
**基于CXF的Web服务发布及访问** 在Java开发中,Apache CXF是一个广泛使用的开源框架,用于构建和实现Web服务。本教程将详细介绍如何利用CXF发布基于SOAP 1.2的Web服务,以及如何进行客户端调用。首先,我们需要...
【标题】"maven项目 cxf webservice"指的是使用Maven构建的一个项目,该项目集成了Apache CXF框架来开发Web服务。Apache CXF是一个开源的Java框架,它允许开发者创建和消费各种Web服务,包括SOAP和RESTful服务。...
C#动态调用CXF WEBSERVICE框架共通类。
在这个主题中,我们将深入探讨CXF WebService所需的最小jar包集合,以及如何利用这些库来开发Web服务。 首先,CXF的核心功能依赖于一系列的jar包,这些jar包包含了处理不同协议、数据绑定、WS-Security等关键组件的...
CXF WebService整合Spring代码(包含服务,客户端两个工程 和 文档) 需要视频的话,留邮箱
使用cxf webservice时容易出现的异常
### 基于CXF的WebService接口开发及调用步骤详解 #### 一、概述 在当前企业级应用开发中,服务化与微服务架构逐渐成为主流趋势,而WebService作为一种跨语言、跨平台的服务交互方式,在众多场景下仍然发挥着重要...
本示例工程是基于CXF框架构建的一个Webservice应用,该应用集成了Spring框架,以实现更高效的服务管理和依赖注入。CXF是一个开源的Web服务框架,它允许开发者创建和部署SOAP和RESTful服务,同时也支持WS-*标准,如...
本文将深入探讨基于Apache CXF实现的Web Service在本地数据交互中的应用,尤其是如何在PC端与Android端之间进行通信。Apache CXF是一个开源框架,专门用于构建和消费Web服务,支持多种协议和标准,如SOAP、RESTful等...
【CXF Webservice初学笔记】 在IT行业中,Web服务是一种允许不同系统之间进行通信和交换数据的方法。Apache CXF是一个流行的开源框架,用于构建和部署Web服务。本笔记将探讨CXF Webservice的基础知识,包括其核心...
根据提供的文件内容,以下知识点是关于基于Apache CXF实现WebService开发的详细说明: Apache CXF是一个开源服务框架,它使得创建和开发WebService变得简单。CXF提供了完整的WebService功能,包括对JAX-WS的支持...