4.2. WebService请求深入分析

1). 分析WebService的WSDL文档结构

1.1). 实例截图

  <definitions>

    <types>

      <schema>

        <element>

    <message>

    <portType>

      <operation>

        <input>

        <output>

    <binding>

      <operation>

        <input>

        <output>

    <service>

      <port>

        binding属性

        <address>

1.2). 文档结构

<definitions>

  <types>

    <schema>

      <element>

  </types>

  <message>

    <part>

  </message>

  <portType>

    <operation>

      <input>

      <output>

  </portType>

  <binding>

    <operation>

      <input>

      <output>

  </binding>

  <service>

    <port>

      <address>

  </service>

</definitions>

1.3). 文档结构图

1.4). 重要标签的说明

  • types - 数据类型(标签)定义的容器,里面使用schema 

    •   定义了一些标签结构供message引用
  • message - 通信消息的数据结构的抽象类型化定义。
    •   引用types中定义的标签
  • operation - 对服务中所支持的操作的抽象描述,
    • 一个operation描述了一个访问入口的请求消息与响应消息对。
  • portType - 对于某个访问入口点类型所支持的操作的抽象集合,
    •   这些操作可以由一个或多个服务访问点来支持。
  • binding - 特定端口类型的具体协议和数据格式规范的绑定。
  • service- 相关服务访问点的集合
  • port - 定义为协议/数据格式绑定与具体Web访问地址组合的单个服务访问点。

2). 测试CXF支持的数据类型

  1. 基本类型

    – int,float,boolean等

  1. 引用类型

    – String

    – 集合:数组,List, Set, Map

    – 自定义类型   Student

    Jdk:不支持 map.

3). 一次Web service请求的流程

  一次web service请求的本质:

    1)客户端向服务器端发送了一个soap消息(http请求+xml片断)

    2) 服务器端处理完请求后, 向客户端返回一个soap消息

  那么它的流程是怎样的呢?

4.3. CXF框架的深入使用

1).CXF的拦截器

1.1) 理解

  • 为什么设计拦截器?
  1. 为了在webservice请求过程中,能动态操作请求和响应数据, CXF设计了拦截器.
  • 拦截器分类:
  1. 按所处的位置分:服务器端拦截器,客户端拦截器
  2. 按消息的方向分:入拦截器,出拦截器
  3. 按定义者分:系统拦截器,自定义拦截器
  • 拦截器API

  Interceptor(拦截器接口)

    AbstractPhaseInterceptor(自定义拦截器从此继承)

      LoggingInInterceptor(系统日志入拦截器类)

      LoggingOutInterceptor(系统日志出拦截器类)

1.2) 编码实现拦截器

  • 使用日志拦截器,实现日志记录

    – LoggingInInterceptor

    – LoggingOutInterceptor

  • 使用自定义拦截器,实现用户名与密码的检验

    – 服务器端的in拦截器

    – 客户端的out拦截器

 服务端:
