WebService 简介

实际开发中,很多系统都是基于历史遗留系统进行开发,有时,这些系统基于不同的语言,如C,C++,C#,java,PHP等等。为了实现历史系统的再利用,或向外部程序暴露调用接口,于是就产生了WebService规范。WebService用于实现系统的透明访问,其最终目的:实现异构系统间通信。

单从Java方面考虑,实现WebService的方法有jdk1.6版本添加的JWS,Axis1/2,XFIRE,Celtix,CXF(Xfire和Celtix的整合)。

综合来看Axis1,Xfire,Celtix成熟但即将退出的版本。内置的JWS,Axis和CXF却也不是很成熟(哎,青黄不接)。


Apache Axis1实现WebService

当利用Java版Axis有两个途径,以Java码作为Web服务。最简单的一种是使用原生的jws(Java Web Service的文件)。另一种方法是使用定制的部署文件。定制部署让您能自选资源,什么要予以曝光。

第一种实现方式:即时发布

实现此功能需要借助 axis-1_4\webapps下的axis工程,将其部署到apache服务器webapps目录下。

原生的jws和java源代码的唯一区别是后缀名,当然采用这种方式也不能使用package进行打包.下面提供简单的原生jws和远程调用实现。

Hello.jws内容:

public class Hello
{
	public String sayHello(String name)
	{
		StringBuffer greeting = new StringBuffer("Hello ");
		if ( name != null )
		{
			greeting.append(name);
		}
		greeting.append(", nice to see you!");
		return greeting.toString();
	}
}
将Hello.jws文件放到apache服务器webapps/axis/目录下,启动服务器。

通过 http://localhost:8080/axis/Hello.jws?wsdl 可以获得Hello.jws的WebService定义,内容如下

至此,简单的Service端就部署成功了,接下来要通过一段程序对Hello.jws进行访问。

使用eclipse创建一个java project,并添加jar包,必须的jar包包括axis.jar;jaxrpc.jar;commons-loggin-1.x.jar;commons-discovery-0.x.jar

import javax.xml.namespace.QName;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;

public class HelloClient {

	public static void main(String[] args) {
		System.out.println(new HelloClient().sayHello("Han MeiMei"));
	}

	public String sayHello(String name)
	{
		String result = null;
		try
		{
			//1.设置远程访问链接
			String url = "http://localhost:8080/axis/Hello.jws";
			//2.获取Service对象
			Service service = new Service();
			//3.通过Service对象获取远程调用对象Call
			Call call = (Call) service.createCall();
			//4.设置远程调用桩
			call.setTargetEndpointAddress(url);
			//5.设置远程操作方法名
			call.setOperationName(new QName(url, "sayHello"));
			//6.设置参数,执行远程方法
			result = (String)call.invoke(new Object[]{name});
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		
		return result;
	}
}

执行结果如下:

May 19, 2014 2:11:40 PM org.apache.axis.utils.JavaUtils isAttachmentSupported
WARNING: Unable to find required classes (javax.activation.DataHandler and javax.mail.internet.MimeMultipart). Attachment support is disabled.
<span style="color:#FF0000;">Hello Han MeiMei, nice to see you!</span>
第二种实现方式:定制发布

第一种发布方式比较快捷,发布方式简单,但有以下缺点

1.必须要有源文件,同时不能包含package结构

2.发布之后所有方法均开放,不可控制

针对以上缺点,axis提供定制发布方式,具体步骤如下

编写Hello.java类

package com.webservice.wsdd;

public class Hello
{
    public String sayHello(String name)
    {
        StringBuffer greeting = new StringBuffer("Hello ");
        if(name != null)
        {
            greeting.append(name);
        }
        greeting.append(",nice to see you!");
        
        return greeting.toString();
    }
    
