lizongbo at 618119.com 工作,生活,Android,前端,Linode,Ubuntu,nginx,java,apache,tomcat,Resin,mina,Hessian,XMPP,RPC

2011年08月21日

手机wap网站开发过程中通过dtd校验来检查wap1.0和wap2.0的页面语法

Filed under: Xhtml — 标签:, , , , , , , — lizongbo @ 13:40

手机wap网站开发过程中通过dtd校验来检查wap1.0和wap2.0的页面语法

对手机wap网站的wap1.0和wap2.0页面内容进行dtd的校验非常有价值,既可以保证页面对移动终端的兼容性,也能促使开发人员写出高质量的代码。

以前早期在做普通web页面开发的时候,对html的语法一知半解就开搞,标签不闭合,嵌套错误等问题从来没注意过,只管在IE6里打开能正常显示即可,
结果带来的后果就是在页面某个位置需要插入一段新内容时,整个页面就错位了,变得非常难看,也不知道怎么样来搞好,痛苦万分。

后来进行的是wap页面开发,wap页面用的是wap1.0的xml,加上各种山寨手机对wap页面的解析可不像电脑上的浏览器那样可以对错误的写法进行兼容,于是各种兼容性问题就出来了。
因此学会了用m3gate打开页面进行检查,只有m3gate打开时不出错的页面,才能放心的在各种山寨上正常显示而不出错。
再到后来,经过学习和总结,发现m3gate的检查其实和dtd校验的效果是一样的,于是摸索出通过dtd校验来发现标签嵌套错误等问题。

移动终端的发展是日新月异,很快就进入到了wap2.0时代,当然这个时候的手机浏览器对wap2.0的兼容性就好多了。
一些小的错误,也能兼容掉,但是难免也出现莫名其妙的错误,由于wap2.0的xml元素定义用的也还是dtd,因此继续用dtd校验来搞定。

wap1.0和wap2.0的自动化监控校验流程如下:
测试工具访问各个页面,获取对应的xml内容,保存为字符串,然后将页面的dtd声明部分,替换为对应的本地声明映射(这样避免联网获取dtd文件而影响性能),
生成新的字符串,然后使用java的xml parser进行解析,解析过程中如果有抛出各种异常,那就是把页面内容有错的地方全部揪出来了,再通知开发人员进行页面内容的bug修复。
通常比如img元素缺少alt属性等问题都可以及时发现。

正式环境则通过自动化监控脚本定期访问业务进行检查。

进行dtd校验的相关代码如下:

1.将远程的dtd等实体解析映射到本地的LocalEntityResolver(自动化监控中是通过字符串替换来将dtd的声明替换为本地路径,我是直接通过EntityResolver来进行映射):

[code]
package com.lizongbo.xml;

import java.io.IOException;

