前段时间有博友在看我的博文《WebService入门案例》后,发邮件问我关于WebService 接口在java中的开发,以及在实际生产环境中的应用。想想自己入职也有一段时间了,似乎也该总结一下自己对于接口化开发的认识,以及如何利用java开发一些可以供其他应用程序使用的web服务。

其实最开始对Web服务的认识还是在课堂上,老师反复地在讲SOAP协议,其实也不懂究竟是什么意思,无缘无故就在大脑中形成了条件反射,SOAP协议的中文意思就是简单对象访问协议;而且,更加巧合的是自己在求职面试时就被项目经理问到这么一个问题,直接回答简单对象访问协议!此时,只能对当时上课的老师表示感谢。

好了,废话不多说,转入正题。在本文中,首先总结一下自己对接口化编程的认识,自己在项目结构方面MVC思想的体现,然后谈谈对WebService的印象,最后以Xfire的实际开发为案例具体谈谈自己的接口开发,以及如何在MVC的结构思想基础上开发WebService。本文为自己学习和工作总结积累所得,欢迎转载。请保留原文出处。

接口化编程,在项目结构方面MVC思想

随着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类或文件具体是干什么的,其主要内容是什么。

对WebService的印象

接口化自己的程序方法可以将自己的实现类进行一定程度的封装,只提供接口方法给其它程序,如果其它程序需要调用这个接口,它不再需要关心具体的实现,数据的如何处理,而且,这也更加体现了分布式应用程序的好处。比如我有一个程序作为整个系统多个项目的数据处理中心,为不同的项目提供数据服务,即所有的项目都是建立在这个基础上的,而且,其它的项目不再进行数据处理服务,只是负责页面和业务逻辑,有效地将数据彻底和业务分开,而且,它还没有数据库和相关环境的依赖。这样开发的优点就不言而喻了。实际上,这样做对数据的安全也有一定的保障。

接着谈谈WebService,开发了这么久的WebService,今天就痛快的总结一下吧。

WebService在当下,它是开发分布式的互操作的应用程序不可缺少的一部分。Web服务,能够使部署在不同平台上的不同语言开发的不同的应用在不需要借助第三方的基础上进行数据的交互和系统的集成。而WebService的基础特点就是开放性,刚才已经体现出来了。要使用WebService,就必须得会用两种技术,分别是XML和SOAP。XML无疑是在web中传输结构化数据的一种伟大方式,它可以用来标记数据,定义数据类型,然而WebService正是需要以一种可靠的方式处理数据,因此XML来实现这样的功能是最理想的;SOAP,前文已经提到的简单对象访问协议,是一种基于XML的简单,轻量的交换数据的协议规范,一条SOAP信息就是一个标准的XML文档,SOAP使用XML信息调用远程方法,这样WebService就可以通过不同的请求方式与远程机进行交互。其实SOAP的实现也挺有意思的,由于篇幅有限,此处就不再赘述。

以Xfire的实际开发,在MVC的结构思想基础上开发WebService

谈了如此多的接口开发,毕竟实践是检验真理的唯一标准。下面就以一个小Demo来说说利用Xfire开发接口,并且供其它程序调用的方式。

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
***版权声明:本文版权归作者和博客园共有,欢迎转载,但请在文章显眼位置标明文章出处。未经本人书面同意,将其作为他用,本人保留追究责任的所有权利。

从xfire谈WebService接口化编程的更多相关文章

  1. c++以代理的方式来实现接口化编程

      假如你项目代码本身已经实现了很多的实体类,但并未采用接口,可以考虑以这种方式来实现接口化编程 struct ITest { virtual void Test()=0; }; class CTes ...

  2. xfire调用webservice接口的实现方式

    package com.test; import java.net.URL; import org.codehaus.xfire.client.Client; import org.codehaus. ...

  3. 使用Xfire发布WebService接口遇到的问题:

    问题一: log4j:WARN No appenders could be found for logger (org.codehaus.xfire.transport.DefaultTranspor ...

  4. webservice接口示例(spring+xfire+webservice)

      webservice接口示例(spring+xfire+webservice) CreateTime--2018年4月2日17:36:07 Author:Marydon 一.准备工作 1.1 ja ...

  5. Java调用webservice接口方法(SOAP message、xfire、axis)

    webservice的 发布一般都是使用WSDL(web service descriptive language)文件的样式来发布的,在WSDL文件里面,包含这个webservice暴露在外面可供使 ...

  6. 谈一谈Java8的函数式编程(二) --Java8中的流

    流与集合    众所周知,日常开发与操作中涉及到集合的操作相当频繁,而java中对于集合的操作又是相当麻烦.这里你可能就有疑问了,我感觉平常开发的时候操作集合时不麻烦呀?那下面我们从一个例子说起. 计 ...

  7. 浅谈WebService SOAP、Restful、HTTP(post/get)请求

    http://www.itnose.net/detail/6189456.html 浅谈WebService SOAP.Restful.HTTP(post/get)请求 2015-01-09 19:2 ...

  8. 『动善时』JMeter基础 — 50、使用JMeter测试WebService接口

    目录 1.什么是WebService 2.WebService和SOAP的关系 3.什么是WSDL 4.测试WebService接口前的准备 (1)如何判断是WebService接口 (2)如何获取W ...

  9. 『动善时』JMeter基础 — 51、使用JMeter测试WebService接口

    目录 1.什么是WebService 2.WebService和SOAP的关系 3.什么是WSDL 4.测试WebService接口前的准备 (1)如何判断是WebService接口 (2)如何获取W ...

随机推荐

  1. react组件的生命周期

    写在前面: 阅读了多遍文章之后,自己总结了一个.一遍加强记忆,和日后回顾. 一.实例化(初始化) var Button = React.createClass({ getInitialState: f ...

  2. 使用 Nodejs 搭建简单的Web服务器

    使用Nodejs搭建Web服务器是学习Node.js比较全面的入门教程,因为要完成一个简单的Web服务器,你需要学习Nodejs中几个比较重要的模块,比如:http协议模块.文件系统.url解析模块. ...

  3. 红黑树——算法导论(15)

    1. 什么是红黑树 (1) 简介     上一篇我们介绍了基本动态集合操作时间复杂度均为O(h)的二叉搜索树.但遗憾的是,只有当二叉搜索树高度较低时,这些集合操作才会较快:即当树的高度较高(甚至一种极 ...

  4. Android数据加密之异或加密算法

    前言: 这几天被公司临时拉到去做Android IM即时通信协议实现,大致看了下他们定的协议,由于之前没有参与,据说因服务器性能限制,只达成非明文传递,具体原因我不太清楚,不过这里用的加密方式是采用异 ...

  5. python+uwsgi导致redis无法长链接引起性能下降问题记录

    今天在部署python代码到预生产环境时,web站老是出现redis链接未初始化,无法连接到服务的提示,比对了一下开发环境与测试环境代码,完全一致,然后就是查看各种日志,排查了半天也没有查明是什么原因 ...

  6. 11、Struts2 的文件上传和下载

    文件上传 表单准备 要想使用 HTML 表单上传一个或多个文件 须把 HTML 表单的 enctype 属性设置为 multipart/form-data 须把 HTML 表单的method 属性设置 ...

  7. 奇葩问题-TextView无法获取值

    问题场景 前几天写一个界面的时候,遇到一个非常奇葩的问题.app第一次安装的时候,这里针对用户第一次安装的时候,后来是不会出现这个问题了.我明明是对某个界面的一个textview赋值了,而且服务端也返 ...

  8. spring boot 部署为jar

    前言 一直在ide中敲代码,使用命令行mvn spring-boot:run或者gradlew bootRun来运行spring boot项目.想来放到prod上面也应该很简单.然而今天试了下,各种问 ...

  9. bzoj3208--记忆化搜索

    题目大意: 花花山峰峦起伏,峰顶常年被雪,Memphis打算帮花花山风景区的人员开发一个滑雪项目.    我们可以把风景区看作一个n*n的地图,每个点有它的初始高度,滑雪只能从高处往低处滑[严格大于] ...

  10. iOS 数据存储之SQLite3的使用

    SQLite3是iOS内嵌的数据库,SQLite3在存储和检索大量数据方面非常有效,它使得不必将每个对象都加到内存中.还能够对数据进行负责的聚合,与使用对象执行这些操作相比,获得结果的速度更快. SQ ...