WebService又是一种高级应用,与之前学习的Struts、Spring、Hibernate等框架不同。WebService是面向服务的架构(SOA),看起来像是比SSH框架要大。那么它到底是做什么用的?什么才是面向服务的架构?

让我们来看一种需求,集团公司可能具有多种WEB应用。比如,前年开发了个进销存系统、去年开发了一个ERP、今年又开发了一个OA。现在这家集团公司需要将这三个系统整合,难道需要重新编码将它们整合吗?而这三个系统又是用不同语言编写的,这种成本对公司来说无疑是一种浪费。WebService可以很好的解决这种需求。

WebService是可以进行跨语言、跨平台、分布式系统间整合的方案,WebService像是一条线将这些系统穿起来——企业服务总线(ESB)。WebService使用简单对象访问协议(SOAP)使用http协议传输xml数据(xml是最常用的,也有其他格式数据。)来完成系带间的整合。

什么是整合?当然是功能和数据的整合,也就是一个系统可以调用另一个系统的WebService接口来完成数据的交互。这样我们就需要知道,提供WebService服务功能的应用公开了哪些接口,我们可以通过WebService描述文档(WSDL)得知。WSDL不需要我们手动编写,Java的WebService实现可以为我们自动生成。JDK1.6新增支持WebService,但还不够成熟。所以我们使用Apache第三方开源组织提供的WebService实现——Axis。

Axis的当前版本是Java版本,它的C++版本正在开发中。Axis是一个功能强大的soap引擎,关于它们的详细信息在此就不做介绍了。下面,让我们来编写一个例子程序,以了解WebService的应用流程。

==================================================================================================================

下面开始编写服务端代码:

1.在MyEclipse中,建立一个WebProject。命名为WebService.

2.下载axis1.4的包,解压,里面有一些关于axis的资料和文件。

将webapps里面的,WEB-INF中的web.xml复制,替换到自己的WebService项目中。

如果你没有,可以将下如代码拷贝到你的web.xml中:

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web
Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
  <display-name>Apache-Axis</display-name>
    
    <listener>
        <listener-class>org.apache.axis.transport.http.AxisHTTPSessionListener</listener-class>
    </listener>
    
  <servlet>
    <servlet-name>AxisServlet</servlet-name>
    <display-name>Apache-Axis Servlet</display-name>
    <servlet-class>
        org.apache.axis.transport.http.AxisServlet
    </servlet-class>
  </servlet>

<servlet>
    <servlet-name>AdminServlet</servlet-name>
    <display-name>Axis Admin Servlet</display-name>
    <servlet-class>
        org.apache.axis.transport.http.AdminServlet
    </servlet-class>
    <load-on-startup>100</load-on-startup>
  </servlet>

<servlet>
    <servlet-name>SOAPMonitorService</servlet-name>
    <display-name>SOAPMonitorService</display-name>
    <servlet-class>
        org.apache.axis.monitor.SOAPMonitorService
    </servlet-class>
    <init-param>
      <param-name>SOAPMonitorPort</param-name>
      <param-value>5001</param-value>
    </init-param>
    <load-on-startup>100</load-on-startup>
  </servlet>

<servlet-mapping>
    <servlet-name>AxisServlet</servlet-name>
    <url-pattern>/servlet/AxisServlet</url-pattern>
  </servlet-mapping>

<servlet-mapping>
    <servlet-name>AxisServlet</servlet-name>
    <url-pattern>*.jws</url-pattern>
  </servlet-mapping>

