关于Dubbox

什么是dubbox?看看别人怎么说的:

Dubbox是Dubbo的一个扩展,假如你知道java, javax 和 dubbo,那你就会明白dubbox是什么了。

Dubbox增加的功能如RESTful remoting, Kyro/FST 系列化等。它已经应用在当当网内部的多个项目中。

dubbox的功能

  • 支持REST风格远程调用(HTTP + JSON/XML):基于非常成熟的JBoss RestEasy框架,在dubbo中实现了REST风格(HTTP + JSON/XML)的远程调用,以显著简化企业内部的跨语言交互,同时显著简化企业对外的Open API、无线API甚至AJAX服务端等等的开发。事实上,这个REST调用也使得Dubbo可以对当今特别流行的“微服务”架构提供基础性支持。 另外,REST调用也达到了比较高的性能,在基准测试下,HTTP + JSON与Dubbo 2.x默认的RPC协议(即TCP + Hessian2二进制序列化)之间只有1.5倍左右的差距,详见文档中的基准测试报告。

  • 支持基于Kryo和FST的Java高效序列化实现:基于当今比较知名的Kryo和FST高性能序列化库,为Dubbo 默认的RPC协议添加新的序列化实现,并优化调整了其序列化体系,比较显著的提高了Dubbo RPC的性能,详见文档中的基准测试报告。

  • 支持基于嵌入式Tomcat的HTTP remoting体系:基于嵌入式tomcat实现dubbo 的HTTP remoting体系(即dubbo-remoting-http),用以逐步取代Dubbo中旧版本的嵌入式Jetty,可以显著的提高REST等的远程调用性能,并将Servlet API的支持从2.5升级到3.1。(注:除了REST,dubbo中的WebServices、Hessian、HTTP Invoker等协议都基于这个HTTP remoting体系)。

  • 升级Spring:将dubbo中Spring由2.x升级到目前最常用的3.x版本,减少版本冲突带来的麻烦

  • 升级ZooKeeper客户端:将dubbo中的zookeeper客户端升级到最新的版本,以修正老版本中包含的bug。

  • 调整Demo应用:暂时将dubbo的demo应用调整并改写以主要演示REST功能和新的Java高效序列化等等。

  • 修正了在JDK1.7上dubbo的部分bug:修正了比如dubbo协议中json序列化的问题。但是还没有修正所有发现的bug。

注:dubbox和dubbo 2.x是兼容的,没有改变dubbo的任何已有的功能和配置方式(除了升级了spring之类的版本)

注:以上文字均为《Dubbo扩展:Dubbox》一文。

环境安装

jdk安装

能看此文的人,我假设你会安装java开发环境,此处省略999+的废话,否则你看到此处心中一定会奔腾着十万匹草泥马。

gradle安装

相信你看到这里会对gradle多多少少有些了解,如果不了解,也没关系,gradle就是maven的升级版,也适用于java项目的包管理器,它抛弃了如maven基于xml的繁琐配置。

Gradle是一个基于JVM的构建工具,它提供了:

  • 像Ant一样,通用灵活的构建工具

  • 可以切换的,基于约定的构建框架

  • 强大的多工程构建支持

  • 基于Apache Ivy的强大的依赖管理

  • 支持maven, Ivy仓库

  • 支持传递性依赖管理,而不需要远程仓库或者是pom.xml和ivy.xml配置文件。

  • 对Ant的任务做了很好的集成

  • 基于Groovy,build脚本使用Groovy编写

  • 有广泛的领域模型支持构建

安装jdk。安装gradle之前一定先安装jdk,并配置JAVA_HOME环境变量。因为gradle是用Groovy编写的,而Groovy基于JAVA。

用vim打开根目录下的 ~/.bashrc或者~/.bash_profile配置用户级别的环境变量,或者打开/etc/profile文件配置系统级别的环境变量,将下面的内容复制到上述文件之一保存(vim保存,编辑后先按ESC进入命令模式,输入:wq保存并退出,然后加载配置后的文件,用命令source ~/.bashrc或者source ~/.bash_profile或者source /etc/profile)即可。

1
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_91.jdk/Contents/Home

下载。在这里下载gradle。

图片描述
解压
下载好的文件是zip格式,mac下载后自动解压,如果没有自动解压,在findler中打开下载目录,双击即可解压,如果还不行,执行命令解压,mac自带了unzip命令工具,如果没有unzip,使用brew安装吧。

安装unzip命令:

1
brew install unzip

解压zip文件命令:

1
cd /Users/xxx/Downloads && unzip gradle-2.13-all.zip

上面命令解释:cd首先进入到你的工作空间,xxx替换为个人用户名;然后执行unzip命令解压gradle。

PS:说一下我的安装习惯吧。

一般情况下,用命令安装的软件基本都在/usr/local/Cellar/目录下面,二进制文件可能会软连接到/usr/local/bin/和/usr/local/sbin/目录下面,配置文件在/usr/local/etc/目录下面。

但是,有一些软件还是喜欢放在个人工作空间,用起来比较方便。比如tomcat,zookeeper,gradle,jmeter等工具,放在用户目录下面的Documents/software目录下,software原来没有,自建一个software文件夹。

图片描述

上面是我的工作空间。只希望给自己创建一个干净整齐的工作空间。

gradle配置

在gradle的根目录下面,找到init.d目录,这就是它的配置文件夹,里面有一个磨人的配置文件init.gradle。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
allprojects {
apply plugin: 'java'
apply plugin: 'idea'
buildDir = 'target'
buildDir = 'target'
repositories {
// maven repository
maven {
url 'http://127.0.0.1:8082/nexus/content/groups/public/'
}
mavenLocal()
mavenCentral()
}

buildscript {
repositories {
maven {
url 'http://127.0.0.1:8082/nexus/content/groups/public/'
}
mavenLocal()
mavenCentral()
}
dependencies {
classpath 'net.nisgits.gradle:gradle-executable-jar-plugin:1.7.0'
}
}
}

上面的仓库地址可以改成你自己的maven仓库,也可以指定为第三方的maven仓库。我这里是本地搭建的,请记得修改

tomcat安装

下载:tomcat的下载点击这里
首先登录官网,点击导航菜单的download,进入下载页面。左边栏就能看到download的下面的一些版本,建议下载8,不要用9,这里只说mac的,我尝试了几次,9在IDEA编辑中运行代码回报错误权限不足,而我的tomcat的意境是777的权限,网上查了一下,也没有更好的解决方案,都是chmod给*.sh权限。

图片描述
以8版本为例,点击进入之后就是这样的:

图片描述

mac和linux用户还是选择tar.gz格式,我们只需要下载Core的包,其他的估计也用不上,完整文档的就别下载了,我相信自己不会去看的,除非你不相信自己或者过分相信自己。
解压:使用tar命令就好,假设你已经进入到下载目录:

1
tar -zxvf apache-tomcat-8.0.35.tar

忽然发现,下载的tomcat8的文件格式不是tar.gz,而是tar;tomcat9的却是tar.gz。不管哪一种,解压命令一样,都可达到你要的效果。

zookeeper安装

zk的下载和安装网上有很多教程,这里不做详细的讲解。默认情况下,运行代码之前假设已经开启了zk,开启命令:

1
sudo sh zkServer.sh start

再次强调,运行dubbox/dubbo构建的代码,一定要开启zk,端口默认2181,如果你修改了端口,后面提到的config.properties文件中记得修改。

用IDEA搭建框架

帮助别人,其实是在帮助自己;纪录总会有用处,只是需要到一定的时机。
[写作感悟]

环境终于配置结束了。
首先搭建一个简单的gradle的project。

打开IDEA,选择创建一个新工程[Create New Project]
图片描述

选择gradle,然后选择jdk,右下角next:
图片描述

接下来填写groupie,artifacts,version,这三个值构成了一个坐标系统,这是maven标识一个工程的唯一依据,gradle依然在使用这个坐标。
图片描述

本地配置了gradle,就选择使用本地的吧,勾选一下自动创建空内容根目录,也就是帮你创建了src,resource等资源文件夹:
图片描述

接下来可以改一下project name为test-demo.
我们的工程目录如下:
图片描述

IDEA很神奇,提供了命令窗口,当然没有mac的好用,对中文的致辞不友好。在改窗口下输入命令(build命令在以后经常用到,用于构建打包):

1
gradle clean idea build --daemon

或者

1
2
gradle clean build --daemon
gradle clean idea

配置gradle工程依赖

打开工程目录下的build.gradle文件,配置dubbed/dubbo、spring、zk、öson等依赖包下面的配置中spring的版本是3.x,你可选择配置4.x版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
group 'Joyven'
version '1.0-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'war'

sourceCompatibility = 1.8

repositories {
mavenLocal()
mavenCentral()
}

dependencies {

compile 'com.google.code.gson:gson:2.3.1'
// log4j2
compile 'org.apache.logging.log4j:log4j-core:2.4.1'
compile 'org.apache.logging.log4j:log4j-api:2.4.1'
compile 'org.apache.logging.log4j:log4j-slf4j-impl:2.4.1'

// validator
compile 'org.hibernate:hibernate-validator:5.2.0.Final'
compile 'javax.validation:validation-api:1.1.0.Final'

compile 'org.jboss.resteasy:jaxrs-api:3.0.7.Final'

//http 异步
compile 'org.apache.httpcomponents:httpasyncclient:4.1.1'


// dubbo
compile ('com.alibaba:dubbo:2.8.4') {
exclude(module: 'log4j')
}
compile 'com.alibaba:dubbo-rpc-rest:2.8.4'


// jackson
compile 'com.fasterxml.jackson.core:jackson-core:2.7.0-rc2'
compile 'com.fasterxml.jackson.core:jackson-databind:2.7.0-rc2'

compile 'org.apache.kafka:kafka-clients:0.9.0.0'

compile 'com.alibaba.rocketmq:rocketmq-client:3.2.6'

//mongodb
compile 'org.springframework.data:spring-data-mongodb:1.8.0.RELEASE'
compile 'org.mongodb:mongo-java-driver:3.1.0'

compile 'com.alibaba:druid:1.0.15'
compile 'org.mybatis:mybatis:3.3.0'
compile 'org.mybatis:mybatis-spring:1.2.3'

compile 'mysql:mysql-connector-java:5.1.36'
compile 'joda-time:joda-time:2.8.1'
compile 'org.springframework:spring-jdbc:3.2.9.RELEASE'
compile 'org.springframework:spring-test:3.2.9.RELEASE'
compile 'org.springframework:spring-webmvc:3.0.9.RELEASE'
compile 'org.springframework.hateoas:spring-hateoas:0.19.0.RELEASE'
compile 'org.glassfish:javax.el:3.0.1-b08'
compile 'commons-beanutils:commons-beanutils:1.8.3'

compile 'org.apache.zookeeper:zookeeper:3.5.0-alpha'
compile 'com.github.sgroschupf:zkclient:0.1'

compile 'log4j:log4j:1.2.17'
testCompile 'junit:junit:4.11'

}

war {
archiveName = "test-demo.war"
}

最后一行的意思是,gradle build的时候,打包的war包文件名,不是带有一串很长的groupid,version等信息的包名,而是指定的包,如test-demo.war

配置玩gradle后,执行上面说过的build命令gradle clean build --daemon,构建依赖包,此过程如果用的是第三方的maven仓库,可能事件会很长。
们还是继续把这场戏演完------------

项目基本配置

工程结构

在main文件夹下面新建一个webapp,webapp下心间一个WEB-INF,web.xml就在WEB-INF目录下面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|____build.gradle
|____settings.gradle
|____src
| |____main
| | |____java
| | |____resources
| | |____webapp
| | | |____index.jsp
| | | |____WEB-INF
| | | | |____web.xml
| |____test
| | |____java
| | |____resources
|____target

上面的目录结构就是我的工程结构,其中一部份idea和gradle的文件没有贴出来。

spring配置

在resource目录下创建一个文件夹:META-INF.spring,在改文件夹下面创建一个spring配置文件services-config.xml。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright 1999-2011 Alibaba Group.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
">


<task:annotation-driven/>

<context:annotation-config/>

