最近有项目客户要求使用 dubbo 进行服务关联和分布式部署, 能基于 dubbo 发布分布式的 rest 服务和基于 wsdl 的 webservice 服务. 看了下 dubbo 这个项目, 其开发基本处于停滞状态, 比较活跃的项目只有当当网维护的 dubbox 项目. 本项目就是基于 dubbox 进行的.
项目模块如下图所示
用 pom 来组织 Jar 包依赖, dubbox 我已经打包成 Jar. 可以看到项目分为四个模块. api 提供 rest 和 webservice 的接口暴露, common 是一些实体和工具类, server 是数据库操作的模块, 这里我们使用 spring-data-jpa 进行操作. web 是前端应用, 它通过 api 模块暴露的接口来调用远程 dubbo 服务, 包括 rest 和 webservice 的.
api 部分的实现
1, 暴露 rest 接口
- package cn.com.egova.easyshare.api.human;
- import cn.com.egova.easyshare.common.dto.ResultDto;
- import cn.com.egova.easyshare.common.entity.Human;
- import com.alibaba.dubbo.rpc.protocol.rest.support.ContentType;
- import javax.ws.rs.Consumes;
- import javax.ws.rs.GET;
- import javax.ws.rs.Path;
- import javax.ws.rs.PathParam;
- import javax.ws.rs.Produces;
- import javax.ws.rs.core.MediaType;
- /**
- * 人员相关接口
- * Created by gongxufan on 2016/3/8.
- */
- @Path("humans")
- @Consumes({MediaType.APPLICATION_JSON, MediaType.TEXT_XML})
- @Produces({ContentType.APPLICATION_JSON_UTF_8, ContentType.TEXT_XML_UTF_8})
- public interface HumanActionApi {
- /**
- * 获取人员信息
- *
- * @param id
- * @return
- */
- @GET
- @Path("view/{id : \\d+}")
- ResultDto getHuman(@PathParam("id") Integer id);
- }
这里使用 rest 的注解暴露接口
2, 暴露 webservice
- public interface WSDLServiceApi {
- List fetchNews(@XmlJavaTypeAdapter(StringObjectMapAdapter.class) Map params);
- }
webservice 的写法很简单, 只是需要注意要在接口返回的实体类上上加上 xml 的注解
- package cn.com.egova.easyshare.common.dto;
- import javax.xml.bind.annotation.XmlAccessType;
- import javax.xml.bind.annotation.XmlAccessorType;
- import javax.xml.bind.annotation.XmlElement;
- import javax.xml.bind.annotation.XmlRootElement;
- import java.util.Date;
- /**
- * Created by gongxufan on 2016/3/30.
- */
- @XmlRootElement
- @XmlAccessorType(XmlAccessType.FIELD)
- public class NewsDto {
- @XmlElement
- private Integer newsID;
- @XmlElement
- private String newsName;
- @XmlElement
- private String newsDescr;
- @XmlElement
- private String newsURL;
- @XmlElement
- private Integer newsTypeID;
- @XmlElement
- private Integer unitID;
- @XmlElement
- private Date createDate;
- @XmlElement
- private Date updateDate;
- @XmlElement
- private Integer displayOrder;
- @XmlElement
- private Integer openFlag = 0;
- @XmlElement
- private String op;
- public Integer getNewsID() {
- return newsID;
- }
- public void setNewsID(Integer newsID) {
- this.newsID = newsID;
- }
- public String getNewsName() {
- return newsName;
- }
- public void setNewsName(String newsName) {
- this.newsName = newsName;
- }
- public String getNewsDescr() {
- return newsDescr;
- }
- public void setNewsDescr(String newsDescr) {
- this.newsDescr = newsDescr;
- }
- public String getNewsURL() {
- return newsURL;
- }
- public void setNewsURL(String newsURL) {
- this.newsURL = newsURL;
- }
- public Integer getNewsTypeID() {
- return newsTypeID;
- }
- public void setNewsTypeID(Integer newsTypeID) {
- this.newsTypeID = newsTypeID;
- }
- public Integer getUnitID() {
- return unitID;
- }
- public void setUnitID(Integer unitID) {
- this.unitID = unitID;
- }
- public Date getCreateDate() {
- return createDate;
- }
- public void setCreateDate(Date createDate) {
- this.createDate = createDate;
- }
- public Date getUpdateDate() {
- return updateDate;
- }
- public void setUpdateDate(Date updateDate) {
- this.updateDate = updateDate;
- }
- public Integer getDisplayOrder() {
- return displayOrder;
- }
- public void setDisplayOrder(Integer displayOrder) {
- this.displayOrder = displayOrder;
- }
- public Integer getOpenFlag() {
- return openFlag;
- }
- public void setOpenFlag(Integer openFlag) {
- this.openFlag = openFlag;
- }
- public String getOp() {
- return op;
- }
- public void setOp(String op) {
- this.op = op;
- }
- }
api 模块单独分出来可以直接提供给其他模块进行调用
接口实现部分
使用 dubbo 服务
在 app-config.xml 中我们需要定义 dubbo 服务相关的信息, 具体网上很多资料可以查看.
这里我们定义了 rest 和 webservice 协议, rest 协议在 8888 下而 webservice 在 8892 下访问. 需要注意的是, 我们把这两个服务都跑在 tomcat 下. 这样我们的接口实现部分可以打成 war 包部署在多个 tomcat 下, 从而实现了接口服务的分布式部署.
这里只是作为演示, 所以 app-db.xml 中的数据源定义都已经注释掉了. 如果你想采用 spring-data-jpa 进行数据操作的话可以把注释去掉, 然后去实现自己的 Repository .
web 应用部分
这个就不用提了, 我提供了一个测试页面测试接口. 需要注意的是, web 调用接口的配置是在 dubbo-consumer.xml 中
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://code.alibabatech.com/schema/dubbo
- http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
- <!-- 消费方应用名, 用于计算依赖关系, 不是匹配条件, 不要与提供方一样 -->
- <dubbo:application name="dubbo-client" owner="egova-client" organization="goutu-client" />
- <!-- zookeeper 注册中心 -->
- <dubbo:registry protocol="zookeeper" address="127.0.0.1:2181" check="false"/>
- <!-- 监控中心配置 -->
- <!--<dubbo:monitor protocol="registry"/>-->
- <!-- 关闭所有服务的启动可用性检查 -->
- <dubbo:consumer check="false" />
- <!-- dubbo 远程服务 -->
- <dubbo:reference id="humanAction" interface="cn.com.egova.easyshare.api.human.HumanActionApi"/>
- <dubbo:reference id="wSDLService" interface="cn.com.egova.easyshare.webservice.WSDLServiceApi" />
- </beans>
在这里配置好 zookeeper 和 api 端的 service, 然后在 contoller 里就可以调用接口方法了.
end
代码下载地址: csdn 下载 http://download.csdn.net/download/qq381332153/9840564
github: https://github.com/gongxufan/dubbo-demo
来源: https://juejin.im/post/5b2b5f786fb9a00e562c4917