WebService开发笔记(一)-- 利用cxf开发WebService竟然如此简单
发布时间:2020-12-17 00:07:54 所属栏目:安全 来源:网络整理
导读:现在的项目中需要用到SOA概念的地方越来越多,最近我接手的一个项目中就提出了这样的业务要求,需要在.net开发的客户端系统中访问java开发的web系统,这样的业务需求自然需要通过WebService进行信息数据的操作。下面就将我们在开发中摸索的一点经验教训总结以下
![]()
现在的项目中需要用到SOA概念的地方越来越多,最近我接手的一个项目中就提出了这样的业务要求,需要在.net开发的客户端系统中访问java开发的web系统,这样的业务需求自然需要通过WebService进行信息数据的操作。下面就将我们在开发中摸索的一点经验教训总结以下,以供大家参考.?
我们项目的整个架构使用的比较流行的WSH MVC组合,即webwork2 + Spring + Hibernate;? 1.首先集成Apacha CXF WebService 到 Spring 框架中;? apache cxf 下载地址>>:? (1)在spring context配置文件中引入以下cxf配置? *****************************************************************************? <import resource="classpath*:META-INF/cxf/cxf.xml" />??? <import resource="classpath*:META-INF/cxf/cxf-extension-soap.xml" />??? <import resource="classpath*:META-INF/cxf/cxf-servlet.xml" />??? <import resource="classpath*:META-INF/cxf/cxf.xml" />? <import resource="classpath*:META-INF/cxf/cxf-extension-soap.xml" />? <import resource="classpath*:META-INF/cxf/cxf-servlet.xml" />? *****************************************************************************? (2)在web.xml中添加过滤器:? *****************************************************************************? <servlet>??? ???? <servlet-name>CXFServlet</servlet-name>??? ???? <servlet-class>??? ???????? org.apache.cxf.transport.servlet.CXFServlet??? ???? </servlet-class>??? </servlet>??? <servlet-mapping>??? ???? <servlet-name>CXFServlet</servlet-name>??? ???? <url-pattern>/services/*</url-pattern>??? </servlet-mapping>? *****************************************************************************? 2.开发服务端WebService接口:? Java代码? /**??? * WebService接口定义类.??? *??? * 使用@WebService将接口中的所有方法输出为Web Service.??? * 可用annotation对设置方法、参数和返回值在WSDL中的定义.??? */??? @WebService??? public interface WebServiceSample {? ???? /**??? ???? * 一个简单的方法,返回一个字符串??? ???? * @param hello??? ???? * @return??? ???? */??? ???? String say(String hello);??? ????????/**??? ???? * 稍微复杂一些的方法,传递一个对象给服务端处理??? ???? * @param user??? ???? * @return??? ???? */??? ???? String sayUserName(??? ????????????@WebParam(name = "user")????? ????????????UserDTO user);??? ???????? /**??? ???? * 最复杂的方法,返回一个List封装的对象集合??? ???? * @return??? ???? */??? ???? public????? ???? @WebResult(partName="o")??? ???? ListObject findUsers();? }??? /**? * WebService接口定义类.? *? * 使用@WebService将接口中的所有方法输出为Web Service.? * 可用annotation对设置方法、参数和返回值在WSDL中的定义.? */? @WebService? public interface WebServiceSample {? /**? * 一个简单的方法,返回一个字符串? * @param hello? * @return? */? String say(String hello);? ??/**? ?? * 稍微复杂一些的方法,传递一个对象给服务端处理? * @param user? * @return? */? String sayUserName(? ?? @WebParam(name = "user")? ?? UserDTO user);? /**? ?? * 最复杂的方法,返回一个List封装的对象集合? * @return? ?? */? public? @WebResult(partName="o")? ListObject findUsers();? }? 由简单到复杂定义了三个接口,模拟业务需求;? 3.实现接口? Java代码? /**??? * WebService实现类.??? * 使用@WebService指向Interface定义类即可.??? */??? @WebService(endpointInterface = "cn.org.coral.biz.examples.webservice.WebServiceSample")??? public class WebServiceSampleImpl implements WebServiceSample {??? ????public String sayUserName(UserDTO user) {??? ???? ????return "hello "+user.getName();??? ???? }??? ?? ??public String say(String hello) {??? ???????? return "hello "+hello;??? ???? }??? ???? public ListObject findUsers() {??? ???????? ArrayList<Object> list = new ArrayList<Object>();??? ???????? list.add(instancUser(1,"lib"));??? ???????? list.add(instancUser(2,"mld"));??? ???????? list.add(instancUser(3,"lq"));??? ???????? list.add(instancUser(4,"gj"));??? ???????? ListObject o = new ListObject();??? ?????? o.setList(list);??? ???????? return o;??? ???? }??? ???? private UserDTO instancUser(Integer id,String name){??? ???????? UserDTO user = new UserDTO();??? ???????? user.setId(id);??? ???????? user.setName(name);??? ???????? return user;??? ???? }??? }??? /**? * WebService实现类.? * 使用@WebService指向Interface定义类即可.? */? @WebService(endpointInterface = "cn.org.coral.biz.examples.webservice.WebServiceSample")? public class WebServiceSampleImpl implements WebServiceSample {? public String sayUserName(UserDTO user) {? ?? return "hello "+user.getName();? }? public String say(String hello) {? ?? return "hello "+hello;? }? public ListObject findUsers() {? ?? ArrayList<Object> list = new ArrayList<Object>();? ?? list.add(instancUser(1,"lib"));? ?? list.add(instancUser(2,"mld"));? ?? list.add(instancUser(3,"lq"));? ?? list.add(instancUser(4,"gj"));? ?? ListObject o = new ListObject();? ?? o.setList(list);? ?? return o;? }? private UserDTO instancUser(Integer id,String name){? ?? UserDTO user = new UserDTO();? ?? user.setId(id);? ?? user.setName(name);? ?? return user;? }? }? 4.依赖的两个类:用户对象与List对象? Java代码? /**??? * Web Service传输User信息的DTO.??? *??? * 分离entity类与web service接口间的耦合,隔绝entity类的修改对接口的影响.??? * 使用JAXB 2.0的annotation标注JAVA-XML映射,尽量使用默认约定.??? *??? */??? @XmlAccessorType(XmlAccessType.FIELD)??? @XmlType(name = "User")??? public class UserDTO {? ???? protected Integer id;? ???? protected String name;? ???? public Integer getId() {??? ???????? return id;??? ???? }? ???? public void setId(Integer value) {??? ???????? id = value;??? ???? }??? ???? public String getName() {??? ???????? return name;??? ???? }? ???? public void setName(String value) {??? ???????? name = value;??? ???? }??? }??? /**? * Web Service传输User信息的DTO.? * 分离entity类与web service接口间的耦合,隔绝entity类的修改对接口的影响.? * 使用JAXB 2.0的annotation标注JAVA-XML映射,尽量使用默认约定.? */? @XmlAccessorType(XmlAccessType.FIELD)? @XmlType(name = "User")? public class UserDTO {? protected Integer id;? protected String name;? public Integer getId() {? return id;? }? public void setId(Integer value) {? id = value;? }? public String getName() {? ??return name;? }? public void setName(String value) {? name = value;? }? }? 关于List对象,参照了有关JWS的一个问题中的描述:DK6.0 自带的WebService中 WebMethod的参数好像不能是ArrayList 或者其他List? 传递List需要将List 包装在其他对象内部才行 (个人理解 如有不对请指出),我在实践中也遇到了此类问题.通过以下封装的对象即可以传递List对象.? Java代码? /**??? * <p>Java class for listObject complex type.??? *??? * <p>The following schema fragment specifies the expected content contained within this class.??? *??? * <pre>??? * <complexType name="listObject">??? *?? <complexContent>??? *???? <restriction base="{? http://www.w3.org/2001/XMLSchema }anyType">??? *?????? <sequence>??? *???????? <element name="list" type="{? http://www.w3.org/2001/XMLSchema }anyType" maxOccurs="unbounded" minOccurs="0"/>??? *?????? </sequence>??? *???? </restriction>??? *?? </complexContent>??? * </complexType>??? * </pre>??? *??? *??? */??? @XmlAccessorType(XmlAccessType.FIELD)??? @XmlType(name = "listObject",propOrder = { "list" })??? public class ListObject {? ???? @XmlElement(nillable = true)??? ???? protected List<Object> list;? ???? /**??? ???? * Gets the value of the list property.??? ???? *??? ???? * <p>??? ???? * This accessor method returns a reference to the live list,??? ???? * not a snapshot. Therefore any modification you make to the??? ???? * returned list will be present inside the JAXB object.??? ???? * This is why there is not a <CODE>set</CODE> method for the list property.??? ???? *??? ???? * <p>??? ???? * For example,to add a new item,do as follows:??? ???? * <pre>??? ???? *????getList().add(newItem);??? ???? * </pre>??? ???? *??? ???? *??? ???? * <p>??? ???? * Objects of the following type(s) are allowed in the list??? ???? * {@link Object }??? ???? *??? ???? *??? ???? */??? ???? public List<Object> getList() {??? ???????? if (list == null) {??? ?????? ???? list = new ArrayList<Object>();??? ?????? }??? ?????? return this.list;??? ???? }? ???? public void setList(ArrayList<Object> list) {??? ???? ????this.list = list;??? ???? }??? }??? /**? * <p>Java class for listObject complex type.? *? * <p>The following schema fragment specifies the expected content contained within this class.? *? * <pre>? * <complexType name="listObject">? *?? <complexContent>? *???? <restriction base="{? http://www.w3.org/2001/XMLSchema }anyType">? *?????? <sequence>? *???????? <element name="list" type="{? http://www.w3.org/2001/XMLSchema }anyType" maxOccurs="unbounded" minOccurs="0"/>? *?????? </sequence>? *???? </restriction>? *?? </complexContent>? * </complexType>? * </pre>? *? *? */? @XmlAccessorType(XmlAccessType.FIELD)? @XmlType(name = "listObject",propOrder = { "list" })? public class ListObject {? @XmlElement(nillable = true)? protected List<Object> list;? /**? ?? * Gets the value of the list property.? ?? *? ?? * <p>? ?? * This accessor method returns a reference to the live list,? ?? * not a snapshot. Therefore any modification you make to the? ?? * returned list will be present inside the JAXB object.? * This is why there is not a <CODE>set</CODE> method for the list property.? ?? *? ?? * <p>? ?? * For example,do as follows:? ?? * <pre>? ?? *????getList().add(newItem);? ?? * </pre>? ?? *? ?? *? ?? * <p>? ?? * Objects of the following type(s) are allowed in the list? ?? * {@link Object }? ?? *? ?? *? ?? */? public List<Object> getList() {? ?? if (list == null) {? ?? list = new ArrayList<Object>();? ?? }? ?? return this.list;? }? public void setList(ArrayList<Object> list) {? ?? this.list = list;? }? }? 5.WebService 服务端 spring 配置文件 ws-context.xml? Xml代码? <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://cxf.apache.org/jaxws ? http://cxf.apache.org/schemas/jaxws.xsd http://www.springframework.org/schema/beans? ;?? http://www.springframework.org/schema/beans/spring-beans.xsd" ;??? ???? default-autowire="byName" default-lazy-init="true">????????? ???? <jaxws:endpoint id="webServiceSample"??? ???????? address="/WebServiceSample" implementor="cn.org.coral.biz.examples.webservice.WebServiceSampleImpl"/>??? </beans>? <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://cxf.apache.org/jaxws ? http://cxf.apache.org/schemas/jaxws.xsd http://www.springframework.org/schema/beans? ;?? http://www.springframework.org/schema/beans/spring-beans.xsd" ;? default-autowire="byName" default-lazy-init="true">? <jaxws:endpoint id="webServiceSample"? ?? address="/WebServiceSample" implementor="cn.org.coral.biz.examples.webservice.WebServiceSampleImpl"/> </beans>? WebService 客户端 spring 配置文件 wsclient-context.xml? Xml代码? <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://cxf.apache.org/jaxws ? http://cxf.apache.org/schemas/jaxws.xsd http://www.springframework.org/schema/beans? ;?? http://www.springframework.org/schema/beans/spring-beans.xsd" ;??? ???? default-autowire="byName" default-lazy-init="true">? ???? <!-- ws client -->??? ???? <bean id="identityValidateServiceClient" class="cn.org.coral.admin.service.IdentityValidateService"??? ???????? factory-bean="identityValidateServiceClientFactory" factory-method="create" />? ???? <bean id="identityValidateServiceClientFactory"??? ???????? class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">??? ???????? <property name="serviceClass"??? ???????????? value="cn.org.coral.admin.service.IdentityValidateService" />??? ——摘自:? ???????? <property name="address"??? ?????????? value="? http://88.148.29.54:8080/coral/services/IdentityValidateService" ;/>??? ???? </bean>? </beans>??? <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://cxf.apache.org/jaxws ? http://cxf.apache.org/schemas/jaxws.xsd http://www.springframework.org/schema/beans? ;?? http://www.springframework.org/schema/beans/spring-beans.xsd" ;? default-autowire="byName" default-lazy-init="true">? <!-- ws client -->? <bean id="identityValidateServiceClient" class="cn.org.coral.admin.service.IdentityValidateService"? ?? factory-bean="identityValidateServiceClientFactory" factory-method="create" />? <bean id="identityValidateServiceClientFactory"? ?? class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">? ?? <property name="serviceClass"? ?? value="cn.org.coral.admin.service.IdentityValidateService" />? ?? <property name="address"? ?? value="? http://88.148.29.54:8080/coral/services/IdentityValidateService" ;/>? </bean>? </beans>? 6.发布到tomcat服务器以后通过以下地址即可查看自定义的webservice接口生成的wsdl:? http://88.148.29.54:8080/aio/services/WebServiceSample?wsdl 7.调用WebService接口的Junit单元测试程序 Java代码 package test.coral.sample; import org.springframework.test.AbstractDependencyInjectionSpringContextTests;?? import cn.org.coral.biz.examples.webservice.WebServiceSample;?? import cn.org.coral.biz.examples.webservice.dto.UserDTO;?? public class TestWebServiceSample extends?? ???????? AbstractDependencyInjectionSpringContextTests {?? ???? WebServiceSample webServiceSampleClient;???? ???? public void setWebServiceSampleClient(WebServiceSample webServiceSampleClient) {?? ???????? this.webServiceSampleClient = webServiceSampleClient;?? ???? }?? ???? @Override?? ???? protected String[] getConfigLocations() {?? ???????? setAutowireMode(AUTOWIRE_BY_NAME);?? ??????????????????//spring 客户端配置文件保存位置?? ???????? return new String[] { "classpath:/cn/org/coral/biz/examples/webservice/wsclient-context.xml" };?? ???? }?? ???? public void testWSClinet(){?? ???????? Assert.hasText(webServiceSampleClient.say(" world"));?? ???? }?? } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容