论坛首页 Java企业应用论坛

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

浏览 2368 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-07-12   最后修改:2011-07-12
项目的需求:需要解析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>

自然是生成


数组格式


其他的不细说了

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里提取对应的值,封装参数,反回该类
主要代码
private static Object setObject(
		HttpServletRequest request,
		com.brightcreek.tradeshow.wsdl.types.schema.complextype.sequence.element.Element element,
		List<ComplexType> complexTypeList, List<SimpleType> simpleTypeList, String parentStr,
		Object parent) throws IOException, FileUploadException, InstantiationException,
		IllegalAccessException, ClassNotFoundException, SecurityException,
		IllegalArgumentException, NoSuchMethodException, InvocationTargetException,
		NoSuchFieldException {
	String paramName = parentStr + element.getName();
	String type = element.getType();
	String maxOccurs = element.getMaxOccurs();
	if (type.equals("xs:string")) {
		if (maxOccurs == null) {
			return WebUtil.setString(request, paramName, parent);
		} else {
			return WebUtil.setStrings(request, paramName, parent);
		}
	} else if (type.equals("xs:base64Binary")) {
		if (maxOccurs == null) {
			return WebUtil.setBinary(request, paramName, parent);
		} else {
			return WebUtil.setBinarys(request, paramName, parent);
		}
	} else if (type.equals("xs:int")) {
		if (maxOccurs == null) {
			return WebUtil.setInt(request, paramName, parent);
		} else {
			return WebUtil.setInts(request, paramName, parent);
		}
	} else {
		Object newParent = null;
		String className = "com.study.webservice."
				+ element.getType().substring(0, 1).toUpperCase()
				+ element.getType().substring(1);
		for (SimpleType simpleType : simpleTypeList) {
			if (simpleType.getName().equals(type)) {
				String param = WebUtil.getString(request, paramName);
				newParent = ReflectUtil.getEnumerationValue(className, param, "getValue");
				if (parent != null) {
					ReflectUtil.setValue(parent, type, newParent);
				} else {
					return newParent;
				}
			}
		}
		newParent = Class.forName(className).newInstance();
		if (parent != null) {
			ReflectUtil.setValue(parent, type, newParent);
		}
		parent = newParent;
		for (ComplexType complexType : complexTypeList) {
			if (complexType.getName().equals(type)) {
				for (com.brightcreek.tradeshow.wsdl.types.schema.complextype.sequence.element.Element e : complexType
						.getSequence().getElementList()) {
					setObject(request, e, complexTypeList, simpleTypeList, paramName + ".",
							parent);
				}
				break;
			}
		}
		return parent;
	}
}

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

枚举类型的属性,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企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics