之前准备试试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-8response.setContentType("text/xml"); //设置响应mime类型为text/xml//获取请求的url,wsdl问了里面需要使用该urlString 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/xmlresponse.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:EnvelopeElement root = document.getDocumentElement();//获取根节点名称String rootname = root.getNodeName();//节点名称":"号的前缀根据不同的请求会有差异,所以这里取出来,响应的soap文档的节点前缀也是用这个String nodename_pre = "";if (rootname.contains(":")) {nodename_pre = rootname.split(":")[0];}// 获取soap的bodyNode body = null; //soap bodyNode 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);}}//没有配到对应参数默认Stringif (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和bodyif (body != null) {root.removeChild(body);}if (header != null) {root.removeChild(header);}//构造新的header和body//构建headerNode 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 version=\"1.0\" encoding=\"UTF-8\" ?>" + 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 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";/*** 命名空间*/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;}
}
WebBase对接获取soap文档和soap调用
实现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*/@WebMethodpublic String Test1(String arg0, String arg1){return "参数:" + arg0 + "," + arg1;}/*** 测试2* @param arg0 参数* @param arg1 参数* @param arg2 参数* @return*/@WebMethodpublic 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;}
}
访问查询soap
用soapui测试
用我以前包的动态调用Webservice工具测试
用VS生成的代理类测试
能调到后台,但是取不到返回结果,比较奇怪,应该是实现不全的事,无所谓了,一般也不这么弄
这篇的代码能很好的体现Webservice的本质,服务器按Post的约定格式的xml执行方法后按约定格式的xml返回