之前准备试试Java发布Webservice,开始以为很简单,因为C#发布很简单。后面发现太费劲了,依赖一堆包,下面几种都试了一下:
JAX-WS (Java API for XML Web Services):这是Java EE平台的标准,用于创建和发布Web服务。JAX-WS提供了一种简单的方法来发布和调用Web服务,它基于SOAP协议。
Apache CXF:这是一个开源框架,用于构建和开发Web服务和RESTful服务。它支持多种协议,包括SOAP和REST。
Axis2:这是另一个开源框架,用于构建和发布SOAP和RESTful Web服务。Axis2是Apache的一个项目,具有高度的可配置性和灵活性。
Spring Boot + Spring Web Services:如果你使用Spring Boot框架,你可以通过集成Spring Web Services来轻松创建和发布Web服务。
Jersey:这是另一个用于构建RESTful Web服务的开源框架。它是JAX-RS规范的一个实现,并且是Java EE 7的一部分。
依赖太多,补了一个又报一个,最终决定放弃算了,反正对外提供Post也行,调别人的服务自己按soapui的串Post就行了。欢哥业余搞了个基础版的soap协议,支持基础类型,这样也不错。我之前介绍过http的本质就是TCP协议上约束发送和响应格式的TCP,并且用C#和M写过测试。
c语言发布http
Cache实现http
Webservice的本质就是基于http的传输协议约定了请求和响应格式,服务器按请求体执行方法,按响应格式组装响应体。没有那么玄乎,任何有TCP协议的语言自己可以比较简单的实现常规http协议,并且在http基础上实现常规的Webservice协议,当然,要实现全套协议还是很费劲的,但是常用的就是最基本的类型。
下面是欢哥实现的Webservice协议:
首先定义服务的注解,服务实现类申明此注解
package JRT.WebService.WS.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* WebService特性,作用类,标识该类可以对外发布服务
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface WebServer
{
/**
* 服务名称
* @return
*/
public String ServiceName() default "WebServer";
/**
* 命名空间
* @return
*/
public String XmlNameSpace() default "";
}
然后定义方法注解,要公布Webservice的方法加上此注解
package JRT.WebService.WS.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* WebService方法特性,作用于方法,标识方法可对外发布服务,没标识该注解的方法不生成soap文档
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface WebMethod
{
}
让后定义参数注解,可以指定参数名
package JRT.WebService.WS.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 标识要发布Webservice的方法的参数对外名称
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface WebParam
{
/**
* 参数名称
* @return
*/
public String Name() default "";
}
然后抽取Webservice调用接口
package JRT.WebService.Http;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
/**
* 抽取的Webservice请求处理接口,WebService基类实现该接口供主请求按接口调用
*/
public interface IBaseWebServiceHandler {
/**
* Http get请求,根据请求处理生成wsdl文档
*
* @param request 请求对象
* @param response 响应对象
* @throws Exception
*/
void DealGet(HttpServletRequest request, HttpServletResponse response) throws Exception;
/**
* Http post请求,解析处理请求的soap文档,反射执行调用方法,并生成项目的soap文档
*
* @param request 请求对象
* @param response 响应对象
* @throws Exception
*/
void DealPost(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
实现Webservice基类,返回soap协议和执行请求体,soap协议就在这里面
package JRT.WebService.Http;
import JRT.Core.Util.JsonUtil;
import JRT.Core.Util.LogUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
/**
* Webservice实现基类,实现soap协议的生成和解析执行,所有webservice实现类都继承该基类
*/
public class BaseWebServiceHandler implements JRT.WebService.Http.IBaseWebServiceHandler {
/**
* Http get请求,根据请求处理生成wsdl文档
*
* @param request 请求对象
* @param response 响应对象
* @throws Exception
*/
public void DealGet(HttpServletRequest request, HttpServletResponse response) throws Exception {
response.setCharacterEncoding("UTF-8"); //设置响应内容编码UTF-8
response.setContentType("text/xml"); //设置响应mime类型为text/xml
//获取请求的url,wsdl问了里面需要使用该url
String url = request.getRequestURL().toString();
//获取当前类名称
Class clz = this.getClass();
//根据类名称和请求url生成wsdl文档
String xml = JRT.WebService.WS.Wsdl.WsdlXmlUtil.GetWsdlXml(clz, url);
response.getWriter().print(xml);
}
/**
* Http post请求,解析处理请求的soap文档,反射执行调用方法,并生成项目的soap文档
*
* @param request 请求对象
* @param response 响应对象
* @throws Exception
*/
public void DealPost(HttpServletRequest request, HttpServletResponse response) throws Exception {
//设置响应内容编码
response.setCharacterEncoding("UTF-8");
//设置响应mime类型为text/xml
response.setContentType("text/xml");
//获取当前类名称,用于反射执行当前类发布的方法
Class clazz = this.getClass();
try {
//获取post提交的内容
BufferedInputStream bis = new BufferedInputStream(request.getInputStream());
//将请求的内容转换成文本,使用utf-8编码
String req = new String(bis.readAllBytes(), Charset.forName("UTF-8"));
//简单清理一些格式化字符
req = req.replaceAll("\n|\r", "").replaceAll(">\\s+<", "><");
//创建字节输入流
ByteArrayInputStream bais = new ByteArrayInputStream(req.getBytes("UTF-8"));
//创建xml文档构建工厂对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
//从字节输入流解析生成xml文档对象
Document document = builder.parse(bais);
// 获取根节点 soapenv:Envelope
Element root = document.getDocumentElement();
//获取根节点名称
String rootname = root.getNodeName();
//节点名称":"号的前缀根据不同的请求会有差异,所以这里取出来,响应的soap文档的节点前缀也是用这个
String nodename_pre = "";
if (rootname.contains(":")) {
nodename_pre = rootname.split(":")[0];
}
// 获取soap的body
Node body = null; //soap body
Node header = null; // soap header
//获取根节点的所有子节点
NodeList rootchildren = root.getChildNodes();
//遍历字节的找到body和header节点,只处理这两个节点
for (int i = 0; i < rootchildren.getLength(); i++) {
Node node = rootchildren.item(i);
String nodename = node.getNodeName();
if (nodename.contains("Body")) {
body = node;
}
if (nodename.contains("Header")) {
header = node;
}
}
//没有body节点认为请求的soap文档不合要求,抛出异常
if (body == null) {
throw new Exception("未获取到Body");
}
// 获取请求的方法节点,此处默认body的第一子节点为请求的方法节点
Node method = body.getFirstChild();
// 方法名称
String methodname = method.getNodeName();
String[] name_arr = methodname.split(":");
//去除方法名称前缀
if (name_arr.length >= 2) {
methodname = name_arr[1];
}
//未获取到方法名称抛出异常
if (methodname == null || methodname.isEmpty()) {
throw new Exception("未获取到请求方法");
}
// 处理参数,方法节点的子节点为参数节点
NodeList params = method.getChildNodes();
//参数个数
int length = params.getLength();
//参数值,数组
Object[] args = new Object[length];
//参数类型对象,数组
Class<?>[] type_arr = new Class[length];
for (int i = 0; i < length; i++) {
Node node = params.item(i);
String value = node.getTextContent();
//获取参数节点属性
NamedNodeMap attrs = node.getAttributes();
Class<?> clz = null;
for (int k = 0; k < attrs.getLength(); k++) {
Node attr = attrs.item(k);
String attrname = attr.getNodeName();
//属性名称包含type,则获取参数类型,并实例化class对象
if (attrname.toLowerCase().contains("type")) {
String typename = attr.getTextContent();
//处理参数名前缀
if (typename.contains(":")) {
typename = typename.split(":")[1];
}
clz = GetTypeClass(typename);
}
}
//没有配到对应参数默认String
if (clz == null) {
clz = String.class;
}
type_arr[i] = clz;
args[i] = GetValue(clz, value);
}
//反射获取当前类方法对象
Method objm = null;
try {
objm = clazz.getMethod(methodname, type_arr);
} catch (Exception ex) {
JRT.Core.Util.LogUtils.WriteExceptionLog("执行" + clazz.getName() + "的方法" + methodname + "异常", ex);
StringWriter stringWriter = new StringWriter();
ex.printStackTrace(new PrintWriter(stringWriter));
response.getWriter().print(stringWriter.toString());
}
//方法不存在抛异常
if (objm == null) {
throw new Exception("请求" + clazz.getName() + "方法不存在!" + methodname);
}
//反射调用方法
Object ret = objm.invoke(this, args);
//方法无返回值默认""
if (ret == null) {
ret = "";
}
//在原xml上构建新的xml,先移除原有的header和body
if (body != null) {
root.removeChild(body);
}
if (header != null) {
root.removeChild(header);
}
//构造新的header和body
//构建header
Node header_node = document.createElement(nodename_pre + ":Header");
root.appendChild(header_node);
//构建body及其执行结果子节点
Node body_node = document.createElement(nodename_pre + ":Body");
Node resp = document.createElement(methodname + "Response");
// 获取节点的属性列表
NamedNodeMap attributes = method.getAttributes();
((Element) resp).setAttribute("xmlns", "http://tempuri.org/");
Node res = document.createElement(methodname + "Result");
res.setTextContent(ret.toString());
resp.appendChild(res);
body_node.appendChild(resp);
root.appendChild(body_node);
//将xml Document转成序列化
TransformerFactory trans = TransformerFactory.newInstance();
Transformer transformer = trans.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "YES");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
StringWriter sr = new StringWriter();
transformer.transform(new DOMSource(document), new StreamResult(sr));
String xml = sr.toString().replaceAll("\n|\r", "").replaceAll(">\\s+<", "><");
//添加xml头并且响应内容,?头部也可以不用添加
response.getWriter().write("" + xml);
} catch (Exception ex) {
StringWriter stringWriter = new StringWriter();
ex.printStackTrace(new PrintWriter(stringWriter));
response.getWriter().print(stringWriter.toString());
JRT.Core.Util.LogUtils.WriteExceptionLog("调用" + clazz.getName() + "异常", ex);
}
}
/**
* 根据名称获取类型对象
*
* @param typename
* @return
*/
private Class<?> GetTypeClass(String typename) {
Class<?> clz = null;
if (typename == null || typename.isEmpty()) {
return clz;
}
switch (typename.toLowerCase()) {
case "int": {
clz = int.class;
break;
}
case "float": {
clz = float.class;
break;
}
case "long": {
clz = long.class;
break;
}
case "string": {
clz = String.class;
break;
}
case "double": {
clz = double.class;
break;
}
case "byte": {
clz = byte.class;
break;
}
case "char": {
clz = char.class;
}
default: {
clz = String.class;
}
}
return clz;
}
/**
* 根据值类型对象,从字符串转换对应的值
*
* @param clz 值类型对象
* @param v 值
* @return
*/
private Object GetValue(Class<?> clz, String v) {
Object value = null;
if (clz.equals(int.class)) {
value = Integer.valueOf(v);
if (value == null) {
value = 0;
}
} else if (clz.equals(float.class)) {
value = Float.valueOf(v);
if (value == null) {
value = 0.0f;
}
} else if (clz.equals(long.class)) {
value = Long.valueOf(v);
if (value == null) {
value = 0L;
}
} else if (clz.equals(byte.class)) {
value = Byte.valueOf(v);
} else if (clz.equals(double.class)) {
value = Double.valueOf(v);
if (value == null) {
value = 0D;
}
} else if (clz.equals(char.class)) {
value = v.charAt(0);
} else {
value = v;
}
return value;
}
}
组装xml用到的节点实体
package JRT.WebService.WS.XML;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* xml节点,供组装wsdl的基础数据结构,存各个块的节点,最后序列化成xml
*/
public class XmlNode {
/**
* 名称
*
* @param name
*/
public XmlNode(String name) {
this.Name = name;
}
/**
* 名称
*/
public String Name = "";
/**
* 属性
*/
public Map<String, String> PropertyList = new HashMap<>();
/**
* 值
*/
public String Value = "";
/**
* 子节点
*/
public List<XmlNode> ChildNode = new ArrayList<>();
/**
* 序列化
*
* @return
*/
public String Serialize() {
if (Name == null || Name.isEmpty()) return "";
String attrs = "";
for (String key : PropertyList.keySet()) {
String value = PropertyList.get(key);
value = JRT.WebService.WS.XML.XmlUtil.XmlEscape(value);
if (attrs.equals("")) {
attrs = key + "=\"" + value + "\"";
} else {
attrs = attrs + " " + key + "=\"" + value + "\"";
}
}
String childStr = "";
for (XmlNode node : ChildNode) {
childStr += node.Serialize();
}
StringBuilder xml = new StringBuilder();
xml.append("<" + Name);
if (!attrs.isEmpty()) {
xml.append(" " + attrs);
}
xml.append(">");
xml.append(JRT.WebService.WS.XML.XmlUtil.XmlEscape(Value));
xml.append(childStr);
xml.append("" + Name + ">");
return xml.toString();
}
/**
* 插入
*
* @param name
* @param value
*/
public void Insert(String name, String value) {
XmlNode node = new XmlNode(name);
node.Value = value;
this.ChildNode.add(node);
}
/**
* 插入
*
* @param node
*/
public void Insert(XmlNode node) {
this.ChildNode.add(node);
}
}
xml冲突符处理工具
package JRT.WebService.WS.XML;
public class XmlUtil {
/**
* XML转义工具
*
* @param xml
* @return
*/
public static String XmlEscape(String xml) {
if (xml == null || xml.isEmpty()) return "";
xml = xml.replace("&", "&");
xml = xml.replace("<", "<");
xml = xml.replace(">", ">");
xml = xml.replace("'", "'");
xml = xml.replace("\"", """);
return xml;
}
}
用该类存组装的soap
package JRT.WebService.WS.Wsdl;
import JRT.WebService.WS.XML.XmlNode;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.Type;
/**
* 用来组装Soap文档
*/
public class WsdlXml {
/**
* soap头
*/
private String xmlheader = "";
/**
* 命名空间
*/
private String xmlns = "";
/**
* 定义
*/
private XmlNode definitions = null;
/**
* 得到定义的soap的xml
*
* @param tns
* @param name
* @return
*/
public XmlNode GetDefinitions(String tns, String name) {
if (this.definitions == null) {
this.definitions = new XmlNode("wsdl:definitions");
this.definitions.PropertyList.put("name", name);
this.definitions.PropertyList.put("targetNamespace", tns);
this.definitions.PropertyList.put("xmlns:tns", tns);
this.definitions.PropertyList.put("xmlns:soap", "http://schemas.xmlsoap.org/wsdl/soap/");
this.definitions.PropertyList.put("xmlns:http", "http://schemas.microsoft.com/ws/06/2004/policy/http");
this.definitions.PropertyList.put("xmlns:msc", "http://schemas.microsoft.com/ws/2005/12/wsdl/contract");
this.definitions.PropertyList.put("xmlns:wsp", "http://schemas.xmlsoap.org/ws/2004/09/policy");
this.definitions.PropertyList.put("xmlns:wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
this.definitions.PropertyList.put("xmlns:wsam", "http://www.w3.org/2007/05/addressing/metadata");
this.definitions.PropertyList.put("xmlns:wsdl", "http://schemas.xmlsoap.org/wsdl/");
this.definitions.PropertyList.put("xmlns:ser", "http://schemas.microsoft.com/2003/10/Serialization/");
}
return definitions;
}
/**
* 类型
*/
private XmlNode types = null;
/**
* 得到类型
*
* @return
*/
public XmlNode GetTypes() {
if (this.types == null) {
this.types = new XmlNode("wsdl:types");
}
return this.types;
}
/**
* 得到schema
*
* @param targetns
* @param method
* @return
*/
public XmlNode NewSchema(String targetns, Method method) {
XmlNode schema = new XmlNode("xsd:schema");
schema.PropertyList.put("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
schema.PropertyList.put("xmlns:ser", "http://schemas.microsoft.com/2003/10/Serialization/");
schema.PropertyList.put("attributeFormDefault", "qualified");
schema.PropertyList.put("elementFormDefault", "qualified");
schema.PropertyList.put("targetNamespace", targetns);
schema.PropertyList.put("xmlns:tns", targetns);
XmlNode element = null;
//形式参数
XmlNode complextype = new XmlNode("xsd:complexType");
XmlNode sequence = new XmlNode("xsd:sequence");
Type[] types = method.getParameterTypes();
Parameter[] paras = method.getParameters();
for (int i = 0; i < types.length; i++) {
Type type = types[i];
String tname = type.getTypeName();
if (tname.equals("java.lang.String")) {
tname = "string";
}
//从注解获取参数名称
JRT.WebService.WS.Annotation.WebParam paraanno = paras[i].getDeclaredAnnotation(JRT.WebService.WS.Annotation.WebParam.class);
String paraname = "";
if (paraanno != null) {
paraname = paraanno.Name();
}
if (paraname.isEmpty()) {
paraname = paras[i].getName();
}
element = new XmlNode("xsd:element");
element.PropertyList.put("minOccurs", "1");
element.PropertyList.put("maxOccurs", "1");
element.PropertyList.put("nillable", "true");
element.PropertyList.put("name", paraname);
element.PropertyList.put("type", "xsd:" + tname);
sequence.Insert(element);
}
complextype.Insert(sequence);
element = new XmlNode("xsd:element");
element.PropertyList.put("name", method.getName());
element.Insert(complextype);
schema.Insert(element);
//返回参数
Type rtype = method.getReturnType();
element = new XmlNode("xsd:element");
String tname = rtype.getTypeName();
if (tname.equals("java.lang.String")) {
tname = "string";
}
element.PropertyList.put("minOccurs", "1");
element.PropertyList.put("maxOccurs", "1");
element.PropertyList.put("nillable", "true");
element.PropertyList.put("name", method.getName() + "Response");
element.PropertyList.put("type", "xsd:" + tname);
sequence = new XmlNode("xsd:sequence");
sequence.Insert(element);
complextype = new XmlNode("xsd:complexType");
complextype.Insert(sequence);
element = new XmlNode("xsd:element");
element.PropertyList.put("name", method.getName() + "Response");
element.Insert(complextype);
schema.Insert(element);
return schema;
}
/**
* Msg
*
* @param name
* @param parttns
* @return
*/
public XmlNode NewMessage(String name, String parttns) {
XmlNode message = new XmlNode("wsdl:message");
message.PropertyList.put("name", name);
XmlNode part = new XmlNode("wsdl:part");
part.PropertyList.put("name", "parameters");
part.PropertyList.put("element", "tns:" + parttns);
message.Insert(part);
return message;
}
/**
* 适配类型
*/
private XmlNode portType = null;
/**
* 得到适配类型
*
* @param name
* @return
*/
public XmlNode GetPortType(String name) {
if (this.portType == null) {
this.portType = new XmlNode("wsdl:portType");
this.portType.PropertyList.put("name", name);
}
return this.portType;
}
/**
* @param operName 方法名称
* @return
*/
public XmlNode NewPortOperation(String operName) {
XmlNode oper = new XmlNode("wsdl:operation");
oper.PropertyList.put("name", operName);
XmlNode input = new XmlNode("wsdl:input");
input.PropertyList.put("name", operName);
input.PropertyList.put("message", "tns:" + operName);
XmlNode output = new XmlNode("wsdl:output");
output.PropertyList.put("name", operName + "Response");
output.PropertyList.put("message", "tns:" + operName + "Response");
oper.Insert(input);
oper.Insert(output);
return oper;
}
/**
* 绑定
*/
private XmlNode binding = null;
/**
* 得到绑定
*
* @param name
* @param type
* @return
*/
public XmlNode GetBinding(String name, String type) {
if (this.binding == null) {
this.binding = new XmlNode("wsdl:binding");
this.binding.PropertyList.put("name", name);
this.binding.PropertyList.put("type", "tns:" + type);
XmlNode wsdlsoap = new XmlNode("soap:binding");
wsdlsoap.PropertyList.put("style", "document");
wsdlsoap.PropertyList.put("transport", "http://schemas.xmlsoap.org/soap/http");
this.binding.Insert(wsdlsoap);
}
return this.binding;
}
/**
* @param operName 方法名称
* @return
*/
public XmlNode NewBindingOperation(String operName) {
XmlNode oper = new XmlNode("wsdl:operation");
oper.PropertyList.put("name", operName);
XmlNode soapact = new XmlNode("soap:operation");
soapact.PropertyList.put("soapAction", operName);
oper.Insert(soapact);
XmlNode input = new XmlNode("wsdl:input");
input.PropertyList.put("name", operName);
input.PropertyList.put("message", "tns:" + operName);
XmlNode sopabody = new XmlNode("soap:body");
sopabody.PropertyList.put("use", "literal");
input.Insert(sopabody);
XmlNode output = new XmlNode("wsdl:output");
output.PropertyList.put("name", operName + "Response");
output.PropertyList.put("message", "tns:" + operName + "Response");
output.Insert(sopabody);
oper.Insert(input);
oper.Insert(output);
return oper;
}
/**
* 得到服务
*/
private XmlNode service = null;
/**
* 得到服务节点
*
* @param name
* @return
*/
public XmlNode GetService(String name) {
if (this.service == null) {
this.service = new XmlNode("wsdl:service");
this.service.PropertyList.put("name", name);
}
return this.service;
}
/**
* 得到约定
*
* @param name
* @param binding
* @param location
* @return
*/
public XmlNode NewPort(String name, String binding, String location) {
XmlNode port = new XmlNode("wsdl:port");
port.PropertyList.put("name", name);
port.PropertyList.put("binding", "tns:" + binding);
XmlNode addr = new XmlNode("soap:address");
addr.PropertyList.put("location", location);
port.Insert(addr);
return port;
}
/**
* 序列化
*
* @return
*/
public String Serialize() {
String xml = this.xmlheader;
xml = "";
if (this.definitions != null) {
xml += this.definitions.Serialize();
}
return xml;
}
}
按类得到soap
package JRT.WebService.WS.Wsdl;
import java.lang.reflect.Method;
/**
* 得到soap文档给调用者
*/
public class WsdlXmlUtil {
/**
* 根据类对象和请求url生成wsdl描述文档,按URL得到类,按类的注解生成wsdl
*
* @param cls
* @param url
* @return
* @throws Exception
*/
public static String GetWsdlXml(Class<?> cls, String url) throws Exception {
JRT.WebService.WS.Annotation.WebServer ws = (JRT.WebService.WS.Annotation.WebServer) cls.getAnnotation(JRT.WebService.WS.Annotation.WebServer.class);
String serviceName = ws.ServiceName();
JRT.WebService.WS.Wsdl.WsdlXml soapXml = new JRT.WebService.WS.Wsdl.WsdlXml();
String targetName = "http://tempuri.org/";
JRT.WebService.WS.XML.XmlNode definitions = soapXml.GetDefinitions(targetName, serviceName);
JRT.WebService.WS.XML.XmlNode types = soapXml.GetTypes();
JRT.WebService.WS.XML.XmlNode portType = soapXml.GetPortType(serviceName + "PortType");
JRT.WebService.WS.XML.XmlNode binding = soapXml.GetBinding(serviceName + "Binding", portType.PropertyList.get("name"));
JRT.WebService.WS.XML.XmlNode service = soapXml.GetService(serviceName);
JRT.WebService.WS.XML.XmlNode port = soapXml.NewPort(serviceName + "Port", binding.PropertyList.get("name"), url);
service.Insert(port);
Method[] methods = cls.getDeclaredMethods();
//遍历方法
for (Method method : methods) {
JRT.WebService.WS.Annotation.WebMethod wmd = method.getAnnotation(JRT.WebService.WS.Annotation.WebMethod.class);
//没标注发布的方法退出
if (wmd == null) {
continue;
}
JRT.WebService.WS.XML.XmlNode schema = soapXml.NewSchema(targetName, method);
types.Insert(schema);
String mdname = method.getName();
JRT.WebService.WS.XML.XmlNode porttypeoperation = soapXml.NewPortOperation(mdname);
portType.Insert(porttypeoperation);
JRT.WebService.WS.XML.XmlNode bindingoperation = soapXml.NewBindingOperation(mdname);
binding.Insert(bindingoperation);
}
definitions.Insert(types);
JRT.WebService.WS.XML.XmlNode message = null;
for (Method method : methods) {
JRT.WebService.WS.Annotation.WebMethod wmd = method.getAnnotation(JRT.WebService.WS.Annotation.WebMethod.class);
if (wmd == null) {
continue;
}
String mdname = method.getName();
message = soapXml.NewMessage(mdname, mdname);
definitions.Insert(message);
message = soapXml.NewMessage(mdname + "Response", mdname + "Response");
definitions.Insert(message);
}
definitions.Insert(portType);
definitions.Insert(binding);
definitions.Insert(service);
String wsdl = soapXml.Serialize();
return wsdl;
}
}
实现demo
import JRT.WebService.Http.BaseWebServiceHandler;
import JRT.WebService.WS.Annotation.*;
/**
* 发布Webservice的示例,请求尾部以.asmx请求
*/
@WebServer
public class WebServiceDemo extends BaseWebServiceHandler
{
/**
* 测试1
* @param arg0 参数
* @param arg1 参数
* @return
*/
@WebMethod
public String Test1(String arg0, String arg1)
{
return "参数:" + arg0 + "," + arg1;
}
/**
* 测试2
* @param arg0 参数
* @param arg1 参数
* @param arg2 参数
* @return
*/
@WebMethod
public String Test2(String arg0,String arg1, String arg2)
{
return "参数:" + arg0 + "," + arg1 + "," + arg2;
}
/**
* 参数
* @param arg0 参数
* @param arg1 参数
* @param arg2 参数
* @return
*/
public String Test3(String arg0,String arg1, String arg2)
{
return "参数:" + arg0 + "," + arg1 + "," + arg2;
}
}
用VS生成的代理类测试
能调到后台,但是取不到返回结果,比较奇怪,应该是实现不全的事,无所谓了,一般也不这么弄
这篇的代码能很好的体现Webservice的本质,服务器按Post的约定格式的xml执行方法后按约定格式的xml返回