看了网上的很多java+axis的Hello World程序,几乎(注意是几乎)千篇一律一个超级简单的服务:输入String,输出String。实践指导性不太强。经过几天的
研究,我来总结总结写一篇超级Hello World,希望对Web
Service的初学者(具备Web Service基本常识)有所帮助。
本文没有系统地涉及的搭建环境的细节,只是多种
接口情况(String等简单对像、
自定义对象、数组做参数,返回对象、数组、多返回值,以及数据库
连接池的使用)的服务的调用方法示例程序。
本人原创,转载请保留本人信息。时间:2011-09-20 作者:隔壁老王 地址:http://wallimn.iteye.com/blog/1176153
一、服务类:
package com.wallimn.services.example;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.xml.rpc.holders.StringHolder;
import com.wallimn.services.util.ConnManager;
public class HelloWorldService {
/**
* 无输入参数,只有返回值
* <br/>
* 作者:wallimn 时间:2011-9-20 下午04:21:32<br/>
* 邮件:wallimn@sohu.com<br/>
* 博客:http://wallimn.iteye.com<br/>
* 参数:<br/>
* @return
*/
public String sayHello() {
return "hello";
}
/**
* 有输入参数,有返回值
* <br/>
* 作者:wallimn 时间:2011-9-20 下午04:21:48<br/>
* 邮件:wallimn@sohu.com<br/>
* 博客:http://wallimn.iteye.com<br/>
* 参数:<br/>
* @param name
* @return
*/
public String sayHelloToPerson(String name) {
if (name == null || "".equals(name)) {
name = "nobody";
}
return "Hello " + name;
}
/**
* 返回String数组的示例
* <br/>
* 作者:wallimn 时间:2011-9-20 下午04:22:05<br/>
* 邮件:wallimn@sohu.com<br/>
* 博客:http://wallimn.iteye.com<br/>
* 参数:<br/>
* @return
*/
public String[] saySimpleArray() {
return new String[] { "one", "two", "three" };
}
/**
* 返回自定义的对象数组
* <br/>
* 作者:wallimn 时间:2011-9-20 下午04:22:23<br/>
* 邮件:wallimn@sohu.com<br/>
* 博客:http://wallimn.iteye.com<br/>
* 参数:<br/>
* @return
*/
public Order[] sayObjectArray() {
return new Order[] {
new Order("隔壁老王"), new Order("wallimn"), new Order("wallimn@sohu.com"), new Order("http://wallimn.iteye.com") };
}
/**
* 自定义对象数组做参数
* <br/>
* 作者:wallimn 时间:2011-9-20 下午04:22:50<br/>
* 邮件:wallimn@sohu.com<br/>
* 博客:http://wallimn.iteye.com<br/>
* 参数:<br/>
* @param order
* @return
*/
public String processOrder(Order order) {
String sep = System.getProperty("line.separator");
String response = "Hi, " + order.getCustomerName() + "!" + sep;
response += sep + "You seem to have ordered the following:" + sep;
String[] items = order.getItemCodes();
int[] quantities = order.getQuantities();
for (int i = 0; i < items.length; i++) {
response += sep + quantities[i] + " of item : " + items[i];
}
response += sep + sep
+ "If this had been a real order processing system, "
+ "we'd probably have charged you about now.";
return response;
}
/**
* 执行数据库查询的服务。使用proxool连接池
* <br/>
* 作者:wallimn 时间:2011-9-20 下午04:23:09<br/>
* 邮件:wallimn@sohu.com<br/>
* 博客:http://wallimn.iteye.com<br/>
* 参数:<br/>
* @return
*/
public String getNameFromDb() {
System.out.println("执行方法,准备获取数据库连接");
Connection conn = ConnManager.getInstance().getConnection();
System.out.println("获取数据库连接:" + conn);
String sql = "select 'wallimn' name from dual";
try {
PreparedStatement stat = conn.prepareStatement(sql);
System.out.println("执行查询!");
ResultSet rs = stat.executeQuery();
rs.next();
String name = rs.getString(1);
rs.close();
stat.close();
return name;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "notfound";
}
/**
* 返回多个值的示例,函数有返回值、有输出参数
* <br/>
* 作者:wallimn 时间:2011-9-20 下午03:46:01<br/>
* 邮件:wallimn@sohu.com<br/>
* 博客:http://wallimn.iteye.com<br/>
* 参数:<br/>
* @param id
* @param name 输出参数,注意,使用的是StringHolder,这类类型wsdl中,自动变成输出参数
* @return
*/
public String getNameById(int id,StringHolder name){
if(id==0){
name.value="wallimn";
}
else if(id==1){
name.value="his wife";
}
else if (id==2){
name.value = "his son";
}
else{
name.value="let me think about";
}
return "ok";
}
}
二、调用示例
package com.wallimn.services.example;
import java.io.IOException;
import java.net.MalformedURLException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.ServiceException;
import junit.framework.TestCase;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* 服务测试类
* <br/>
* 编码:wallimn 时间:2011-9-20 下午04:37:38<br/>
* 版本:V1.0<br/>
*/
public class TestHelloWorldService extends TestCase{
private static final Log log = LogFactory.getLog(TestHelloWorldService.class);
//这两个值的IP、端口、ContextPath根据实际情况进行修改
private static final String HELLO_SERVICE_ENDPOINT = "http://127.0.0.1:8181/TEST/services/HelloServices?wsdl";
private static final String namespaceURI = "http://127.0.0.1:8181/TEST/services/HelloServices";
public void testSayHello() {
try {
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(new java.net.URL(
HELLO_SERVICE_ENDPOINT));
call.setOperationName(new QName(namespaceURI, "sayHello"));
call.setReturnType(org.apache.axis.Constants.XSD_STRING);
try {
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!");
}
public void testSayHelloToPerson() {
try {
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(new java.net.URL(
HELLO_SERVICE_ENDPOINT));
call.setOperationName(new QName(namespaceURI,"sayHelloToPerson"));
call.addParameter("name", org.apache.axis.Constants.XSD_STRING, ParameterMode.IN);
call.setReturnType(org.apache.axis.Constants.XSD_STRING);
try {
String ret = (String) call.invoke(new Object[] { "Stephen" });
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 callSayHelloToPerson service error!");
}
public void testGetNameFromDb() {
try {
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(new java.net.URL(
HELLO_SERVICE_ENDPOINT));
call.setOperationName(new QName(namespaceURI,
"getNameFromDb"));
//测试数据库查询服务,使用下面的代码
// call.setOperationName(new QName(namespaceURI,
// "getNameFromDb"));
call.setReturnType(org.apache.axis.Constants.XSD_STRING);
try {
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 callGetNameFromDb service error!");
}
public void testSaySimpleArray() {
try {
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(new java.net.URL(
HELLO_SERVICE_ENDPOINT));
call.setOperationName(new QName(namespaceURI, "saySimpleArray"));
call.setReturnType(new QName(namespaceURI, "saySimpleArrayResponse"),
String[].class);
try {
String[] ret = (String[]) call.invoke(new Object[] {});
System.out.println("返回数组示例:");
for(int i=0; i<ret.length; i++){
System.out.println(ret[i]);
}
return;
} catch (IOException e) {
e.printStackTrace();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ServiceException e) {
e.printStackTrace();
}
log.error("call callSayArray service error!");
}
public void testSayObjectArray() {
try {
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(new java.net.URL(
HELLO_SERVICE_ENDPOINT));
call.setOperationName(new QName(namespaceURI, "sayObjectArray"));
QName qn = new QName("urn:BeanService", "Order");
call.registerTypeMapping(Order.class, qn,
new org.apache.axis.encoding.ser.BeanSerializerFactory(
Order.class, qn),
new org.apache.axis.encoding.ser.BeanDeserializerFactory(
Order.class, qn));
call.setReturnType(new QName(namespaceURI, "sayObjectArrayResponse"),
Order[].class);
try {
Order[] ret = (Order[]) call.invoke(new Object[] {});
System.out.println("返回数组示例:");
for(int i=0; i<ret.length; i++){
System.out.println(ret[i].getCustomerName());
}
return;
} catch (IOException e) {
e.printStackTrace();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ServiceException e) {
e.printStackTrace();
}
log.error("call callObjectArray service error!");
}
public void testShowOrder() {
Order order = new Order();
order.setCustomerName("http://wallimn.iteye.com");
order.setShippingAddress("275 Grove Street, Newton, MA");
String[] items = new String[] { "mp3jukebox", "1600mahBattery" };
int[] quantities = new int[] { 1, 4 };
order.setItemCodes(items);
order.setQuantities(quantities);
String result;
try {
Service service = new Service();
Call call = (Call) service.createCall();
QName qn = new QName("urn:BeanService", "Order");
call.registerTypeMapping(Order.class, qn,
new org.apache.axis.encoding.ser.BeanSerializerFactory(
Order.class, qn),
new org.apache.axis.encoding.ser.BeanDeserializerFactory(
Order.class, qn));
call.setTargetEndpointAddress(new java.net.URL(HELLO_SERVICE_ENDPOINT));
call.setOperationName(new QName("OrderProcessor", "processOrder"));
call.addParameter("arg1", qn, ParameterMode.IN);
call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);
result = (String) call.invoke(new Object[] { order });
} catch (Exception fault) {
result = "Error : " + fault.toString();
}
System.out.println(result);
}
public void testGetNameById(){
try {
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(new java.net.URL(HELLO_SERVICE_ENDPOINT));
call.setOperationName(new QName(namespaceURI,"getNameById"));
QName qnName = new QName("name");
call.addParameter("id", org.apache.axis.Constants.XSD_INTEGER, ParameterMode.IN);
//call.addParameter("name", org.apache.axis.Constants.XSD_STRING, ParameterMode.OUT);
call.addParameter(qnName, org.apache.axis.Constants.XSD_STRING, ParameterMode.OUT);
call.setReturnType(org.apache.axis.Constants.XSD_STRING);
try {
String ret = (String) call.invoke(new Object[] { 1 });
call.getOutputParams().get("name");
System.out.println("The return value is:" + ret);
//call.getOutputParams()返回的Map中的key为QName,debug一下才发现。
System.out.println("The person is "+call.getOutputParams().get(qnName));
return;
} catch (IOException e) {
e.printStackTrace();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ServiceException e) {
e.printStackTrace();
}
log.error("call callSayHelloToPerson service error!");
}
}
三、其它辅助的东东[b][/b]
package com.wallimn.services.example;
public class Order {
/** Who's ordering */
private String customerName;
/** Where do they live */
private String shippingAddress;
/** Which items do we want */
private String itemCodes[];
/** And how many */
private int quantities[];
// Bean accessors
public Order(String name){
this.customerName = name;
}
public Order(){
}
public String getCustomerName()
{ return customerName; }
public void setCustomerName(String name)
{ customerName = name; }
public String getShippingAddress()
{ return shippingAddress; }
public void setShippingAddress(String address)
{ shippingAddress = address; }
public String [] getItemCodes()
{ return itemCodes; }
public void setItemCodes(String [] items)
{ itemCodes = items; }
public int [] getQuantities()
{ return quantities; }
public void setQuantities(int [] quants)
{ quantities = quants; }
}
部署文件 (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="com.wallimn.services.example.HelloWorldService"/>
<parameter name="allowedMethods" value="*"/>
<beanMapping qname="myNS:Order" xmlns:myNS="urn:BeanService" languageSpecificType="java:com.wallimn.services.example.Order"/>
</service>
</deployment>
部署
脚本(deploy.bat):
java -Djava.ext.dirs=../lib org.apache.axis.client.AdminClient -lhttp://localhost:8181/TEST/services/AdminService deploy.wsdd
pause
获取数据库连接的类(使用了proxool连接池):
package com.wallimn.services.util;
import java.sql.Connection;
import java.sql.DriverManager;
import org.logicalcobwebs.proxool.ProxoolException;
import org.logicalcobwebs.proxool.configuration.PropertyConfigurator;
public class ConnManager {
static String CLASS_ROOT = null;
static{
CLASS_ROOT = ConnManager.class.getResource("/").getPath();
try {
// Java应用中先要加载配置文件,否则谁知道你配置给谁用的
PropertyConfigurator.configure(CLASS_ROOT+ "proxool.properties");
} catch (ProxoolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Connection getConnection() {
try {
// 1:注册驱动类,这次这个驱动已经不是Oracle的驱动了,是Proxool专用的驱动
Class.forName("org.logicalcobwebs.proxool.ProxoolDriver");
// 2:创建数据库连接,这个参数是一个字符串,是数据源的别名,在配置文件中配置的timalias,参数格式为:proxool.数据源的别名
Connection conn = DriverManager.getConnection("proxool.proxool-pool");
return conn;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static ConnManager instance = null;
public static ConnManager getInstance() {
if (instance == null)
instance = new ConnManager();
return instance;
}
}