最近在一個的三級數據庫考試系統采用了分布式架構,需要使用web service來實現客戶端的C#與服務器端的java的交互,我依然選擇了最近最火的cxf框架
首先是Cxf與spring的集成,在我的前一篇博客中已經說明:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2451570.html
現在我就拿一個其中簡單例子來實現下(這里只實現java服務器端的)
首次是Service層:ExamStartService:
package xidian.sl.service.webService; import javax.jws.WebParam; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import javax.jws.soap.SOAPBinding.Style; @WebService @SOAPBinding(style = Style.RPC) //@SOAPBinding(style = Style.RPC)這個必須要加否則在客戶端加載服務時會出現參數的錯誤 public interface ExamStartService { /* * 客戶端傳過來的應該是學生的學號和考試的名字 * **/ public String startExam(@WebParam(name = "stuNum")String stuNum, @WebParam(name = "examName")String examName, @WebParam(name = "sign")String sign, @WebParam(name = "ipaddr")String ipaddr)throws Exception; }
service的實現層:ExamStartServiceImpl:
package xidian.sl.service.impl.webService; import java.util.List; import java.util.Random; import javax.jws.WebService; import xidian.sl.dao.webService.ExamStartDAO; import xidian.sl.entity.Exam; import xidian.sl.entity.Examinee; import xidian.sl.entity.Paper; import xidian.sl.service.webService.ExamStartService; import xidian.sl.util.FormatDate; @WebService(endpointInterface = "xidian.sl.service.webService.ExamStartService") public class ExamStartServiceImpl implements ExamStartService { private ExamStartDAO examStartDAO; public ExamStartDAO getExamStartDAO() { return examStartDAO; } public void setExamStartDAO(ExamStartDAO examStartDAO) { this.examStartDAO = examStartDAO; } /** * @author shenliang 2011-11-29 * 客戶端點擊開始考試后的處理(客戶端傳過來的是考生的學號,和本場考試的考試名) * 1.###先根據客戶端傳過來的參數sign{"false","true"},false表示在客戶端還沒有壓縮包的存在,true表示已經有壓縮包的存在 * 若為false,則先判斷該考生是剛開始考生還是再次的請求(查詢該考生表中是否已經存在開始考試的時間),若無,則為第一次考試, * 將開始考試的時間更新進去,並返回success,若已經有考試開始時間,則表示該考生已更換電腦, * 則需要將該考生原先的試卷包和考試的剩余時間發送過去, * 若為true,表示該考試已開始考生並且是有壓縮包的,此時服務器端只需要將該考試的剩余時間進行返回即可 * @throws Exception * * */ public String startExam(String stuNum, String examName, String sign, String ipaddr) throws Exception { System.out.println("成功了! "+"學號="+stuNum+" 考試="+examName+" 標記="+sign+" ip="+ipaddr); //查找該場考試 List<Exam> examList = examStartDAO.getExamList(examName); //考試的名字必須是唯一的 Exam exam = examList.get(0); //判斷該場考試是否有ip范圍的限制 String ipAddr = exam.getExamIpaddr(); if(!"未設定".equals(ipAddr)){ String[] ips = ipAddr.split("-"); //將ip地址切分為開始和結束ip Boolean boo = isBetween(ipaddr, ips[0], ips[1]); if(boo == false){ //考試機所屬ip不在指定的范圍 System.out.println("不合法的ip地址"); return "wrongfulIP"; }else{ System.out.println("合法的ip地址"); } } //查找該考生 List<Examinee> examineeList = examStartDAO.getExamineeByNumAndExamName(stuNum, examName); //該集合中只可能有一條記錄 Examinee examinee = examineeList.get(0); //此處還要判斷該考生是否已經完成考試了 防止第二次重復考試 if(!"???".equals(examinee.getExamEndtime())){ return "finished"; } if("false".equals(sign)){ //false表示客戶端還沒有壓縮包 System.out.println("進入false"); //查詢該考生的開始考試時間是否存在 if( !"???".equals(examinee.getExamStartime()) ){ //該考生已經開始考試,但中途更換了電腦 System.out.println("已經開始考試了,但是換機子了"); //更新考生表,將機子的變換加1 examStartDAO.updateChangeComNum(examinee); //將ip更新進去 examinee.setExamineeIpaddr(ipaddr); examStartDAO.updateExaminee(examinee); String examLong = exam.getExamLong(); //獲得考試的時長 //則將剩余的時間返回,先計算使用了的時間,返回的是一個字符串,分#秒 String examUserdTime = FormatDate.examRemainTime(examinee.getExamStartime(), FormatDate.getFormateDateAll()); //param:1.考試開始時間,2.現在的時間 String[] splitTime = examUserdTime.split("#"); //這里先忽略秒 String examRemainTime = String.valueOf(Integer.valueOf(examLong) - Integer.valueOf(splitTime[0])); /** * 將下載的操作交給客戶端處理了,這邊只需要傳遞試卷名參數給客戶端即可 * */ //將該考生原先的壓縮包再次發送,更加該考生得到該試卷包 //String paperPath = examinee.getPaper().getZipPath()+examinee.getPaper().getZipName(); //調用FileDownload類中的downloadFile()方法 //FileDownload.downloadFile(paperPath); //返回的 剩余時間#試卷名 StringBuilder str = new StringBuilder(examRemainTime); str.append("#"); str.append(examinee.getPaper().getZipName()); return str.toString(); //返回考試的剩余時間 }else{ System.out.println("未開始過考試"); //更新ip examinee.setExamineeIpaddr(ipaddr); examStartDAO.updateExaminee(examinee); //得到本場考試的所有試卷編號 List<Integer> paperIdList = examStartDAO.getPaperId(examName); //產生一個隨機編號 Random random = new Random(); int rand = random.nextInt(paperIdList.size()); //利用nextInt(產生0到指定值之間的) 產生隨機數 int paperId = paperIdList.get(rand); //list.get()返回列表中指定位置的元素,題目的編號 System.out.println("隨機編號:"+ paperId); //將相應的試卷包的id更新到考生表中 examStartDAO.UpdateExamZipAndStartTime(stuNum, examName, paperId, FormatDate.getFormateDateAll()); //得到試卷, Paper paper = examStartDAO.getPaperById(paperId); /** * 將下載的操作交給客戶端處理了,這邊只需要傳遞試卷名參數給客戶端即可 * */ //String paperPath = paper.getZipPath()+paper.getZipName(); //獲得試卷的地址 //調用FileDownload類中的downloadFile()方法 //FileDownload.downloadFile(paperPath); //返回的 success#試卷名 StringBuilder str = new StringBuilder("success"); str.append("#"); str.append(paper.getZipName()); return str.toString(); } }else{ System.out.println("已經開始過考試了,現在重新開始了"); //這里就不需要更新ip String examLong = exam.getExamLong(); //獲得考試的時長 //則將剩余的時間返回,先計算使用了的時間,返回的是一個字符串,分#秒 String examUserdTime = FormatDate.examRemainTime(examinee.getExamStartime(), FormatDate.getFormateDateAll()); //param:1.考試開始時間,2.現在的時間 String[] splitTime = examUserdTime.split("#"); //這里先忽略秒 String examRemainTime = String.valueOf(Integer.valueOf(examLong) - Integer.valueOf(splitTime[0])); return examRemainTime; //只需返回考試的剩余時間即可 } } //判斷ip的范圍 public static boolean isBetween(String ip, String start, String end){ //注意一下用點切割時要注意轉義 String[] ipArray = ip.split("\\."); String[] startArray = start.split("\\."); String[] endArray = end.split("\\."); //以上是將三個ip都以點進行切分 System.out.println(ipArray.length); if(ipArray.length != 4){ return false; } long ipLong=((long)((((Integer.parseInt(ipArray[0])<< 8)+Integer.parseInt(ipArray[1]))<< 8)+ Integer.parseInt(ipArray[2]))<< 8)+Integer.parseInt(ipArray[3]); long startLong=((long)((((Integer.parseInt(startArray[0])<< 8)+Integer.parseInt(startArray[1]))<< 8)+ Integer.parseInt(startArray[2]))<< 8)+Integer.parseInt(startArray[3]); long endLong=((long)((((Integer.parseInt(endArray[0])<< 8)+Integer.parseInt(endArray[1]))<< 8)+ Integer.parseInt(endArray[2]))<< 8)+Integer.parseInt(endArray[3]); return ipLong>= startLong&& ipLong<= endLong; } }
這樣就初步實現了客戶端,然后根據配置文件中配置的方法,客戶端就能進行接口的調用了