当前位置:文档之家› 基于spring+cxf实现用户文件传输的webservice

基于spring+cxf实现用户文件传输的webservice

基于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 方式发送到中心文件服务器上,并给出传输结果;二是报文传输记录查询,实际上是从数据库中查询到用户所发送的报文记录信息,并将结果回传给用户。

相关主题