针对java–具有本机@WebService支持的可嵌入Web服务器,作为Endpoint.publish的替代方案这个问题,本篇文章进行了详细的解答,同时本文还将给你拓展Axis2webservic
针对java – 具有本机@WebService支持的可嵌入Web服务器,作为Endpoint.publish的替代方案这个问题,本篇文章进行了详细的解答,同时本文还将给你拓展Axis2 webservice 之使用java调用webservice、axis2 发布 webservice 和 java调用webservice、axis2开发webservice之将Spring的装配JavaBean发布成WebService、CXF 发布WebService - jaxws:endpoint等相关知识,希望可以帮助到你。
本文目录一览:- java – 具有本机@WebService支持的可嵌入Web服务器,作为Endpoint.publish的替代方案
- Axis2 webservice 之使用java调用webservice
- axis2 发布 webservice 和 java调用webservice
- axis2开发webservice之将Spring的装配JavaBean发布成WebService
- CXF 发布WebService - jaxws:endpoint
java – 具有本机@WebService支持的可嵌入Web服务器,作为Endpoint.publish的替代方案
如果您构建一个简单的独立应用程序,它使用Endpoint.publish公开一个或多个@WebService注释类,然后您遇到无法再使用Endpoint.publish的情况(出于任何原因)什么是最简单的迁移路径?
我知道您可以使用sun-jaxws.xml和可选的Metro jar创建一个WAR,然后可以将其部署到嵌入式Web服务器(如Jetty或Winstone),但我喜欢简单的“拿这个类并在这个URL上公开它” Endpoint.publish()的API,没有任何XML或完整容器.
有没有一个很好的方法来做到这一点?
解决方法
com.sun.net.httpserver.HttpServer
的实例中自定义端点的HTTP行为.谨慎使用com.sun API始终是一个好主意,但根据您的具体情况,这可能是合适的.例如,有一个
HttpsServer子类可用于提供SSL.
这个过程似乎是:
>使用HttpServer.create(new InetSocketAddress(listenPortNumber),waitQueueDepth)
创建服务器实例.
>使用server.createContext("/path")
创建将托管端点的上下文.
>使用Endpoint.create(new RpcLitEndpoint())创建端点.目前尚不清楚RpcLitEndpoint的定义位置或是否严格要求;它可能是Metro JAX-WS的一部分.
>调用endpoint.publish(context)以将端点与HttpServer(或HttpsServer)实例相关联.
完成后,使用endpoint.stop和server.stop关闭.
还有一个blog entry on blogs.oracle.com描述了自定义网络传输的创建.它没有足够的细节让我从快速扫描中获得很好的理解,但也许你可以从中获得更多.
Axis2 webservice 之使用java调用webservice
在上一篇中写了一个简单了webservice,实现了一个sayHello功能。那么webservice写好之后我们如何使用Java程序来调用webservice呢?
一、java调用的webservice的第一种方式:RPC调用AXIS2 webservice
下面这个方法是我抽象出来的一个方法,
import javax.xml.namespace.QName; org.apache.axis2.AxisFault; org.apache.axis2.addressing.EndpointReference; org.apache.axis2.client.Options; org.apache.axis2.rpc.client.RPCServiceClient; public class Client { /** * @param args * @throws Exception */ static void main(String[] args) throws Exception { // 调用PublishWebService String wsdlUrl = "http://localhost:8080/DigitalProduct/services/PublishWebService?wsdl";//webservice地址 String method = "updatePublishSysParam"; //调用的那个方法 Object[] param = new Object[] { "AASSDDFF" };//传递的参数值 String namespaceUrl1 = "http://service.digitalproduct.tkbs.com";//命名空间 Class[] opReturnType1 = new Class[] { String[]. };//返回值类型 String result = axis2RPCInvoke(wsdlUrl,method,param,namespaceUrl1,opReturnType1); System.out.println(result); } * RPC调用AXIS2 webservice * * wsdlUrl * 服务地址 如:http://192.168.0.1:2597/aixs2/services/jqservice?wsdl * methodName * 方法名 如<xs:element name="Receive"> * parameter * 方法参数 如Object[] opArgs = new Object[] { param }; * namespaceURI * 命名空间 如 :targetNamespace="http://server.test.com.cn"> * returnType * 返回类型 如字符串:Class[] opReturnType = new Class[] { String[].class * }; static String axis2RPCInvoke(String wsdlUrl,String methodName,Object[] parameter,String namespaceURI,Class[] returnType) { Object[] ret = null; RPCServiceClient serviceClient = ; try { /* * 此处RPCServiceClient 对象实例建议定义成类中的static变量 ,否则多次调用会出现连接超时的错误。 */ serviceClient = new RPCServiceClient(); Options options = serviceClient.getoptions(); EndpointReference targetEPR = EndpointReference(wsdlUrl); options.setTo(targetEPR); QName opQName = QName(namespaceURI,methodName); ret = serviceClient.invokeBlocking(opQName,parameter,returnType); System.out.println(((String[]) ret[0])[0]); } catch (AxisFault e) { e.printstacktrace(); } return ((String[]) ret[0])[0]; } }
二、使用java调用webservice的第二种方式:使用myeclipse中的axis2插件生成客户端代码
new -->others到如下界面:
点next 到如下界面:
现在我们想生成调用webservice的客户端代码,首先我们需要生成一个service.wsdl文件,选择第2个,点next,
在界面里边点击add folder 选择项目--》webroot--》webinf-->classes,输入好webservice那个类的全名后点击Test Class Loading ,这时候如果你选择的路径是对的,类全名是对的,就可以点next,否则next按钮式灰色的。如图:
然后点击next,这个界面中的内容基本不用修改,有一个service name,你可以改成你自己取。
继续点next 在界面中选择wsdl文件的输出路径,选择第一个,就是输出到当前的workspace,的某个项目下,选择第二个,就是输出到系统文件夹中,例如你可以选择桌面。
这里我选择第二个,然后点browse选择桌面,点finish,会看到桌面上有一个service.wsdl文件。
下面我们就可以根据这个wsdl文件生成客户端代码了。
首先建一个java项目,例如取名myclient
new -->others-->
选择第1个,点next.
在界面中点 browse找到你刚才生成service.wsdl文件。
点next,这个界面不用管,继续点next
这个时候需要选择代码生成的地方,选择当前工作的workspace,然后选择刚才新建的myclient如图:
点finsh,刷新myclient项目会看到src下多了两个java文件:TestServiceCallbackHandler 和 TestServiceStub
接下来就可以写java代码调用了,如下:
myservice.service.TestServiceStub; Test { Exception Todo Auto-generated method stub 初始化Sub类 TestServiceStub stub = TestServiceStub(); 传递AxisServiceStub.ShowName对象,相关参数在这边赋值。 TestServiceStub.SayHello command = TestServiceStub.SayHello(); command.setName("zhangsan"); 取得返回值 String name = stub.sayHello(command).get_return(); System.out.println(name); } }
如此,第二种方式就写完了。
公司几个同事都喜欢第二种。但是,我个人喜欢用第一种。第二种方式如果插件使用熟练的话,很快就可以生产客户端代码,然后测试代码也可以很快写出来。
注:可能会出现错误,根据我的经历的错误经验,有以下情况:
1.tomcat端口问题,你打开刚才插架自动生成的TestServiceStub 类 ctrl+f查找 http://localhost,查到后看他后面的端口是多少,是不是8080,?好像生成的就是8080,但是我们的tomcat可能被自己修改过,端口可能不是8080,所以这里你要改这个端口。
2.spring的注入问题,如果你写的webservice是在spring整合的环境下,可能会报错误,一般是由 spring注入失败,导致xxxService类注入失败。关于这个我下一篇会详细解释。
3.一切都正常,打断点调试看到方法执行成功了、执行完毕了,但是并没有成功的返回我们要的结果,而是报超时了,这时候,我们需要在TestServiceStub 中加入一行代码
这行代码的作用是 规定超时时间 是多长,例如你可以设为10分钟。_operationClient.getoptions().setTimeOutInMilliSeconds(600000L); //600*1000毫秒(10分钟
我感觉这样设置不合理,但是可以解决这个错误,让你的程序运行成功,看到运行成功返回的结果。才有继续学习的劲头啊。
axis2 发布 webservice 和 java调用webservice
apache-tomcat-6.0.35.zip axis2-1.6.1-war.zip解压,然后将axis2.war复制到tomcat的webapp目录中,安装完毕!
启动tomcat测试axis2是否安装成功:
http://localhost:8080/axis2
2.首先简单介绍一下webapp/axis2/的目录结构如下:
axis2 |-- axis2-web | |-- xxx.jsp... |-- meta-inf |-- WEB-INF | |-- classes | |-- conf | |-- lib | |-- modules | |-- services | | |-- version-1.6.1.aar | |-- web.xml其中,services目录就是用来发布webservice的目录,这里有一个自带的service:version-1.6.1.aar
3.开发service端:HelloService .java
package com.service; public class HelloService { public String getName(String name) { return "hello: " + name; } }
4.配置文件:service.xml
<service name="HelloService"> <description>HelloWorld webservice</description> <parameter name="ServiceClass"> com.service.HelloService </parameter> <messageReceivers> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"https://www.jb51.cc/tag/cme/" target="_blank">cmessageReceiver"/> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"/> </messageReceivers> </service>
5.建立如下的目录结构:
test |-- meta-inf | |--services.xml | |-- com | |-- service | |-- HelloService.java | |-- HelloService.class这里test可以随便命名,然后要把test目录里面的所有文件打包成zip格式的,后缀必须是*.aar。
打包方法1,使用7-Zip压缩工具打包,格式选择zip,压缩之后,把文件的后缀改为aar,test.aar。
打包方法2,其实“con/...”这个部分是class文件,可以放入/webapps/WEB-INF/class目录下。也就是说打包的时候可以之打包“meta-inf/...”部分。而“con/...”部分可能会经常更改,在Eclipse开发过程中可以放入src目录中。
打包完成之后,然后将文件test.aar复制到services目录下面。重启tomcat,进行测试:
http://localhost:8080/axis2/services/listServices
6.开发客户端:RPcclient.java
package com.client; import javax.xml.namespace.QName; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.rpc.client.RPCServiceClient; public class RPcclient { public static void main(String[] args) throws Exception { RPCServiceClient client = new RPCServiceClient(); Options options = client.getoptions(); // 指定调用WebService的URL options.setTo(new EndpointReference("http://localhost:8080/axis2/services/HelloService")); // 指定getName方法的参数值 Object[] objects = new Object[] { "超人" }; // 指定getName方法返回值的数据类型的Class Class<?>[] classes = new Class[] { String.class }; // 指定要调用的方法名:getName 和 WSDL文件中的命名空间:http://service.com // 注意:命名空间(http://service.com)与类HelloService的包名(com.service)有一定关系。 QName qname = new QName("http://service.com","getName"); String result = (String) client.invokeBlocking(qname,objects,classes)[0]; System.out.println(result); } }
7.运行客户端,端测试结果: 你好 超人
axis2开发webservice之将Spring的装配JavaBean发布成WebService
前些阵子刚好学会了spring,现在来把axis2和spring结合一下,这也是做企业开发的时候必须的,结合教程来学习一遍。
在现今的Web应用中经常使用Spring框架来装载JavaBean。如果要想将某些在Spring中装配的JavaBean发布成WebService,使用Axis2的Spring感知功能是非常容易做到的。
在本文的例子中,除了<Tomcat安装目录>\webapps\axis2目录及该目录中的相关库外,还需要Spring框架中的spring.jar文件(这里是基于spring2.X的,spring3.X没有此包,改名了),将该文件复制到<Tomcat安装目录>\webapps\axis2\WEB-INF\lib目录中。
下面先建立一个JavaBean(该JavaBean最终要被发布成WebService),代码如下:
其中Person也是一个JavaBean,代码如下:
将上面两个Java源文件编译后,放到<Tomcat安装目录>\webapps\axis2\WEB-INF\classes目录中。
在<Tomcat安装目录>\webapps\axis2\WEB-INF\web.xml文件中加入下面的内容:
在<Tomcat安装目录>\webapps\axis2\WEB-INF目录中建立一个applicationContext.xml文件,该文件是Spring框架用于装配JavaBean的配置文件,内容如下:
在applicationContext.xml文件中装配了service.SpringService类,并被始化了name和job属性。在配置完SpringService类后,就可以直接在程序中FileSystemXmlApplicationContext类或其他类似功能的类读取applicationContext.xml文件中的内容,并获得SpringService类的对象实例。但现在我们并不这样做,而是将SpringService类发布成WebService。
在<Tomcat安装目录>\webapps\axis2\WEB-INF\lib目录中有一个axis2-spring-1.4.1.jar文件,该文件用于将被装配JavaBean的发布成WebService。在D盘建立一个axi2-spring-ws目录,并在该目录中建立一个meta-inf子目录。在meta-inf目录中建立一个services.xml文件,内容如下:
在Windows控制台进入axi2-spring-ws目录,并使用jar命令将axi2-spring-ws目录中的内容打包成axi2-spring-ws.aar,然后将该文件复制到<Tomcat安装目录>\webapps\axis2\WEB-INF\services目录中,启动Tomcat后,就可以访问该WebService了,访问方式与前面几篇文章的访问方式相同。获得wsdl内容的URL如下:
http://localhost:8080/axis2/services/springService?wsdl
在将Spring中的装配JavaBean发布成WebService需要注意以下几点:
1. 由JavaBean编译生成的.class文件需要放在WEB-INF\classes目录中,或打成.jar包后放在WEB-INF\lib目录中,而WEB-INF\services目录中的.aar包中不需要包含.class文件,而只需要包含一个meta-inf目录,并在该目录中包含一个services.xml文件即可。
2. services.xml的配置方法与前几篇文章的配置方法类似,只是并不需要使用ServiceClass参数指定要发布成WebService的Java类,而是要指定在applicationContext.xml文件中的装配JavaBean的名称(SpringBeanName参数)。
3. 在services.xml文件中需要通过ServiceObjectsupplier参数指定SpringServletContextObjectsupplier类来获得Spring的ApplicationContext对象。
接下来就没什么难度了,就是我们熟悉的stub类了,编写客户端代码了。如下
运行结果
这里就比较有意思了,咋一看,不对啊,我们已经更新了name和job了,为什么最后的输入还是spring注入赋值的状态呢。其实我们可以看到,这是由于访问的路径不同所造成的,虽说我们都是在访问发布在webservice上的getPerson()方法,但是访问的入口不对,sss是客户端类的成员变量,是全局结构,与spring联系紧密,spring注入的时候是从springService类的setter,getter方法注入到当前的name和job(即代码中的this),再把当前对象的变量当做参数传到person类的setter方法中。而用person访问的时候,没有见过spring注入到当前对象中这一环节,直接是从最底层的person类中用其setter方法设置变量值的,这时候name和job已经变成了person的设置值,如果这时候再用sss去获取name和job,这时候为了初始化sss这个对象,必然会加载stub类,这时候就相当于再次注入spring了,name和job的值再次改变。因此我们看上去才会觉得两次访问好像是访问了不同的地方似的。
CXF 发布WebService - jaxws:endpoint
# 依赖 jar
commons-logging-1.1.1.jar
cxf-2.7.5.jar
httpasyncclient-4.0-beta3.jar
httpclient-4.2.1.jar
httpcore-4.2.2.jar
httpcore-nio-4.2.2.jar
neethi-3.0.2.jar
org.springframework.aop-3.1.3.RELEASE.jar
org.springframework.asm-3.1.3.RELEASE.jar
org.springframework.beans-3.1.3.RELEASE.jar
org.springframework.context-3.1.3.RELEASE.jar
org.springframework.core-3.1.3.RELEASE.jar
org.springframework.expression-3.1.3.RELEASE.jar
org.springframework.web-3.1.3.RELEASE.jar
org.springframework.web.servlet-3.1.3.RELEASE.jar
stax2-api-3.1.1.jar
woodstox-core-asl-4.2.0.jar
wsdl4j-1.6.3.jar
wss4j-1.6.10.jar
xmlschema-core-2.0.3.jar
xmlsec-1.5.4.jar
# download url
http://cxf.apache.org/download.html
http://repo.spring.io/release/org/springframework/spring
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/overview.html
1. 一个接口
package org.demo.ws; import javax.jws.WebService; @WebService public interface HelloWorld { String sayHi(String text); }2. 一个实现类
package org.demo.ws.server; import javax.jws.WebService; import org.demo.ws.HelloWorld; @WebService(serviceName="hello",endpointInterface="org.demo.ws.HelloWorld") public class HelloWorldImpl implements HelloWorld { public HelloWorldImpl() { System.out.println("-- init HelloWorldImpl --"); } public String sayHi(String text) { System.out.println("in sayHi,text : " + text); return "hi " + text + "."; } }3. 一个服务端用户名密码回调类
package org.demo.ws.server; import java.io.IOException; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import javax.servlet.http.HttpServletRequest; import javax.xml.stream.XMLStreamReader; import org.apache.cxf.binding.soap.soapMessage; import org.apache.cxf.headers.Header; import org.apache.cxf.transport.http.AbstractHTTPDestination; import org.apache.ws.security.WSPasswordCallback; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class MyPasswordCallback implements CallbackHandler { @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { WSPasswordCallback pwCallback = (WSPasswordCallback)callbacks[0]; String userName = pwCallback.getIdentifier(); // 1. get client ip SoapMessage msg = (SoapMessage)pwCallback.getRequestData().getMsgContext(); HttpServletRequest req = (HttpServletRequest)msg.getContextualProperty(AbstractHTTPDestination.HTTP_Request); String clientIp = req.getRemoteAddr(); // 2. get method name XMLStreamReader xmlReader = msg.getContent(XMLStreamReader.class); String methodName = xmlReader.getLocalName(); // 3. get header Header header = msg.getHeaders().get(0); Element securityElement = (Element)header.getobject(); String password = getFirstElementValue(securityElement,"Password"); String nonce = getFirstElementValue(securityElement,"Nonce"); String time = getFirstElementValue(securityElement,"Created"); // 4. log System.out.println("clientIp=" + clientIp + ",methodName=" + methodName + ",userName=" + userName + ",password=" + password + ",nonce=" + nonce + ",time=" + time); if ("user1".equals(userName)) { pwCallback.setPassword("password1"); } } /** * 根据tagName获取第一个匹配的XML元素内容 * @param current * @param tagName * @return */ private String getFirstElementValue(Element current,String tagName) { String result = null; Element tmpElement = null; Element firstElement = null; NodeList nodeList = current.getChildNodes(); for (int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item(i); if (!(node instanceof Element)) { continue; } tmpElement = (Element)node; if (tmpElement.getLocalName().equals(tagName)) { result = tmpElement.getTextContent(); break; } if (firstElement == null) { firstElement = tmpElement; } } if (result == null && firstElement != null) { result = getFirstElementValue(firstElement,tagName); } return result; } }4. web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation=" http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>cxf</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>cxf</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> </web-app>5. spring.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd" > <!-- 隐式地向spring容器注册了注解处理器 --> <context:annotation-config /> <!-- CXF Web Service --> <import resource="classpath:meta-inf/cxf/cxf.xml" /> <bean id="myPasswordCallback"/> <bean id="wSS4JInInterceptor"https://www.jb51.cc/tag/ecurity/" target="_blank">ecurity.wss4j.WSS4JInInterceptor"> <constructor-arg> <map> <entry key="action" value="Usernametoken" /> <entry key="passwordType" value="PasswordText" /> <entry key="user" value="cxfServer" /> <entry key="passwordCallbackRef"> <ref bean="myPasswordCallback" /> </entry> </map> </constructor-arg> </bean> <bean id="helloWorldImpl"/> <jaxws:endpoint id="helloWorld" address="/hello" implementor="#helloWorldImpl"> <jaxws:inInterceptors> <ref bean="wSS4JInInterceptor"/> </jaxws:inInterceptors> <jaxws:properties> <!-- the max size of soap message,default value is Long.MAX_VALUE --> <!-- refer to: http://cxf.apache.org/docs/security.html#Security-ControllingLargeRequestPayloads --> <entry key="org.apache.cxf.stax.maxXMLCharacters" value="10240" /> </jaxws:properties> </jaxws:endpoint> </beans>
6. 访问 web service
http://localhost:8080/context/services/hello?wsdl
今天关于java – 具有本机@WebService支持的可嵌入Web服务器,作为Endpoint.publish的替代方案的讲解已经结束,谢谢您的阅读,如果想了解更多关于Axis2 webservice 之使用java调用webservice、axis2 发布 webservice 和 java调用webservice、axis2开发webservice之将Spring的装配JavaBean发布成WebService、CXF 发布WebService - jaxws:endpoint的相关知识,请在本站搜索。
本文标签: