欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-28 18:02:39
...
项目的需求:需要解析WSDL,动态生成对应的HTML,页面上输入对应的参数或者选择文件,打印最后的信息

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

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

思路:
1.通过配置装载对应的WSDL文件(通过对应的网址解析)
关于这点,鄙人曾经花过时间去查询对应的WSDL装载和解析的方法,有一个WSDL4j,但是这个项目应该是个半成品,所以解析不完善。
因此,我决定自己解析成比较通俗易懂的类包类的方式,虽然暴力,但是易懂如何通过WSDL动态生成HTML,并且提交测试
            
    
    博客分类: java新路 反射枚举WSDL

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

如何通过WSDL动态生成HTML,并且提交测试
            
    
    博客分类: java新路 反射枚举WSDL

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

如何通过WSDL动态生成HTML,并且提交测试
            
    
    博客分类: java新路 反射枚举WSDL

其他的不细说了

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")