webservice系列1---基於web工程上寫一個基本數據類型的webservice


本節摘要:之前在一篇博客中介紹過如何寫一個webservice(http://www.cnblogs.com/java-pan/archive/2011/11/25/axis_webservice.html),不過那個webservice是在工作項目中直接添加的,中間少了很多麻煩,不是白手起家總感覺前面一步一步的過程不清楚。myeclipse自帶的也有如何新建一個webservice工程,這也不是我要說的,項目中這個也不實用,項目中都是在當前開發的web工程中寫一個webservice,誰會再去新建一個工程,那不是扯淡嗎?本節在一個已經存在的web工程中,來新建類、新建配置文件,發布webservice、訪問webservice。基於axis1.4的版本來完成的。

preparation

1.在閱讀本機之前你需要看以下相關知識:

JDBC;

JDBC的介紹這里就不說了,網上忒多的資料了,這個也是做java接觸數據庫時必會的

ibatis;

可以參考我之前的博客http://www.cnblogs.com/java-pan/archive/2012/03/21/ibatis.html

XStream;

可以參考我之前的博客http://www.cnblogs.com/java-pan/archive/2011/10/25/Object_xml.html

axis;

可以參考我之前的博客http://www.cnblogs.com/java-pan/archive/2011/11/25/axis_webservice.html

2.項目結構

myeclipse:6.5  tomcat:5.0  system:win7 JDK:項目的版本是1.5 編譯采用的是1.4 

說明:本節介紹的是基於axis的webservice,采用的版本為axis1.4

3.下載項目中用到的jar包

 http://files.cnblogs.com/java-pan/lib-axis1.4.rar

以上鏈接包含下面的所有包。下載的jar包主要包含以下幾部分:

(1)oracle數據庫驅動包 :classes12.jar

(2)ibatis包:ibatis-2.3.4.jar

(3)xstream-1.2.1.jar

(4)axis包(從以下鏈接下載http://mirror.bjtu.edu.cn/apache/ws/axis/1_4/ 下載后解壓把lib下所有包導入)

(5)activation.jar和mail.jar 建議導入的包

以上除最后一個jar包外,其它的程序運行必須導入。(可能axis不需要導入所有的包,不過我們就全部導入好了)

項目jar包的詳細列表如下:

說明:lib下一共中13個jar包,截圖的圖片也有13個jar包,但是博客發布后顯示的只有8個jar包,可以圖片另存為看到所有的jar包。

4.class&mthod

JDBC:DriverManager、Connection、PreparedStatement、ResultSet

DriverManager:

getConnection(String url, String user, String password)獲得一個Connection對象,參數依次為數據庫驅動的url、用戶名、密碼

Connection:

prepareStatement(String sql)獲得一個預處理對象PreparedStatement

PreparedStatement:

executeQuery()執行查詢操作,返回一個結果集對象ResultSet,不要傳入任何參數

ResultSet:

next()返回一個布爾類型的值,用於判斷是否還有記錄

 

Ibatis:SqlMapClient、SqlMapClientBuilder

SqlMapClient:

SqlMapClient buildSqlMapClient(Reader reader)傳入一個reader對象,創建一個SqlMapClient 對象

startTransaction();開始事務

getCurrentConnection()獲取當前連接,回滾事務的時候用到

endTransaction結束事務

SqlMapClientBuilder:

queryForObject(String s, Object obj)第一個參數為實體類對應的配置文件的id屬性,第二個為傳入的參數,此方法的返回值是一個Object對象

 

xstream:XStream

XStream:

alias(String name, Class type)設置節點的別名

alias(String name, Class type)設置某一元素節點的別名

toXML(Object obj)把對應的obj轉換為xml格式的字符串

 

其他類:Reader、Resources、StringBuffer

Reader:java I/O對象,用於讀取字符流的抽象類,這里就不再介紹,請查看JDK幫助文檔

Resources:此類為ibatis的jar包中的類,非JDK的類

getResourceAsReader(String resource)對於resource路徑的文件,獲得一個Reader對象

StringBuffer:線程安全的可變字符序列

append(String str)將指定的字符串追加到此字符序列

toString()返回此序列中數據的字符串表示形式

 

start

新建一個web工程,項目命名為WebService,按照工程目錄新建對應的文件如下:

實體類-Dept.java

Dept
 1 package com.bean;
 2 
 3 /**
 4  * 
 5  *Module:          Dept.java
 6  *Description:     寫一個oracle數據庫自帶的部門表dept的javabean
 7  *Company:       
 8  *Author:           pantp
 9  *Date:              May 1, 2012
10  */
11 public class Dept {
12     public int deptNo;
13     public String dName;
14     public String loc;
15 
16     public int getDeptNo() {
17         return deptNo;
18     }
19 
20     public void setDeptNo(int deptNo) {
21         this.deptNo = deptNo;
22     }
23 
24     public String getDName() {
25         return dName;
26     }
27 
28     public void setDName(String name) {
29         dName = name;
30     }
31 
32     public String getLoc() {
33         return loc;
34     }
35 
36     public void setLoc(String loc) {
37         this.loc = loc;
38     }
39 }

數據庫連接文件-ConnectDataBase.java

ConnectDataBase
 1 package com.cn;
 2 
 3 import java.io.IOException;
 4 import java.io.Reader;
 5 
 6 import java.sql.Connection;
 7 import java.sql.DriverManager;
 8 import java.sql.SQLException;
 9 
10 import com.ibatis.common.resources.Resources;
11 import com.ibatis.sqlmap.client.SqlMapClient;
12 import com.ibatis.sqlmap.client.SqlMapClientBuilder;
13 
14 /**
15  * 
16  *Module:          ConnectDataBase.java
17  *Description:    數據庫連接類,采用兩種方式:1.JDBC 2.Ibatis框架
18  *Company:       
19  *Author:           pantp
20  *Date:              May 1, 2012
21  */
22 public class ConnectDataBase {
23 
24     //采用JDBC的方式連接數據
25     private final static String USERNAME = "scott";
26     private final static String PASSWORD = "orcl";
27     private final static String URL = "jdbc:Oracle:thin:@localhost:1521:orcl";
28     private final static String DRIVER = "oracle.jdbc.driver.OracleDriver";
29     static Connection conn = null;
30     
31     // 獲取連接
32     static {
33         // 加載驅動
34         try {
35             Class.forName(DRIVER);
36         } catch (ClassNotFoundException e) {
37             e.printStackTrace();
38         }
39         // 獲得連接對象conn
40         try {
41             conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
42         } catch (SQLException e) {
43             e.printStackTrace();
44         }
45     }
46     
47     //提供一個方法供外部調用,獲得JDBC連接對象conn
48     public static Connection getConnection() {
49         return conn;
50     }
51     
52     
53     // 定義ibatis映射文件的位置,寫配置文件的完整路徑
54     private static String resource = "com/ibatis/SqlMapConfig.xml";
55     private static SqlMapClient sqlMapClient = null;
56     static {
57         try {
58             Reader reader = Resources.getResourceAsReader(resource);
59             sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);
60             reader.close();
61         } catch (IOException e) {
62             e.printStackTrace();
63         } 
64     }
65 
66     //提供一個方法供外部調用,獲得Ibatis的連接對象sqlMapClient
67     public static SqlMapClient getSqlMapClient(){
68         return sqlMapClient;
69     }
70 
71 
72 }

實體類對應的映射文件-Dept.xml

Dept
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!-- 
 3     author:pantp
 4     date:2012/05/01
 5     description:javabean對應的xml配置文件
 6 -->
 7 <!DOCTYPE sqlMap      
 8     PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"      
 9     "http://ibatis.apache.org/dtd/sql-map-2.dtd">
10 
11 <sqlMap>
12     <typeAlias alias="Dept" type="com.bean.Dept" />
13 
14     <!-- 精確查詢 按照條件查詢記錄  按照部門編號DEPTNO查詢 -->
15     <select parameterClass="int" resultClass="Dept" id="selectById">
16         select deptno,dname,loc from dept where deptno=#deptNo#
17     </select>
18 
19 </sqlMap>

數據庫連接屬性文件-SqlMap.properties

SqlMap.properties
1 driver=oracle.jdbc.driver.OracleDriver
2 url=jdbc:Oracle:thin:@127.0.0.1:1521:orcl
3 username=scott
4 password=orcl

ibatis核心配置文件-SqlMapConfig.xml

SqlMapConfig.xml
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!-- 
 3     author:pantp
 4     date:2012/05/01
 5     description:Ibatis框架的核心配置文件,主要是數據庫連接屬性文件和實體類和表的映射文件引入進來
 6 -->
 7 <!DOCTYPE sqlMapConfig      
 8     PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"      
 9     "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
10 
11 <sqlMapConfig>
12 
13     <!-- 數據庫連接的屬性文件 -->
14     <properties resource="com/ibatis/SqlMap.properties" />
15     <transactionManager type="JDBC">
16         <dataSource type="SIMPLE">
17             <property value="${driver}" name="JDBC.Driver" />
18             <property value="${url}" name="JDBC.ConnectionURL" />
19             <property value="${username}" name="JDBC.Username" />
20             <property value="${password}" name="JDBC.Password" />
21         </dataSource>
22     </transactionManager>
23 
24     <!-- 實體類和數據庫表的映射 -->
25     <sqlMap resource="com/ibatis/Dept.xml" />
26 
27 </sqlMapConfig>

定義查詢服務的接口文件-IQueryInfoSV.java

IQueryInfoSV
 1 package com.interfaces;
 2 
 3 import java.sql.SQLException;
 4 
 5 /**
 6  * 
 7  *Module:          IQueryInfoSV.java
 8  *Description:    定義查詢的接口
 9  *Company:       
10  *Author:           pantp
11  *Date:              May 1, 2012
12  */
13 public interface IQueryInfoSV {
14 
15     //JDBC
16     public abstract String queryDept1(int deptNo) throws SQLException;
17     
18     //ibatis
19     public abstract String queryDept2(int deptNo) throws SQLException;
20     
21 }

定義查詢服務的實現類-QueryInfoSVImpl.java

QueryInfoSVImpl
  1 package com.impl;
  2 
  3 import java.sql.Connection;
  4 import java.sql.PreparedStatement;
  5 import java.sql.ResultSet;
  6 import com.bean.Dept;
  7 import com.cn.ConnectDataBase;
  8 import com.ibatis.sqlmap.client.SqlMapClient;
  9 import com.interfaces.IQueryInfoSV;
 10 import com.thoughtworks.xstream.XStream;
 11 import com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer;
 12 import com.thoughtworks.xstream.io.xml.XppDriver;
 13 
 14 import java.sql.SQLException;
 15 
 16 /**
 17  * 
 18  *Module:          QueryInfoSVImpl.java
 19  *Description:     根據部門編號查詢oracle自帶的dept表,提供兩種查詢方式:1.JDBC 2.Ibatis
 20  *Company:       
 21  *Author:           pantp
 22  *Date:              May 1, 2012
 23  */
 24 public class QueryInfoSVImpl implements IQueryInfoSV {
 25 
 26     // 采用JDBC方式連接數據庫的查詢操作
 27     public String queryDept1(int deptNo) throws SQLException {
 28         // 獲取JDBC的連接
 29         Connection conn = ConnectDataBase.getConnection();
 30         // 拼裝SQL語句
 31         String sql = "select deptno,dname,loc from dept where deptno=" + deptNo;
 32         // 獲得預處理對象pst
 33         PreparedStatement pst = conn.prepareStatement(sql);
 34         // 查詢結果集
 35         ResultSet rs = pst.executeQuery();
 36 
 37         // 采用next()方法取得數據庫數據,deptNo是逐漸采用deptNo查詢,要么沒有查到數據,要么只能查到一條數據
 38         String result = "";
 39         Dept dept = null;
 40         while (rs.next()) {
 41             dept = new Dept();
 42             dept.deptNo = deptNo;
 43             dept.dName = rs.getString("dName");
 44             dept.loc = rs.getString("loc");

 45         }
 46         result = getXML(dept);
 47         return result;
 48     }
 49 
 50     // 采用ibatis連接數據庫並按部門編號精確查找
 51     public String queryDept2(int deptNo) throws SQLException {
 52         // 獲得ibatis的連接對象sqlMapClient
 53         SqlMapClient sqlMapClient = ConnectDataBase.getSqlMapClient();
 54         Dept dept = null;
 55         try {
 56             sqlMapClient.startTransaction();// 開始事務
 57             // 執行查詢 此處的"selectById"對應Dept.xml文件中select標簽的id屬性
 58             dept = (Dept) sqlMapClient.queryForObject("selectById",
 59                     new Integer(deptNo));
 60             sqlMapClient.commitTransaction();// 提交事務
 61         } catch (SQLException e) {
 62             try {
 63                 sqlMapClient.getCurrentConnection().rollback();// 回滾事務
 64             } catch (SQLException e1) {
 65                 e1.printStackTrace();
 66             }
 67             e.printStackTrace();
 68         } finally {
 69             try {
 70                 sqlMapClient.endTransaction();// 結束事務
 71             } catch (SQLException e) {
 72                 e.printStackTrace();
 73             }
 74         }
 75         // 組裝xml報文並返回
 76         return getXML(dept);
 77     }
 78 
 79     // 采用XStream方式組裝XML
 80     public static String getXML(Dept dept) {
 81         // 用於保存XML的內容
 82         String xmlbody = "";
 83         // 用於保存XML的頭部
 84         String xmlhead = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
 85 
 86         if (null != dept) {
 87             // 構造一個xstream對象,此種構造方式解決下划線站兩個字符的問題
 88             XStream xstream = new XStream(new XppDriver(
 89                     new XmlFriendlyReplacer("-_", "_")));
 90             
 91             // 設置別名,不設置的話顯示為Dept_Info顯示為com.bean.Dept
 92             xstream.alias("DEPT_INFO", Dept.class);
 93             xstream.aliasField("DEPTNO", Dept.class, "deptNo");
 94             xstream.aliasField("DNAME", Dept.class, "dName");
 95             xstream.aliasField("LOC", Dept.class, "loc");
 96             
 97             // 把實體類轉換為XML
 98             xmlbody = xstream.toXML(dept);
 99         } else {
100             // 處理根據編號沒有查詢到數據的情況
101             StringBuffer sb = new StringBuffer();
102             sb
103                     .append("<DEPT_INFO><DEPTNO></DEPTNO><DNAME></DNAME><LOC></LOC></DEPT_INFO>");
104             xmlbody = sb.toString();
105         }
106         return xmlhead + xmlbody;
107     }
108 }

測試類-Test1.java 用於測試JDBC和ibatis的數據庫連接是否正常

Test1
 1 package com.test;
 2 
 3 import java.sql.SQLException;
 4 import com.impl.QueryInfoSVImpl;
 5 import com.interfaces.IQueryInfoSV;
 6 
 7 /**
 8  * 
 9  *Module:          Test1.java
10  *Description:     測試JDBC和Ibatis數據庫查詢是否正常
11  *Company:       
12  *Author:           ptp
13  *Date:              May 1, 2012
14  */
15 public class Test1 {
16 
17     // 測試數據庫是可以正常查詢
18     public static void main(String[] args) throws SQLException {
19         int deptNo = 10;
20         test1(deptNo);
21         test2(deptNo);
22     }
23 
24     //測試JDBC方式連接數據庫是否正常 
25     public static void test1(int deptNo) throws SQLException {
26         IQueryInfoSV query = new QueryInfoSVImpl();
27         String dept = query.queryDept1(deptNo);
28 
29         System.out
30                 .println("\n===============采用JDBC方式查詢數據庫連接正常  author<pantp>=======\n");
31         System.out.println(dept);
32         System.out
33                 .println("\n===============采用JDBC方式查詢數據庫連接正常==================\n");
34     }
35 
36     //測試ibatis方式連接數據庫是否正常
37     public static void test2(int deptNo) throws SQLException {
38         IQueryInfoSV query = new QueryInfoSVImpl();
39         String dept = query.queryDept2(deptNo);
40 
41         System.out
42                 .println("\n===============采用ibatis方式查詢數據庫連接正常 author<pantp>========\n");
43         System.out.println(dept);
44         System.out
45                 .println("\n===============采用ibatis方式查詢數據庫連接正常==================\n");
46     }
47 
48 }

測試類-Test2.java 用於測試webservice服務是否可以正常調用

Test2
 1 package com.test;
 2 
 3 import java.net.MalformedURLException;
 4 import java.net.URL;
 5 import java.rmi.RemoteException;
 6 
 7 import javax.xml.rpc.ParameterMode;
 8 import javax.xml.rpc.ServiceException;
 9 
10 import org.apache.axis.client.Call;
11 import org.apache.axis.encoding.XMLType;
12 
13 /**
14  * 
15  *Module:          Test2.java
16  *Description:     項目中常用調用webservice方式有兩種,stub樁的形式和動態調用,本次測試就用動態調用的方式
17  *Company:       
18  *Author:           pantp
19  *Date:              May 1, 2012
20  */
21 public class Test2 {
22 
23    // 調用webservice
24     public static void main(String[] args) {
25         test2();
26     }
27     
28     /**
29      * 動態調用接口訪問webservice服務的步驟如下:
30      * 1.創建service對象 
31      * 2.創建url對象 
32      * 3.創建call對象,
33      * 4.調用webservice的方法
34      * 5.處理返回結果
35      */
36     public static void test2() {
37         try {
38             // 1.創建service對象,通過axis自帶的類創建
39             org.apache.axis.client.Service service = new org.apache.axis.client.Service();
40 
41             // 2.創建url對象
42             String wsdlUrl = "http://127.0.0.1:8080/WebService/services/queryInfo?WSDL";// 請求服務的URL
43             URL url = new URL(wsdlUrl);// 通過URL類的構造方法傳入wsdlUrl地址創建URL對象
44         
45             // 2.創建服務方法的調用者對象call,設置call對象的屬性
46             Call call = (Call) service.createCall();
47             call.setTargetEndpointAddress(url);// 給call對象設置請求的URL屬性
48             String serviceName = "queryDept2";//webservice的方法名
49             call.setOperationName(serviceName);// 給call對象設置調用方法名屬性
50             call.addParameter("deptNo", XMLType.XSD_INT, ParameterMode.IN);// 給call對象設置方法的參數名、參數類型、參數模式
51             call.setReturnType(XMLType.SOAP_STRING);// 設置調用方法的返回值類型
52 //            call.setTimeout(new Integer(5000));//設置超時限制
53                         
54             // 4.通過invoke方法調用webservice
55             Integer deptNo = new Integer(50);
56             String dept = (String) call.invoke(new Object[] { deptNo });// 調用服務方法
57 
58             //5.打印返回結果
59             System.out
60                     .println("\n===============調用webservice成功(無安全機制) author<pantp>=======\n");
61             System.out.println(dept);
62             System.out
63                     .println("\n===============調用webservice成功(無安全機制)==================\n");
64 
65         } catch (MalformedURLException e) {
66             e.printStackTrace();
67         } catch (ServiceException e) {
68             e.printStackTrace();
69         } catch (RemoteException e) {
70             e.printStackTrace();
71         }
72     }
73 
74 }

web.xml-項目配置文件

Web.xml
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
 5     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 6   <servlet>
 7     <servlet-name>AxisServlet</servlet-name>
 8     <servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
 9   </servlet>
10     <servlet-mapping>
11         <servlet-name>AxisServlet</servlet-name>
12         <url-pattern>/services/*</url-pattern>
13     </servlet-mapping>
14     <mime-mapping>
15         <extension>wsdl</extension>
16         <mime-type>text/xml</mime-type>
17     </mime-mapping>
18     <mime-mapping>
19         <extension>xsd</extension>
20         <mime-type>text/xml</mime-type>
21     </mime-mapping>
22 
23 </web-app>

server-config.wsdd-webservice服務部署的配置文件

server-config.wsdd
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <deployment name="defaultClientConfig"
 3     xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"
 4     xmlns:handler="http://xml.apache.org/axis/wsdd/providers/handler" xmlns="http://xml.apache.org/axis/wsdd/">
 5     
 6     <globalConfiguration name="GlobalConfiguration1" type="" regenerateElement="false">
 7         <requestFlow name="RequestFlow1" type="" regenerateElement="false">
 8             <handler name="Handler1"
 9                 type="java:org.apache.axis.handlers.JWSHandler" regenerateElement="false">
10                 <parameter name="scope" value="session" regenerateElement="false"/>
11             </handler>
12             <handler name="Handler2"
13                 type="java:org.apache.axis.handlers.JWSHandler" regenerateElement="false">
14                 <parameter name="scope" value="request" regenerateElement="false"/>
15                 <parameter name="extension" value=".jwr" regenerateElement="false"/>
16             </handler>
17         </requestFlow>
18     </globalConfiguration>
19     
20     <handler name="URLMapper"
21         type="java:org.apache.axis.handlers.http.URLMapper" regenerateElement="false"/>
22     <handler name="LocalResponder"
23         type="java:org.apache.axis.transport.local.LocalResponder" regenerateElement="false"/>
24     <handler name="Authenticate"
25         type="java:org.apache.axis.handlers.SimpleAuthenticationHandler" regenerateElement="false"/>
26     <transport name="http" type="" regenerateElement="false">
27         <requestFlow name="RequestFlow1" type="" regenerateElement="false">
28             <handler name="Handler1" type="URLMapper" regenerateElement="false"/>
29             <handler name="Handler2"
30                 type="java:org.apache.axis.handlers.http.HTTPAuthHandler" regenerateElement="false"/>
31         </requestFlow>
32     </transport>
33     <transport name="local" type="" regenerateElement="false">
34         <responseFlow name="ResponseFlow1" type="" regenerateElement="false">
35             <handler name="Handler1" type="LocalResponder" regenerateElement="false"/>
36         </responseFlow>
37     </transport>
38 
39     <service name="queryInfo" provider="java:RPC">
40         <!-- 服務類名 -->
41         <parameter name="className" value="com.impl.QueryInfoSVImpl" />
42         <!-- 允許訪問所有方法 -->
43         <parameter name="allowedMethods" value="*" />
44     </service>
45 </deployment>

---把博客貼出來主要是請大家幫看看后面的問題,關於配置文件的介紹后面會加上詳細的說明---

result

發布項目,啟動tomcat。
運行Test1.java中的main方法,測試JDBC和ibatis數據庫查詢是否正常,查詢結果如下:

 在瀏覽器訪問發布的wsdl

輸入如下地址:http://127.0.0.1:8080/WebService/services/queryInfo?WSDL

訪問界面如圖:

 

 運行Test2類中的main方法,測試結果如下圖:

webservice服務存在以下2個問題:

(1)如上圖所示,按說在瀏覽器中可以正常的訪問wsdl的話,就說明服務已經發布好了。為什么客戶端調用會報如此錯誤呢?

(2)如果我把訪問的127.0.0.1改為localhost就不能正常的訪問wsdl了,這個是什么原因呢?

急需大蝦出現解決小弟的問題,我也在努力的查找中。跪求ing。

 

為方便各位大俠幫小弟查問題,源碼下載地址如下:http://files.cnblogs.com/java-pan/WebService.rar

 

modified by pantp  2012/08/22

問題定位及解決方法:

     關於此博客中的問題一直未解決,心中的石頭也一直未落地;

     經過這兩天的再一次拿出來查找問題、定位問題,終於得到了答案。

解決方式:把ConnectDataBase類中采用ibatis操作數據庫的代碼給去掉,然后再一次重新發布工程,啟動tomcat,

此時,在IE瀏覽器可以正常的訪問wsdl地址,采用webservice客戶端形式(包括動態調用和stub樁的形式)也可以正常的調用webservice服務。

初步分析原因,可能是ibatis和axis的版本不兼容導致。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM