WebService之超級HelloWorld

wallimn發表於2011-09-20
  看了網上的很多java+axis的Hello World程式,幾乎(注意是幾乎)千篇一律一個超級簡單的服務:輸入String,輸出String,實踐指導性不太強。經過幾天的研究,我來總結總結寫一篇超級Hello World,希望對Web Service的初學者(具備Web Service基本常識)有所幫助。
  本文沒有系統地涉及的搭建環境的細節,只是多種介面情況(String等簡單對像、自定義物件、陣列做引數,返回物件、陣列、多返回值,以及資料庫連線池的使用)的服務編寫及呼叫方法示例程式。
  本人原創,轉載請保留本人資訊。時間:2011-09-20 作者:隔壁老王 地址:http://wallimn.iteye.com/blog/1176153

[b]一、服務類:[/b]

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";
}
}


[b]二、呼叫示例[/b]

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][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;
}

}

相關文章