前段時間有博友在看個人博文《WebService入門案例》後,發郵件問我關於WebService 接口在java中的開發,以及在實際生產環境中的應用。想一想本身入職也有一段時間了,彷佛也該總結一下本身對於接口化開發的認識,以及如何利用java開發一些能夠供其餘應用程序使用的web服務。html
其實最開始對Web服務的認識仍是在課堂上,老師反覆地在講SOAP協議,其實也不懂到底是什麼意思,平白無故就在大腦中造成了條件反射,SOAP協議的中文意思就是簡單對象訪問協議;並且,更加巧合的是本身在求職面試時就被項目經理問到這麼一個問題,直接回答簡單對象訪問協議!此時,只能對當時上課的老師表示感謝。java
好了,廢話很少說,轉入正題。在本文中,首先總結一下本身對接口化編程的認識,本身在項目結構方面MVC思想的體現,而後談談對WebService的印象,最後以Xfire的實際開發爲案例具體談談本身的接口開發,以及如何在MVC的結構思想基礎上開發WebService。本文爲本身學習和工做總結積累所得,歡迎轉載。請保留原文出處。mysql
接口化編程,在項目結構方面MVC思想web
隨着J2EE實際開發的機會增多,經驗也在慢慢地積累,就是這些小知識的積累就造成了本身開發實踐的一種模式。可是就整個項目的結構思想而言,是沒有任何變化的,即MVC。畢竟就MVC自己來講,它已是一種軟件典範,這種邏輯,界面,數據分離的設計早就被行業內所承認。就拿都比較熟悉的,也比較熱的J2EE中SSH三大框架來講,就是很好的體現了這麼一個特色,而有一些企業則是用ibatis或mybatis替代Hibernate進行數據層的操做。二者都有其各自的優缺點,此處就不談了。由於畢竟不是在說MVC或者框架的開發實踐。可是,咱們須要在這樣的基礎上開發接口,就必需要對這些框架有必定的瞭解。面試
在我我的而言,開發接口,我喜歡用interface的首字母加上須要開發的接口名稱再加上服務的英文單詞就能夠了。好比說,我須要開發一個用戶的接口,那麼我給這個接口的名稱就是IUserService;並且實現這個接口的類則命名爲UserService。我的感受比較簡單,容易分辨。至於在此基礎上的框架開發,不一樣的功能使用不一樣的包名,其命名規範也得講究才行,我本身的項目中包名一般用com.red.功能包,實體包bean,接口包service,DAO包dao,工具包util等,具體狀況具體分析;實體bean類,則用User或UserBean,若是數據層採用的是Hibernate那就用User.hbm.xml或UserBean.hbm.xml;若是是ibatis等,那就用User.xml或UserBean.xml。個人原則就是儘量一眼就分辨出這個java類或文件具體是幹什麼的,其主要內容是什麼。sql
接口化本身的程序方法能夠將本身的實現類進行必定程度的封裝,只提供接口方法給其它程序,若是其它程序須要調用這個接口,它再也不須要關心具體的實現,數據的如何處理,並且,這也更加體現了分佈式應用程序的好處。好比我有一個程序做爲整個系統多個項目的數據處理中心,爲不一樣的項目提供數據服務,即全部的項目都是創建在這個基礎上的,並且,其它的項目再也不進行數據處理服務,只是負責頁面和業務邏輯,有效地將數據完全和業務分開,並且,它尚未數據庫和相關環境的依賴。這樣開發的優勢就不言而喻了。實際上,這樣作對數據的安全也有必定的保障。 數據庫
接着談談WebService,開發了這麼久的WebService,今天就痛快的總結一下吧。編程
WebService在當下,它是開發分佈式的互操做的應用程序不可缺乏的一部分。Web服務,可以使部署在不一樣平臺上的不一樣語言開發的不一樣的應用在不須要藉助第三方的基礎上進行數據的交互和系統的集成。而WebService的基礎特色就是開放性,剛纔已經體現出來了。要使用WebService,就必須得會用兩種技術,分別是XML和SOAP。XML無疑是在web中傳輸結構化數據的一種偉大方式,它能夠用來標記數據,定義數據類型,然而WebService正是須要以一種可靠的方式處理數據,所以XML來實現這樣的功能是最理想的;SOAP,前文已經提到的簡單對象訪問協議,是一種基於XML的簡單,輕量的交換數據的協議規範,一條SOAP信息就是一個標準的XML文檔,SOAP使用XML信息調用遠程方法,這樣WebService就能夠經過不一樣的請求方式與遠程機進行交互。其實SOAP的實現也挺有意思的,因爲篇幅有限,此處就再也不贅述。瀏覽器
談了如此多的接口開發,畢竟實踐是檢驗真理的惟一標準。下面就以一個小Demo來講說利用Xfire開發接口,而且供其它程序調用的方式。tomcat
1. 建庫:
所用的數據庫demo和測試用表userinfo:
CREATE TABLE `userinfo` ( `USER_ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '用戶id', `USER_NAME` varchar(45) DEFAULT NULL COMMENT '用戶名', `USER_PASSWORD` varchar(45) DEFAULT NULL COMMENT '用戶密碼', `USER_EMAIL` varchar(45) DEFAULT NULL COMMENT '用戶郵箱', PRIMARY KEY (`USER_ID`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
測試數據以下:
2. 服務器端:提供WebService
a. 新建一個web工程,爲其添加xfire功能;直接點擊項目,而後鼠標右鍵,添加Xfire功能,根據嚮導下一步就行。我在這個demo中只是把xfire配置文件的路徑給改了,放到了WEB-INF下面;添加完成後,在web.xml中能夠看到多出的幾行代碼:
<servlet> <servlet-name>XFireServlet</servlet-name> <servlet-class>org.codehaus.xfire.transport.http.XFireConfigurableServlet</servlet-class> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>XFireServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
b. 能夠新建一個接口了,而後實現它,數據處理等。就如同我在上文中提到的同樣,以MVC的方式進行結構化,我在這個demo中只是爲了說明WebService的開發,就沒涉及到多的框架,採用JDBC訪問的mysql數據庫,demo的項目結構總體以下:
c. 現將重點代碼粘貼:
User實體類:其get和set方法以及構造方法已經省略。
private int user_id; private String user_name; private String user_password; private String user_email;
數據庫開啓和關閉連接的工具類Conn類:
public Connection getConn() { try { String Driver = "com.mysql.jdbc.Driver"; String url = "jdbc:mysql://127.0.0.1:3306/demo"; String user = "root"; String password = "123456"; Class.forName(Driver); Connection conn = DriverManager.getConnection(url, user, password); return conn; } catch (Exception e) { e.printStackTrace(); } return null; } public void closeConn(ResultSet rs, Statement stmt, Connection conn) { try { if (null != rs && !rs.isClosed()) rs.close(); if (null != stmt && !stmt.isClosed()) stmt.close(); if (null != conn && !conn.isClosed()) conn.close(); } catch (Exception e) { e.printStackTrace(); } }
用戶接口類IUserService:
public interface IUserServices { /** * 查詢全部 * @return list集合 */ public List<User> findAll(); /** * 經過用戶id查找 * @param user_id 客戶id * @return 用戶對象 */ public User findById(int user_id); }
用戶接口實現類UserService:
public class UserServices implements IUserServices { private UserDao userDao=new UserDao(); public List<User> findAll() { return userDao.findAll(); } public User findById(int userId) { return userDao.findById(userId); } public UserDao getUserDao() { return userDao; } public void setUserDao(UserDao userDao) { this.userDao = userDao; } }
數據庫操做類UserDao:
public List<User> findAll() { try { List<User> list = new ArrayList<User>(); String sql = "SELECT USER_ID, USER_NAME, USER_PASSWORD, USER_EMAIL FROM userinfo"; Connection conn = new ConnUtil().getConn(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); while (rs.next()) { User user = new User(); user.setUser_id(rs.getInt("USER_ID")); user.setUser_name(rs.getString("USER_NAME")); user.setUser_password(rs.getString("USER_PASSWORD")); user.setUser_email(rs.getString("USER_EMAIL")); list.add(user); } return list; } catch (Exception e) { e.printStackTrace(); } return null; } public User findById(int userId) { try { User user = new User(); String sql = "SELECT USER_ID, USER_NAME, USER_PASSWORD, USER_EMAIL FROM userinfo AS u WHERE u.USER_ID= '" + userId + "'"; Connection conn = new ConnUtil().getConn(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); while (rs.next()) { user.setUser_id(rs.getInt("USER_ID")); user.setUser_name(rs.getString("USER_NAME")); user.setUser_password(rs.getString("USER_PASSWORD")); user.setUser_email(rs.getString("USER_EMAIL")); } return user; } catch (Exception e) { e.printStackTrace(); } return null; }
此時的開發已經基本上完成了,最後配置xfire.xml就算完成了webService 的開發。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://xfire.codehaus.org/config/1.0"> <service> <name>UserServices.cis</name> <serviceClass>com.red.services.IUserServices</serviceClass> <implementationClass>com.red.services.UserServices </implementationClass> </service> </beans>
將這個新項目部署到tomcat,而後啓動tomcat。在瀏覽器中輸入:http://localhost:8080/svc/UserServices.cis?wsdl 就會看到以下的頁面,說明開發完成:
3. 客戶端訪問WebService的開發:
a. 爲了方便,直接新建一個java工程,只要可以訪問剛剛開發好的webService就行。項目結構以下:
b. 重點代碼粘貼:同名類的代碼和service端相同。
ConfigUtil類:
public class ConfigUtil { private static final long serialVersionUID = -5639833339612968585L; private volatile static ConfigUtil client = null; public static ConfigUtil getInstance() { if (null == client) { client = new ConfigUtil(); } return client; } public Object createTunnel(Class<?> interfaceclass, String url) { try { Service srvcModel = new ObjectServiceFactory().create(interfaceclass); XFire client = XFireFactory.newInstance().getXFire(); XFireProxyFactory factory = new XFireProxyFactory(client); Object service = factory.create(srvcModel, url); return service; } catch (MalformedURLException e) { } return null; } }
ServiceTest類進行測試:
public class ServiceTest { public static void main(String[] args) { try { IUserServices service = getService(); List<User> list = service.findAll(); for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i).getUser_name() + "::" + list.get(i).getUser_email()); } User user=service.findById(1); System.out.println(user.getUser_email()+"::mail"); } catch (Exception e) { e.printStackTrace(); } } public static IUserServices getService() { ConfigUtil util = ConfigUtil.getInstance(); String url = "http://127.0.0.1:8080/svc/UserServices.cis"; IUserServices ctservice = (IUserServices) util.createTunnel(IUserServices.class, url); return ctservice; } }
Main方法測試結果:控制檯打印結果。
順利完成。
做者:itRed 郵箱:it_red@sina.com 博客:http://www.cnblogs.com/itred 我的網站:http://wangxingyu.jd-app.com ***版權聲明:本文版權歸做者和博客園共有,歡迎轉載,但請在文章顯眼位置標明文章出處。未經本人書面贊成,將其做爲他用,本人保留追究責任的全部權利。