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

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

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

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

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

2.动态生成HTML表格
通过已经装载的WSDL,解析成对应的表格
例如:

<xsd:complexType name="helloWord">
<xsd:sequence>
<xsd:element minOccurs="0" name="name" type="xs:string" />
</xsd:sequence>
</xsd:complexType>

[img]http://dl.iteye.com/upload/picture/pic/94183/bafbaa26-095b-33d6-8d17-5b9d8299fd9d.bmp[/img]

数组格式

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

[img]http://dl.iteye.com/upload/picture/pic/94185/abf3457c-9ff7-37e2-807e-644086aea79e.bmp[/img]

其他的不细说了

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")
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值