    public int add(int a,int b)
    {
        return a + b;
    }
}

使用命令行进行编译,得到class文件(包括包)

javac -d ./ Hello.java

com包所有内容拷贝到apache服务器webapps/axis/WEB-INF/classes下。

编写hello.wsdd配置文件,放置到webapps/axis/WEB-INF/classes/com下   WSDD文档具体意义可查看Axis WSDD文件参考文档

启动服务器,进入到hello.wsdd位置,使用命令生成server-config.wsdd配置文件

java org.apache.axis.client.AdminClient hello.wsdd  --需要自己配置classpath环境变量

生成的server-config.wsdd配置文件位于webapps/axis/WEB-INF/路径下,内容如下,如果不想生成,也可以拷贝一份放在该路径下


使用http://localhost:8080/axis/services/Hello?wsdl 可以查看WebService描述,内容如下


此时定制服务发布完成。

访问方式只需把第一步的访问链接替换成上面红字部分即可

补充:开发中,有时候需要通过WebService传递对象,此时的处理方式与上述方法又有不同

Axis处理对象参数/返回值

编写Question.java和Answer.java   注意:Bean对象一定要实现Serializable接口。

package com.webservice.wsdd;

import java.io.Serializable;

@SuppressWarnings("serial")
public class Question implements Serializable
{
	private int id;
	
	private String question;
	
	private String answer;
	
	public void setId(int id)
	{
		this.id = id;
	}
	
	public int getId()
	{
		return this.id;
	}
	
	public void setQuestion(String question)
	{
		this.question = question;
	}
	
	public String getQuestion()
	{
		return this.question;
	}
	
	public void setAnswer(String answer)
	{
		this.answer = answer;
	}
	
	public String getAnswer()
	{
		return this.answer;
	}
}

package com.webservice.wsdd;

public class Answer
{
	public Question answerQuestion(Question question)
	{
		Question tmp = question;
		
		doRead(tmp);
		tmp.setAnswer("do not know the answer!");
		
		return tmp;
	}
	
	private void doRead(Question question)
	{
		System.out.println("read question:"+question.getQuestion());
	}
}

编译后放到服务器classes目录下,在server-config.wsdd中注册服务,较之前多了红字部分。


启动服务器,服务发布成功。可以在 http://localhost:8080/axis/servlet/AxisServlet 下查看到该服务

客户端代码QuestionClient.java

package com.client;

import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.ser.BeanDeserializerFactory;
import org.apache.axis.encoding.ser.BeanSerializerFactory;

import com.webservice.wsdd.Question;

public class QuestionClient {

	public static void main(String[] args) {
		Question question = new Question();
		question.setQuestion("先有鸡还是先有蛋!");
		
		new QuestionClient().askAndAnswer(question);
	}

	/**
	 * @param question
	 */
	public void askAndAnswer(Question question)
	{
		String url = "http://localhost:8080/axis/services/Answer";
		Service service = new Service();
		
		try
		{
			Call call = (Call)service.createCall();
			
			call.setTargetEndpointAddress(url);
			
			//注册Bean及序列化和反序列化工程映射关系
			QName qname = new QName("bean:BeanManger","Question");
			call.registerTypeMapping(Question.class, qname, 
					new BeanSerializerFactory(Question.class, qname),
					new BeanDeserializerFactory(Question.class, qname)
			);
			call.setOperationName(new QName(url, "answerQuestion"));
			call.setReturnClass(Question.class);
			
			//设置调用方法的参数
			call.addParameter("question", qname, ParameterMode.IN);
			
			Question tmp = (Question)call.invoke(new Object[]{question});
			
			if(tmp!=null)
			{
				System.out.println("Question:"+tmp.getQuestion());
				System.out.println("Answer:"+tmp.getAnswer());
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
}

执行结果:

Question:先有鸡还是先有蛋!
Answer:do not know the answer!

下一篇  Java WebService学习笔记 - Axis进阶(二)



相关文章:

  • 2021-07-27
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-01-04
  • 2021-07-11
  • 2021-05-19
  • 2021-06-11
  • 2021-08-23
  • 2021-10-12
  • 2021-09-25
相关资源
相似解决方案