<servlet-mapping>
    <servlet-name>AxisServlet</servlet-name>
    <url-pattern>/services/*</url-pattern>
  </servlet-mapping>

<servlet-mapping>
    <servlet-name>SOAPMonitorService</servlet-name>
    <url-pattern>/SOAPMonitor</url-pattern>
  </servlet-mapping>

<!-- uncomment this if you want the admin servlet -->
 <!--
  <servlet-mapping>
    <servlet-name>AdminServlet</servlet-name>
    <url-pattern>/servlet/AdminServlet</url-pattern>
  </servlet-mapping>
 -->

<session-config>
        <!-- Default to 5 minute session timeouts -->
        <session-timeout>5</session-timeout>
    </session-config>

<!-- currently the W3C havent settled on a media type for WSDL;
    http://www.w3.org/TR/2003/WD-wsdl12-20030303/#ietf-draft
    for now we go with the basic 'it's XML' response -->
  <mime-mapping>
    <extension>wsdl</extension>
     <mime-type>text/xml</mime-type>
  </mime-mapping>
  
  <mime-mapping>
    <extension>xsd</extension>
    <mime-type>text/xml</mime-type>
  </mime-mapping>

<welcome-file-list id="WelcomeFileList">
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jws</welcome-file>
  </welcome-file-list>
</web-app>

然后,引入jar包,

在自己下的axis的jar包中,有一些jar包,可以将其全部引入。

我只引入了其中一部分axis.jar,axis-ant.jar,commons-discovery-0.2.jar,commons-logging-1.0.4.jar,jaxrpc.jar,log4j-1.2.8.jar,saaj.jar,wsdl4j-1.5.1.jar,xercesImpl-2.8.1.jar,xmlsec-1.4.5.jar。

然后,将项目部署,启动tomcat,输入http://10.64.59.12:8080/WebService/services,查看页面。

如果出现了

And now... Some Services

  • AdminService (wsdl)

    • AdminService
  • Version (wsdl)
    • getVersion

就表示你环境搭建工作已经完成了。可以进入真正的开发了。

3.在src中,建立类:HelloService.java

public class HelloService {
public String sayHello(){
return "hello";
}

public String sayHelloToPerson(String name){
if(name == "" || name.equals("")){
name = "nobody";
}
return "hello " + name;
}
}

4.其实开发工作就已经完成了,如此简单。下一步,就是将这个发布到webservice上。

编写一个文件:deploy.wsdd

内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/"  xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">    
<service name="HelloServices" provider="java:RPC">        
<parameter name="className" value="HelloService"/>      //如果将类放在包下,value应写成packagename.className的形式    
<parameter name="allowedMethods" value="*"/>     
</service> 
</deployment>

把它放在F:\test下,

然后cmd,进入F:test,再输入:

java -cp F:\axis-1_4\lib\axis.jar;F:\axis-1_4\lib\axis-ant.jar;F:\axis-1_4\lib\commons-discovery-0.2.jar;F:\axis-1_4\lib\commons-logging-1.0.4.jar;F:\axis-1_4\lib\jaxrpc.jar;F:\axis-1_4\lib\log4j-1.2.8.jar;F:\axis-1_4\lib\mail-1.4.jar;F:\axis-1_4\lib\saaj.jar;F:\axis-1_4\lib\wsdl4j-1.5.1.jar;F:\axis-1_4\lib\xercesImpl-2.8.1.jar;F:\axis-1_4\lib\xml-apis-1.3.03.jar;F:\axis-1_4\lib\xmlsec-1.4.5.jar;F:\axis-1_4\lib\xmlsecSamples-1.4.5.jar;F:\axis-1_4\lib\xmlsecTests-1.4.5.jar org.apache.axis.client.AdminClient -lhttp://10.64.59.12:8080/WebService/services/AdminService deploy.wsdd

回车,在窗口中下面出现:

Processing file deploy.wsdd
<Admin>Done processing</Admin>

就表示你发布成功了。

再在浏览器中输入http://10.64.59.12:8080/WebService/services时,看到

And now... Some Services

  • HelloServices (wsdl)

    • sayHello
    • sayHelloToPerson
  • AdminService (wsdl)
    • AdminService
  • Version (wsdl)
    • getVersion

则HelloServices就被成功发布了。

===================================================================================================================================

下面,就是客户端对webservice的访问

写个测试类:

import java.io.IOException;
import java.net.MalformedURLException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceException;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class TestService {
private static final Log log = LogFactory.getLog(TestService.class);
private static final String HELLO_SERVICE_ENDPOINT = "http://10.64.59.12:8080/WebService/services/HelloServices?wsdl";

/**
 * 调用sayHello方法
 */
