dubbox/dubbo+spring+mybatis+gradle構建REST服務

雜七雜八的雜

我的博客: 呆萌的程序猿
原文:dubbox/dubbo+spring+mybatis+gradle構建REST服務
聲明:
因爲sf的編輯自動校驗,致使某些英文單詞出錯,例如:gradle被編輯器自動替換爲grade,jdk替換爲idk等,查看的時候,請自行翻譯。html

------------------------------多圖預警------------------------------java

什麼是dubbox?看看別人怎麼說的:mysql

Dubbox是Dubbo的一個擴展,假如你知道java, javax 和 dubbo,那你就會明白dubbox是什麼了。linux

Dubbox增長的功能如RESTful remoting, Kyro/FST 系列化等。它已經應用在噹噹網內部的多個項目中。git

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之類的版本)github


注:以上文字均爲《Dubbo擴展:Dubbox》一文。web

環境安裝

jdk安裝

能看此文的人,我假設你會安裝java開發環境,此處省略999+的廢話,不然你看到此處心中必定會奔騰着十萬匹草泥馬。spring

gradle安裝

如題,Mac開發環境,windows請自行實踐,若是出了什麼問題,別罵我就行。sql

廢話少說,言歸正傳。mongodb

相信你看到這裏會對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)便可。

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

下載。在這裏下載gradle。

圖片描述
解壓
下載好的文件是zip格式,mac下載後自動解壓,若是沒有自動解壓,在findler中打開下載目錄,雙擊便可解壓,若是還不行,執行命令解壓,mac自帶了unzip命令工具,若是沒有unzip,使用brew安裝吧。

安裝unzip命令:

brew install unzip

解壓zip文件命令:

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。

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命令就好,假設你已經進入到下載目錄:

tar -zxvf apache-tomcat-8.0.35.tar

突然發現,下載的tomcat8的文件格式不是tar.gz,而是tar;tomcat9的倒是tar.gz。無論哪種,解壓命令同樣,均可達到你要的效果。

zookeeper安裝

zk的下載和安裝網上有不少教程,這裏不作詳細的講解。默認狀況下,運行代碼以前假設已經開啓了zk,開啓命令:

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命令在之後常常用到,用於構建打包):

gradle clean idea build --daemon

或者

gradle clean build --daemon
 gradle clean idea

配置gradle工程依賴

打開工程目錄下的build.gradle文件,配置dubbed/dubbo、spring、zk、öson等依賴包下面的配置中spring的版本是3.x,你可選擇配置4.x版本。

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倉庫,可能事件會很長。

----------- 原本覺得一篇就寫完了,前戲太長,一篇容納不下,可是,sf表字段確定足夠大,表擔憂,咱們仍是繼續把這場戲演完------------

項目基本配置

工程結構

在main文件夾下面新建一個webapp,webapp下心間一個WEB-INF,web.xml就在WEB-INF目錄下面。

|____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。

<?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: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:

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配置

<?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/目錄下面:

<?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>

 配置後的工程基本目錄結構

|____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,而後運行一下,應該能夠啓動了。
打印的日誌以下:

/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
package com.web.service;

import java.util.List;

/**
 * Created by zhoujunwen on 16/5/21.
 */
public interface TestService {
    List sayHello();
}
  • com.web.biz/TestServiceImpl.java
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文件:

<?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鍵值對,內容以下:

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的數據庫。

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

而後在改數據庫下面建立表:

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數據(數據來源僞造,明星年齡我真沒時間去查):

INSERT INTO `student`(`name`,`age`,`sex`,`tel`) VALUES
('姚明','45','男','17092679981'),
('易建聯','36','男','17092679982'),
('李娜','38','女','17092679983'),
('邁克爾喬丹','46','男','17092679984'),
('劉翔','40','男','17092679985'),
('李冰冰','32','女','17092679986');

說明:下面全部java代碼的命名均與類的名字保持一致,所在位置與包名一致,故而不在寫類或接口的名字。

接口定義(interface)

package com.web.service;


import com.web.pojos.Student;

import java.util.List;

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

實現接口(implements)

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)

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)

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:

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中暴露接口:

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

項目完整的目錄結構

|____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/du...

相關文章
相關標籤/搜索