[置顶] webservice系列1---基于web工程上写一个基本数据类型
本节摘要:之前在一篇博客中介绍过如何写一个webservice(http://www.cnblogs.com/java-pan/archive/2011/11/25/axis_webservice.html),不过那个webservice是在工作项目中直接添加的,中间少了很多麻烦,不是白手起家总感觉前面一步一步的过程不清楚。myeclipse自带的也有如何新建一个webservice工程,这也不是我要说的,项目中这个也不实用,项目中都是在当前开发的web工程中写一个webservice,谁会再去新建一个工程,那不是扯淡吗?本节在一个已经存在的web工程中,来新建类、新建配置文件,发布webservice、访问webservice。基于axis1.4的版本来完成的。
preparation 1.在阅读本机之前你需要看以下相关知识: JDBC; JDBC的介绍这里就不说了,网上忒多的资料了,这个也是做java接触数据库时必会的 ibatis; 可以参考我之前的博客http://www.cnblogs.com/java-pan/archive/2012/03/21/ibatis.html XStream; 可以参考我之前的博客http://www.cnblogs.com/java-pan/archive/2011/10/25/Object_xml.html axis; 可以参考我之前的博客http://www.cnblogs.com/java-pan/archive/2011/11/25/axis_webservice.html 2.项目结构 myeclipse:6.5 tomcat:5.0 system:win7 JDK:项目的版本是1.5 编译采用的是1.4 说明:本节介绍的是基于axis的webservice,采用的版本为axis1.4 说明:lib下一共中13个jar包,截图的图片也有13个jar包,但是博客发布后显示的只有8个jar包,可以图片另存为看到所有的jar包。 package com.bean; /** * *Module: Dept.java *Description: 写一个oracle数据库自带的部门表dept的javabean *Company: *Author: pantp *Date: May 1,2012 */ public class Dept { public int deptNo; public String dName; public String loc; public int getDeptNo() { return deptNo; } public void setDeptNo(int deptNo) { this.deptNo = deptNo; } public String getDName() { return dName; } public void setDName(String name) { dName = name; } public String getLoc() { return loc; } public void setLoc(String loc) { this.loc = loc; } }数据库连接文件-ConnectDataBase.java ConnectDataBase package com.cn; import java.io.IOException; import java.io.Reader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import com.ibatis.common.resources.Resources; import com.ibatis.sqlmap.client.SqlMapClient; import com.ibatis.sqlmap.client.SqlMapClientBuilder; /** * *Module: ConnectDataBase.java *Description: 数据库连接类,采用两种方式:1.JDBC 2.Ibatis框架 *Company: *Author: pantp *Date: May 1,2012 */ public class ConnectDataBase { //采用JDBC的方式连接数据 private final static String USERNAME = "scott"; private final static String PASSWORD = "orcl"; private final static String URL = "jdbc:Oracle:thin:@localhost:1521:orcl"; private final static String DRIVER = "oracle.jdbc.driver.OracleDriver"; static Connection conn = null; // 获取连接 static { // 加载驱动 try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { e.printStackTrace(); } // 获得连接对象conn try { conn = DriverManager.getConnection(URL,USERNAME,PASSWORD); } catch (SQLException e) { e.printStackTrace(); } } //提供一个方法供外部调用,获得JDBC连接对象conn public static Connection getConnection() { return conn; } // 定义ibatis映射文件的位置,写配置文件的完整路径 private static String resource = "com/ibatis/SqlMapConfig.xml"; private static SqlMapClient sqlMapClient = null; static { try { Reader reader = Resources.getResourceAsReader(resource); sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader); reader.close(); } catch (IOException e) { e.printStackTrace(); } } //提供一个方法供外部调用,获得Ibatis的连接对象sqlMapClient public static SqlMapClient getSqlMapClient(){ return sqlMapClient; } } 实体类对应的映射文件-Dept.xml <?xml version="1.0" encoding="UTF-8"?> <!-- author:pantp date:2012/05/01 description:javabean对应的xml配置文件 --> <!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd"> <sqlMap> <typeAlias alias="Dept" type="com.bean.Dept" /> <!-- 精确查询 按照条件查询记录 按照部门编号DEPTNO查询 --> <select parameterClass="int" resultClass="Dept" id="selectById"> select deptno,dname,loc from dept where deptno=#deptNo# </select> </sqlMap>数据库连接属性文件-SqlMap.properties driver=oracle.jdbc.driver.OracleDriver url=jdbc:Oracle:thin:@127.0.0.1:1521:orcl username=scott password=orclibatis核心配置文件-SqlMapConfig.xml <?xml version="1.0" encoding="UTF-8"?> <!-- author:pantp date:2012/05/01 description:Ibatis框架的核心配置文件,主要是数据库连接属性文件和实体类和表的映射文件引入进来 --> <!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-config-2.dtd"> <sqlMapConfig> <!-- 数据库连接的属性文件 --> <properties resource="com/ibatis/SqlMap.properties" /> <transactionManager type="JDBC"> <dataSource type="SIMPLE"> <property value="${driver}" name="JDBC.Driver" /> <property value="${url}" name="JDBC.ConnectionURL" /> <property value="${username}" name="JDBC.Username" /> <property value="${password}" name="JDBC.Password" /> </dataSource> </transactionManager> <!-- 实体类和数据库表的映射 --> <sqlMap resource="com/ibatis/Dept.xml" /> </sqlMapConfig>定义查询服务的接口文件-IQueryInfoSV.java package com.interfaces; import java.sql.SQLException; /** * *Module: IQueryInfoSV.java *Description: 定义查询的接口 *Company: *Author: pantp *Date: May 1,2012 */ public interface IQueryInfoSV { //JDBC public abstract String queryDept1(int deptNo) throws SQLException; //ibatis public abstract String queryDept2(int deptNo) throws SQLException; }定义查询服务的实现类-QueryInfoSVImpl.java package com.impl; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import com.bean.Dept; import com.cn.ConnectDataBase; import com.ibatis.sqlmap.client.SqlMapClient; import com.interfaces.IQueryInfoSV; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer; import com.thoughtworks.xstream.io.xml.XppDriver; import java.sql.SQLException; /** * *Module: QueryInfoSVImpl.java *Description: 根据部门编号查询oracle自带的dept表,提供两种查询方式:1.JDBC 2.Ibatis *Company: *Author: pantp *Date: May 1,2012 */ public class QueryInfoSVImpl implements IQueryInfoSV { // 采用JDBC方式连接数据库的查询操作 public String queryDept1(int deptNo) throws SQLException { // 获取JDBC的连接 Connection conn = ConnectDataBase.getConnection(); // 拼装SQL语句 String sql = "select deptno,loc from dept where deptno=" + deptNo; // 获得预处理对象pst PreparedStatement pst = conn.prepareStatement(sql); // 查询结果集 ResultSet rs = pst.executeQuery(); // 采用next()方法取得数据库数据,deptNo是逐渐采用deptNo查询,要么没有查到数据,要么只能查到一条数据 String result = ""; Dept dept = null; while (rs.next()) { dept = new Dept(); dept.deptNo = deptNo; dept.dName = rs.getString("dName"); dept.loc = rs.getString("loc"); } result = getXML(dept); return result; } // 采用ibatis连接数据库并按部门编号精确查找 public String queryDept2(int deptNo) throws SQLException { // 获得ibatis的连接对象sqlMapClient SqlMapClient sqlMapClient = ConnectDataBase.getSqlMapClient(); Dept dept = null; try { sqlMapClient.startTransaction();// 开始事务 // 执行查询 此处的"selectById"对应Dept.xml文件中select标签的id属性 dept = (Dept) sqlMapClient.queryForObject("selectById",new Integer(deptNo)); sqlMapClient.commitTransaction();// 提交事务 } catch (SQLException e) { try { sqlMapClient.getCurrentConnection().rollback();// 回滚事务 } catch (SQLException e1) { e1.printStackTrace(); } e.printStackTrace(); } finally { try { sqlMapClient.endTransaction();// 结束事务 } catch (SQLException e) { e.printStackTrace(); } } // 组装xml报文并返回 return getXML(dept); } // 采用XStream方式组装XML public static String getXML(Dept dept) { // 用于保存XML的内容 String xmlbody = ""; // 用于保存XML的头部 String xmlhead = "<?xml version="1.0" encoding="UTF-8"?>n"; if (null != dept) { // 构造一个xstream对象,此种构造方式解决下划线站两个字符的问题 XStream xstream = new XStream(new XppDriver( new XmlFriendlyReplacer("-_","_"))); // 设置别名,不设置的话显示为Dept_Info显示为com.bean.Dept xstream.alias("DEPT_INFO",Dept.class); xstream.aliasField("DEPTNO",Dept.class,"deptNo"); xstream.aliasField("DNAME","dName"); xstream.aliasField("LOC","loc"); // 把实体类转换为XML xmlbody = xstream.toXML(dept); } else { // 处理根据编号没有查询到数据的情况 StringBuffer sb = new StringBuffer(); sb .append("<DEPT_INFO><DEPTNO></DEPTNO><DNAME></DNAME><LOC></LOC></DEPT_INFO>"); xmlbody = sb.toString(); } return xmlhead + xmlbody; } }测试类-Test1.java 用于测试JDBC和ibatis的数据库连接是否正常 package com.test; import java.sql.SQLException; import com.impl.QueryInfoSVImpl; import com.interfaces.IQueryInfoSV; /** * *Module: Test1.java *Description: 测试JDBC和Ibatis数据库查询是否正常 *Company: *Author: ptp *Date: May 1,2012 */ public class Test1 { // 测试数据库是可以正常查询 public static void main(String[] args) throws SQLException { int deptNo = 10; test1(deptNo); test2(deptNo); } //测试JDBC方式连接数据库是否正常 public static void test1(int deptNo) throws SQLException { IQueryInfoSV query = new QueryInfoSVImpl(); String dept = query.queryDept1(deptNo); System.out .println("n===============采用JDBC方式查询数据库连接正常 author<pantp>=======n"); System.out.println(dept); System.out .println("n===============采用JDBC方式查询数据库连接正常==================n"); } //测试ibatis方式连接数据库是否正常 public static void test2(int deptNo) throws SQLException { IQueryInfoSV query = new QueryInfoSVImpl(); String dept = query.queryDept2(deptNo); System.out .println("n===============采用ibatis方式查询数据库连接正常 author<pantp>========n"); System.out.println(dept); System.out .println("n===============采用ibatis方式查询数据库连接正常==================n"); } }测试类-Test2.java 用于测试webservice服务是否可以正常调用 package com.test; import java.net.MalformedURLException; import java.net.URL; import java.rmi.RemoteException; import javax.xml.rpc.ParameterMode; import javax.xml.rpc.ServiceException; import org.apache.axis.client.Call; import org.apache.axis.encoding.XMLType; /** * *Module: Test2.java *Description: 项目中常用调用webservice方式有两种,stub桩的形式和动态调用,本次测试就用动态调用的方式 *Company: *Author: pantp *Date: May 1,2012 */ public class Test2 { // 调用webservice public static void main(String[] args) { test2(); } /** * 动态调用接口访问webservice服务的步骤如下: * 1.创建service对象 * 2.创建url对象 * 3.创建call对象, * 4.调用webservice的方法 * 5.处理返回结果 */ public static void test2() { try { // 1.创建service对象,通过axis自带的类创建 org.apache.axis.client.Service service = new org.apache.axis.client.Service(); // 2.创建url对象 String wsdlUrl = "http://127.0.0.1:8080/WebService/services/queryInfo?WSDL";// 请求服务的URL URL url = new URL(wsdlUrl);// 通过URL类的构造方法传入wsdlUrl地址创建URL对象 // 2.创建服务方法的调用者对象call,设置call对象的属性 Call call = (Call) service.createCall(); call.setTargetEndpointAddress(url);// 给call对象设置请求的URL属性 String serviceName = "queryDept2";//webservice的方法名 call.setOperationName(serviceName);// 给call对象设置调用方法名属性 call.addParameter("deptNo",XMLType.XSD_INT,ParameterMode.IN);// 给call对象设置方法的参数名、参数类型、参数模式 call.setReturnType(XMLType.SOAP_STRING);// 设置调用方法的返回值类型 // call.setTimeout(new Integer(5000));//设置超时限制 // 4.通过invoke方法调用webservice Integer deptNo = new Integer(50); String dept = (String) call.invoke(new Object[] { deptNo });// 调用服务方法 //5.打印返回结果 System.out .println("n===============调用webservice成功(无安全机制) author<pantp>=======n"); System.out.println(dept); System.out .println("n===============调用webservice成功(无安全机制)==================n"); } catch (MalformedURLException e) { e.printStackTrace(); } catch (ServiceException e) { e.printStackTrace(); } catch (RemoteException e) { e.printStackTrace(); } } } web.xml-项目配置文件 <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>AxisServlet</servlet-name> <servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> <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> </web-app> server-config.wsdd-webservice服务部署的配置文件 <?xml version="1.0" encoding="UTF-8"?> <deployment name="defaultClientConfig" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java" xmlns:handler="http://xml.apache.org/axis/wsdd/providers/handler" xmlns="http://xml.apache.org/axis/wsdd/"> <globalConfiguration name="GlobalConfiguration1" type="" regenerateElement="false"> <requestFlow name="RequestFlow1" type="" regenerateElement="false"> <handler name="Handler1" type="java:org.apache.axis.handlers.JWSHandler" regenerateElement="false"> <parameter name="scope" value="session" regenerateElement="false"/> </handler> <handler name="Handler2" type="java:org.apache.axis.handlers.JWSHandler" regenerateElement="false"> <parameter name="scope" value="request" regenerateElement="false"/> <parameter name="extension" value=".jwr" regenerateElement="false"/> </handler> </requestFlow> </globalConfiguration> <handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper" regenerateElement="false"/> <handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder" regenerateElement="false"/> <handler name="Authenticate" type="java:org.apache.axis.handlers.SimpleAuthenticationHandler" regenerateElement="false"/> <transport name="http" type="" regenerateElement="false"> <requestFlow name="RequestFlow1" type="" regenerateElement="false"> <handler name="Handler1" type="URLMapper" regenerateElement="false"/> <handler name="Handler2" type="java:org.apache.axis.handlers.http.HTTPAuthHandler" regenerateElement="false"/> </requestFlow> </transport> <transport name="local" type="" regenerateElement="false"> <responseFlow name="ResponseFlow1" type="" regenerateElement="false"> <handler name="Handler1" type="LocalResponder" regenerateElement="false"/> </responseFlow> </transport> <service name="queryInfo" provider="java:RPC"> <!-- 服务类名 --> <parameter name="className" value="com.impl.QueryInfoSVImpl" /> <!-- 允许访问所有方法 --> <parameter name="allowedMethods" value="*" /> </service> </deployment> result 发布项目,启动tomcat。 运行Test1.java中的main方法,测试JDBC和ibatis数据库查询是否正常,查询结果如下: 在浏览器访问发布的wsdl 运行Test2类中的main方法,测试结果如下图: webservice服务存在以下2个问题: 源码:http://download.csdn.net/detail/xuxu198899223/5344482 问题定位及解决方法: 关于此博客中的问题一直未解决,心中的石头也一直未落地; 经过这两天的再一次拿出来查找问题、定位问题,终于得到了答案。 解决方式:把ConnectDataBase类中采用ibatis操作数据库的代码给去掉,然后再一次重新发布工程,启动tomcat, 此时,在IE浏览器可以正常的访问wsdl地址,采用webservice客户端形式(包括动态调用和stub桩的形式)也可以正常的调用webservice服务。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |