最近的任务可是不少,组织上面要求发布WebService进行旧系统和新系统之间的数据通信,旧系统使用了EJB实现远程调用,EJB本身是可以发布成WebService的,就单纯的在EJB的类上面多加一个
最近的任务可是不少,组织上面要求发布WebService进行旧系统和新系统之间的数据通信,旧系统使用了EJB实现远程调用,EJB本身是可以发布成WebService的,就单纯的在EJB的类上面多加一个@WebService注解就能发布成功了。
不过最近听说有个CXF框架挺好的,可以支持Map,然而我查的所有资料中都指出WebService不支持Map类型。。。还不如就随便搞一个http接口然后整一个json返回去- -。
然而既然花了时间去搞这个了,那就好好的总结一下。
首先我创建了一个maven项目,用maven一开始就有的maven-archetype-webapp项目就行,maven依赖添加下面两个。
<properties> <cxf.version>3.1.6</cxf.version> </properties> <dependencies> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>${cxf.version}</version> </dependency> </dependencies>
随便定义了一个实体。
/** * 机构 */ public class Institution { /** * 机构代码 */ private String institutionCode; /** * 机构名称 */ private String institutionName; /** * 学制 */ private String schoolSystem; public String getInstitutionCode() { return institutionCode; } public void setInstitutionCode(String institutionCode) { this.institutionCode = institutionCode; } public String getInstitutionName() { return institutionName; } public void setInstitutionName(String institutionName) { this.institutionName = institutionName; } public String getSchoolSystem() { return schoolSystem; } public void setSchoolSystem(String schoolSystem) { this.schoolSystem = schoolSystem; } }写了三个属性,然后getter和setter。
定义一个接口,在里面添加两个方法,加入@WebService注解。
@WebService public interface InstitutionBean { /** * WebService demo * * @param id * @return */ @WebMethod @XmlJavaTypeAdapter(MapAdapter.class) @WebResult(partName = "return") Map<String, Object> queryProfessionalByCollageId( @WebParam(name = "collageId") String collageId, @WebParam(name = "dataBaseName") String dataBaseName, @WebParam(name = "name") String name); Institution queryEntity(@WebParam(name="InstitutionId")String InstitutionId); }第一个方法是返回的Map,第二个方法就随便返回了个实体,WebService是可以通过JDK的适配器处理Map的,这次重点不是这个,下篇博客会详细说明,回到我们的发布流程上。
@WebService(endpointInterface = "api.service.InstitutionBean") public class InstitutionBeanImpl implements InstitutionBean { /** * WebService demo * * @return */ @Override public Map<String, Object> queryProfessionalByCollageId(String collageId, String dataBaseName, String name) { // 随便写个方法,返回个Map Map<String, Object> map = new HashMap<String, Object>(); for (int i=0;i<10;i++){ Institution in=new Institution(); in.setInstitutionCode(String.valueOf(i)); in.setInstitutionName(String.valueOf(i)); map.put(String.valueOf(i),in); } return map; } @Override public Institution queryEntity(String InstitutionId) { Institution in=new Institution();<span style="white-space:pre"> </span>//再随便创建个方法,返回实体 in.setInstitutionCode(String.valueOf(i)); in.setInstitutionName(String.valueOf(i)); return in; } }
在类的上面也加上@WebService注解,endpointInterface属性指向接口的全限定名。
创建一个spring的配置文件,加入JAX-WS的Schema
<?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:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml" /> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> <jaxws:endpoint id="InstitutionService" implementor="serviceImpl.InstitutionBeanImpl" address="/InstitutionService" /> </beans>import的是cxf自己需要的配置文件,就这没写就可以了。
jaxws标签里面写的是endpoint的bean,如果调用的是Spring里面已经声明的类,还可以这么写。
<bean id="hello" class="demo.spring.service.HelloWorldImpl" /> <jaxws:endpoint id="helloWorld" implementor="#hello" address="/HelloWorld" />最后写web.xml,使用spring加载配置文件。
<web-app version="3.0" 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_3_0.xsd"> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:config/application*-webservice.xml </param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <servlet> <description>Apache CXF Endpoint</description> <display-name>cxf</display-name> <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> <!--CXF服务发布的路径--> <!--例如我这里发布好了,访问的是:http://localhost:8080/cxfdemo/ws/InstitutionService--> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>注意,这里一定要使用ContextLoaderListener加载配置文件,如果使用DispatcherServlet,会出现No service was found.的错误。
OK,用你的IDE部署项目,启动tomcat就能访问了。
我这里使用了tomcat,默认打开了localhost:8080,会出现这个页面
点击页面上的连接,就能看到wsdl地址了,然后发给需要的人就行了~