`
lyw985
  • 浏览: 39772 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

如何通过WSDL动态生成HTML,并且提交测试

阅读更多
项目的需求:需要解析WSDL,动态生成对应的HTML,页面上输入对应的参数或者选择文件,打印最后的信息

没有找到对应的Java语言的第三方软件,因此决定自己制作

软件环境:SSH,JSP,Servlet,Mysql

思路:
1.通过配置装载对应的WSDL文件(通过对应的网址解析)
关于这点,鄙人曾经花过时间去查询对应的WSDL装载和解析的方法,有一个WSDL4j,但是这个项目应该是个半成品,所以解析不完善。
因此,我决定自己解析成比较通俗易懂的类包类的方式,虽然暴力,但是易懂

2.动态生成HTML表格
通过已经装载的WSDL,解析成对应的表格
例如:
  <xsd:complexType name="helloWord">
    <xsd:sequence>
      <xsd:element minOccurs="0" name="name" type="xs:string" />
    </xsd:sequence>
  </xsd:complexType>



数组格式
  <xs:complexType name="sum">
    <xs:sequence>
      <xs:element maxOccurs="unbounded" minOccurs="0" name="number" type="xs:int" />
    </xs:sequence>
  </xs:complexType>



其他的不细说了

3.动态解析表单数据,并且测试
这里用到了大量的反射,因为所有的一切都是基于WSDL,全部的东西(类名,属性,方法,参数)都是字符串

主要的代码如下:
//从WSDL和operation上获取key,从request上获得值
Object[] objs = WSDLUtil.getObjects(request, wsdl, operation);
//getWebServiceType(wsdl)获取对应的webService类,反射调用方法
Object obj = ReflectUtil.invoke(getWebServiceType(wsdl),
		operation.getName(), objs);
response.getWriter().println(obj);



普通类型比较简单,直接通过request的提取即可
文本类型稍微有点复杂,因为wsdl里是没有xs:file的,所以需要转化成xs:base64Binary
也就是byte[]
关于文件的解析有两种模式
Action,主要代码如下
if (request instanceof MultiPartRequestWrapper) {
	MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) request;
	File[] files = multiWrapper.getFiles(paramName);
	byte[] param = null;
	for (File file : files) {
		FileInputStream fis = new FileInputStream(file);
		param = new byte[fis.available()];
		fis.read(param);
		fis.close();
	}
	return param;
}

Servlet,主要代码如下
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload servletFileUpload = new ServletFileUpload(factory);
List<FileItem> fileItemList = servletFileUpload.parseRequest(request);
List<byte[]> list = new ArrayList<byte[]>();
for (FileItem fileItem : fileItemList) {
	String fileName = fileItem.getFieldName();
	if (fileName.equals(paramName)) {
		InputStream is = fileItem.getInputStream();
		byte[] bs = new byte[is.available()];
		is.read(bs);
		list.add(bs);
		is.close();
		return bs;
	}
}

自定义类型,例如这个
@XmlType
@XmlAccessorType(XmlAccessType.FIELD)
public class User {
	private String username;
	private String password;

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

}

WSDL上的表述是这样的
  <xs:complexType name="user">
    <xs:sequence>
      <xs:element minOccurs="0" name="username" type="xs:string" />
      <xs:element minOccurs="0" name="password" type="xs:string" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="login" type="login" />
  <xs:complexType name="login">
    <xs:sequence>
      <xs:element minOccurs="0" name="user" type="user" />
    </xs:sequence>
  </xs:complexType>


通过反射,初始化一个类,从request里提取对应的值,封装参数,反回该类
主要代码
Object newParent = null;
String className = packagePath + element.getType().substring(0, 1).toUpperCase()
		+ element.getType().substring(1);
for (SimpleType simpleType : simpleTypeList) {
	if (simpleType.getName().equals(type)) {
		if (maxOccurs == null) {
			String param = WebUtil.getString(request, paramName);
			if (param == null) {
				return null;
			}
			newParent = ReflectUtil.getFieldObject(Class.forName(className), param);
			return newParent;
		} else {
			String[] strs = WebUtil.getStrings(request, paramName);
			if (strs == null) {
				return null;
			}
			Object[] param = ReflectUtil.getArrayByClassName(className, strs.length);
			for (int i = 0; i < strs.length; i++) {
				param[i] = ReflectUtil
						.getFieldObject(Class.forName(className), strs[i]);
			}
			return param;
		}
	}
}
for (ComplexType complexType : complexTypeList) {
	if (complexType.getName().equals(type)) {
		if (maxOccurs == null) {
			newParent = Class.forName(className).newInstance();
			Object param = null;
			for (com.brightcreek.tradeshow.wsdl.types.schema.complextype.sequence.element.Element e : complexType
					.getSequence().getElementList()) {
				param = getObject(request, e, complexTypeList, simpleTypeList,
						paramName + ".", newParent, packagePath);
				if (null != param) {
					ReflectUtil.setValue(newParent, e.getName(), param);
				} else {
					return null;
				}
			}
			return newParent;
		} else {
			int index = 0;
			Object[] parents = ReflectUtil.getArrayByClassName(className, 0);
			List list = new ArrayList(Arrays.asList(parents));
			Object param = null;
			while (true) {
				newParent = Class.forName(className).newInstance();
				for (com.brightcreek.tradeshow.wsdl.types.schema.complextype.sequence.element.Element e : complexType
						.getSequence().getElementList()) {
					param = getObject(request, e, complexTypeList, simpleTypeList,
							paramName + "[" + index + "].", newParent, packagePath);
					if (null != param) {
						ReflectUtil.setValue(newParent, e.getName(), param);
					} else {
						return list.toArray(ReflectUtil.getArrayByClassName(className,
								list.size()));
					}
				}
				list.add(newParent);
				index++;
			}
		}
	}
}

进行迭代处理,也可以处理类包含类

枚举类型的属性,HTML是通过select展示的
枚举代码
@XmlType
@XmlAccessorType(XmlAccessType.FIELD)
public enum NoteMessage {
	A("A value"), B("B value");
	private final String value;

	public String getValue() {
		return value;
	}

	NoteMessage(String value) {
		this.value = value;
	}
}

反射获取对应值的代码为:
public static Object getEnumerationValue(String className, String fieldName, String methodName)
		throws ClassNotFoundException, SecurityException, NoSuchMethodException,
		NoSuchFieldException, IllegalArgumentException, IllegalAccessException,
		InvocationTargetException {
	Class clazz = Class.forName(className);
	Method method = clazz.getDeclaredMethod(methodName);
	for (Object obj : clazz.getEnumConstants()) {
		if (obj.toString().equals(fieldName)) {
			return method.invoke(obj);
		}
	}
	return null;
}

对应这个枚举的反射方法的调用就是
getEnumerationValue("NoteMessage", "A", "getValue")





分享到:
评论

相关推荐

    Java语言如何通过WSDL动态生成HTML,并且提交测试(附源码)

    NULL 博文链接:https://lyw985.iteye.com/blog/1124472

    yavijava_generator:代码生成器可帮助根据 html 文档生成尽可能多的 yavijava

    yavijava_generator 使用用 Groovy 编写的代码生成器,用于解析 VMWare 提供的 HTML 文档,用于为生成代码。为什么yavijava 中的大... 在提交拉取请求之前,请确保先运行测试,以确保所做的更改不会破坏测试。 要运行

    C++实现56dxw短信验证码WebService接口--

    (2)项目中添加以下文件:注意,这些文件都是通过gsoap自动生成,无须修改。 stdsoap2.cpp stdsoap2.h soapC.cpp soapH.h WebServiceInterfaceSoap.nsmap.cpp soapWebServiceInterfaceSoapProxy.cpp ...

    php网络开发完全手册

    7.5.6 通过回调函数执行正则表达式 7.5.6 的搜索和替换——preg_replace_ 7.5.6 callback 114 7.5.7 用正则表达式进行字符串分割 7.5.7 ——preg_split 115 7.6 字符操作的注意事项 117 7.7 小结 118 第8章 数组操作...

    JAVA程序开发大全---上半部分

    14.4.2 使用WSDL生成客户端代码 253 14.4.3 创建Web Service客户端测试代码 255 14.5 本章小结 255 第15章 Java EE中EJB的开发 256 15.1 EJB概述 256 15.2 WebLogic服务器的安装与配置 257 15.2.1 WebLogic服务器的...

    Python编程入门经典

    14.3.4 使用事务并提交结果 245 14.3.5 检查模块的功能和元 数据 246 14.3.6 处理错误 246 14.4 本章小结 247 14.5 习题 248 第15章 使用Python处理XML 249 15.1 XML的含义 249 15.1.1 层次标记语言 249 15.1.2 一组...

    JavaScript高级教程

    第 1 章 JavaScript 是什么...............................................1 3 1.1 历史简述.........................3.5.5 动态原型方法..............................................82 3.5.6 混合工厂方式........

Global site tag (gtag.js) - Google Analytics