一、基于JAX-WS的Web Service服务端/客户端
下面描述的是在main函数中使用JAX-WS的Web Service的方法,不是在web工程里访问,在web工程里访问,参加第二节。
JAX-WS简介:
JAX_RPC(Java API for XML-Based RPC)允许Java应用程序可以通过已知的描述信息调用一个基于Java的Web服务,描述信息与Web服务的WSDL描述相一致
JAX-RPC2.0更名为JAX-WS2.0(Java API for XML-Based Web Services)
JAX-WS中,一个远程调用可以转换为一个基于XML的协议,如SOAP。开发者在使用JAX-WS的过程中,不需要编写任何生成、处理SOAP消息的代码,JAX-WS在运行时自动将API的调用转换为相应的SOAP消息
在服务器端,用户只需要通过Java语言定义远程调用所需实现的接口,并提供相应实现,通过调用JAX-WS的服务发布接口即可将其发布为WebService接口
在客户端,用户可以通过JAX-WS的API创建一个代理来实现对于远程服务器端的调用
JAX-WS服务端:
JAX-WS服务端采用注释描述WebService,不再依赖WebService描述文件
使用JDK1.6_45(JDK1.5中不包含所需类)
程序启动后,访问http://127.0.0.1:8888/Plus?wsdl即可查看自动生成的WSDL文件
小注:addr是随便定义的,只要保证ip和端口可用即可,例如可以改成如下形式
String addr = "http://127.1.1.1:8889/Plus1?wsdl";
客户端访问,根据该地址进行访问。
JAX-WS客户端:
package com.sean.client; import java.net.URL; import javax.xml.namespace.QName; import javax.xml.ws.Service; import com.sean.server.Plus; public class Client { public static void main(String[] args) throws Exception { QName serviceName = new QName("http://server.sean.com/", "PlusImplService"); QName portName = new QName("http://server.sean.com/", "PlusImplPort"); String addr = "http://127.0.0.1:8888/Plus?wsdl"; URL url = new URL(addr); Service service = Service.create(url, serviceName); Plus plus = service.getPort(portName,Plus.class); //Plus plus = service.getPort(Plus.class); int result = plus.plus(1, 2); System.out.println("result:" + result); } }
使用Plus plus = service.getPort(Plus.class)方法时,客户端调用时报错:
Exception in thread "main" javax.xml.ws.WebServiceException: Undefined port type: {http://server.sean.com/}Plus
Exception in thread "main" javax.xml.ws.WebServiceException: Undefined port type: {http://server.sean.com/}Plus
解决方式一:
如客户端示例,将Plus plus = service.getPort(Plus.class)修改为Plus plus = service.getPort(portName,Plus.class)
解决方式二:
修改PlusImpl类的@WebService标记修改为@WebService(endpointInterface="com.sean.server.Plus")
参考资料:
http://blog.csdn.net/a19881029/article/details/32101373
http://ethan163.iteye.com/blog/1779194
http://www.micmiu.com/soa/webservice/jdk6-webservice-doc-rpc/
------------------------------------------------------------------------------------------------------------------------------
第一种:使用独立的端口(指端口可以在spring中自定义配置)
首先说第一种方式,这种方式不需要添加额外的jar包,他使用的是JDK自带的JWS来实现的。
web.xml文件配置:不需要额外配置,只需要配置spring相关的配置即可。
<?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" 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"> <display-name>JAXWSExample</display-name> <!-- applicationContext*.xml文件在src目录下的conf文件夹中--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:conf/applicationContext*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Log4j 日志 --> <listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener> <!-- 防止内存泄露 --> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> </web-app>
applicationContext-jaxws.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config />
<context:component-scan base-package="com.example.ws"></context:component-scan>
<!-- baseAddress 的value地址以及端口号是自定义的,端口号不要为已使用过的 ,ip和端口可以随便定义-->
<bean class="org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter">
<property name="baseAddress" value="http://localhost:8088/" />
</bean>
</beans>
java Code
package com.example.ws; import javax.jws.WebMethod; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import javax.jws.soap.SOAPBinding.Style; import org.springframework.stereotype.Service; // spring注解使用 @Service("exampleService") // webservice地址使用 @WebService(serviceName="example") // 防止jdk版本问题 @SOAPBinding(style=Style.RPC) public class ExampleService { // dependency dao/service //@Autowired //private IBaseDao baseDao; @WebMethod public String example1 (String request){ System.out.println(request); String response= request + "hello"; return response; } }
java代码中方法写的比较简单,也可以将输入参数和输出参数写为对象,这个根据需求来定。
以上就是第一种方法的实现方式,本地访问地址直接是:http://localhost:8088/example?wsdl
小注:wsdl访问的方法:
http://ip地址:服务器端口号/serviceName?wsdl
其中ip地址:服务器端口号:是在 <property name="baseAddress" value="http://localhost:8088/" />中配置的(即localhost:8088),
serviceName在程序中配置(即@WebService(serviceName="example")。
第二种方式: 使用servlet方式,该方式使用服务器端口
此种方式的话需要依赖于jax-ws 2.2中的jar文件,另外还需要下载额外的jaxws-spring-1.8.jar和xbean-spring-3.0.jar
web.xml,需要配置servlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 到END处用来配置启动spring容器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/applicationContext*.xml</param-value>
</context-param>
<!-- END -->
<!-- 用于配置地址栏请求路径 -->
<servlet> <servlet-name>JaxWsServlet</servlet-name> <servlet-class>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>JaxWsServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping>
</web-app>
applicationContext-jaxws.xml,与之前不同之处在于,需要xml头需要增加wss的声明
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ws="http://jax-ws.dev.java.net/spring/core" xmlns:wss="http://jax-ws.dev.java.net/spring/servlet" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://jax-ws.dev.java.net/spring/core http://jax-ws.dev.java.net/spring/core.xsd http://jax-ws.dev.java.net/spring/servlet http://jax-ws.dev.java.net/spring/servlet.xsd">
<!-- 扫描spring注解 --> <context:annotation-config /> <context:component-scan base-package="com.example.ws"> </context:component-scan>
<!-- 绑定webservice地址,需要与web.xml的地址对应 --> <wss:binding url="/services/add"> <wss:service> <ws:service bean="#exampleService" /> </wss:service> </wss:binding>
</beans>
java Code
package com.example.ws; import javax.jws.WebMethod; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import javax.jws.soap.SOAPBinding.Style; import org.springframework.stereotype.Service; @Service("exampleService")
// 只有此处与方法一不同 @WebService @SOAPBinding(style=Style.RPC) public class ExampleService { @WebMethod public String example1(String request){ System.out.println(request); String response = request+ "hello"; return response; } }
小注:
此种方式的本地请求地址为:http://localhost:8080/JAXWsExample2/services/add?wsdl
http://ip地址:服务器端口号/ 项目应用名/servlet定义地址?wsdl
参考资料:
http://www.cnblogs.com/mengzw/p/4040976.html
http://www.cnblogs.com/Johness/p/3824850.html
http://blog.csdn.net/lalicw/article/details/8897466
https://jax-ws-commons.java.net/spring/
http://www.mkyong.com/webservices/jax-ws/jax-ws-spring-integration-example/(maven工程配置)
(jax-ws webservice注解详解,参考以下资料)
http://wenku.baidu.com/link?url=cMKeybJvkAA_t5kaXmlPYm0J7I0mggnNLj4bXp0QGtpcpQbohMP275zd15IgBWobETDuaQUIYAaQV1OFyqY2qhyfCLiYClvcedVIlC2_hGa
---------------------------------------------------------------------------------------------
@WebService
public interface IMyService {
public int add(int a,int b);
public int minus(int a,int b);
}
@Service
@WebService(serviceName="myService")
@SOAPBinding(style = Style.DOCUMENT)
public class MyServiceImpl implements IMyService {
public int add(int a, int b) {
System.out.println(a+"+"+b+"="+(a+b));
return a+b;
}
public int minus(int a, int b) {
System.out.println(a+"-"+b+"="+(a-b));
return a-b;
}
}
2. spring配置文件如下:
<!--add bean for webservice in server-->
<bean class="org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter">
<property name="baseAddress" value="http://127.1.1.10:8089/"/>
</bean>
3. 客户端方法,首先需要生成客户端的java代码,其次是调用
3.1 用wsimport命令生成客户端java代码
在JDK中也提供了相应的工具来根据wsdl生成客户端代码这就是wsimport,可以通过wsimport -help来查看相应的参数。这里采用了以下几个参数
-verbose 显示编译的信息
-p 指定客户端package的名称
-keep 生成客户端的源文件和编译好的class文件,即导出客户端的class文件的同时,也导出源代码java文件
-d表示输出的目录,目录必须事先存在,否则导出失败
上例中:wsimport -verbose -p cn.cpic.koala.module.demo.webservice.client.myService -keep -d d: http://127.1.1.10:8089/myService?wsdl
MyService test = new MyService();
MyServiceImpl a = test.getMyServiceImplPort();
a.add(1, 2);
a.minus(6, 1);