http://jojayong.bokee.com/5592591.html
http://hi.baidu.com/zhengmh/blog/item/cf0f8011feb6c512b9127b8a.html
http://zqding.iteye.com/blog/834827
http://ziapple.blog.51cto.com/271886/55512
使用Axis开发Web Service< xmlnamespace prefix ="o" ns ="urn:schemas-microsoft-com:office:office" />
1. 概述
1.1.什么是WEB SERVICE
Web Service是一个软件接口,它描述了一组可以在网络上通过标准化的 XML 消息传递访问的操作,使得应用程序可以通过与平台和编程语言无关的方式相互通信。
1.2.什么是WSDL
WSDL(Web Service Description Language,Web服务描述语言)是基于XML的、用于描述Web服务标准、定义Web服务接口的定义语言。主要描述Web服务的三个基本属性:
·服务做些什么——服务所提供的操作(方法)
·如何访问服务——和服务交互的数据格式以及必要协议
·服务位于何处——协议相关的地址,如URL
1.3.什么是SOAP
SOAP(Simple Object Access Protocol, 简单对象访问协议)是一个基于XML的用于在分散或分布式的环境中交换信息的的协议。SOAP是Web Service的基本通信协议。
1.4.什么是AXIS
Axis是Apache组织推出的SOAP引擎,提供创建服务器端、客户端和网关SOAP操作的基本框架。
2. 配置与开发
2.1. 配置AXIS
2.1.1. 下载Axis
从Apache网站(http://ws.apache.org/axis/)下载最新的Axis资源包(目前最新版本为1.4,axis-src-1_4.zip)。解压Axis资源包,定义解压后的文件夹为AXIS_UNZIP_FOLDER,定义web应用系统的目录为APP_FOLDER。
2.1.2. 配置jar
将AXIS_UNZIP_FOLDER webapps axis WEB-INF lib目录下的全部jar文件复制到APP_FOLDER WEB-INF lib目录下,并将这些jar包加进构件工程的编译路径中(Eclipse的Java Build Path)。另外,如果APP_FOLDER WEB-INF lib中存在多个用途相同并且仅仅是版本不同的jar文件时,建议只保留最新版本jar文件。
2.1.3. 配置web.xml
将AXIS_UNZIP_FOLDER webapps axis WEB-INF web.xml文件中<web-app>元素包含范围内除了<display-name>、<session-config>和<welcome-file-list>这三个元素外的元素都复制到APP_FOLDER WEB-INF web.xml的<web-app>元素中。注意web.xml文件中的一些元素是不允许重复的,否则可能导致抛出IllegalArgumentException使得服务无法启动。等服务启动完成后,使用浏览器访问web应用系统的服务访问路径(一般是web应用系统的访问路径后加上services,如http://localhost:8088/fjdlweb/services),如果出现包含AdminService和Version这两个Services的页面则说明配置已经基本完成。
< xmlnamespace prefix ="v" ns ="urn:schemas-microsoft-com:vml" />
2.1.4. 配置server-config.wsdd
此时查看服务控制台则可以发现以下错误信息:ERROR EngineConfigurationFactoryServlet:162 - Unable to find config file. Creating new servlet engine config file: /WEB-INF/server-config.wsdd,要求在WEB-INF目录下增加用于暴露Web服务给客户程序的server-config.wsdd配置文件。
虽然Axis可以自动生成这个文件,但我们却无法对这个自动生成的文件进行配置。所以需要在APP_FOLDER WEB-INF目录下增加server-config.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">
<globalConfiguration>
<parameter name="adminPassword" value="admin"/>
<parameter name="attachments.Directory" value=""/>
<parameter name="attachments.implementation" value="org.apache.axis.attachments.AttachmentsImpl"/>
<parameter name="sendXsiTypes" value="true"/>
<parameter name="sendMultiRefs" value="true"/>
<parameter name="sendXMLDeclaration" value="true"/>
<parameter name="axis.sendMinimizedElements" value="true"/>
<requestFlow>
<handler type="java:org.apache.axis.handlers.JWSHandler">
<parameter name="scope" value="session"/>
</handler>
<handler type="java:org.apache.axis.handlers.JWSHandler">
<parameter name="scope" value="request"/>
<parameter name="extension" value=".jwr"/>
</handler>
</requestFlow>
</globalConfiguration>
<handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder"/>
<handler name="Authenticate" type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>
<handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper"/>
<service name="Version" provider="java:RPC">
<parameter name="allowedMethods" value="getVersion"/>
<parameter name="className" value="org.apache.axis.Version"/>
</service>
<service name="AdminService" provider="java:MSG">
<parameter name="allowedMethods" value="AdminService"/>
<parameter name="enableRemoteAdmin" value="false"/>
<parameter name="className" value="org.apache.axis.utils.Admin"/>
<namespace>http://xml.apache.org/axis/wsdd/</namespace>
</service>
<transport name="local">
<responseFlow>
<handler type="LocalResponder"/>
</responseFlow>
</transport>
<transport name="http">
<requestFlow>
<handler type="URLMapper"/>
<handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/>
</requestFlow>
</transport>
</deployment>
重启tomcat服务后再次访问web应用系统的服务访问路径将看到和第一次成功访问web应用系统的服务访问路径时出现的页面则说明(由于浏览器会缓存xml文件,所以每次修改配置后都应重新打开浏览器访问)。server-config.wsdd的attachments.Directory参数配置的是使用Web Service调用上传附件的存放位置,由于目前暂不使用该功能,所以将其值置空,以后有需要时再设置成相应的附件存放目录。此外,我们还可以从server-config.wsdd中发现发布的服务是在<service>元素中定义的。以后增加服务和接口也是在server-config.wsdd中增加一个<service>元素并设置。至此,Axis的配置都已完成。接下来就是使用Axis开发Web Service了。
2.2. 使用AXIS开发WEB SERVICE
由于Axis封装了用于通讯的SOAP的相关内容,并提供了自动将Java类发布成WSDL的功能,所以在完成对Axis的配置后进行Web Service开发就显得异常简单。我们所要做的仅仅是用Java写一个用于提供了调用方法的Web服务类,然后将调用方法发布。
2.2.1. Web服务类的实现
Web服务类和以前系统开发中所实现的服务类是类似的,都是建立在DAO层上的对业务逻辑的实现,两者仅有的区别可能在于Web服务类对事务的要求和返回类型的要求比较严格。由于服务器到客户端中间传递的是xml,所以在提供服务的过程中,请求和响应发送的的内容中的数据类型非常有限的,所以目前仅使用String作为请求参数和返回消息。
以下是实现用户注册的Web服务类:
public class SystemUserService {
protected static Log log = LogFactory.getLog(SystemUserService.class);
private DBAction dbaction = null;
private static final String USER_SELECT_SQL = "select fusercode,fpassword from t_system_user where fusername = ? and fusercode = ? ";
private static final String USER_DELETE_SQL = "delete from t_system_user where fusername = ? and fusercode = ? ";
private static final String USER_INSERT_SQL = "insert into t_system_user (fuser_id,fusercode,fusername,fpassword,fpersonnel_id,fdep_id,fdep_name) values (?,?,?,?,?,?,?)";
private static final String PERSON_SELECT_SQL = "select personnel_id,dept_id,dept_name from t_ljdl_rlzygl_personnel,t_ljdl_rlzygl_dept where organize_id=dept_id and first_name = ? and personnel_inside_id = ?";
private static final String ID_PREFIX_USER = "user";
private static final String PARAM_KEY_DEPT_ID = "dept_id";
private static final String PARAM_KEY_DEPT_NAME = "dept_name";
private static final String PARAM_KEY_PESON_ID = "personnel_id";
private static final String MSG_PERSON_NOT_FOUND = "错误:人员[?,?]不存在";
private static final String MSG_USER_EXISTS = "错误:帐号[?,?]已存在";
//初始化资源
public SystemUserService(){
try {
dbaction = new DBAction();
} catch (Exception e) {
log.error("SystemUserService fails to initialize resource");
}
}
public String addUser(String userCode,String userName,String account,String password){
try {
//判断用户帐号是否存在
String[] userArray = new String[]{userName,account};
dbaction.setDBStmt(StringUtils.fillParams(USER_SELECT_SQL,userArray));
ResultSet userRS = dbaction.doSelectRs();
if(userRS != null && userRS.next()){
return StringUtils.fillParams(MSG_USER_EXISTS,userArray,false);
}
//判断人员是否存在
ArrayList sqlList = new ArrayList();
String[] userValues;
String userID = IDBuilder.getID(ID_PREFIX_USER);
String[] personArray = new String[]{userName,userCode};
dbaction.setDBStmt(StringUtils.fillParams(PERSON_SELECT_SQL,personArray));
ResultSet personRS = dbaction.doSelectRs();
if(personRS != null && personRS.next()){ //人员存在时才允许注册帐号表
String deptID = personRS.getString(PARAM_KEY_DEPT_ID);
String deptName = personRS.getString(PARAM_KEY_DEPT_NAME);
String dbPersonID = personRS.getString(PARAM_KEY_PESON_ID);
UserValues = new String[]{userID,account,userName,password,dbPersonID,deptID,deptName};
sqlList.add(StringUtils.fillParams(USER_DELETE_SQL,userArray));
sqlList.add(StringUtils.fillParams(USER_INSERT_SQL,userValues));
dbaction.batchUpdate(sqlList);
log.info(StringUtils.fillParams("register User[?,?] success ",userArray,false));
}else{ //人员不存在时返回提示
return StringUtils.fillParams(MSG_PERSON_NOT_FOUND,personArray,false);
}
} catch (Exception e) {
log.error(e);
return WebServiceConstants.MSG_DB_EXCEPTION;
}
return WebServiceConstants.MSG_SUCCESS;
}
}
2.2.2. Web服务类的发布
修改APP_FOLDER WEB-INF server-config.wsdd,加入以下内容。
<service provider="java:RPC">
<parameter value="com.zkhx.webservice.service.SystemUserService"/>
<parameter value="addUser"/>
<!--
<parameter value="*"/>
à
</service>
当service元素中设置<parameter value="*"/>时,Web服务类的所有方法及其继承自基类的方法都将被发布。出于安全方面的考虑,建议不这使用allowedMethods参数,而采用allowedMethod参数逐一发布方法。另外,同样出于安全上的考虑,请将server-config.wsdd中的Version、AdminService这两个服务删除。
重启动Tomcat服务,使用浏览器访问web应用系统的服务访问路径,确认配置是否生效。
2.2.3. Web服务类的测试
Axis不仅实现了对Web Service发布的支持,同样实现了对Web Service调用的支持。以下是调用SystemUserService的测试类:
public class SystemUserServiceClient {
//WSDL文件中service的address
private static final String SERVICE_END_POINT = "http://localhost:8088/fjdlweb/services/SystemUserService";
//WSDL文件中service的namespace
private static final String NAMESPACE_URI = "http://service.webservice.zkhx.com";
public static void main(String[] arsg) {
try{
Service service = new Service();
Call addCall = (Call) service.createCall();
addCall.setOperationName(new QName(NAMESPACE_URI, "addUser"));
addCall.setTargetEndpointAddress(new URL(SERVICE_END_POINT));
Object[] addParamsArray = new Object[]{
new Object[]{"用户工号","用户姓名","帐号","密码"}, //错误人员
new Object[]{"a0022","陈秀琴","a0022","888888"}, //已存在的帐号
new Object[]{"a0022","陈秀琴","abcdef","888888"}, //允许注册的帐号(测试完成后请删除)
new Object[]{"a0022","陈秀琴","abcdef","888888"} //已存在的帐号
};
System.out.println("----------开始测试注册用户服务----------");
for (int i = 0; i < addParamsArray.length; i++) {
//service的request的参数
Object[] params = (Object[])addParamsArray[i];
System.out.println((String) addCall.invoke(params));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行测试程序代码,将看到下面的输出内容:
----------开始测试注册用户服务----------
错误:人员[用户姓名,用户工号]不存在
错误:帐号[陈秀琴,a0022]已存在
成功:服务调用完成
错误:帐号[陈秀琴,abcdef]已存在
至此,使用Axis发布、调用Web Service都已完成。
3. 待完善内容
4.1.安全
目前对于服务调用的权限控制、日志均未采取相应的处理措施,应在下一步工作中实现Filter(或Handler)来监听服务的调用并对需要记录的调用进行日志处理。
应对参数的准确性进行校验,以防止注入攻击等其他外部攻击,提高系统的安全性。
4.2.高级用法
目前仅仅是使用String作为参数使用,对如何在WSDL中定义对象类型、如何调用以对象类型为参数的接口、如何处理以对象类型为参数的返回内容都不清楚。
4. 资源
4.1.WSDL
http://www.cnblogs.com/meil/archive/2006/08/26/487280.html
4.2.SOAP
http://zmdxyboyandy.blog.bokee.net/bloggermodule/blog_viewblog.do?id=72058
4.3.AXIS
4.4. WEB SERVICES开发
http://jojayong.bokee.com/5592591.html
4.5. 使用 AJAX 调用 SOAP WEB 服务
http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/