项目的需求:需要解析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 ...
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分别...