public class CheckUserInterceptor extends AbstractPhaseInterceptor<SoapMessage> { public CheckUserInterceptor() {
super(Phase.PRE_PROTOCOL);
} @Override
public void handleMessage(SoapMessage msg) throws Fault {
Header header = msg.getHeader(new QName("thecheck"));
if(header != null){
Element chenkEle = (Element) header.getObject();
String username = chenkEle.getElementsByTagName("username").item(0).getTextContent();
String password = chenkEle.getElementsByTagName("password").item(0).getTextContent(); if("ymmm".equals(username) && "123456".equals(password)){
System.out.println("Client de "+username+" 通过了 服务器的检查");
return;
}
}
System.out.println("client 没有通过拦截器检查"); throw new Fault(new RuntimeException("请输入正确的用户名和密码!!!")); } } 客户端:
public class AddUserInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
private String username;
private String password; public AddUserInterceptor(String username , String password) {
super(Phase.PRE_PROTOCOL);
this.username = username;
this.password = password;
}
/*
<Envelope>
<head>
<chenkEle>
<name>xfzhang</name>
<password>123456</password>
</chenkEle>
<chenkEle2>
<name>xfzhang</name>
<password>123456</password>
</chenkEle2>
<head>
<Body>
<sayHello>
<arg0>BOB</arg0>
<sayHello>
</Body>
</Envelope>
*/ @Override
public void handleMessage(SoapMessage msg) throws Fault {
List<Header> list = msg.getHeaders(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document document;
try {
document = factory.newDocumentBuilder().newDocument(); Element chenkEle = document.createElement("thecheck"); Element usernameEle = document.createElement("username");
usernameEle.setTextContent(username);
chenkEle.appendChild(usernameEle); Element passwordEle = document.createElement("password");
passwordEle.setTextContent(password);
chenkEle.appendChild(passwordEle); list.add(new Header(new QName("thecheck"), chenkEle));
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

MyInterceptor

 public class TestService2 {

     public static void main(String[] args) {
String address = "http://192.168.1.102:8787/webService_02_sayService/hellows";
Endpoint publish = Endpoint.publish(address, new HelloWsImpl());
EndpointImpl endImpl = (EndpointImpl) publish; //添加日志入拦截器拦截器
List<Interceptor<? extends Message>> inList = endImpl.getInInterceptors();
inList.add(new LoggingInInterceptor());
inList.add(new CheckUserInterceptor()); //添加日志出拦截器
List<Interceptor<? extends Message>> outIplm = endImpl.getOutInterceptors();
outIplm.add(new LoggingOutInterceptor()); System.out.println("发布 webService_01_cxf_sayService 成功");
}
}

Service

 public class Test2 {

     public static void main(String[] args) {
HelloWsImplService factory = new HelloWsImplService();
HelloWs helloWs = factory.getHelloWsImplPort(); Client client = ClientProxy.getClient(helloWs); List<Interceptor<? extends Message>> outList = client.getOutInterceptors();
outList.add(new AddUserInterceptor("ymmm", "123456")); String string = helloWs.sayHello("cxf-client3 yyy");
System.out.println(string);
}
}

Client

2). 用CXF编写基于springweb service

2.1). 编码实现

  1. Server

  – 创建spring的配置文件beans.xml,在其中配置SEI

 <?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:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<!-- 如果是低版本,还要引入更多文件 -->
<import resource="classpath:META-INF/cxf/cxf.xml" />
<!-- 配置终端 -->
<jaxws:endpoint
id="orderWS"
implementor="com.ittest.servcie_02_cxf_.ws.OrderWsImpl"
address="/orderws" >
<!-- 配置拦截器 -->
<jaxws:inInterceptors>
<bean class="com.ittest.ws.interceptor.CheckUserInterceptor"></bean>
</jaxws:inInterceptors> </jaxws:endpoint>
</beans>

applicationContext.xml

  – 在web.xml中,配置上CXF的一些核心组件

      <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>/*</url-pattern>
</servlet-mapping>

web.xml

    注意:各种cxf版本在配置xml的时候有区别( 在Cxf的高版本中要引入的其它文件较少  ).

  1. Client

  – 生成客户端代码

  – 创建客户端的spring配置文件beans-client.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:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <jaxws:client id="orderClient" serviceClass="com.ittest.servcie_02_cxf_.ws.OrderWs"
address="http://localhost:8080/webService_02_cxf_sayService_spring/orderws" > <!-- 添加拦截器 -->
<jaxws:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
<bean class="com.ittest.ws.client.intercepter.AddUserInterceptor">
<constructor-arg name="username" value="ymmm"/>
<constructor-arg name="password" value="123456"/>
</bean>
</jaxws:outInterceptors> </jaxws:client> </beans>

Client-bean.xml

  – 编写测试类请求web service

 public class Test1 {

     public static void main(String[] args) {
String path = "classpath:applicationContext.xml";
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(path); OrderWs orderWs = (OrderWs) applicationContext.getBean("orderClient");
Order order = orderWs.getOrder(3);
System.out.println(order);
}
}

Test

2.2). 添加自定义拦截器

  1. Server

– 在beans.xml中,在endpoint中配置上入拦截器   (同上)

  1. Client

– 通过Client对象设置出拦截器  (同上)

4.4. 其它调用WebService的方式

1). Ajax调用webService

  跨域请求问题:   

  1. 什么是跨域请求?     (jquery还要求都是 localhost)

    1. sina.com--=->baidu.com/xxx.jsp

    2. localhost----à192.168.42.165

  2. 解决ajax跨域请求webservice的问题?

    在客户端应用中使用java编码去请求webservice, 在页面中去请求自己的后台

2). Jquery调用WebService

3). HttpURLConnection调用WebService

以上三个的代码(一起):

 <%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="jquery-1.8.3.js" ></script>
<script type="text/javascript"> $(document).ready(function(){ $("#btn2").click(function(){
var name = document.getElementById("name").value;
$.post(
"HttpURLConnectionServlet",
"name="+name,
function(msg){
var $Result = $(msg);
var value = $Result.find("return").text();
alert(value);
},
"xml"
);
}); $("#btn1").click(function(){ var name = document.getElementById("name").value;
var date = '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><thecheck><username>ymmm</username><password>123456</password></thecheck></soap:Header><soap:Body><ns2:getOrder xmlns:ns2="http://ws.servcie_02_cxf_.ittest.com/"><arg0>3</arg0></ns2:getOrder></soap:Body></soap:Envelope>';
alert(name+" "+date);
$.ajax({
type : "POST",
url : "http://localhost:8080/webService_02_cxf_sayService_spring/orderws",
data : date,
success : function(msg){
alert("------");
var $Result = $(msg);
var value = $Result.find("return").text();
alert(value);
},
error : function(msg) {
//alert("-----"+msg);
},
dataType : "xml"
});
});
}); function reqWebService() { var name = document.getElementById("name").value;
var date = '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHello xmlns:ns2="http://service.ws.ittest.com/"><arg0>'
+ name + '</arg0></ns2:sayHello></soap:Body></soap:Envelope>'; var xmlhttp = getRequest();
alert("---");
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
alert("前");
var result = xmlhttp.responseXML;
alert("后");
var returnEle = result.getElementsByTagName("return")[0];
var vale = returnEle.firstChild.data;
alert(vale); }
}; xmlhttp.open("POST",
"http://192.168.1.102:8787/webService_02_sayService/hellows"); xmlhttp.setRequestHeader("Content-type",
"application/x-www-form-urlencoded"); xmlhttp.send(date); } function getRequest() {
var xmlhttp = null;
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else {// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
return xmlhttp;
}
</script> </head>
<body>
用户名:
<input type="text" id="name" name="username" />
<br />
<div>
<button onclick="reqWebService()">使用Ajax连接 webservice</button></div>
<button id="btn1">使用JQuery链接webService</button>
<button id="btn2">使用Connection链接webService</button> </body>
</html>

insex.jsp

 package com.ittest.servcie_02_cxf_.web;

 import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection; import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.jasper.tagplugins.jstl.core.Url; import com.sun.jndi.toolkit.url.Uri; /**
* Servlet implementation class HttpURLConnectionServlet
*/
@WebServlet("/HttpURLConnectionServlet")
public class HttpURLConnectionServlet extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* 跨域请求webService
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name"); String path = "http://192.168.1.102:8787/webService_02_sayService/hellows";
String data = "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Body><ns2:sayHello xmlns:ns2='http://service.ws.ittest.com/'><arg0>"
+ name + "</arg0></ns2:sayHello></soap:Body></soap:Envelope>"; URL url = new URL(path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestProperty("Content-Type", "text/xml;charset=utf-8"); OutputStream os = connection.getOutputStream();
os.write(data.getBytes("utf-8"));
os.flush(); int code = connection.getResponseCode();
if(code==200){
InputStream is = connection.getInputStream(); response.setContentType("text/xml;charset=utf-8");
ServletOutputStream outputStream = response.getOutputStream(); int len=0;
byte[] buff = new byte[1024]; while((len = is.read(buff))>0){
outputStream.write(buff,0,len);
} outputStream.flush();
outputStream.close();
}
}
}

HttpURLConnectionServlet

4.5. 通过注解修改wsdl文档

1). JDK中的相关注解

1.1).  @WebService

l 作用在具体类上。而不是接口。

l 一个类只有添加了此注解才可以通过Endpoint发布为一个web服务。

l 一个添加了此注解的类,必须要至少包含一个实例方法。静态方法和final方法不能被发布为服务方法。

l WebService注解包含以下参数:

1.2).  @WebMethod

l 此注解用在方法上,用于修改对外暴露的方法。

1.3).  @WebResult

用于定制返回值到WSDL的映射

1.4).  @WebParam 

用于定义WSDL中的参数映射

1.5).  @XmlElement 

用于定义实体类的属性到WSDL中的映射(get/set方法上)

2). 说明

即使是没有修改源代码,只修改了注解,客户端的代码也必须要重新生成, 否则调用将会失败。

WebService 及 CXF 的进阶讲解的更多相关文章

  1. WebService之CXF注解报错(一)

    WebService之CXF注解 1.详细报错例如以下 usage: java org.apache.catalina.startup.Catalina [ -config {pathname} ] ...

  2. WebService它CXF注释错误(两)

    WebService它CXF注解 1.详细报错例如以下 五月 04, 2014 11:24:12 下午 org.apache.cxf.wsdl.service.factory.ReflectionSe ...

  3. WebService之CXF注解报错(三)

    WebService之CXF注解 1.具体错误如下 五月 04, 2014 11:29:28 下午 org.apache.cxf.wsdl.service.factory.ReflectionServ ...

  4. WebService之CXF注解报错(二)

    WebService之CXF注解 1.具体报错如下 五月 04, 2014 11:24:12 下午 org.apache.cxf.wsdl.service.factory.ReflectionServ ...

  5. 转载 WebService 的CXF框架 WS方式Spring开发

    WebService 的CXF框架 WS方式Spring开发   1.建项目,导包. 1 <project xmlns="http://maven.apache.org/POM/4.0 ...

  6. 【WebService】WebService之CXF和Spring整合(六)

    前面介绍了WebService与CXF的使用,项目中我们经常用到Spring,这里介绍CXF与Spring整合 步骤 1.创建一个Maven Web项目,可以参照:[Maven]Eclipse 使用M ...

  7. 转-JAVA webservice之CXF 范例--http://cxshun.iteye.com/blog/1275408

    JAVA webservice之CXF 博客分类: j2ee相关 昨天我们一起学习了一下xfire,今天我们来看一下CXF,为什么学完那个接着学这个呢.因为CXF是在xfire的基础上实现 的,所以我 ...

  8. Webservice与CXF框架快速入门

    1. Webservice Webservice是一套远程调用技术规范 远程调用RPC, 实现了系统与系统进程间的远程通信.java领域有很多可实现远程通讯的技术,如:RMI(Socket + 序列化 ...

  9. WebService之CXF框架

    本文主要包括以下内容 ant工具的使用 利用cxf实现webservice cxf与spring整合 ajax访问webservice ant 工具 1.为什么要用到ant这个工具呢? Ant做为一种 ...

随机推荐

  1. 解决mybatis generator警告Cannot obtain primary key information from the database, generated objects may be incomplete

    使用 mybatis generator 生成pojo.dao.mapper时 经常出现 Cannot obtain primary key information from the database ...

  2. java中的缓冲流!

    package cn.zhozuohou; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; impor ...

  3. Oracle minus用法详解及应用实例

    本文转载:https://blog.csdn.net/jhon_03/article/details/78321937 Oracle minus用法 “minus”直接翻译为中文是“减”的意思,在Or ...

  4. Lodop输出页面input文本框的最新值

    默认使用Lodop打印页面上的文本框等,会发现虽然页面上文本框输入了值,打印预览却是空的,这是由于没有把最新的值传入Lodop. 如图,演示的是Lodop如何输出文本框内的新值,这里整个页面只有inp ...

  5. How to remove unwant Internet Explorer Context Menu

    HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt

  6. Vue插件plugins的基本操作

    前面的话 本文将详细介绍Vue插件plugins的基本操作 开发插件 插件通常会为 Vue 添加全局功能.插件的范围没有限制——一般有下面几种: 1.添加全局方法或者属性,如: vue-custom- ...

  7. Power Spectral Density

    对于一个特定的信号来说,有时域与频域两个表达形式,时域表现的是信号随时间的变化,频域表现的是信号在不同频率上的分量.在信号处理中,通常会对信号进行傅里叶变换得到该信号的频域表示,从而得到信号在频域上的 ...

  8. GLSL 变量属性

    1. attribute变量为这个attribute变量指定一个位置(用无符号值表示):glBindAttribLocation利用这个“位置”来指定需要传给shader里的attribue变量的数据 ...

  9. mosquitto发布消息

    ./mosquitto_pub -t '$SYS/broker/clients/status/online' -m 1

  10. python 机械学习之sklearn的数据正规化

    from sklearn import preprocessing    #导入sklearn的处理函数用于处理一些大值数据 x_train, x_test, y_train, y_test = tr ...