import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
* 将xml组件依赖的远程的schema文件都映射到本地
*
* @author lizongbo
*
*/
public class LocalEntityResolver implements EntityResolver {

@Override
public InputSource resolveEntity(String publicId, String systemId)
throws SAXException, IOException {
System.out.println(“publicId==” + publicId + “,systemId==” + systemId);
if (“-//W3C//DTD XHTML 1.0 Strict//EN”.equals(publicId)) {
String url = “/com/lizongbo/web/validation/dtds/www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”;
System.out.println(systemId + ” LocalEntityResolver yyyy map to:”
+ url);
System.out.println(String.class.getResource(url));
if (String.class.getResource(url) != null) {
InputSource is = new InputSource(
String.class.getResourceAsStream(url));
is.setPublicId(publicId);
is.setSystemId(systemId);
return is;
}
}
if (systemId != null) {
String ids[] = new String[] { “/xhtml-attribs-1.mod”,
“/xhtml-notations-1.mod”, “/xhtml-datatypes-1.mod”,
“/xhtml-qname-1.mod”, “/xhtml-mobile10-model-1.mod”,
“/xhtml-mobile10-model-1.mod”, “xhtml-charent-1.mod”,
“/xhtml-symbol.ent”, “/xhtml-lat1.ent”,
“/xhtml-special.ent”, “/xhtml-inlstruct-1.mod”,
“/xhtml-inlphras-1.mod”, “/xhtml-blkstruct-1.mod”,
“xhtml-blkphras-1.mod”, “/xhtml-lat1.ent”,
“/xhtml-lat1.ent” };

for (int i = 0; i < ids.length; i++) {
if (systemId.endsWith(ids[i])) {
String url = “/com/lizongbo/web/validation/dtds/www.w3.org/xhtml-modularization/DTD/”
+ systemId.substring(systemId.lastIndexOf(“/”) + 1);
System.out.println(” local ” + systemId + ” try map to:”
+ url);
if (String.class.getResource(url) == null) {
url = “/com/lizongbo/web/validation/dtds/www.w3.org/TR/xhtml-modularization/DTD/”
+ systemId
.substring(systemId.lastIndexOf(“/”) + 1);
System.out.println(” local ” + systemId
+ ” retry map to:” + url);
}
if (String.class.getResource(url) == null) {
url = “/com/lizongbo/web/validation/dtds/www.wapforum.org/DTD/”
+ systemId
.substring(systemId.lastIndexOf(“/”) + 1);
System.out.println(” local ” + systemId
+ ” retry map to:” + url);
}
System.out.println(“try get ”
+ String.class.getResource(url));
if (String.class.getResource(url) != null) {
InputSource is = new InputSource(
String.class.getResourceAsStream(url));
is.setPublicId(publicId);
is.setSystemId(systemId);
return is;
}
}
}
if (systemId.endsWith(“.xsd”)) {
String url = “/com/lizongbo/web/validation/xsds/”
+ systemId.replace(“http://”, “”);
System.out.println(systemId + ” LocalEntityResolver 22 map to:”
+ url);
System.out.println(String.class.getResource(url));
if (String.class.getResource(url) != null) {
InputSource is = new InputSource(
String.class.getResourceAsStream(url));
is.setPublicId(publicId);
is.setSystemId(systemId);
return is;
}
} else {
String url = “/com/lizongbo/web/validation/dtds/”
+ systemId.replace(“http://”, “”);
System.out.println(systemId + ” LocalEntityResolver 11 map to:”
+ url);
System.out.println(String.class.getResource(url));
if (String.class.getResource(url) == null) {
url = “/com/lizongbo/web/validation/dtds/www.w3.org/TR/xhtml-modularization/DTD/”
+ systemId.replace(“http://”, “”);
System.out.println(” local ” + systemId + ” retry map to:”
+ url);
}
if (String.class.getResource(url) != null) {
InputSource is = new InputSource(
String.class.getResourceAsStream(url));
is.setPublicId(publicId);
is.setSystemId(systemId);
return is;
}
}
}
return null;
}
}

[/code]

2.实际校验的代码:
[code]
package com.lizongbo.xml;

import java.io.*;
import java.net.*;

import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.parsers.*;

/**
* DTD校验工具类
*
* @author lizongbo
*
*/
public class DTDUtil {

/**
* @param args
* @throws SAXException
* @throws ParserConfigurationException
*/
public static void main(String[] args) throws SAXException,
ParserConfigurationException {
String urls[] = new String[] { “http://3g.sina.com.cn/?vt=1&pos=200”,// 新浪wap1.0
http://3g.sina.com.cn/?vt=3&pos=200”,// 新浪wap2.0
http://wap.sohu.com/?nid=1&v=1”,// 搜狐 wap1.0
http://wap.sohu.com/?nid=1&v=3”,// 搜狐 wap2.0
http://info50.3g.qq.com/g/s?aid=index&g_ut=1”,// 手机腾讯网wap1.0
http://info50.3g.qq.com/g/s?aid=index&g_ut=2”, // 手机腾讯网wap2.0
};
for (int i = 0; i < urls.length; i++) {
try {
String urlStr = urls[i];
String xml = downloadUrl(urlStr, null, “UTF-8”);
// System.out.println(xml);
validateWap(xml);
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println(“Over”);
}

/**
* 通过dtd校验wap2.0页面内容,如果抛出异常则说明页面内容有错
*
* @param xml
* @throws ParserConfigurationException
* @throws SAXException
* @throws IOException
*/
public static void validateWap(String xml)
throws ParserConfigurationException, SAXException, IOException {
// //xml = setDTDforWap20(xml);
// //System.out.println(xml);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(true);
DocumentBuilder db = dbf.newDocumentBuilder();
db.setEntityResolver(new LocalEntityResolver());
Document doc = db.parse(new InputSource(new StringReader(xml)));
System.out.println(doc.getFirstChild());
}

public static String downloadUrl(String urlStr, String referer,
String encoding) throws Exception {
String line = “”;
StringBuilder sb = new StringBuilder();
HttpURLConnection httpConn = null;
try {
URL url = new URL(urlStr);
System.out.println(urlStr);
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(
“proxy.lizongbo.com”, 8080));
proxy = Proxy.NO_PROXY;
httpConn = (HttpURLConnection) url.openConnection(proxy);
httpConn.setRequestProperty(“User-Agent”, “Nokia”);
httpConn.setDoInput(true);
httpConn.setDoOutput(true);
httpConn.setRequestMethod(“GET”);
if (referer != null) {
httpConn.setRequestProperty(“Referer”, referer);
}
httpConn.setConnectTimeout(1000);
BufferedReader in = null;
if (httpConn.getResponseCode() != 200) {
System.err.println(“error:” + httpConn.getResponseMessage());
in = new BufferedReader(new InputStreamReader(
httpConn.getErrorStream(), “UTF-8”));
} else {
in = new BufferedReader(new InputStreamReader(
httpConn.getInputStream(), “UTF-8”));
}
while ((line = in.readLine()) != null) {
sb.append(line).append(‘\n’);
}
System.out.println(httpConn.getHeaderFields());
// 关闭连接
httpConn.disconnect();
return sb.toString();
} catch (Exception e) {
// 关闭连接
if (httpConn != null) {
try {
httpConn.disconnect();
} catch (Exception e2) {
// TODO: handle exception
}
}
System.out.println(e.getMessage());
throw e;
}
}
}

[/code]

通过上面的例子,可以看到新浪,搜狐,手机腾讯网的wap1.0都校验ok。
而新浪的wap2.0(3G版)使用的声明不是http://www.wapforum.org/DTD/xhtml-mobile10.dtd,却是:xhtml1-strict.dtd

按xhtml1-strict.DTD校验的出错信息为:
Error: URI=null Line=127: Attribute “width” must be declared for element type “input”.
Error: URI=null Line=127: Attribute “height” must be declared for element type “input”.
Error: URI=null Line=127: The content of element type “form” must match “(p|h1|h2|h3|h4|h5|h6|div|ul|ol|dl|pre|hr|blockquote|address|fieldset|table|noscript|ins|del|script)*”.
Error: URI=null Line=155: The content of element type “form” must match “(p|h1|h2|h3|h4|h5|h6|div|ul|ol|dl|pre|hr|blockquote|address|fieldset|table|noscript|ins|del|script)*”.
Error: URI=null Line=236: Attribute value “gototop” of type ID must be unique within the document.
搜狐的wap2.0(彩版)虽然使用的dtd声明是:http://www.wapforum.org/DTD/xhtml-mobile10.dtd,但是页面内容中却使用xhtml1所定义的元素。
按xhtml-mobile10.dtd校验的出错信息为:
Error: URI=null Line=63: Element type “script” must be declared.
Error: URI=null Line=99: The content of element type “div” must match “(h1|h2|h3|h4|h5|h6|ul|ol|dl|p|div|pre|blockquote|address|hr|table|form|fieldset|br|span|em|strong|dfn|code|samp|kbd|var|cite|abbr|acronym|q|i|b|big|small|a|img|object|input|select|textarea|label)”.
Error: URI=null Line=100: Attribute “name” must be declared for element type “form”.
Error: URI=null Line=100: Attribute “accept-charset” must be declared for element type “form”.
Error: URI=null Line=107: Attribute “onclick” must be declared for element type “a”.
Error: URI=null Line=108: Attribute “onclick” must be declared for element type “a”.
Error: URI=null Line=109: Attribute “onclick” must be declared for element type “a”.
Error: URI=null Line=110: The content of element type “form” must match “(h1|h2|h3|h4|h5|h6|ul|ol|dl|p|div|pre|blockquote|address|hr|table|fieldset)+”.
Error: URI=null Line=112: Element type “font” must be declared.
Error: URI=null Line=112: The content of element type “div” must match “(h1|h2|h3|h4|h5|h6|ul|ol|dl|p|div|pre|blockquote|address|hr|table|form|fieldset|br|span|em|strong|dfn|code|samp|kbd|var|cite|abbr|acronym|q|i|b|big|small|a|img|object|input|select|textarea|label)”.

手机腾讯网的wap2.0使用xhtml-mobile10.dtd进行校验,出错信息最少,只有一条:
Error: URI=null Line=141: The content of element type “form” must match “(h1|h2|h3|h4|h5|h6|ul|ol|dl|p|div|pre|blockquote|address|hr|table|fieldset)+”.

 

 

2010年11月21日

根据sitemap.org的schema使用JAXB生成sitemap.xml的读写方法

Filed under: Java,Web — 标签:, , , , , , — lizongbo @ 13:37

根据sitemap.org的schema使用JAXB生成sitemap.xml的读写方法

sitemap协议的中文说明在:
http://sitemaps.org/zh_CN/protocol.php
对应的schema在:
Sitemap 的 XML 格式定义: http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd
Sitemap 索引文件格式定义:http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd
向google提交sitemap.xml是在:
https://www.google.com/webmasters/tools/home?hl=zh_CN
向百度提交sitemap.xml是在:http://sitemap.baidu.com/

xsd文件生成java代码的操作步骤如下:
1.下载xsd文件保存到D:\dev\xsds。
2.在JDK的bin目录下运行xjc命令生成java文件:
D:\dev\Java\jdk1.6.0_22\bin>xjc -d D:\dev\javasrc -p com.lizongbo.web.sitemaps.sitemap D:\dev\xsds\sitemap.xsd
parsing a schema…
compiling a schema…
com\lizongbo\web\sitemaps\sitemap\ObjectFactory.java
com\lizongbo\web\sitemaps\sitemap\TChangeFreq.java
com\lizongbo\web\sitemaps\sitemap\TUrl.java
com\lizongbo\web\sitemaps\sitemap\Urlset.java
com\lizongbo\web\sitemaps\sitemap\package-info.java

D:\dev\Java\jdk1.6.0_22\bin>xjc -d D:\dev\javasrc -p com.lizongbo.web.sitemaps.siteindex D:\dev\xsds\siteindex.xsd
parsing a schema…
compiling a schema…
com\lizongbo\web\sitemaps\siteindex\ObjectFactory.java
com\lizongbo\web\sitemaps\siteindex\Sitemapindex.java
com\lizongbo\web\sitemaps\siteindex\TSitemap.java
com\lizongbo\web\sitemaps\siteindex\package-info.java
3.将java文件都复制到java工程的src目录的对应包中。
4.将xsd文件复制到java工程的com.lizongbo.web.sitemaps包对应的文件夹中。
5.封装工具类SitemapUtil.java,代码如下:
[code]
package com.lizongbo.web.sitemaps;

import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.xml.sax.SAXException;

import com.lizongbo.web.sitemaps.siteindex.Sitemapindex;
import com.lizongbo.web.sitemaps.siteindex.TSitemap;
import com.lizongbo.web.sitemaps.sitemap.TUrl;
import com.lizongbo.web.sitemaps.sitemap.Urlset;
import com.lizongbo.web.sitemaps.sitemap.ObjectFactory;

/**
* 通过jaxb对sitemap.xml进行生成和解析的工具类
*
* @author lizongbo
*
*/
public class SitemapUtil {
private final static ObjectFactory sitemapFac = new ObjectFactory();
private final static com.lizongbo.web.sitemaps.siteindex.ObjectFactory siteindexFac = new com.lizongbo.web.sitemaps.siteindex.ObjectFactory();
private final static String SITEMAP_SCHEMA_LOCATION = “http://www.sitemaps.org/schemas/sitemap/0.9
+ “http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd”;
private final static String SITEINDEX_SCHEMA_LOCATION = “http://www.sitemaps.org/schemas/sitemap/0.9
+ “http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd”;
private final static String DOCTYPE = “<?xml version=\”1.0\” encoding=\”utf-8\”?>”;
private final static String ProcessingInstruction = “<?xml-stylesheet type=’text/xsl’ href=’http://618119.com/wp-content/plugins/google-sitemap-generator/sitemap.xsl’ ?>”;

public static Sitemapindex createSitemapindex() {
return siteindexFac.createSitemapindex();
}

public static TSitemap createTSitemap() {
return siteindexFac.createTSitemap();
}

public static TUrl createTUrl() {
return sitemapFac.createTUrl();
}

public static Urlset createUrlset() {
return sitemapFac.createUrlset();
}

public static String getSitemapXML(Urlset urlset) throws JAXBException,
SAXException {
JAXBContext jc = JAXBContext
.newInstance(“com.lizongbo.web.sitemaps.sitemap”);
Marshaller m = jc.createMarshaller();
StringWriter sw = new StringWriter();
sw.append(DOCTYPE).append(“\n”);
sw.append(ProcessingInstruction).append(“\n”);
//设置xml文本编码
m.setProperty(Marshaller.JAXB_ENCODING, “UTF-8”);
//设置为格式化输出结果
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
//设置为只输出xml节点片段
m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
//指定xsd路径
m.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, SITEMAP_SCHEMA_LOCATION);
SchemaFactory sf = SchemaFactory
.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(SitemapUtil.class
.getResource(“sitemap.xsd”));
//绑定Schema进行校验
m.setSchema(schema);
m.marshal(urlset, sw);
return sw.toString();
}

public static Urlset getUrlset(String xml) throws JAXBException,
SAXException {
JAXBContext jc = JAXBContext
.newInstance(“com.lizongbo.web.sitemaps.sitemap”);
Unmarshaller um = jc.createUnmarshaller();
SchemaFactory sf = SchemaFactory
.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(SitemapUtil.class
.getResource(“sitemap.xsd”));
um.setSchema(schema);
return (Urlset) um.unmarshal(new StringReader(xml));
}

public static String getSitemapindexXML(Sitemapindex sitemapindex)
throws JAXBException, SAXException {
JAXBContext jc = JAXBContext
.newInstance(“com.lizongbo.web.sitemaps.siteindex”);
Marshaller m = jc.createMarshaller();
StringWriter sw = new StringWriter();
sw.append(DOCTYPE).append(“\n”);
sw.append(ProcessingInstruction).append(“\n”);
m.setProperty(Marshaller.JAXB_ENCODING, “UTF-8”);
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
m.setProperty(Marshaller.JAXB_SCHEMA_LOCATION,
SITEINDEX_SCHEMA_LOCATION);
SchemaFactory sf = SchemaFactory
.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(SitemapUtil.class
.getResource(“siteindex.xsd”));
m.setSchema(schema);
m.marshal(sitemapindex, sw);
return sw.toString();
}

public static Sitemapindex getSitemapindex(String xml)
throws JAXBException, SAXException {
JAXBContext jc = JAXBContext
.newInstance(“com.lizongbo.web.sitemaps.siteindex”);
Unmarshaller um = jc.createUnmarshaller();
SchemaFactory sf = SchemaFactory
.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(SitemapUtil.class
.getResource(“siteindex.xsd”));
um.setSchema(schema);
return (Sitemapindex) um.unmarshal(new StringReader(xml));
}

public static void main(String[] args) throws JAXBException, SAXException {
Urlset urlset = SitemapUtil.createUrlset();
TUrl url = SitemapUtil.createTUrl();
url.setLoc(“http://lizongbo.com”);
urlset.getUrl().add(url);
String xml = getSitemapXML(urlset);
System.out.println(xml);
xml = xml.replace(“lizongbo”, “google”);
System.out.println(getSitemapXML(getUrlset(xml)));
Sitemapindex sitemapindex = SitemapUtil.createSitemapindex();
TSitemap tSitemap = SitemapUtil.createTSitemap();
tSitemap.setLoc(“http://618119.com/sitemap.xml”);
sitemapindex.getSitemap().add(tSitemap);
xml = getSitemapindexXML(sitemapindex);
System.out.println(xml);
xml = xml.replace(“lizongbo”, “google”);
System.out.println(getSitemapindexXML(getSitemapindex(xml)));
}
}

[/code]

2007年12月28日

基于Axis的WebService测试,开发,部署

Filed under: Java,JAVA IDE — 标签:, , , , — lizongbo @ 09:01

前段时间给同事做了简单的WebService开发培训,效果不太理想。
因此把当时准备的资料备份一下,避免清理硬盘的时候弄没了。

带抓图的word文档在:http://618119.com/docs/WebService/Webservice_axis_dev.doc

http://618119.com/docs/WebService/soaptest.html

下面是从word里保存出来的文字:
1 WebService 测试
不编写代码的情况下,对webservice进行测试,编写代码进行测试的方法.
1.1 使用xmlspy测试接口
测试webservice接口地址为:
http://www.webservicex.net/globalweather.asmx?WSDL
http://www.ayandy.com/Service.asmx?WSDL
http://www.ayandy.com/Service.asmx/getSupportProvince

http://www.ayandy.com/Service.asmx?op=getSupportCity

在xmlspy中的测试步骤:
1. 启动XmlSpy,主菜单–>SOAP –> Create new SOAP request.

2. 选择wsdl文件或者提供wsdl的网址:

3. 选择要测试的方法

4. 填写调用参数

5. 发送请求

6. 查看服务端返回的结果

7. 由于wsdl描述的webservice入口和我们要连接的服务器不一定是同一个地址,因此还可以改变连接参数

8. 因此
参考: http://www.altova.com/products/xmlspy/soap_test_debugger.html

这种方式的优点是:门槛低,只要会填参数就可以测试webservice。
缺点是:xmlspy不是免费的,xmlspy文件超大,携带不方便。无法查看http header.
1.2 用tcpmon测试捕获SOAP数据包
工具来源,下载地址:
http://apache.mirror.phpchina.com/ws/commons/tcpmon/1_0/tcpmon-1.0-bin.zip

优点,文件小巧,不只是测试webserice可以用,测试其它http接口也很方便。
缺点,没法设置contenttype,所以会有乱码。
1.3 用xmlhttp发送SOAP数据包

优点,简单的html可以存放在各地,可以在预先准备好SAOP数据的情况下,将该测试用例发给工程人员在现场进行测试。
缺点,soap数据要靠自己组装。

2 WebService开发
2.1 客户端代码开发
2.1.1 Wsdl2java命令方式
2.1.1.1 预备wsdl2java.bat
wsdl2java.bat的内容为:
%JAVA_HOME%/bin/java.exe -classpath “./axis-ant.jar;./axis.jar;./commons-discovery-0.2.jar;./commons-logging-1.0.4.jar;./jaxrpc.jar;./log4j-1.2.8.jar;./saaj.jar;./wsdl4j-1.5.1.jar”  org.apache.axis.wsdl.WSDL2Java  -v -n -O -1 -D -W -t -a -o E:\mywork\wsdl2javatest\src http://www.webservicex.net/globalweather.asmx?WSDL

(没有 –s –S两个选项, -s用来生成服务端代码,使用-s后, -t无效).
-o是原代码输出的地方。
2.1.1.2 在Jbuilder新建空白工程.
2.1.1.3 导入Axis和Junit的lib.
2.1.1.4 运行wsdl2java.bat
2.1.1.5 在Jbuilder中测试代码
2.1.1.6 以Ant方式运行WSDL2Java

wsdl2java.xml的配置为:

<?xml version=”1.0″ encoding=”UTF-8″?>
<project xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
default=”buildclient” xsi:type=”project”>
<path id=”axis.classpath”>
<fileset dir=”./”>
<include name=”**/*.jar” />
</fileset>
</path>
<taskdef resource=”axis-tasks.properties”  classpathref=”axis.classpath” />

<!– http://10.108.20.207:8080/test/services/Version?wsdl –>
<!– http://www.ayandy.com/Service.asmx?WSDL –>
<target name=”buildclient”>
<axis-wsdl2java
url=”http://www.ayandy.com/Service.asmx?WSDL”
output=”E:/mywork/testwebws/classes/ws-gen/src”
all=”true”
debug=”true”
deployscope=”Request”
helpergen=”true”
noimports=”false”
serverside=”false”
skeletondeploy=”false”
testcase=”true”
timeout=”-1″
typemappingversion=”1.1″
verbose=”true”
noWrapped=”true”>
<!–mapping
namespace=”http://10.108.20.207:8080/test/services/Version” package=”com.test.services.Version”/>
<mapping namespace=”http://xml.apache.org/xml-soap” package=”org.apache.xml.xml_soap”/ –>

<classpath refid=”axis.classpath”/>
</axis-wsdl2java>
</target>
</project>

2.1.2 完全在Jbuilder中开发客户端代码
2.1.2.1 新建客户端工程.
点Finish.
2.1.2.2 新建Axis Web Services Client Configuration.
2.1.2.3 将Jbuilder自带的Axis1.2 lib升级为1.4版本
1.4版本生成的代码和 1.2有所不同。
2.1.2.4 创建Webservice Client
2.1.2.4.1 导入 WSDL文件方式一 — 直接填写URL
输入url之后,鼠标点到”Opeerations”,系统会自动读取url的内容。
url例子:http://www.webservicex.net/globalweather.asmx?WSDL

可以看到能够调用的WebService方法:
2.1.2.4.2 导入 WSDL文件方式二– 导入WSDL文件
2.1.2.4.3 直接操作
点击感叹号,直接选择
2.1.2.5 生成客户端代码
2.1.2.6 进行单元测试
2.1.2.6.1 察看生成好的测试代码.
2.1.2.6.2 补充测试代码
生成的测试代码只是测试框架,需要补充具体的测试代码
//TBD
就是需要补充代码的地方
补充了测试代码之后:

2.1.2.6.3 运行单元测试
2.1.2.6.4 观察单元测试结果
2.1.2.7 捕获单元测试数据包
2.1.2.7.1 启动捕获数据的代理服务器
双击运行 tcpmon.bat
使用 listener模式,Listen Port 填写 8080
Target Hostname为刚才察看到的远程ip
TargetPort 为80.
点“Add”.
察看监控面板。
2.1.2.7.2 修改测试代码的目标地址
2.1.2.7.3 运行单元测试
2.1.2.7.4 察看监控得到的数据
观察http请求的头信息.
2.1.2.8 捕获html测试数据包
2.2 服务端代码开发
2.2.1 基于Axis开发服务端
2.2.1.1 新建服务端工程.
2.2.1.2 新建服务端接口声明(可选).
2.2.1.3 新建服务端实现类.
填写实现代码
2.2.1.4 通过Jbuilder导出实现类为WebService接口.
必须选J2EE 1.3 ,因为要选择1.4的话,必须实现Remote接口
创建 Axis Server Module.
由于目前没有创建WebApp,因此还需要新建Web Module.
选择 Servlet 2.3 和JSP 1.2。
2.2.1.5 启动WebService服务端
http://localhost:8080/ws/servlet/AxisServlet
http://localhost:8080/ws/services/WsServerImpl?wsdl

2.2.2 在Spring中导出bean为WebService接口.
略。
3 WebService手工部署
3.1 部署Axis
3.1.1 提取Axis的web应用
提取 axis-bin-1_4.zip\axis-1_4\webapps\axis
到 E:\apache-tomcat-6.0.14\webapps\axis
3.1.2 启动Tomcat并检查axis是否正常
3.2 发布WebService
3.2.1 查看现有部署的服务
命令行为:
%JAVA_HOME%/bin/java.exe -classpath “E:\mywork\wsserver\classes;./axis-ant.jar;./axis.jar;./commons-discovery-0.2.jar;./commons-logging-1.0.4.jar;./jaxrpc.jar;./log4j-1.2.8.jar;./saaj.jar;./wsdl4j-1.5.1.jar”  org.apache.axis.client.AdminClient  -d -lhttp://localhost:8080/axis/servlet/AxisServlet list

3.2.2 编写部署描述文件 axis.wsdd

<?xml version=”1.0″ encoding=”UTF-8″?>
<deployment 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/”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
name=”defaultClientConfig” xsi:type=”deployment”>
<service name=”WsServerImpl” type=”” regenerateElement=”true”
provider=”java:RPC” style=”rpc” use=”encoded” validate=”true”>
<parameter name=”scope” value=”Request” regenerateElement=”false”/>
<parameter name=”className” value=”com.lizongbo.WsServerImpl” regenerateElement=”false”/>
<parameter name=”allowedMethods” value=”*” regenerateElement=”false”/>
<namespace>http://lizongbo.com</namespace>
</service>
</deployment>

3.2.3 复制class文件
复制E:\mywork\wsserver\classes下面的com目录的文件到
E:\apache-tomcat-6.0.14\webapps\axis\WEB-INF\classes\com
重新启动Tomcat.
3.2.4 命令行方式发布WebService
%JAVA_HOME%/bin/java.exe -classpath “E:\mywork\wsserver\classes;./axis-ant.jar;./axis.jar;./commons-discovery-0.2.jar;./commons-logging-1.0.4.jar;./jaxrpc.jar;./log4j-1.2.8.jar;./saaj.jar;./wsdl4j-1.5.1.jar”  org.apache.axis.client.AdminClient  -d -lhttp://localhost:8080/axis/servlet/AxisServlet axis.wsdd
3.2.5 察看部署的服务
http://localhost:8080/axis/servlet/AxisServlet
http://localhost:8080/axis/services/WsServerImpl?wsdl

3.2.6 测试部署的服务
略…
4 附录
4.1 相关资源下载
Axis1.4 :
http://apache.mirror.phpchina.com/ws/axis/1_4/axis-bin-1_4.zip
http://apache.mirror.phpchina.com/ws/axis/1_4/axis-src-1_4.zip
TcpMon 1.0:
http://apache.mirror.phpchina.com/ws/commons/tcpmon/1_0/tcpmon-1.0-bin.zip
http://apache.mirror.phpchina.com/ws/commons/tcpmon/1_0/tcpmon-1.0-src.zip

Ant 1.7.0 :
http://apache.mirror.phpchina.com/ant/binaries/apache-ant-1.7.0-bin.zip

Tomcat 6.0.14:
http://apache.mirror.phpchina.com/tomcat/tomcat-6/v6.0.14/bin/apache-tomcat-6.0.14.zip

XmlSpy 2008 :
http://software.altova.com/download/2008/XMLSpyEnt2008.exe
http://www.jydex.cn/attachments/month_0711/w2007111215514.rar

Spring 2.5:
http://superb-east.dl.sourceforge.net/sourceforge/springframework/spring-framework-2.5-with-dependencies.zip

4.2 相关参考资料
参考: http://www.ibm.com/developerworks/cn/webservices/ws-noide1/
http://www.ibm.com/developerworks/cn/webservices/ws-noide2/
http://www.blogjava.net/pdw2009/archive/2007/10/25/155889.html
http://www.ibm.com/developerworks/cn/webservices/ws-whichwsdl/

4.3 将wsdl生成文档提供给接口调用者
在xmlspy中,打开wsdl文件,
主菜单–> WSDL –> Generate Documentation。

Powered by WordPress