基于spring+cxf实现用户文件传输的webservice
- 格式:docx
- 大小:49.86 KB
- 文档页数:15
基于Spring+CXF实现用户文件上传的webSerivce
孙磊
【期刊名称】《电脑编程技巧与维护》
【年(卷),期】2012(000)003
【摘要】基于Spring+CXF,实现带有基本验证功能的WebService,并实现文件上传和相关查询的功能,以便其在使用.NET或其他框架开发的MIS系统中能够自动生成报文并上传.
【总页数】7页(P16-22)
【作者】孙磊
【作者单位】
【正文语种】中文
【相关文献】
1.一种基于WCF的文件上传方法实现 [J], 周虎;
2.基于jQuery EasyUI框架的动态多文件上传的实现 [J], 谷洪彬
3.一种基于WCF的文件上传方法实现 [J], 周虎
4.基于Struts框架实现文件上传功能 [J], 李鑫
5.基于递归算法的多级独立目录文件上传技术的实现 [J], 张立涛;阮智;汪玲;田越因版权原因,仅展示原文概要,查看原文内容请购买。
WebService开发笔记 1 -- 利用cxf开发WebService竟然如此简单关键字: webservice cxf soaWebService开发笔记 1 -- 利用cxf开发WebService竟然如此简单现在的项目中需要用到SOA概念的地方越来越多,最近我接手的一个项目中就提出了这样的业务要求,需要在.net开发的客户端系统中访问java开发的web 系统,这样的业务需求自然需要通过WebService进行信息数据的操作。
下面就将我们在开发中摸索的一点经验教训总结以下,以供大家参考.在WebService开发笔记 2 -- VS 2005 访问WebServcie更简单中作一个跨平台访问WebServcie服务的例子....在WebService开发笔记 3 -- 增强访问 WebService 的安全性通过一个简单的用户口令验证机制来加强一下WebService的安全性....我们项目的整个架构使用的比较流行的WSH MVC组合,即webwork2 + Spring + Hibernate;1.首先集成Apacha CXF WebService 到 Spring 框架中;apache cxf 下载地址:/dist/incubator/cxf/2.0.4-incubator/apache -cxf-2.0.4-incubator.zip在spring context配置文件中引入以下cxf配置Xml代码1.<import resource="classpath*:META-INF/cxf/cxf.xml"/>2.<import resource="classpath*:META-INF/cxf/cxf-extension-soap.xml"/>3.<import resource="classpath*:META-INF/cxf/cxf-servlet.xml"/>在web.xml中添加过滤器:Xml代码1.<servlet>2.<servlet-name>CXFServlet</servlet-name>3.<servlet-class>4. org.apache.cxf.transport.servlet.CXFServlet5.</servlet-class>6.</servlet>7.<servlet-mapping>8.<servlet-name>CXFServlet</servlet-name>9.<url-pattern>/services/*</url-pattern>10.</servlet-mapping>2.开发服务端WebService接口:Java代码1./**2. * WebService接口定义类.3. *4. * 使用@WebService将接口中的所有方法输出为Web Service.5. * 可用annotation对设置方法、参数和返回值在WSDL中的定义.6. */7.@WebService8.public interface WebServiceSample {9.10.11. /**12. * 一个简单的方法,返回一个字符串13. * @param hello14. * @return15. */16. String say(String hello);17.18. /**19. * 稍微复杂一些的方法,传递一个对象给服务端处理20. * @param user21. * @return22. */23. String sayUserName(24. @WebParam(name = "user")25. UserDTO user);26.27. /**28. * 最复杂的方法,返回一个List封装的对象集合29. * @return30. */31. public32. @WebResult(partName="o")33. ListObject findUsers();34.35.}由简单到复杂定义了三个接口,模拟业务需求;3.实现接口Java代码1./**2. * WebService实现类.3. *4. * 使用@WebService指向Interface定义类即可.5. */6.@WebService(endpointInterface = ".examples.webservice.WebServiceSample")7.public class WebServiceSampleImpl implements WebServiceSample {8.9. public String sayUserName(UserDTO user) {10. return "hello "+user.getName();11. }12.13. public String say(String hello) {14. return "hello "+hello;15. }16.17. public ListObject findUsers() {18. ArrayList<Object> list = new ArrayList<Object>();19.20. list.add(instancUser(1,"lib"));21. list.add(instancUser(2,"mld"));22. list.add(instancUser(3,"lq"));23. list.add(instancUser(4,"gj"));24. ListObject o = new ListObject();25. o.setList(list);26. return o;27. }28.29. private UserDTO instancUser(Integer id,String name){30. UserDTO user = new UserDTO();31. user.setId(id);32. user.setName(name);33. return user;34. }35.}4.依赖的两个类:用户对象与List对象Java代码1./**2. * Web Service传输User信息的DTO.3. *4. * 分离entity类与web service接口间的耦合,隔绝entity类的修改对接口的影响.5. * 使用JAXB 2.0的annotation标注JAVA-XML映射,尽量使用默认约定.6. *7. */8.@XmlAccessorType(XmlAccessType.FIELD)9.@XmlType(name = "User")10.public class UserDTO {11.12. protected Integer id;13.14. protected String name;15.16. public Integer getId() {17. return id;18. }19.20. public void setId(Integer value) {21. id = value;22. }23.24. public String getName() {25. return name;26. }27.28. public void setName(String value) {29. name = value;30. }31.}关于List对象,参照了有关JWS的一个问题中的描述:DK6.0 自带的WebService 中 WebMethod的参数好像不能是ArrayList 或者其他List传递List需要将List 包装在其他对象内部才行 (个人理解如有不对请指出) ,我在实践中也遇到了此类问题.通过以下封装的对象即可以传递List对象.Java代码1./**2. * <p>Java class for listObject complex type.3. *4. * <p>The following schema fragment specifies the expected content contained within this class.5. *6. * <pre>7. * <complexType name="listObject">8. * <complexContent>9. * <restriction base="{/2001/XMLSchema}anyType">10. * <sequence>11. * <element name="list" type="{/2001/XMLSchema}anyType" maxOccurs="unbounded" minOccurs="0"/>12. * </sequence>13. * </restriction>14. * </complexContent>15. * </complexType>16. * </pre>17. *18. *19. */20.@XmlAccessorType(XmlAccessType.FIELD)21.@XmlType(name = "listObject", propOrder = { "list" })22.public class ListObject {23.24. @XmlElement(nillable = true)25. protected List<Object> list;26.27. /**28. * Gets the value of the list property.29. *30. * <p>31. * This accessor method returns a reference to the live list,32. * not a snapshot. Therefore any modification you make to the33. * returned list will be present inside the JAXB object.34. * This is why there is not a <CODE>set</CODE> method for the list property.35. *36. * <p>37. * For example, to add a new item, do as follows:38. * <pre>39. * getList().add(newItem);40. * </pre>41. *42. *43. * <p>44. * Objects of the following type(s) are allowed in the list45. * {@link Object }46. *47. *48. */49. public List<Object> getList() {50. if (list == null) {51. list = new ArrayList<Object>();52. }53. return this.list;54. }55.56. public void setList(ArrayList<Object> list) {57. this.list = list;58. }59.60.}5.WebService 服务端 spring 配置文件 ws-context.xmlXml代码1.<beans xmlns="/schema/beans"2.xmlns:xsi="http://www.w/2001/XMLSchema-instance"3.xmlns:jaxws="/jaxws"4.xsi:schemaLocation="/jaxws http://cxf./schemas/jaxws.xsd /sch ema/beans /schema/beans/spring-b eans.xsd"5.default-autowire="byName"default-lazy-init="true">6.7.<jaxws:endpoint id="webServiceSample"8.address="/WebServiceSample"implementor=".coral.biz.examples.webservice.WebServiceSampleImpl"/>9.10.</beans>WebService 客户端 spring 配置文件 wsclient-context.xmlXml代码1.<beans xmlns="/schema/beans"2.xmlns:xsi="http://www.w/2001/XMLSchema-instance"3.xmlns:jaxws="/jaxws"4.xsi:schemaLocation="/jaxws http://cxf./schemas/jaxws.xsd /sch ema/beans /schema/beans/spring-b eans.xsd"5.default-autowire="byName"default-lazy-init="true">6.7. <!-- ws client -->8.<bean id="identityValidateServiceClient"class=".coral.admin.service.IdentityValidateService"9.factory-bean="identityValidateServiceClientFactory"factory-method="create"/>10.11. <bean id="identityValidateServiceClientFactory"12. class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">13. <property name="serviceClass"14. value=".coral.admin.service.IdentityValidateService"/>15. <property name="address"16. value="http://88.148.29.54:8080/coral/services/IdentityValidateService"/>17. </bean>18.19.</beans>6.发布到tomcat服务器以后通过以下地址即可查看自定义的webservice接口生成的wsdl:http://88.148.29.54:8080/aio/services/WebServiceSample?wsdl7.调用WebService接口的Junit单元测试程序Java代码1.package test.coral.sample;2.3.import org.springframework.test.AbstractDependencyInjectionSpringContextTests;4.5.import .examples.webservice.WebServiceSample;6.import erDTO;7.8.public class TestWebServiceSample extends9. AbstractDependencyInjectionSpringContextTests {10. WebServiceSample webServiceSampleClient;11.12. public void setWebServiceSampleClient(WebServiceSample webServiceSampleClient) {13. this.webServiceSampleClient = webServiceSampleClient;14. }15.16. @Override17. protected String[] getConfigLocations() {18. setAutowireMode(AUTOWIRE_BY_NAME);19. //spring 客户端配置文件保存位置20. return new String[] { "classpath:/cn/org/coral/biz/examples/webservice/wsclient-context.xml" };21. }22.23. public void testWSClinet(){24. Assert.hasText(webServiceSampleClient.say(" world"));25. }26.}。
ESB基于 CXF 实现 Web Service 开发项目:企业服务总线 ESB 编写:华腾 ESB 项目组ESB文档版本 版本号 修改日期 1.0 2009-10-14 1.1 2010-01-12编写 林荣坤 田坤评审批准修改内容 初稿 修正ESB目录基于 CXF 实现 Web Service 开发..................................................................................................... 1 1 简介........................................................................................................................................... 4 1.1 CXF 功能特性 .......................................................................................................... 4 1.2 CXF 项目目标 .......................................................................................................... 4 2 开发环境需求及工具安装 ....................................................................................................... 6 2.1 CXF 安装包 ............................................................................................................. 6 2.1.1 下载及目录结构 ............................................................................................... 6 2.1.2 CXF 框架支撑环境 ........................................................................................... 9 2.1.3 JDK 版本选择、下载和安装 ......................................................................... 10 2.1.4 Servlet 容器下载和安装................................................................................ 10 3 CXF 环境配置及示例运行...................................................................................................... 10 4 SOAP OVER JMS 开发 ............................................................................................................ 12 4.1 文本 JNDI 配置 ...................................................................................................... 12 4.2 服务契约优先 ......................................................................................................... 12 4.3 命令行方式生成服务端 ......................................................................................... 12 4.4 命令行方式生成客户端 ......................................................................................... 14 4.5 测试......................................................................................................................... 15 5 集成 Sping ............................................................................................................................... 15 5.1 服务契约修改 ......................................................................................................... 15 5.2 代码生成................................................................................................................. 16 5.3 Spring 配置 ............................................................................................................. 16 5.3.1 服务端配置 ..................................................................................................... 16 5.3.2 客户端配置 ..................................................................................................... 18 5.4 其他设置................................................................................................................. 20 5.4.1 配置拦截器 ..................................................................................................... 20 5.4.2 配置特征 ......................................................................................................... 21 5.4.3 配置编码 ......................................................................................................... 21 5.5 Sping 加载方式 ...................................................................................................... 21 5.5.1 独立加载 ......................................................................................................... 21 5.5.2 容器加载 ......................................................................................................... 21 5.6 测试......................................................................................................................... 22 6 集成 WebSphere Application Server v6.1 ........................................................................... 23 6.1 删除 Servlet 和 HTTP 服务器相关包.................................................................... 23 6.2 修改 WEB 模块类加载方式 .................................................................................. 23ESB1 简介本文档介绍定义好服务 WSDL、schema 文件后,通过 WSDL First 的方式,基于 CXF 的 JAX-WS 实现 Web Service 开发。
一、CXF介绍Apache CXF=Celtix+XFire,Apache CXF的前身叫Apache CeltiXfire。
CXF继承了Celtix和XFire两大开源项目的精华,提供了对JAX-WS全面的支持,并且提供了多种Binding、DataBinding、Transport以及各种Format的支持,并且可以根据实际项目的需要,采用代码优先(Code First)或者WSDL优先(WSDL First)来轻松地实现Web Services的发布和使用。
Apache CXF已经是一个正式的Apache顶级项目。
CXF支持多种协议,如:SOAP、XML/HTTP、RESTful HTTP、CORBA,并且可以在多种传输协议上运行,比如:HTTP、JMS、JBI。
CXF可以与Spring进行无缝集成。
CXF框架是一种基于Servlet技术的SOA应用开发框架,要正常运行基于CXF应用框架开发的企业应用,除了CXF框架本身之外,还需要JDK和Servlet容器的支持。
CXF下载地址:/download.html,选择“File”列中的zip格式下载。
解压后可以看到一些文件夹:└─apache-cxf-2.5.0├─bin各种工具├─docs API文档├─etc各种配置文件├─lib开发所需jar包├─licenses说明├─modules jar包└─samples使用例子samples文件夹中给提供了在各种环境下使用的例子,个人感觉只需参照样例即可。
二、使用CXF+Spring编写并发布WebService首先,新建一个Web项目,名字叫cxftest,将下载的压缩包中lib文件夹下的jar包全部拷贝到项目的WEB-INF/lib中,在web.xml中配置如下:[html]view plaincopy1.<servlet>2.<servlet-name>CXFServlet</servlet-name>3.<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>4.<load-on-startup>1</load-on-startup>5.</servlet>6.<servlet-mapping>7.<servlet-name>CXFServlet</servlet-name>8.<url-pattern>/services/*</url-pattern>9.</servlet-mapping>然后,在项目src目录下新建包:com.test,在新建的包中创建TestService.java,代码如下:[java]view plaincopy1.package com.test;2.3.import javax.jws.WebService;4.5.@WebService6.public interface TestService{7.8.public String sayHi(String name);9.10.}接着,在创建TestServiceImpl.java,代码如下:[java]view plaincopy1.package com.test;2.3.import javax.jws.WebService;4.5.@WebService(endpointInterface="com.test.TestService")6.public class TestServiceImpl implements TestService{7.8.public String sayHi(String name){9.10.return name+",welcome to here!";11.}12.}CXF中采用注解的方式声明哪些类作为WebService进行发布,@WebService:声明webservice接口;@WebService(endpointInterface="com.test.TestService"):声明这个类是TestService接口的实现类。
使用Spring+CXF开发WebServiceApache CXF 提供方便的Spring整合方法,可以通过注解、Spring标签式配置来暴露Web Services和消费Web Services各种类型的Annotation。
@WebService和@WebMethod是WSDL映射Annatotion。
这些Annotation将描述Web Service的WSDL文档元素和Java源代码联系在一起。
@SOAPBinding是一个绑定的annotation用来说明网络协议和格式。
1、@WebService annotation的元素name,serviceName和targetNamespace成员用来描述wsdl:portType,wsdl:service,和targetNameSpace生成WebService中的WSDL文件。
2、@SOAPBinding是一个用来描述SOAP格式和RPC的协议的绑定Annotation。
3、@WebMethod Annotation的operationName成员描述了wsdl:operation,而且它的操作描述了WSDL文档中的SOAPAction头部。
这是客户端必须要放入到SQAPHeader中的数值,SOAP 1.1中的一种约束。
4、@WebParam Annotation的partName成员描述了WSDL文档中的wsdl:part。
5、@WebResult Annotation的partName成员描述了wsdl:part用来返回WSDL文档的值。
例如下面使用annotation定义了一个webservice:import java.util.List;import javax.jws.WebMethod;import javax.jws.WebParam;import javax.jws.WebResult;import javax.jws.WebService;import er;@WebService(targetNamespace = "/client") public interface UserService {@WebMethod(operationName="Insert")public void insert( @WebParam(name = "userId") String userid,@WebParam(name = "userName") String username,@WebParam(name = "userEmail") String useremail,@WebParam(name = "userAge") int userage);@WebMethod(operationName="GetUserById")@WebResult(name = "result")public User getUserById(@WebParam(name="userid") String userid);@WebMethod(operationName="GetAllUsers")@WebResult(name = "result")public List getAllUsers();}其实现类如下所示:import java.util.List;import javax.jws.WebService;import erDao;import er;import erService;@WebService(endpointInterface="erService")public class UserServiceImpl implements UserService {private UserDao userDao;public List getAllUsers() {return userDao.findAllUser();}public User getUserById(String userid) {return userDao.findUserById(userid);}public void insert(String userid, String username, String useremail, int userage) {User user=new User();user.setUserage(userage);user.setUseremail(useremail);user.setUserid(userid);user.setUsername(username);userDao.insert(user);System.out.println("insert successfully!");}public void setUserDao(UserDao userDao) {erDao = userDao;}}注意:实现类中的@WebService,其中的endpointInterface成员指定了该类实现的接口在Spring的配置文件中,需要对其进行配置:首先在ApplicationContext.xml(Spring的配置文件)中引入CXF的XML Scheam 配置文件),如下:<beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:jaxws="/jaxws"xsi:schemaLocation="/schema/beans /schema/beans/spring-beans.xsd /jaxws/schemas/jaxws.xsd"><!—还需要引入以下3个关于CXF的资源文件,这三个文件在cxf.jar中--><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" />……………………………………………………</bean>其次就是在Spring的配置文件中配置webservice,如下所示:<jaxws:endpoint id="userManager" address="/UserManager"implementorClass="erService"><jaxws:implementor><bean id="userServiceImpl"class="erServiceImpl"><property name="userDao"><ref bean="userDao" /></property></bean></jaxws:implementor></jaxws:endpoint>注意:①、address 为webservice发布的地址②、implementorClass 为该webservice实现的接口③、<jaxws:implementor></jaxws:implementor>之间定义的是implementorClass指定接口的实现类另外,在Spring的配置文件中配置完成后,需要修改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>注意<url-pattern>/ services /*</url-pattern>配置,CXFServlet会拦截此类url,进行处理。
CXF框架实现Webservice服务——于2015年02月05日Apache CXF是一种基于Servlet技术的SOA应用开发框架。
CXF 继承了Celtix 和XFire 两大开源项目的精华,提供了对多种Web Services 标准的支持,包含SOAP、Basic Profile、WS-Addressing等。
CXF允许根据实际项目的需要,采用代码优先(Code First)或者WSDL 优先(WSDL First)来实现Web Services应用的发布和使用。
一、SOA架构与Webservice1.1 SOA架构的产生SOA(Service-oriented architecture) 面向服务的体系结构,是构造分布式系统应用程序的方法。
它将应用程序功能作为服务发送给最终用户或者其他服务,采用开放标准、与软件资源进行交互并采用表示的标准方式。
SOA架构思想的产生源于两个方面:需求拉动和技术推动。
(1) 需求拉动需求拉动方面,主要来自于两种信息化的困境。
一个是“信息孤岛”造成基于系统之间互联互通的整合需求;另一个是业务的变化所导致对IT灵活性,以适应变化的需求。
企业在不同的时期和不同的厂商合作,建立了不同的应用系统,而系统之间彼此互不关联。
因此导致企业内部各个系统成为一个“信息孤岛”,造成信息不一致。
同时,系统的互联互通不仅包含一个企业内部,也包括集团和各个分公司系统之间的互通。
另一方面,由于行业竞争的日益激烈,企业需要不断地调整自身的业务流程,而僵化的IT基础设施跟不上这种不断加快的变化。
传统的信息化方法和软件研究方法是对业务需求的直接映射,这种“需求驱动”的信息系统最大的缺陷就是对变化的适应性差,因此需要一种按照架构驱动,对业务进行适当的抽象,通过服务的表达和业务过程的原子化,来满足系统是按照企业架构来构造,这种架构是动态重构技术来支撑的,这种架构就是SOA。
(2) 技术推动造成系统之间不能互联互通的一个重要原因,就是系统的异构性。
在Spring3.1.0上使用CXF3.0.5开发webservice(一)一、使用CXF3.0.5生成webservice服务1.首先,在maven上引入cxf使用的jar包依赖:<cxf.version>3.0.5</cxf.version><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-core</artifactId><version>${cxf.version}</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-transports-http</artifactId><version>${cxf.version}</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-frontend-jaxws</artifactId><version>${cxf.version}</version><exclusions><exclusion><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-ws-policy</artifactId></exclusion><exclusion><groupId>javax.xml.stream</groupId><artifactId>stax-api</artifactId></exclusion></exclusions></dependency>2.在web.xml中添加cxf配置:<!-- 添加webservice服务 --><servlet><servlet-name>CXFService</servlet-name><servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> </servlet><servlet-mapping><servlet-name>CXFService</servlet-name><url-pattern>/*</url-pattern></servlet-mapping>3.在Spring文件中引入applicationContext-webservice.xml,文件内容如下:<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:p="/schema/p"xmlns:jaxws="/jaxws" xmlns:cxf="/core"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-3.1.xsd/jaxws/schemas/jaxws.xsd"><import resource="classpath:META-INF/cxf/cxf.xml" /> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /><bean id="sayHello" class="com.breeze.xiabai.SayHelloImpl"></bean><!--第一种方式--><jaxws:server id="hello" serviceBean="#sayHello" address="/SayHello" /><!--第二种方式<jaxws:endpoint id="hello" implementor="#sayHello" address="/SayHello" />--></beans>4.业务接口类SayHellopackage com.breeze.xiabai;import javax.jws.WebService;@WebServicepublic interface SayHello {public void sayHello(People p);}5.接口实现类SayHelloImplpackage com.breeze.xiabai;import javax.jws.WebService;@WebService(endpointInterface = "com.breeze.xiabai.SayHello")public class SayHelloImpl implements SayHello {@Overridepublic void sayHello(People p) {System.out.println("hello " + p.getName());}}6.访问服务地址:http://AppServername/SayHello?wsdl二、wsdl2java 生成不带JAXBElement的客户端1.在官网下载cxf3.0.5,地址:/download.html2.配置环境变量CXF_HOME3.使用wsdl2java命令生成java文件wsdl2java -p com -d srcl aa.wsdl-p 指定其wsdl的命名空间,也就是要生成代码的包名:-d 指定要产生代码所在目录-client 生成客户端测试web service的代码-server 生成服务器启动web service的代码-impl 生成web service的实现代码-b binding-file-name-frontend jaxws21支持jax-ws2.1如果直接使用wsdl2java.bat -client -d E:/tmp -frontend jaxws21 wsdl文件生成的客户端代码中有JAXBElement<String>新建1.txt,内容为:<jaxb:bindings version="2.1"xmlns:jaxb="/xml/ns/jaxb"xmlns:xjc="/xml/ns/jaxb/xjc"xmlns:xs="/2001/XMLSchema"><jaxb:globalBindings generateElementProperty="false"/> </jaxb:bindings>使用wsdl2java.bat -b "1.txt" -client -d E:/tmp -frontend jaxws21 wsdl文件,就可以生成正常的pojo类折腾了好几天,做个记录。
基于spring+cxf实现用户文件传输的webservice1 引言在EDI系统中,用户数量较多,并且信息化水平差距较大,所以对报文的收发方式具有多样化的需求。
相对其他访问方式而言,http(s)的访问在防火墙限制、安全性等方面都有较好表现。
因此,有相当部分用户提出通过webservice发送报文的需求。
本文介绍了如何采用cxf 结合spring框架实现具有文件上传和相关查询功能的webservice,以便其在使用.net或其他框架开发的MIS系统中能够自动生成报文并上传。
同时,该webservice还提供了用户基本身份验证功能,对访问请求进行限制。
Apache CXF 是一个开源的 Services 框架,CXF 帮助您利用 Frontend 编程 API 来构建和开发 Services ,像 JAX-WS 。
这些 Services 可以支持多种协议,比如:SOAP、XML/HTTP、RESTful HTTP 或者 CORBA ,并且可以在多种传输协议上运行,比如:HTTP、JMS 或者 JBI,CXF 大大简化了 Services 的创建,同时它继承了 XFire 传统,一样可以天然地和 Spring 进行无缝集成。
2.功能分析(1)该webservice需要提供报文上传到服务器上的基本功能。
(2)用户可以查询已经发送的报文历史信息列表,包括报文名称、报文大小和发送时间。
(3)由于不是开放服务,所以还需要对用户身份进行基本认证。
3.服务构建(1)定义要提供的服务接口首先要定义webservice输入输出的数据类型,主要包括报文名称、报文类型、报文发送时间以及处理文件流的DataHandler属性。
代码片段如下:public class MsgItem{//报文名称private String filename;//报文类型private String filetype;//传输时间private String trans_time;//文件流指针private DataHandler msgfile;public String getFilename(){return filename;}public void setFilename(String filename){this.filename = filename;}public String getFiletype(){return filetype;}public void setFiletype(String filetype){this.filetype = filetype;}public String getTrans_time(){return trans_time;}public void setTrans_time(String trans_time) {this.trans_time = trans_time;}public DataHandler getMsgfile(){return msgfile;}public void setMsgfile(DataHandler msgfile){this.msgfile = msgfile;}}在定义好输入输出的数据结构后,就可以定义要提供的业务服务接口。
在该接口中使用@WebService注释来声明接口名称和命名空间,使用@WebResult注释来声明返回变量名称,使用@WebParam注释来声明传入变量名称,代码片段如下:/***报文上传服务接口*/@WebService(name = "MsgTrans", targetNamespace ="/com/test/busw/service/file")public interface MsgTrans{/*** 上传报文* @param item 报文实例* @return报文上传结果消息*/@WebResult(name = "up_ret")public String UploadMsg(@WebParam(name = "msg_item")MsgItem item);/*** 查询报文信息列表* @return报文信息列表*/@WebResult(name = "msgList")public ListObject select_msglist ();}(2)实现接口在完成接口的定义之后,可以开始编写java 类来实现上述接口。
此处使用@WebService 指定服务接口的路径。
代码片段如下:@WebService(endpointInterface = "com.test.busw.service.file.MsgTrans") public class MsgTransServ implements MsgTrans { private String ftphost = "192.168.1.118"; private String ftpuser = null ; private String ftpuserpasswd = null ;private final static String msgoutpath = " msgout/"; private final static String localpath_err = "err/"; private static final String MyCharSet = "GB2312";// 实现报文上传方法@WebResult(name = "up_ret") public String UploadMsg(@WebParam(name = "msg_item") MsgItem item) { Object obj = SecurityContextHolder.getContext ().getAuthentication().getPrincipal(); if (obj instanceof UserDetails){ ftpuser = ((UserDetails) obj).getUsername(); ftpuserpasswd = ((UserDetails) obj).getPassword(); } else {return "用户验证失败!";} DataHandler handler = item.getMsgfile(); try { InputStream is = handler.getInputStream(); SimpleDateFormat format = newSimpleDateFormat("yyyyMMddHHmmssSSS"); String token = format.format(new Date()); String filename = item.getFilename() + token + "." + item.getFiletype(); OutputStream os = new FileOutputStream(new File(msgoutpath + filename)); byte [] b = new byte [100000]; int bytesread = 0; while ((bytesread = is.read(b)) != -1) {os.write(b, 0, bytesread);①os.flush();os.close();is.close();sendFtpFiles("in", filename, token);}catch (Exception e){return "上传报文失败:" + e.getMessage();}return "上传报文成功";}/*** 上传报文至中心服务器** @param svrPath* @param localPath* @throws Exception*/private void sendFtpFiles(String svrPath, String localfile, String token) throws Exception{FTPClient ftp = null;try{ftp = new FTPClient();ftp.setRemoteHost(this.ftphost);ftp.setControlEncoding(MyCharSet);ftp.connect();ftp.login(this.ftpuser, this.ftpuserpasswd);ftp.setConnectMode(FTPConnectMode.PASV);ftp.setType(FTPTransferType.BINARY);ftp.chdir(svrPath);File file = new File(msgoutpath + localfile);try{ftp.put(msgoutpath + localfile, localfile.replaceAll(token + ".", "."));log(localfile + " sent to ftpserver.(" + file.length() + ")");file.delete();}catch (Exception e){saveErrFile(localfile);logError("", localfile + " send error." + e);throw e;}catch (Exception e){log("FTP连接错误!" + e.getMessage());throw new Exception("FTP连接错误!" + e.getMessage());}finally{try{if (ftp != null){ftp.quit();}}catch (Exception e){}}}private void logError(String sessionID, String errinfo){Logger.getLogger().logToFile(errinfo);}private void log(String errinfo){Logger.getLogger().logToFile(errinfo);}private void saveErrFile(String filename){File file = new File(msgoutpath, filename);File errdir = new File(localpath_err, filename);file.renameTo(errdir);}@WebResult(name=" msgList ")public ListObject select_msglist (){Object obj =SecurityContextHolder.getContext().getAuthentication().getPrincipal();if (obj instanceof UserDetails){ftpuser = ((UserDetails) obj).getUsername();ftpuserpasswd = ((UserDetails) obj).getPassword();}else { return null ; } ApplicationContext ctx = SpringContextUtil.getApplicationContext (); MsgDao msgdao = (MsgDao) ctx.getBean("MsgDaoProxy"); List<Object> list = new ArrayList<Object>(); try { list = msgdao.select_MsgList(ftpuser); } catch (Exception ex) {ex.printStackTrace(); } finally { msgdao = null ; } ListObject msglist = new ListObject();msglist.setList(list);return msglist; } }本实现类中实现了接口定义的两个方法,一是接收上传的报文,并将接收到的报文以FTP 方式发送到中心文件服务器上,并给出传输结果;二是报文传输记录查询,实际上是从数据库中查询到用户所发送的报文记录信息,并将结果回传给用户。