<context:component-scan base-package=""/>

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="ignoreResourceNotFound" value="true"/>
<property name="locations">
<list>
<!-- 越靠后越有效,取到最后一个有效的未知 -->
<value>classpath:conf/properties/*.properties</value>
</list>
</property>
</bean>


<dubbo:application name="test-demo" owner="Joyven" organization="freedom"/>

<!--激活注解-->
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>


<!-- 声明需要暴露的服务接口 -->
<!-- <dubbo:protocol name="dubbo" port="${dubbo.server.port}" host="${dubbo.server.host}"/>-->

<!--<dubbo:monitor protocol="registry" />-->

<dubbo:registry protocol="zookeeper" address="${zkHost}"/>

<dubbo:protocol name="rest" port="${rest.server.port}" threads="500" contextpath="test-demo"
server="servlet" accepts="500"
extension="com.alibaba.dubbo.rpc.protocol.rest.support.LoggingFilter"/>

<!-- 声明需要暴露的服务接口 -->
</beans>

说明:

  • 该文件配置的就是你所期望的dubbox/dubbo和spring的信息。<context:component-scan base-package=""/>这一句配置的内容暂时为空,后面要指定我们要扫描的包。
  • <dubbo:application name="test-demo" owner="Joyven" organization="freedom"/>这一句指出dubbo应用的名字、所属以及组织,name一半填写工程名字,owner一般指定为公司,或者项目组,organization一般为公司,我是自用组织者,哈哈😄~~
  • 估计眼明的你已经看到了,<dubbo:registry protocol=“zookeeper” address=“zkHost"/><dubbo:protocolname="rest"port="{zkHost}"/><dubbo:protocol name="rest" port="{rest.server.port}” threads=“500” contextpath=“test-demo” server=“servlet” accepts=“500”
    extension=“com.alibaba.dubbo.rpc.protocol.rest.support.LoggingFilter”/>,这里面的配置都是动态获取的,${variable}指代properties文件中配置的属性。
  • port的配置必须与服务器的端口相同,这个是实现rest服务所必须要求的,而在dubbo中是不做要求的,因为dubbo只是一个服务提供方,不提供直接通过http协议访问。
  • contextpath路径必须与工程部署的路径相同,意思呢,就是contextpath的值和war包的名字一样。
  • server 如果不指定,默认启动Jetty服务器,如果是tomcat指定servlet,方便在web.xml中配置rest过滤器。如果配置成tomcat,则会出现一些错误。

配置properties文件,在main/conf/properties/config.properties:

1
2
3
4
5
6
7
8
9
server.port=30010

dubbo.server.port=30011
dubbo.server.host=127.0.0.1

rest.server.port=8080

zkHost=127.0.0.1:2181

web.xml配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:META-INF/spring/*.xml</param-value>
</context-param>

<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>WEB-INF/classes/log4j.xml</param-value>
</context-param>

<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>60000</param-value>
</context-param>



<!--this listener must be defined before the spring listener-->
<listener>
<listener-class>com.alibaba.dubbo.remoting.http.servlet.BootstrapListener</listener-class>
</listener>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>

<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>


<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

<!--<servlet>
<servlet-name>springServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:META-INF/spring/*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springServlet</servlet-name>
<url-pattern>/service/*</url-pattern>
</servlet-mapping>-->
</web-app>

log4j.xml配置

log4j.xml在main/resources/目录下面:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright 1999-2011 Alibaba Group.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-->
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%d{dd/MM/yy hh:mm:ss:sss z}] %t %5p %c{2}: %m%n" />
</layout>
</appender>
<appender name="rollingFile" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="logs/server.log" />
<param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="[%d{MMdd HH:mm:ss SSS\} %-5p] [%t] %c{3\} - %m%n" />
</layout>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="CONSOLE" />
<!--<appender-ref ref="rollingFile" />-->
</root>
</log4j:configuration>

配置后的工程基本目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|____build.gradle
|____settings.gradle
|____src
| |____main
| | |____java
| | |____resources
| | | |____log4j.xml
| | | |____META-INF
| | | | |____spring
| | | | | |____services-config.xml
| | |____webapp
| | | |____index.jsp
| | | |____WEB-INF
| | | | |____web.xml
| |____test
| | |____java
| | |____resources

Talk is cheap Show you my code

在项目的main文件夹下面新建几个包:
com.web.service (接口)
com.web.biz (实现+业务)
com.web.repository (dao层)
com.web.mapper (db映射mapper)

至此,一个完整的项目结构成型。回过头来,修改spring的配置,指明扫描包路径。services-config.xml中的这一句<context:component-scan base-package=""/>替换为<context:component-scan base-package="com.web.*"/>

这个很重要,否则会报错误。

现在我们在IDEA中配置tomcat,然后运行一下,应该可以启动了。
打印的日志如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/Users/zhoujunwen/Documents/software/apache-tomcat-8.0.35/bin/catalina.sh run
[2016-05-21 05:46:49,256] Artifact Gradle : Joyven:test : test-demo.war (exploded): Server is not connected. Deploy is not available.
21-May-2016 17:46:51.467 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version: Apache Tomcat/8.0.35
21-May-2016 17:46:51.468 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built: May 11 2016 21:57:08 UTC
21-May-2016 17:46:51.469 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server number: 8.0.35.0
21-May-2016 17:46:51.469 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name: Mac OS X
21-May-2016 17:46:51.469 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version: 10.11.4
21-May-2016 17:46:51.469 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture: x86_64
21-May-2016 17:46:51.469 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home: /Library/Java/JavaVirtualMachines/jdk1.8.0_91.jdk/Contents/Home/jre
21-May-2016 17:46:51.469 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version: 1.8.0_91-b14
21-May-2016 17:46:51.469 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor: Oracle Corporation
21-May-2016 17:46:51.469 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: /Users/zhoujunwen/Library/Caches/IntelliJIdea15/tomcat/Unnamed_test
21-May-2016 17:46:51.470 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME: /Users/zhoujunwen/Documents/software/apache-tomcat-8.0.35
21-May-2016 17:46:51.471 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/Users/zhoujunwen/Library/Caches/IntelliJIdea15/tomcat/Unnamed_test/conf/logging.properties
21-May-2016 17:46:51.471 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
21-May-2016 17:46:51.471 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcom.sun.management.jmxremote=
21-May-2016 17:46:51.471 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcom.sun.management.jmxremote.port=1099
21-May-2016 17:46:51.471 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcom.sun.management.jmxremote.ssl=false
21-May-2016 17:46:51.471 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcom.sun.management.jmxremote.authenticate=false
21-May-2016 17:46:51.471 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.rmi.server.hostname=127.0.0.1
21-May-2016 17:46:51.472 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
21-May-2016 17:46:51.472 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.endorsed.dirs=/Users/zhoujunwen/Documents/software/apache-tomcat-8.0.35/endorsed
21-May-2016 17:46:51.472 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/Users/zhoujunwen/Library/Caches/IntelliJIdea15/tomcat/Unnamed_test
21-May-2016 17:46:51.472 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/Users/zhoujunwen/Documents/software/apache-tomcat-8.0.35
21-May-2016 17:46:51.472 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/Users/zhoujunwen/Documents/software/apache-tomcat-8.0.35/temp
21-May-2016 17:46:51.472 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /Users/zhoujunwen/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.
21-May-2016 17:46:51.712 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
21-May-2016 17:46:51.827 INFO [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
21-May-2016 17:46:51.833 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["ajp-nio-8009"]
21-May-2016 17:46:51.834 INFO [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
21-May-2016 17:46:51.839 INFO [main] org.apache.catalina.startup.Catalina.load Initialization processed in 1559 ms
21-May-2016 17:46:51.913 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service Catalina
21-May-2016 17:46:51.913 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.0.35
21-May-2016 17:46:51.935 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
21-May-2016 17:46:51.947 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
21-May-2016 17:46:51.948 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 109 ms
Connected to server
[2016-05-21 05:46:52,287] Artifact Gradle : Joyven:test : test-demo.war (exploded): Artifact is being deployed, please wait...
21-May-2016 17:46:57.182 INFO [RMI TCP Connection(2)-127.0.0.1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/Users/zhoujunwen/Documents/workspace/java/test-demo/out/artifacts/test/exploded/test-demo.war/WEB-INF/lib/log4j-slf4j-impl-2.4.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/Users/zhoujunwen/Documents/workspace/java/test-demo/out/artifacts/test/exploded/test-demo.war/WEB-INF/lib/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
[21/05/16 05:46:58:058 CST] RMI TCP Connection(2)-127.0.0.1 INFO logger.LoggerFactory: using logger: com.alibaba.dubbo.common.logger.log4j.Log4jLoggerAdapter
[21/05/16 05:46:58:058 CST] RMI TCP Connection(2)-127.0.0.1 ERROR common.Version: [DUBBO] Duplicate class com/alibaba/dubbo/common/Version.class in 2 jar [file:/Users/zhoujunwen/Documents/workspace/java/test-demo/out/artifacts/test/exploded/test-demo.war/WEB-INF/lib/dubbo-2.8.4.jar!/com/alibaba/dubbo/common/Version.class, file:/Users/zhoujunwen/Documents/workspace/java/test-demo/out/artifacts/test/exploded/test-demo.war/WEB-INF/lib/dubbo-common-2.8.4.jar!/com/alibaba/dubbo/common/Version.class], dubbo version: 2.8.4, current host: 127.0.0.1
[21/05/16 05:46:58:058 CST] RMI TCP Connection(2)-127.0.0.1 INFO config.AbstractConfig: [DUBBO] The service ready on spring started. service: com.web.services.TestService, dubbo version: 2.8.4, current host: 127.0.0.1
[21/05/16 05:46:58:058 CST] RMI TCP Connection(2)-127.0.0.1 INFO config.AbstractConfig: [DUBBO] Export dubbo service com.web.services.TestService to local registry, dubbo version: 2.8.4, current host: 127.0.0.1
[21/05/16 05:46:58:058 CST] RMI TCP Connection(2)-127.0.0.1 INFO config.AbstractConfig: [DUBBO] Export dubbo service com.web.services.TestService to url rest://192.168.0.4:8080/test-demo/com.web.services.TestService?accepts=500&anyhost=true&application=test-demo&dubbo=2.8.4&extension=com.alibaba.dubbo.rpc.protocol.rest.support.LoggingFilter&generic=false&interface=com.web.services.TestService&methods=sayHello&organization=freedom&owner=Joyven&pid=1417&server=servlet&side=provider&threads=500&timestamp=1463824018811, dubbo version: 2.8.4, current host: 127.0.0.1
[21/05/16 05:46:58:058 CST] RMI TCP Connection(2)-127.0.0.1 INFO config.AbstractConfig: [DUBBO] Register dubbo service com.web.services.TestService url rest://192.168.0.4:8080/test-demo/com.web.services.TestService?accepts=500&anyhost=true&application=test-demo&dubbo=2.8.4&extension=com.alibaba.dubbo.rpc.protocol.rest.support.LoggingFilter&generic=false&interface=com.web.services.TestService&methods=sayHello&organization=freedom&owner=Joyven&pid=1417&server=servlet&side=provider&threads=500&timestamp=1463824018811 to registry registry://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?application=test-demo&dubbo=2.8.4&organization=freedom&owner=Joyven&pid=1417&registry=zookeeper&timestamp=1463824018795, dubbo version: 2.8.4, current host: 127.0.0.1
[21/05/16 05:46:59:059 CST] RMI TCP Connection(2)-127.0.0.1 INFO zookeeper.ZookeeperRegistry: [DUBBO] Load registry store file /Users/zhoujunwen/.dubbo/dubbo-registry-127.0.0.1.cache, data: {cn.idongjia.tianji.services.NotifyService=empty://10.0.0.24/cn.idongjia.tianji.services.NotifyService?application=dongjia-web-service&category=configurators&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.NotifyService&methods=notifyOne,notifyAll,sms,unregister,notifyList,messageSend,register,checkCode&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355564 empty://10.0.0.24/cn.idongjia.tianji.services.NotifyService?application=dongjia-web-service&category=routers&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.NotifyService&methods=notifyOne,notifyAll,sms,unregister,notifyList,messageSend,register,checkCode&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355564 empty://10.0.0.24/cn.idongjia.tianji.services.NotifyService?application=dongjia-web-service&category=providers&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.NotifyService&methods=notifyOne,notifyAll,sms,unregister,notifyList,messageSend,register,checkCode&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355564, com.web.services.TestService=empty://192.168.0.4:8080/test-demo/com.web.services.TestService?accepts=500&anyhost=true&application=test-demo&category=configurators&check=false&dubbo=2.8.4&extension=com.alibaba.dubbo.rpc.protocol.rest.support.LoggingFilter&generic=false&interface=com.web.services.TestService&methods=sayHello&organization=freedom&owner=Joyven&pid=1376&server=servlet&side=provider&threads=500&timestamp=1463822337491, cn.idongjia.tianji.services.ReturnGoodsService=empty://10.0.0.24/cn.idongjia.tianji.services.ReturnGoodsService?application=dongjia-web-service&category=configurators&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.ReturnGoodsService&methods=cancel,allow,aliNotify,apply,list,confirm,disallow,reject,batchGet,getByOrder,detail,send&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044359264 empty://10.0.0.24/cn.idongjia.tianji.services.ReturnGoodsService?application=dongjia-web-service&category=routers&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.ReturnGoodsService&methods=cancel,allow,aliNotify,apply,list,confirm,disallow,reject,batchGet,getByOrder,detail,send&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044359264 empty://10.0.0.24/cn.idongjia.tianji.services.ReturnGoodsService?application=dongjia-web-service&category=providers&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.ReturnGoodsService&methods=cancel,allow,aliNotify,apply,list,confirm,disallow,reject,batchGet,getByOrder,detail,send&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044359264, cn.idongjia.tianji.services.BankcardService=empty://10.0.0.24/cn.idongjia.tianji.services.BankcardService?application=dongjia-web-service&category=configurators&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.BankcardService&methods=add,getAll,modifyDefault,get,update,delete,getCount,getUserBankcard&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355819 empty://10.0.0.24/cn.idongjia.tianji.services.BankcardService?application=dongjia-web-service&category=routers&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.BankcardService&methods=add,getAll,modifyDefault,get,update,delete,getCount,getUserBankcard&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355819 empty://10.0.0.24/cn.idongjia.tianji.services.BankcardService?application=dongjia-web-service&category=providers&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.BankcardService&methods=add,getAll,modifyDefault,get,update,delete,getCount,getUserBankcard&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355819, cn.idongjia.cashout.service.CashoutService=empty://10.0.0.24/cn.idongjia.cashout.service.CashoutService?application=dongjia-web-service&category=configurators&check=false&dubbo=2.8.4&interface=cn.idongjia.cashout.service.CashoutService&methods=execute&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355776 empty://10.0.0.24/cn.idongjia.cashout.service.CashoutService?application=dongjia-web-service&category=routers&check=false&dubbo=2.8.4&interface=cn.idongjia.cashout.service.CashoutService&methods=execute&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355776 empty://10.0.0.24/cn.idongjia.cashout.service.CashoutService?application=dongjia-web-service&category=providers&check=false&dubbo=2.8.4&interface=cn.idongjia.cashout.service.CashoutService&methods=execute&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355776, cn.idongjia.tianji.services.OrderService=empty://10.0.0.24/cn.idongjia.tianji.services.OrderService?application=dongjia-web-service&category=configurators&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.OrderService&methods=notes,hidden,getDetail,setPayed,searchCount,update,ship,delete,wxNotify,search,inWXPay,get,changeAddress,alipayNotify,close,getCount,payed,add,getAll,pay,confirm,delay,changeRealpay,evaluate&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355881 empty://10.0.0.24/cn.idongjia.tianji.services.OrderService?application=dongjia-web-service&category=routers&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.OrderService&methods=notes,hidden,getDetail,setPayed,searchCount,update,ship,delete,wxNotify,search,inWXPay,get,changeAddress,alipayNotify,close,getCount,payed,add,getAll,pay,confirm,delay,changeRealpay,evaluate&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355881 empty://10.0.0.24/cn.idongjia.tianji.services.OrderService?application=dongjia-web-service&category=providers&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.OrderService&methods=notes,hidden,getDetail,setPayed,searchCount,update,ship,delete,wxNotify,search,inWXPay,get,changeAddress,alipayNotify,close,getCount,payed,add,getAll,pay,confirm,delay,changeRealpay,evaluate&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355881, cn.idongjia.search.service.QueryService=empty://10.0.0.24/cn.idongjia.search.service.QueryService?application=dongjia-web-service&category=configurators&check=false&dubbo=2.8.4&interface=cn.idongjia.search.service.QueryService&methods=searchCraftsMan,searchItemWithPrice,searchItem&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044359316 empty://10.0.0.24/cn.idongjia.search.service.QueryService?application=dongjia-web-service&category=routers&check=false&dubbo=2.8.4&interface=cn.idongjia.search.service.QueryService&methods=searchCraftsMan,searchItemWithPrice,searchItem&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044359316 empty://10.0.0.24/cn.idongjia.search.service.QueryService?application=dongjia-web-service&category=providers&check=false&dubbo=2.8.4&interface=cn.idongjia.search.service.QueryService&methods=searchCraftsMan,searchItemWithPrice,searchItem&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044359316, cn.idongjia.tianji.services.ItemService=empty://10.0.0.24/cn.idongjia.tianji.services.ItemService?application=dongjia-web-service&category=configurators&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.ItemService&methods=add,onShelf,getEvaluateCount,getAll,tagItems,getLogs,addAndDown,searchCount,update,getFeed,craftsmans,delete,search,createAuction,getFeeds,offShelf,get,getAuction,addStock,topic,batchGet,getEvaluates,getCount&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355306 empty://10.0.0.24/cn.idongjia.tianji.services.ItemService?application=dongjia-web-service&category=routers&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.ItemService&methods=add,onShelf,getEvaluateCount,getAll,tagItems,getLogs,addAndDown,searchCount,update,getFeed,craftsmans,delete,search,createAuction,getFeeds,offShelf,get,getAuction,addStock,topic,batchGet,getEvaluates,getCount&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355306 empty://10.0.0.24/cn.idongjia.tianji.services.ItemService?application=dongjia-web-service&category=providers&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.ItemService&methods=add,onShelf,getEvaluateCount,getAll,tagItems,getLogs,addAndDown,searchCount,update,getFeed,craftsmans,delete,search,createAuction,getFeeds,offShelf,get,getAuction,addStock,topic,batchGet,getEvaluates,getCount&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355306, cn.idongjia.auction.api.AuctionService=empty://10.0.0.24/cn.idongjia.auction.api.AuctionService?application=dongjia-web-service&category=configurators&check=false&dubbo=2.8.4&interface=cn.idongjia.auction.api.AuctionService&methods=createAuction,getMaxAuction,getAuctionRecord,getAuction,updateAuction,getAuctionRecordCount,searchAuctionCount,searchAuction&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355418 empty://10.0.0.24/cn.idongjia.auction.api.AuctionService?application=dongjia-web-service&category=routers&check=false&dubbo=2.8.4&interface=cn.idongjia.auction.api.AuctionService&methods=createAuction,getMaxAuction,getAuctionRecord,getAuction,updateAuction,getAuctionRecordCount,searchAuctionCount,searchAuction&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355418 empty://10.0.0.24/cn.idongjia.auction.api.AuctionService?application=dongjia-web-service&category=providers&check=false&dubbo=2.8.4&interface=cn.idongjia.auction.api.AuctionService&methods=createAuction,getMaxAuction,getAuctionRecord,getAuction,updateAuction,getAuctionRecordCount,searchAuctionCount,searchAuction&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355418, cn.idongjia.tianji.services.AfterSaleService=empty://10.0.0.24/cn.idongjia.tianji.services.AfterSaleService?application=dongjia-web-service&category=configurators&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.AfterSaleService&methods=add,getAll,get,update,delete,getCount&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355478 empty://10.0.0.24/cn.idongjia.tianji.services.AfterSaleService?application=dongjia-web-service&category=routers&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.AfterSaleService&methods=add,getAll,get,update,delete,getCount&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355478 empty://10.0.0.24/cn.idongjia.tianji.services.AfterSaleService?application=dongjia-web-service&category=providers&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.AfterSaleService&methods=add,getAll,get,update,delete,getCount&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355478, cn.idongjia.tianji.services.AutoTaskService=empty://10.0.0.24/cn.idongjia.tianji.services.AutoTaskService?application=dongjia-web-service&category=configurators&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.AutoTaskService&methods=addCollect&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355958 empty://10.0.0.24/cn.idongjia.tianji.services.AutoTaskService?application=dongjia-web-service&category=routers&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.AutoTaskService&methods=addCollect&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355958 empty://10.0.0.24/cn.idongjia.tianji.services.AutoTaskService?application=dongjia-web-service&category=providers&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.AutoTaskService&methods=addCollect&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044355958, cn.idongjia.kuaidi.services.ShipService=empty://10.0.0.24/cn.idongjia.kuaidi.services.ShipService?application=dongjia-web-service&category=configurators&check=false&dubbo=2.8.4&interface=cn.idongjia.kuaidi.services.ShipService&methods=add,deleteCompany,getCompanies,getAll,getShipment,subscribe,addCompany,update,getMessage,delete,getCount&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044359376 empty://10.0.0.24/cn.idongjia.kuaidi.services.ShipService?application=dongjia-web-service&category=routers&check=false&dubbo=2.8.4&interface=cn.idongjia.kuaidi.services.ShipService&methods=add,deleteCompany,getCompanies,getAll,getShipment,subscribe,addCompany,update,getMessage,delete,getCount&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044359376 empty://10.0.0.24/cn.idongjia.kuaidi.services.ShipService?application=dongjia-web-service&category=providers&check=false&dubbo=2.8.4&interface=cn.idongjia.kuaidi.services.ShipService&methods=add,deleteCompany,getCompanies,getAll,getShipment,subscribe,addCompany,update,getMessage,delete,getCount&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044359376, cn.idongjia.web.service.VideoViewService=empty://192.168.0.4:8080/presentation/cn.idongjia.web.service.VideoViewService?accepts=500&anyhost=true&application=doangjia-data-presentation&category=configurators&check=false&dubbo=2.8.4&extension=com.alibaba.dubbo.rpc.protocol.rest.support.LoggingFilter&generic=false&interface=cn.idongjia.web.service.VideoViewService&methods=getVideoViews,count&organization=dongjia&owner=dongjia&pid=611&server=servlet&side=provider&threads=500&timestamp=1463817345564, cn.idongjia.web.service.PageViewService=empty://192.168.0.4:8080/presentation/cn.idongjia.web.service.PageViewService?accepts=500&anyhost=true&application=doangjia-data-presentation&category=configurators&check=false&dubbo=2.8.4&extension=com.alibaba.dubbo.rpc.protocol.rest.support.LoggingFilter&generic=false&interface=cn.idongjia.web.service.PageViewService&methods=getCount,getPageView&organization=dongjia&owner=dongjia&pid=1330&server=servlet&side=provider&threads=500&timestamp=1463822156360, cn.idongjia.web.service.OrderChannelService=empty://192.168.0.4:8080/presentation/cn.idongjia.web.service.OrderChannelService?accepts=500&anyhost=true&application=doangjia-data-presentation&category=configurators&check=false&dubbo=2.8.4&extension=com.alibaba.dubbo.rpc.protocol.rest.support.LoggingFilter&generic=false&interface=cn.idongjia.web.service.OrderChannelService&methods=totalCountByOrderInfo,getChannelByOderInfo&organization=dongjia&owner=dongjia&pid=1330&server=servlet&side=provider&threads=500&timestamp=1463822157325, cn.idongjia.web.service.ConversionRateService=empty://192.168.0.4:8080/presentation/cn.idongjia.web.service.ConversionRateService?accepts=500&anyhost=true&application=doangjia-data-presentation&category=configurators&check=false&dubbo=2.8.4&extension=com.alibaba.dubbo.rpc.protocol.rest.support.LoggingFilter&generic=false&interface=cn.idongjia.web.service.ConversionRateService&methods=getConversionRateCount,getConversionRate&organization=dongjia&owner=dongjia&pid=611&server=servlet&side=provider&threads=500&timestamp=1463817345675, cn.idongjia.kunwu.service.RiskService=empty://10.0.0.24/cn.idongjia.kunwu.service.RiskService?application=dongjia-web-service&category=configurators&check=false&dubbo=2.8.4&interface=cn.idongjia.kunwu.service.RiskService&methods=execute&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044353160 empty://10.0.0.24/cn.idongjia.kunwu.service.RiskService?application=dongjia-web-service&category=routers&check=false&dubbo=2.8.4&interface=cn.idongjia.kunwu.service.RiskService&methods=execute&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044353160 empty://10.0.0.24/cn.idongjia.kunwu.service.RiskService?application=dongjia-web-service&category=providers&check=false&dubbo=2.8.4&interface=cn.idongjia.kunwu.service.RiskService&methods=execute&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044353160, cn.idongjia.article.services.ArticleService=empty://10.0.0.24/cn.idongjia.article.services.ArticleService?application=dongjia-web-service&category=configurators&check=false&dubbo=2.8.4&interface=cn.idongjia.article.services.ArticleService&methods=getRecommends,getTabs,getRed,getFeeds,getNewGoodNum,getNewGoodFeeds,getNewGoodTitle,getSearchInfo&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044359189 empty://10.0.0.24/cn.idongjia.article.services.ArticleService?application=dongjia-web-service&category=routers&check=false&dubbo=2.8.4&interface=cn.idongjia.article.services.ArticleService&methods=getRecommends,getTabs,getRed,getFeeds,getNewGoodNum,getNewGoodFeeds,getNewGoodTitle,getSearchInfo&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044359189 empty://10.0.0.24/cn.idongjia.article.services.ArticleService?application=dongjia-web-service&category=providers&check=false&dubbo=2.8.4&interface=cn.idongjia.article.services.ArticleService&methods=getRecommends,getTabs,getRed,getFeeds,getNewGoodNum,getNewGoodFeeds,getNewGoodTitle,getSearchInfo&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044359189, cn.idongjia.mq.config.MessageQueueService=empty://10.0.0.24/cn.idongjia.mq.config.MessageQueueService?application=dongjia-web-service&category=configurators&check=false&dubbo=2.8.4&interface=cn.idongjia.mq.config.MessageQueueService&methods=getMqConfig&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044356001 empty://10.0.0.24/cn.idongjia.mq.config.MessageQueueService?application=dongjia-web-service&category=routers&check=false&dubbo=2.8.4&interface=cn.idongjia.mq.config.MessageQueueService&methods=getMqConfig&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044356001 empty://10.0.0.24/cn.idongjia.mq.config.MessageQueueService?application=dongjia-web-service&category=providers&check=false&dubbo=2.8.4&interface=cn.idongjia.mq.config.MessageQueueService&methods=getMqConfig&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044356001, cn.idongjia.tianji.services.UserMergeService=empty://10.0.0.24/cn.idongjia.tianji.services.UserMergeService?application=dongjia-web-service&category=configurators&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.UserMergeService&methods=mergeAll,mergeByUid,isWxLogin,ifNeedMerge,merge&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044359443 empty://10.0.0.24/cn.idongjia.tianji.services.UserMergeService?application=dongjia-web-service&category=routers&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.UserMergeService&methods=mergeAll,mergeByUid,isWxLogin,ifNeedMerge,merge&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044359443 empty://10.0.0.24/cn.idongjia.tianji.services.UserMergeService?application=dongjia-web-service&category=providers&check=false&dubbo=2.8.4&interface=cn.idongjia.tianji.services.UserMergeService&methods=mergeAll,mergeByUid,isWxLogin,ifNeedMerge,merge&organization=dongjia&owner=dongjia&pid=27456&revision=1.2.3-63111df&side=consumer&timestamp=1463044359443}, dubbo version: 2.8.4, current host: 127.0.0.1
[21/05/16 05:46:59:059 CST] ZkClient-EventThread-39-127.0.0.1:2181 INFO zkclient.ZkEventThread: Starting ZkClient event thread.
[21/05/16 05:46:59:059 CST] RMI TCP Connection(2)-127.0.0.1-EventThread INFO zkclient.ZkClient: zookeeper state changed (SyncConnected)
[21/05/16 05:46:59:059 CST] RMI TCP Connection(2)-127.0.0.1 INFO zookeeper.ZookeeperRegistry: [DUBBO] Register: rest://192.168.0.4:8080/test-demo/com.web.services.TestService?accepts=500&anyhost=true&application=test-demo&dubbo=2.8.4&extension=com.alibaba.dubbo.rpc.protocol.rest.support.LoggingFilter&generic=false&interface=com.web.services.TestService&methods=sayHello&organization=freedom&owner=Joyven&pid=1417&server=servlet&side=provider&threads=500&timestamp=1463824018811, dubbo version: 2.8.4, current host: 127.0.0.1
[21/05/16 05:46:59:059 CST] RMI TCP Connection(2)-127.0.0.1 INFO zookeeper.ZookeeperRegistry: [DUBBO] Subscribe: provider://192.168.0.4:8080/test-demo/com.web.services.TestService?accepts=500&anyhost=true&application=test-demo&category=configurators&check=false&dubbo=2.8.4&extension=com.alibaba.dubbo.rpc.protocol.rest.support.LoggingFilter&generic=false&interface=com.web.services.TestService&methods=sayHello&organization=freedom&owner=Joyven&pid=1417&server=servlet&side=provider&threads=500&timestamp=1463824018811, dubbo version: 2.8.4, current host: 127.0.0.1
[21/05/16 05:46:59:059 CST] RMI TCP Connection(2)-127.0.0.1 INFO zookeeper.ZookeeperRegistry: [DUBBO] Notify urls for subscribe url provider://192.168.0.4:8080/test-demo/com.web.services.TestService?accepts=500&anyhost=true&application=test-demo&category=configurators&check=false&dubbo=2.8.4&extension=com.alibaba.dubbo.rpc.protocol.rest.support.LoggingFilter&generic=false&interface=com.web.services.TestService&methods=sayHello&organization=freedom&owner=Joyven&pid=1417&server=servlet&side=provider&threads=500&timestamp=1463824018811, urls: [empty://192.168.0.4:8080/test-demo/com.web.services.TestService?accepts=500&anyhost=true&application=test-demo&category=configurators&check=false&dubbo=2.8.4&extension=com.alibaba.dubbo.rpc.protocol.rest.support.LoggingFilter&generic=false&interface=com.web.services.TestService&methods=sayHello&organization=freedom&owner=Joyven&pid=1417&server=servlet&side=provider&threads=500&timestamp=1463824018811], dubbo version: 2.8.4, current host: 127.0.0.1
[2016-05-21 05:46:59,636] Artifact Gradle : Joyven:test : test-demo.war (exploded): Artifact is deployed successfully
[2016-05-21 05:46:59,637] Artifact Gradle : Joyven:test : test-demo.war (exploded): Deploy took 7,350 milliseconds
[21/05/16 05:47:00:000 CST] http-nio-8080-exec-1 WARN core.ExceptionHandler: failed to execute
javax.ws.rs.NotFoundException: Could not find resource for full path: http://localhost:8080//
at org.jboss.resteasy.core.registry.ClassNode.match(ClassNode.java:73)
at org.jboss.resteasy.core.registry.RootClassNode.match(RootClassNode.java:48)
at org.jboss.resteasy.core.ResourceMethodRegistry.getResourceInvoker(ResourceMethodRegistry.java:444)

有一个错误,说的是http://localhost:8080/找不到,因为我们的请求路径在web.xml中做了过滤,不支持这种请求,它必须是service中的@path指定的路由。

先跑一个demo:

  • com.web.service/TestService.java
1
2
3
4
5
6
7
8
9
10
11
package com.web.service;

import java.util.List;

/**
* Created by zhoujunwen on 16/5/21.
*/
public interface TestService {
List sayHello();
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.web.biz;

import com.alibaba.dubbo.rpc.protocol.rest.support.ContentType;
import com.web.service.TestService;
import org.springframework.stereotype.Component;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import java.util.ArrayList;
import java.util.List;


@Component("testService")
@Path("test")
@Produces({ContentType.APPLICATION_JSON_UTF_8})
public class TestServiceImpl implements TestService {
@Override
@GET
@Path("say")
public List sayHello() {
List list = new ArrayList<>();
list.add("I am a test service");
return list;
}
}

使用gradle命令编译打包,gradle clean build --daemon,打包完后运行代码,服务启动后,在浏览器中访问:http://127.0.0.1:8080/test-demo/test/say,可以看到页面中的内容:
图片描述

在Advance REST Client中看到是这样的:
图片描述

下面实现一个与mybatis整合的demo。

配置mybatis

在main/resource/META-INF/spring/下面创建mybatis.xml文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<tx:annotation-driven transaction-manager="txManager_test"/>

<bean id="txManager_test"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="testDataSource"/>
</bean>

<!-- Use c3p0 as the database connection pool -->
<bean id="testDataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close" >
<property name="url"
value="jdbc:mysql://${mysql.test.host}:${mysql.test.port}/${mysql.test.database}?characterEncoding=utf8" />
<property name="username" value="${mysql.test.user}" />
<property name="password" value="${mysql.test.pwd}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="1" />
<property name="minIdle" value="1" />
<property name="maxActive" value="20" />

<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="30000" />

<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />

<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />

<property name="testWhileIdle" value="true" />

<!-- 这里建议配置为TRUE,防止取到的连接不可用 -->
<property name="testOnBorrow" value="true" />
<property name="testOnReturn" value="false" />

<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="false" />

<!-- 验证连接有效与否的SQL,不同的数据配置不同 -->
<property name="validationQuery" value="select 1 " />
<property name="filters" value="stat" />
<!--
<property name="proxyFilters">
<list>
<ref bean="logFilter" />
</list>
</property>
-->
</bean>

<tx:advice id="advice" transaction-manager="transactionManager_test">
<tx:attributes>
<tx:method name="select*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="get*" read-only="true"/>
<tx:method name="has*" read-only="true"/>
<tx:method name="count*" read-only="true"/>
<tx:method name="search*" read-only="true"/>
</tx:attributes>
</tx:advice>

<bean id="transactionManager_test"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref local="testDataSource"/>
</property>
</bean>

<!-- Session Factory -->
<bean id="sqlSessionFactory_test" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="testDataSource"/>
<!-- <property name="configLocation" value="classpath:META-INF/spring/configuration.xml"/>-->
<!--<property name="mapperLocations" value="classpath:mapper/*mapper.xml"/>-->
</bean>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory_test"></property>
<property name="basePackage" value="com.web.mapper"/>
</bean>
</beans>

需要注意的是数据库的配置,我们把这些以变量的形式配置,在前面所得config.properties文件中,增加mysql配置的key-value键值对,内容如下:

1
2
3
4
5
6
mysql.test.host=127.0.0.1
mysql.test.port=3306
mysql.test.database=dubbox_test #替换成你的数据库
mysql.test.user=root #替换成你的用户名
mysql.test.pwd=root #替换成你的密码

mybatis.xml中的最后一行配置org.mybatis.spring.mapper.MapperScannerConfigurer的属性name值为basePackage,其value值是我们项目中mapper的包路径。

还有,对事物管理的配置重复了,如果你看着不舒服,可以把上面的重复部分去掉。

数据库创建

创建一个名为dubbox_test的数据库。

1
CREATE DATABASE IF NOT EXISTS dubbox_test DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

然后在改数据库下面创建表:

1
2
3
4
5
6
7
8
9
10
use dubbox_test;

CREATE TABLE IF NOT EXISTS`student` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(11) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`sex` char(2) DEFAULT NULL,
`tel` char(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

插入test数据(数据来源伪造,明星年龄我真没时间去查):

1
2
3
4
5
6
7
INSERT INTO `student`(`name`,`age`,`sex`,`tel`) VALUES
('姚明','45','男','17092679981'),
('易建联','36','男','17092679982'),
('李娜','38','女','17092679983'),
('迈克尔乔丹','46','男','17092679984'),
('刘翔','40','男','17092679985'),
('李冰冰','32','女','17092679986');

说明:下面所有java代码的命名均与类的名字保持一致,所在位置与包名一致,故而不在写类或接口的名字。

接口定义(interface)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.web.service;


import com.web.pojos.Student;

import java.util.List;

/**
* 查询学生信息
*/
public interface StudentService {
List<Student> getStudentsInfo(int sid);
}

实现接口(implements)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.web.biz;

import com.alibaba.dubbo.rpc.protocol.rest.support.ContentType;
import com.web.Repository.StudentRepo;
import com.web.pojos.Student;
import com.web.service.StudentService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import java.util.List;

@Component("studentService")
@Path("student")
@Produces({ContentType.APPLICATION_JSON_UTF_8})
public class StudentServiceImpl implements StudentService {
Log logger = LogFactory.getLog(StudentServiceImpl.class);

@Resource
private StudentRepo studentRepo;
/**
* 获取学生信息
* @param id
* @return
*/
@Override
@GET
@Path("getinfo/{id: \\d+}")
public List<Student> getStudentsInfo(@PathParam("id") int id) {
logger.debug("获取学生信息,学号为:" + id);
System.out.println("获取学生信息,学号为:" + id);
return studentRepo.getStudentInfo(id);
}
}

业务逻辑(repository)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.web.Repository;


import com.web.mapper.StudentInfoMapper;
import com.web.pojos.Student;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.List;

@Repository("studentRepo")
public class StudentRepo {

@Resource
private StudentInfoMapper studentInfoMapper;

public List<Student> getStudentInfo(final int sid) {
if (sid == 0) {
return null;
}
return studentInfoMapper.getStudentInfo(sid);

}
}

dao层(mapper)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.web.mapper;


import com.web.pojos.Student;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Component;

import java.util.List;

@Component("studentInfoMapper")
public interface StudentInfoMapper {
@Select(
"<script>select * from student where 1 = 1 " +
" <if test=\"id != null or id != 0\"> and id = #{id}</if>" +
" limit 1000</script>")
@Results({
@Result(id = true, property = "id", column = "id"),
@Result(property = "name", column = "name"),
@Result(property = "age", column = "age"),
@Result(property = "sex", column = "sex"),
@Result(property = "tel", column = "tel")
})
List<Student> getStudentInfo(@Param("id") final int id);
}

说明:如果你的数据库字段与pojo的字段对应,则可以不用@Results@Result注解,根据情况而定。一般,数据表中的字段如果是下划线连接,则pojo中的因该去掉下划线并将下划线后面单词首字母大写。例如:

表字段 pojo属性
age age
create_time createTime

pojos

注意,返回的list中装载的是一个Student对象,所以,我们需要创建一个实现了Serializable接口的pojo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package com.web.pojos;


import java.io.Serializable;

public class Student implements Serializable {
private int id;

private String name;

private int age;

private String sex;

private String tel;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}

public String getTel() {
return tel;
}

public void setTel(String tel) {
this.tel = tel;
}
}

最后,在dubbox中暴露接口:

1
<dubbo:service interface="com.web.service.StudentService" ref="studentService"/>

项目完整的目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|____settings.gradle
|____src
| |____main
| | |____java
| | | |____com
| | | | |____web
| | | | | |____biz
| | | | | | |____StudentServiceImpl.java
| | | | | | |____TestServiceImpl.java
| | | | | |____mapper
| | | | | | |____StudentInfoMapper.java
| | | | | |____pojos
| | | | | | |____Student.java
| | | | | |____Repository
| | | | | | |____StudentRepo.java
| | | | | |____service
| | | | | | |____StudentService.java
| | | | | | |____TestService.java
| | |____resources
| | | |____conf
| | | | |____properties
| | | | | |____config.properties
| | | |____log4j.xml
| | | |____META-INF
| | | | |____spring
| | | | | |____mybatis.xml
| | | | | |____services-config.xml
| | |____webapp
| | | |____index.jsp
| | | |____WEB-INF
| | | | |____web.xml
| |____test
| | |____java
| | |____resources

查看结果

打包运行该项目,浏览器中访问:http://localhost:8080/test-demo/student/getinfo/1,输出结果:
图片描述

在Advanced REST Client中访问:
图片描述

总结

虽然这是个小demo,涉及到的东西相对还是挺多的,各种注解,各种配置很繁琐,好在mybatis这一块全部用注解,如果用xml写,估计一点都不清晰,当然,萝卜白菜各有所爱。

  • spring的配置,这里面没有用到springmvc,所以可以不引入springmvc的dtd,同样在gradle中也可以不引入spring webmvc的包。
  • web上下文的配置,dispatcher已经不是org.springframework.web.servlet.DispatcherServlet,而是dubbo的com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet
  • dubbox/dubbo的配置,server,port,contentpath格外注意。dubbo配置声明暴露接口注意写正确。
  • 还是注解吧,@Component,@Produces,@Consumes,@POST,@GET,@Path,@Repository,@Param,@QueryParam,@PathParam,@BeanParam,@Resource等等,区分起作用吧。
  • 开发中遇到的错误很多,在接下来的写作中,尽量整理一份自己遇到的错误和解决方法,与君共同学习。

最后,奉上code的git地址:https://git.coding.net/zjw/dubbox-demo.git
【原文最早发布在segmentfault】