项目的需求:需要解析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,并进行测试。首先,我们需要理解WSDL文件的基本结构和用途,它是Web服务客户端和服务提供者之间的桥梁,定义了服务的操作、输入和输出消息格式。 要通过Java动态生成...
4. **生成客户端代理**:服务消费者使用WSDL文件生成客户端代理类,这个类提供了调用服务的接口。例如,在Java中,可以使用wsimport工具,而在.NET中,可以使用svcutil.exe。 5. **构建XML请求**:根据服务接口的...
yavijava_generator 使用用 Groovy 编写的代码生成器,用于解析 VMWare 提供的 HTML 文档,用于为生成代码。为什么yavijava 中的大... 在提交拉取请求之前,请确保先运行测试,以确保所做的更改不会破坏测试。 要运行
通过AXIS,开发者可以方便地创建基于SOAP的Web服务,并且能够处理服务的部署、WSDL生成以及客户端的代理类创建。 综上所述,Web服务实现技术涉及服务的开发策略、生命周期管理、运行环境的组件以及辅助工具的使用。...
1. **自顶向下**:这种开发方式是从服务接口描述(WSDL)开始,先定义服务的行为和消息格式,然后根据WSDL生成服务的实现。例如,从EJB或Java类生成WSDL。 2. **自底向上**:这种方式是先编写服务实现,然后逆向...
4. **portlet交互**:portlet可以通过动作请求处理用户交互,例如表单提交,也可以通过资源请求获取动态内容。 5. **portlet集成**:在RAD中,可以创建基于JSR 168的portlet项目,进行portlet的开发、测试和部署。 ...
在Ant的构建文件中,可以定义一个任务来运行JUnit测试,并根据测试结果生成HTML格式的报告。 **执行程序** 在Ant中执行Java程序通常是通过`java`任务完成的。这个任务可以设置程序的主类、类路径、系统属性等参数...
2. 使用gSOAP的工具生成客户端代码,这些代码将解析服务的WSDL(Web服务描述语言)文件,从而知道如何与服务接口进行交互。 3. 在客户端代码中,编写业务逻辑,调用生成的接口函数,发送请求并接收响应。 4. "server...
2. **Servlet和JSP**:作为J2EE的基础,Servlet负责处理HTTP请求,而JSP用于生成动态HTML内容。实验中,你可能需要编写Servlet来处理用户请求,并用JSP展示结果。 3. **EJB(Enterprise JavaBeans)**:EJB是J2EE的...
(2)项目中添加以下文件:注意,这些文件都是通过gsoap自动生成,无须修改。 stdsoap2.cpp stdsoap2.h soapC.cpp soapH.h WebServiceInterfaceSoap.nsmap.cpp soapWebServiceInterfaceSoapProxy.cpp ...
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章 数组操作...
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服务器的...
1. **Dynamic Web Project**:Myeclipse支持创建动态Web项目,允许开发者构建基于Servlet、JSP、JSF等技术的Web应用。用户只需通过简单的几步操作,即可快速搭建Web项目的结构,包括WEB-INF目录、src目录以及默认的...
通过将对象的创建和管理权交给第三方容器(如Spring容器),实现控制反转,使对象不再控制其自身的创建过程,提高代码的可复用性和可测试性。 #### IO和NIO的区别,NIO优点 - **IO(InputStream/OutputStream)**:...
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 一组...
它们可以嵌入到其他ASP.NET页面中,并且能够通过属性进行参数化设置,提高代码的复用性和维护性。 #### 3. 叫应用程序域?什么是受管制的代码?什么是强类型系统?什么是装箱和拆箱?什么是重载?CTS、CLS和CLR分别...