public void callSayHello() {
try {
Service service = new Service();
Call call = (Call) service.createCall();
//传递url
call.setTargetEndpointAddress(new java.net.URL(HELLO_SERVICE_ENDPOINT));
//调用方法名字
call.setOperationName(new QName("http://webservice.sinosoft.com/","sayHello"));
call.setReturnType(org.apache.axis.Constants.XSD_STRING);
try {
//ret即执行方法之后得到的返回值,此处不用传参,故不用写字符串
String ret = (String) call.invoke(new Object[] {});
System.out.println("The return value is:" + ret);
return;
} catch (IOException e) {
e.printStackTrace();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ServiceException e) {
e.printStackTrace();
}
log.error("call sayHello service error!");
}

/**
 * 调用sayHelloToPerson方法
 */
public void callSayHelloToPerson() {
try {
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(new java.net.URL(HELLO_SERVICE_ENDPOINT));
call.setOperationName(new QName("http://webservice.sinosoft.com/","sayHelloToPerson"));
call.addParameter("name", org.apache.axis.Constants.XSD_STRING, javax.xml.rpc.ParameterMode.IN);
call.setReturnType(org.apache.axis.Constants.XSD_STRING);
try {
//ret即执行方法之后得到的返回值,此处传了一个字符串做为参数,如果不写空,会报错
String ret = (String) call.invoke(new Object[] {"Seven"});
System.out.println("The return value is:" + ret);
return;
} catch (IOException e) {
e.printStackTrace();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ServiceException e) {
e.printStackTrace();
}
log.error("call sayHello service error!");
}

/**
 * 调用两个方法
 * @param args
 */
public static void main(String[] args) {
TestService tester = new TestService(); 
tester.callSayHello();
tester.callSayHelloToPerson();
}
}

会打印出:

The return value is:hello
The return value is:hello Seven

就表示 这个Demo做成功了。

此时,如果修改HelloService.java,执行测试类时,就可以即时响应HelloService.java中的变化了。

当然,生成webservice接口还可以定义wsdl文件,直接在eclipse中生成服务端与客户端;测试工具可以选择soapui工具;

  下面开始讲讲Http接口的调用(这里使用HttpClient):

http有两种请求方式,post和get,这里测试工具推荐firefox的restclient;上代码:

//这里type 请求方式  0:post,1:get

public static String sendSms(String type,String url,Map paramMap)
throws HttpException, IOException {
if(paramMap == null){
paramMap = new HashMap();
}
HttpClient client = new HttpClient();
if("1".equals(type)){
url = url+"?client_id="+paramMap.get("client_id")+
"&access_token="+paramMap.get("access_token")+
"&mobile="+paramMap.get("mobile")+
"&terminal_code="+paramMap.get("terminal_code");
GetMethod getMethod = new GetMethod(url);
String returnStr = "";

logger.info("-----------调用接口开始-----------");
client.executeMethod(getMethod);// 执行请求
returnStr = getMethod.getResponseBodyAsString();
logger.info("-----------调用接口结束-----------"+"返回数据:"+returnStr);
return returnStr;// 返回结果
}

PostMethod postMethod = new PostMethod(url);
String returnStr = "";

if(paramMap == null || paramMap.size() == 0){
logger.info("-----------调用接口开始-----------");
client.executeMethod(postMethod);// 执行请求
returnStr = postMethod.getResponseBodyAsString();
logger.info("-----------调用接口结束-----------"+"返回数据:"+returnStr);
return returnStr;// 返回结果
}
NameValuePair[] param = new NameValuePair[paramMap.size()];
int i = 0;
for(Iterator<String> it = paramMap.keySet().iterator();it.hasNext();){
String key = it.next();
String value = (String)paramMap.get(key);
param[i] = new NameValuePair(key,value);
i++;
}
postMethod.setRequestBody(param);
client.getHttpConnectionManager().getParams()
.setConnectionTimeout(120000);// 设置超时
logger.info("-----------调用接口开始-----------");
client.executeMethod(postMethod);// 执行请求
returnStr = postMethod.getResponseBodyAsString();
logger.info("-----------调用接口结束-----------"+"返回数据:"+returnStr);
return returnStr;
}

Webservice接口和Http接口的更多相关文章

  1. 转载-- http接口、api接口、RPC接口、RMI、webservice、Restful等概念

     http接口.api接口.RPC接口.RMI.webservice.Restful等概念 收藏 Linux一叶 https://my.oschina.net/heavenly/blog/499661 ...

  2. 基于Axis1.4的webservice接口开发(接口调用)

    基于Axis1.4的webservice接口开发(接口调用) 一.webservice接口代码参考上一篇博客: http://www.cnblogs.com/zhukunqiang/p/7125668 ...

  3. 【接口】SpringBoot+接口开发(一)

    一.接口的简单介绍 1.什么是接口:接口及服务: 2.接口的分类:(1)系统的内部接口;(2)第三方的外部接口; 3.简述接口原理图: 4.接口协议:是指客户端跟服务器之间或者接口与接口间进行的通讯时 ...

  4. 转】C#接口-显式接口和隐式接口的实现

    [转]C#接口-显式接口和隐式接口的实现 C#中对于接口的实现方式有隐式接口和显式接口两种: 类和接口都能调用到,事实上这就是“隐式接口实现”. 那么“显示接口实现”是神马模样呢? interface ...

  5. JDBC的使用(二):PreparedStatement接口;ResultSet接口(获取结果集);例题:SQL注入

    ResultSet接口:类似于一个临时表,用来暂时存放数据库查询操作所获得的结果集. getInt(), getFloat(), getDate(), getBoolean(), getString( ...

  6. 比较器:Compare接口与Comparator接口区别与理解

    一.实现Compare接口与Comparator接口的类,都是为了对象实例数组排序的方便,因为可以直接调用 java.util.Arrays.sort(对象数组名称),可以自定义排序规则. 不同之处: ...

  7. 集合中Set接口与Collection接口,常用子类TreeSet,HashSet.

    Set接口与List接口的不同之处在于: 不允许有重复的数据. 定义如下: public interface Set<E>extends Collection<E> 主要方法与 ...

  8. Callable接口、Runable接口、Future接口

    1. Callable与Runable区别 Java从发布的第一个版本开始就可以很方便地编写多线程的应用程序,并在设计中引入异步处理.Thread类.Runnable接口和Java内存管理模型使得多线 ...

  9. C#集合--ICollection接口和IList接口

    虽然列举接口提供了一个协议,用于向前的方式遍历集合,但它们没有提供一种机制来确定集合的大小,通过索引访问集合的成员,搜索集合,或修改集合.为了实现这些功能,.NET Framework定义了IColl ...

  10. Java对象克隆(Clone)及Cloneable接口、Serializable接口的深入探讨

    Java对象克隆(Clone)及Cloneable接口.Serializable接口的深入探讨 Part I 没啥好说的,直接开始Part II吧. Part II 谈到了对象的克隆,就不得不说为什么 ...

随机推荐

  1. A Mathematical Curiosity 分类: HDU 2015-06-25 21:27 11人阅读 评论(0) 收藏

    A Mathematical Curiosity Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Ot ...

  2. 2016 Al-Baath University Training Camp Contest-1 I

    Description It is raining again! Youssef really forgot that there is a chance of rain in March, so h ...

  3. 使用 JavaScript

    我们要用 JavaScript,但是把它写在哪里呢?   这里 ↘   1. HTML 页面中 .   2. 单独的一个文件中,文件后缀名是“.js”.     ——————————————————— ...

  4. An error occurred while filtering resources-----maven项目报错

    解决办法 需要在pom中设定jdk的版本 <plugins> <!-- compiler插件, 设定JDK版本 --> <plugin> <groupId&g ...

  5. c++学习总结--复合类型,const。

    复习c++,有必要对一些东西做一下笔记,方便以后学习,如有问题,欢迎提出. 首先,最常用两种复合类型应该是引用和指针. 所谓复合类型,是在基本类型基础(如:int)上定义的类型. 引用是c++的一个复 ...

  6. context是什么意思

    context上下文吗,可以解释为程序运行的某一区间之内,提供对这一区间之内操作的一种对象,而且往往这一区间之内得核心操作都需要这个对象来进行 把Context翻译成“上下文”只是不直观罢了,不过也没 ...

  7. 详细介绍java中的数据结构

    详细介绍java中的数据结构 http://developer.51cto.com/art/201107/273003.htm 本文介绍的是java中的数据结构,本文试图通过简单的描述,向读者阐述各个 ...

  8. 关于async & await(TAP)异步模型的异常捕获

    在TAP之前,若要捕获线程中Task的异常,通常有两种办法: 1.阻塞:线程开始后,在适当的时机,调用 wait,或waitAll方法. 2.非阻塞(推荐):在建立任务的时候,写该task的conti ...

  9. 通过两根RS232连接两台电脑

    把RS232的有5脚那边放下面,最左边是GND,第二三是TXD和RXD,两个RS232反接,然后两个usb连接电脑就可以通信了

  10. VirtualBox下Ubuntu利用桥接方式上网

    1.打开virtualbox,选择[设置]-[网络]将连接方式改为[Bridged Adapter] 2.在Ubuntu中, 运行sudo gedit /etc/network/interfaces ...