作者:jinnee5921_866 | 来源:互联网 | 2023-09-13 10:04
WebService的三个基本技术:1.SOAP--webService的基本通信协议,是一种规范,用来定义SOAP消息的xml格式2.WSDL--是一个用来描述We
Web Service的三个基本技术:
1.SOAP -- web Service的基本通信协议,是一种规范,用来定义SOAP消息的xml格式
2.WSDL -- 是一个用来描述Web服务和说明如何与Web服务通信的XML语言,
WSDL是Web Service的描述语言,用于描述Web Service的服务,接口绑定等,为用户提供详细的接口说明书
3.UUID -- 即统一描述,发现和集成协议,UUID实现了一组可公开访问的接口,通过这些接口,网络服务可以
以向服务信息库注册其服务信息,服务需求者可以找到分散在世界各地的网络服
(二)代理工厂,安全验证,数据绑定
代理工厂
1.服务端:ServerFactoryBean,JaxWsServerFactoryBean 用于服务端调用.前者针对POJO,后者针对JAX-WS,他们用于生成服务端的EndPoint,暴露出服务接口
2.客户端:ClientProxyFactoryBean,JaxWsProxyFactoryBean 用于客户端调用.前者针对POJO,后者针对JAX-WS,他用于在客户端生成Web Service的代理proxy
3.除了这些Factory,CXF客户端还有ClientFactoryBean,JaxWsClientFactoryBean,这两个Factory生成的不是Web Service的代理,而是一个Endpoint,提供一些更该机的功能.
安全验证
Apache WSS4J(WebService Security For Java) 实现了java语言的 WS-Security.WSS4J依赖于SAAJ.CXF中使用拦截器机制完成WSS4J功能的支持.只需要初始化WSS4JInInterceptor(对应还有一个WSS4JOutInterceptor)实例并添加相关信息即可.CXF2.1.x之后的版本可以完成SAAJInInterceptor(对应的一个SAAJOutInterceptor)拦截器的自动注册,否则需要再注册一下SAAJ拦截器.
1.在spring.xml中配置WSS4J输入拦截器
Xml代码
- <span style="font-family: YouYuan,幼圆,tahoma,arial,helvetica,sans-serif;"><bean id="wss4jInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
- <map>
- <entry key="xx" value="xx"/>
- map>
- bean>
- span>
在接口服务里面加入关系
Xml代码
- <span style="font-family: YouYuan,幼圆,tahoma,arial,helvetica,sans-serif;"><jaxws:inInterceptors>
- <ref bean="wss4jInInterceptor" />
- jaxws:inInterceptors>
- span>
下面是服务器端具体密码回调处理类,它负责接收并处理客户端提交的用户名和密码,这个方法没有返回值,显示,如果验证失败,抛出异常表示.
Java代码
- "font-family: YouYuan,幼圆,tahoma,arial,helvetica,sans-serif;">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.WSConstants;
- import org.apache.ws.security.WSPasswordCallback;
- import org.apache.ws.security.WSSecurityException;
-
- public class ServerPasswordCallbackHandler implements CallbackHandler {
-
- public final static String USER = "liu";
- public final static String PASSWORD = "lius";//设置用户名密码
- public void handle(Callback[] callbacks) throws IOException,
- UnsupportedCallbackException {
- WSPasswordCallback wspassCallback = (WSPasswordCallback) callbacks[0];
- System.out.println(wspassCallback.getIdentifier() + "\t"
- + wspassCallback.getPassword());
-
- if(WSConstants.PASSWORD_TEXT.equals(wspassCallback.getPasswordType())){
- if (wspassCallback.getIdentifier().equals(USER)
- && wspassCallback.getPassword().equals(PASSWORD)) {
- System.out.println(".................验证通过!");
- System.out.println(".................identifier = " + USER);
- System.out.println(".................password = " + PASSWORD);
- } else {
- throw new WSSecurityException("............未通过验证!");
- }
- } else {
- //密码使用MD5密文发送
- System.out.println(wspassCallback.getIdentifier());
- wspassCallback.setPassword(PASSWORD);
- }
- }
- }
-
2.客户端实现:在spring.xml中配置WSS4J输出拦截器
Xml代码
- <span style="font-family: YouYuan,幼圆,tahoma,arial,helvetica,sans-serif;"><bean id="wss4jOutInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
- <map>
- <entry key="xx" value="xx"/>
- map>
- bean>span>
在服务接口里加入关系
Xml代码
- <span style="font-family: YouYuan,幼圆,tahoma,arial,helvetica,sans-serif;"><jaxws:outInterceptors>
- <ref bean="wss4jOutInterceptor" />
- jaxws:outInterceptorsspan>
这里使用了WSS4J输出拦截器,因为要将用户名和密码输出到服务器进行验证处理.另外与服务端不同的是多了一个user参数初始化WSS4J的输出拦截器,用于初始化用户名,这是一个必选,稍后将在下面的客户端密码回调处理类进行重新设定值
Java代码
- "font-family: YouYuan,幼圆,tahoma,arial,helvetica,sans-serif;">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 ClientPasswordCallbackHandler implements CallbackHandler{
- public final static String USER = "liu";
- public final static String PASSWORD = "lius";//设置用户名密码
- public void handle(Callback[] callbacks) throws IOException,
- UnsupportedCallbackException {
- WSPasswordCallback wspassCallback = (WSPasswordCallback)callbacks[0];
- wspassCallback.setIdentifier(USER);
- wspassCallback.setPassword(PASSWORD);
- }
- }
-
然后我们访问这个web服务,从控制台查看日志,可以看到在SOAP信封的Header中包装了
数据绑定
1.JAXB绑定.JAXB是一套自动映射XML和JAVA 实例的开发接口和工具.如果Web Service发布的接口的参数类型时类,而且返回的类型是List,String等,这样发布的Web Service 与普通的java没区别,因为JAXB都支持.但是JAXB不能将一些java类型自然映射到XML表现形式,例如HashMap,或其他非JavaBean之类,例如接口,Map,这样就要定义一个适配器,使java类型自动适应.一般可以编写一个类继承XmlAdapter,以实现此抽象类的适配器,另外可以安装使用注释XmlJavaTypeAdapter的适配器
2.Aegis Databingding.Aegis是一个快速,基于STAX的数据绑定,他能使采用代码优先方式发布Web Service的情况更简单.Aegis支持接口,集合类,MAP和各种数据类型.也不需要注释,也不需要写适配器
(三)HelloWorld
准备工作
eclipse 3.6
tomcat 6
jdk 1.7
cxf 相关架包,spring相关架包,jdbc相关架包
创建一个工程,把架包添加到lib中
写一个接口
Java代码
- package com.cxf.test;
-
- import javax.jws.WebParam;
- import javax.jws.WebService;
-
- @WebService
- public interface HelloWorld {
- String zhuce(String username, String password);
- }
写一个实现
Java代码
- package com.cxf.test;
-
- import javax.jws.WebService;
-
-
-
-
-
- @WebService(endpointInterface ="com.cxf.test.HelloWorld",
- serviceName = "HelloWorld")
- public class HelloWorldImpl implements HelloWorld {
-
- public String zhuce(String username, String password) {
- String result = "";
- if(username.equals("admin")){
- result = "用户名已经存在";
- }
- else if (password.length() != 6) {
- result = "请输入6位数密码";
- }
- return result;
- }
- }
发布web service
Java代码
- package com.cxf.test;
-
- import javax.xml.ws.Endpoint;
-
- import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
-
- public class service {
-
- public static void startService() throws Exception{
-
-
- HelloWorldImpl hw = new HelloWorldImpl();
- JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean();
- factoryBean.setAddress("http://localhost:8080/cxf/HelloWorld");
- factoryBean.setServiceClass(HelloWorld.class);
- factoryBean.setServiceBean(hw);
- factoryBean.create();
- System.out.println("方法1");
-
-
-
-
-
- }
-
- public static void main(String[] args) throws Exception{
- startService();
- System.out.println("Web Service 发布成功");
- }
- }
在浏览器里面输入http://localhost:10080/cxf/HelloWorld?wsdl,就可以看见XML文件了,控制台打印 发布成功.
cxf+web service(四)cxf+spring集成
客户端
Java代码
- public class Client {
-
- private Client(){}
-
- public static void main(String[] args) {
- ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-client.xml");
- HelloWorld hw = (HelloWorld) context.getBean("client");
- String response = hw.zhuce("piter", "123456");
- System.out.println(response);
- }
- }
客户端配置文件,这里面配置代理工厂,地址,暴露的服务接口.这里也可以直接在客户端代码里面使用JaxWsProxyFactoryBean来发布
Java代码
- <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"/>
-
- "client" class="com.cxf.test.HelloWorld" factory-bean="clientFactory" factory-method="create" />
"clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
"serviceClass" value="com.cxf.test.HelloWorld" />
"address" value="http://localhost:8080/cxf/ws/HelloWorld" />
然后在spring.xml中加入接口的配置
Java代码
-
- <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"/>
-
- "helloWorld"
implementor="com.cxf.test.HelloWorldImpl"
address="/HelloWorld"/>
OK,最后在浏览器输入http://localhost:8080/cxf/ws,如下图,发布成功!