如何通过WSDL动态生成HTML,并且提交测试
程序员文章站
2022-05-28 18:02:39
...
项目的需求:需要解析WSDL,动态生成对应的HTML,页面上输入对应的参数或者选择文件,打印最后的信息
没有找到对应的Java语言的第三方软件,因此决定自己制作
软件环境:SSH,JSP,Servlet,Mysql
思路:
1.通过配置装载对应的WSDL文件(通过对应的网址解析)
关于这点,鄙人曾经花过时间去查询对应的WSDL装载和解析的方法,有一个WSDL4j,但是这个项目应该是个半成品,所以解析不完善。
因此,我决定自己解析成比较通俗易懂的类包类的方式,虽然暴力,但是易懂
2.动态生成HTML表格
通过已经装载的WSDL,解析成对应的表格
例如:
数组格式
其他的不细说了
3.动态解析表单数据,并且测试
这里用到了大量的反射,因为所有的一切都是基于WSDL,全部的东西(类名,属性,方法,参数)都是字符串
主要的代码如下:
普通类型比较简单,直接通过request的提取即可
文本类型稍微有点复杂,因为wsdl里是没有xs:file的,所以需要转化成xs:base64Binary
也就是byte[]
关于文件的解析有两种模式
Action,主要代码如下
Servlet,主要代码如下
自定义类型,例如这个
WSDL上的表述是这样的
通过反射,初始化一个类,从request里提取对应的值,封装参数,反回该类
主要代码
进行迭代处理,也可以处理类包含类
枚举类型的属性,HTML是通过select展示的
枚举代码
反射获取对应值的代码为:
对应这个枚举的反射方法的调用就是
没有找到对应的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")
上一篇: 通过类名获取特定的类型数组
下一篇: 通过类名获取不知道长度的类型数组