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. composer 出现You are running Composer with SSL/TLS protection disabled.

    开启php的ssl开启 composer config -g -- disable-tls false

  2. Lodop获取全部JS代码,传统JS模版的生成

    Lodop模版有两种方法,一种是传统的JS语句,可以用JS方法里的eval来执行,一种是文档式模版,是特殊格式的base64码,此篇博文介绍传统JS模版的生成方法.两种模版都可以存入一下地方进行调用, ...

  3. LODOP安装参数 及静默安装

    在cmd命令里里静默安装lodop(c-lodop不能静默安装),本人的安装文件放在D:\lodopdownload\3060\Lodop6.224_Clodop3.060,如下所示: lodop静默 ...

  4. HTML中文本过长时自动隐藏末尾部分或中间等任意部分

    一.    一般情况下,HTML字符串过长时都会将超过的部分隐藏点,方法如下: 设置CSS: .ellipsis-type{ max-width: 50px;                      ...

  5. mybatis,主键返回指的是返回到传入的对象中

  6. codeforces611C

    New Year and Domino CodeForces - 611C 他们说:“每一年都像多米诺骨牌,一个接一个地倒下去”.但是,一年能够像多米诺骨牌那样放在网格中吗?我不这么认为. Zydsg ...

  7. Centos使用虚拟环境创建python django工程

    本地环境 通常我们登录就是后就是本地环境 本地环境下查看pip安装了那些包 pip3 list 可以看到本地环境下我们安装的是django1.11.16版本,现在我有个项目要使用django 2.0以 ...

  8. winserver 2008 R2服务器安装IIS

    winserver 2008 R2 IIS7 安装IIS 打开服务器管理器 选择“角色”,右击添加角色 点击“下一步” 勾选”Web服务器(IIS)“,点击”下一步“ 勾选”常见Http功能.应用程序 ...

  9. StringBuffer作为参数传递的问题

    public class Foo {2.   public static void main (String [] args)  {3.      StringBuffer a = new Strin ...

  10. JVM是如何处理异常的

    JVM处理异常 异常处理的两大组成要素是抛出异常和捕获异常.这两大要素共同实现程序控制流的非正常转移. 抛出异常可分为显式和隐式两种.显式抛异常的主体是应用程序,指的是在程序中使用throw关键字,手 ...