Android webservice的用法詳細講解


看到有很多朋友對WebService還不是很了解,在此就詳細的講講WebService,爭取說得明白吧。此文章采用的項目是我畢業設計的webservice部分。
  首先要建一個web工程和android工程,在此采用myeclipse開發,個人覺得比較方便,要是eclipse安裝了tomcat也行。這的web端采用了框架hibernate和spring,因為我的項目只是client端調用web端的數據,沒什么web頁面,所以就沒用struts了。
  講解前先說說流程:此項目里,在web端里webservice把實體類轉換成json的對象通過一個web地址發布出去;(由於WebService 是一種基於SOAP協議的遠程調用標准。通過WebService可以將不同操作系統平台,不同語言、不同技術整合到一起,而在Android SDK中並沒有提供調用WebService的庫,因此需要使用第三方類庫(KSOAP2)來調用WebService ),client端就需要通過發布的地址來獲取數據了。
  以下就一步一步來講解了,所有的代碼和流程就以用用戶登錄來體現了:
  一、Web端
  1、Model和Hibernate配置
  實體類SysUser:Java代碼

public class SysUser implements Serializable {   
    private Long id;   
    private String userPwd;   
    private String userPhone;   
    public SysUser() {   
    }   
    public SysUser(Long id,  String userPwd, String userPhone) {   
        super();   
        this.id = id;   
        this.userPwd = userPwd;   
        this.userPhone = userPhone;   
        }   
    //get和set   
    }  

Hibernate:

<hibernate-mapping>   
    <class name="com.silent.cn.model.SysUser" table="SYS_USER">   
        <id name="id" type="java.lang.Long">   
            <column name="ID" precision="22" scale="0" />   
            <generator class="native" />   
        </id>   
        <property name="userPwd" type="java.lang.String">   
            <column name="USER_PWD" length="20" />   
        </property>   
        <property name="userPhone" type="java.lang.String">   
            <column name="USER_PHONE" length="11" />   
        </property>   
    </class>   
    </hibernate-mapping>  

2、PoJo包
  這里面是服務器端返回使用的類,webservice傳遞數據時,可能只會傳遞一部分數據,這樣的話,就要把要傳遞的數據封裝成一個pojo類,再轉成一個json對象,這樣的話無論是從代碼的整潔、邏輯還是高效,都會是非常完美的寫法。在web端和client端的類要完全一樣,這樣的話更為簡單。

/**  
 * 登陸狀態  
 */  
public class DataOperateResult {   
    private String status;   
    public String getStatus() {   
        return status;   
    }   
    public void setStatus(String status) {   
        this.status = status;   
    }   
} 

3、WebService接口
  這里面是封裝的webservice接口,手機端就是直接通過這些接口進行數據的傳送與接收,最重要的是在接口上一定要加上"@WebService"這個注解,這樣才能把此類里面的方法封裝成一個webservice接口,關鍵代碼如下:

//手機客戶端服務類(專門負責與手機客戶端進行交互)   
@WebService  
public interface MobileClientService {   
    /**  
     * 登陸  
     * @param opPhone  
     * @param loginPwd  
     */  
    public String userLogin(@WebParam(name = "opPhone") String opPhone, @WebParam(name = "loginPwd") String loginPwd);   
} 

要注意的是方法里的參數前一定要加上@WebParam(name = "***(隨便取的名字)"),這是因為這個opPhone參數通過webservice發布出去之后是以opPhone這個名稱存在的,在手機端那邊的方法直接獲取opPhone就可以了。
  4、WebService接口實現類
  ws里面接口的實現類,在這個類的開始,一定要加上"@WebService(endpointInterface = "com.silent.cn.ws.MobileClientService")"這個注解,它表示是繼承自com.silent.cn.ws.MobileClientService的類,沒有這一步,webservice接口是不會實現其功能的。下面是代碼:

@WebService(endpointInterface = "com.silent.cn.ws.MobileClientService")   
public class MobileClientServiceImpl implements MobileClientService {   
    public String userLogin(String opPhone, String loginPwd) {   
        SysUser sysUser = userLoginDao.userLogin(opPhone, loginPwd);   
        DataOperateResult dataOperateResult = new DataOperateResult();   
        if (sysUser != null) {   
            // 封裝登錄驗證結果   
            dataOperateResult.setStatus(SUCC);   
            System.out.println("登陸成功!");   
            return JSONObject.fromObject(dataOperateResult).toString();   
        } else {   
            System.out.println("不存在或手機號碼和密碼不正確!");   
            dataOperateResult.setStatus(FAIL);   
            return JSONObject.fromObject(dataOperateResult).toString();   
        }   
    }   
}  

5、Dao和Dao實現類Java代碼

/**  
 * 用戶登錄DAO  
 */  
public interface UserLoginDao {   
    /**  
     * 根據用戶名和用戶密碼登陸  
     * @param userPhone 用戶手機號碼  
     * @param passWord 用戶密碼  
     * <a href='\"http://www.eoeandroid.com/home.php?mod=space&uid=7300\"' target='\"_blank\"'>@return</a>  
     */  
    public SysUser userLogin(String userPhone, String passWord);   
}  

 

/**  
 * 用戶登錄DAO實現類  
 */  
public class UserLoginDaoImpl extends BaseDao implements UserLoginDao {   
    public SysUser userLogin(String userPhone, String passWord) {   
        String sql = " from SysUser where userPhone=? and userPwd=? ";   
        List<SysUser> list = this.getHibernateTemplate().find(sql, new Object[] { userPhone, passWord });   
        if (list.size() == 0) {   
            return null;   
        }   
        return list.get(0);   
    }   
}  

6、Spring配置
  這里spring的配置為了整潔與不臃腫,分成了三部分,分別實現了不同功能:
  applicationContext.xml:所有的spring配置信息,包括連接數據庫、配置事務管理器、配置事務傳播特性 、dao模板等等

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">   
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />   
    <property name="url" value="jdbc:mysql://localhost:3306/phonesell" />   
    <property name="username" value="root" />   
    <property name="password" value="root" />   
</bean>   
<bean id="sessionFactory"  
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">   
    <property name="dataSource">   
        <ref bean="dataSource" />   
    </property>   
    <property name="hibernateProperties">   
        <props>   
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>   
            <prop key="hibernate.show_sql">true</prop>   
        </props>   
    </property>   
    <!-- 實體類資源映射 -->   
    <property name="mappingDirectoryLocations">   
        <list>   
            <value>classpath:/com/silent/cn/model/</value>   
        </list>   
    </property>   
</bean>   
<!-- 配置事務管理器 -->   
<bean id="transactionManager"  
class="org.springframework.orm.hibernate3.HibernateTransactionManager">   
    <property name="sessionFactory">   
        <ref bean="sessionFactory" />   
    </property>   
</bean>   
<!-- 配置事務傳播特性 -->   
<tx:advice id="txAdvice" transaction-manager="transactionManager">   
    <tx:attributes>   
        <tx:method name="save*" propagation="REQUIRED" />   
        <tx:method name="delete*" propagation="REQUIRED" />   
        <tx:method name="update*" propagation="REQUIRED" />   
        <tx:method name="do*" propagation="REQUIRED" />   
        <tx:method name="*" read-only="false" />   
    </tx:attributes>   
</tx:advice>   
<!-- 哪些類的哪些方法參與事務 -->   
<aop:config>   
    <aop:pointcut id="allManagerMethod"  
        expression="execution(* com.silent.cn.dao.impl.*.*(..))" />   
    <aop:advisor pointcut-ref="allManagerMethod" advice-ref="txAdvice" />   
</aop:config>   
<!-- dao模板(所有dao都將使用此模板) -->   
<bean id="daoTemplate" abstract="true">   
    <property name="sessionFactory" ref="sessionFactory"></property>   
</bean>   
<bean id="jdbcTemplate" abstract="true">   
    <property name="dataSource" ref="dataSource"></property>   
</bean>   
<!--WebService配置-->   
<import resource="applicationContext-webservice.xml" />   
<import resource="applicationContext-dao.xml" />   
</beans>  

7、WebService接口配置
  這里設定的address就是該webservice的實際地址了:

<!--   
配置WebService接口 http://localhost:8080/PhoneSell/ws/clientService?wsdl   
    -->   
<jaxws:endpointid="clientServiceEndpoint"address="/clientService" implementorClass="com.silent.cn.ws.MobileClientService">   
        <jaxws:implementor>   
            <bean id="clientService" class="com.silent.cn.ws.impl.MobileClientServiceImpl">   
                <property name="userLoginDao" ref="userLoginDao" />   
            </bean>   
        </jaxws:implementor>   
    </jaxws:endpoint>

8、配置web.xml
  在web里添加下面的語句:

<servlet>   
   <servlet-name>CXFServlet</servlet-name>   
   <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>   
</servlet>   
<servlet-mapping>   
    <servlet-name>CXFServlet</servlet-name>   
    <url-pattern>/ws/*</url-pattern>   
</servlet-mapping>

9、WebService接口測試
  最好安裝soapUI  pro這個軟件,SOAPUI這個工具功能非常強大,是作為測試工具來用的,它既可以模擬客戶端,也可以模擬服務端,可以根據描述文件很容易就生成的模擬的服務端和服務端,還可以有測試用例管理,負荷測試等,對通訊的中間過程也可以全程監控。
  SOAPUI是一個免費的工具,而SOAPUI PRO是收費的,功能更強大。詳細的SOAPUI用法可以參考下面的網址:http://xzhoumin.blog.163.com/blog/static/40881136201231955833137/

Client端

1、
  首先,我們要獲取Web端在Tomcat發布成功之后的接口地址與方法地址,如果是模擬器的話,其IP地址必須是10.0.2.2;如果是真機,那么電腦和真機都要用wifi連接到同一個網段下,而且IP地址就是電腦的實際IP地址,這樣手機才能從Tomcat上獲取數據,代碼如下:

//WebService接口地址   
public static String NAME_SPACE_SALE = "http://ws.cn.silent.com/";   
// 網址(如果是模擬器額話,需要把IP地址<192.168.1.***:8080>換成10.0.2.2:8080)   
public static String NAME_SPACE = "http://10.0.2.2:8080/PhoneSell/";   
// 連接地址(WebService的方法地址)   
public static String END_POINT_SALE = NAME_SPACE + "ws/clientService";  

2、
  然后,我們要寫一個通用的WebService接口請求方法,此方法是通用的,只要是通過ksoap與web端交互的都可以使用該方法,代碼如下:

public static SoapObject common(String methodName, HashMap<String, Object> map, String nameSpace, String endPoint) {   
         String soapAction = nameSpace + methodName;   
         // 指定WebService的命名空間和調用的方法名   
        SoapObject rpc = new SoapObject(nameSpace, methodName);   
        // 設置需調用WebService接口需要傳入的參數   
        if (null != map && map.size() > 0) {   
            Object[] key = map.keySet().toArray();   
            for (int i = 0; i < key.length; i++) {   
                rpc.addProperty(key<i>.toString(), map.get(key<i>));   
            }   
        }   
        // 生成調用WebService方法的SOAP請求信息,並指定SOAP的版本   
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);   
        envelope.bodyOut = rpc;   
        // 設置是否調用的是dotNet開發的WebService   
        envelope.dotNet = false;   
        // 設置連接超時時間為20秒   
    HttpTransportSE transport = new HttpTransportSE(endPoint, timeout);   
        try {   
            // 調用WebService   
            transport.call(soapAction, envelope);   
        } catch (IOException e) {   
            e.printStackTrace();   
        } catch (XmlPullParserException e) {   
            e.printStackTrace();   
        }   
        // 獲取返回的數據   
        SoapObject soapObject = (SoapObject) envelope.bodyIn;   
        return soapObject;   
    }   
}  

3、
  接着,就是寫各種webservice數據交互的方法了,基本上都是封裝成一個json對象再以字符串形式傳遞,這里是用戶登錄方法:

public static String verifyUser(Context context, String userPhone, String userPwd)      {   
        // 設置調用接口需要傳遞的參數名稱、值   
        HashMap<String, Object> paramMap = new HashMap<String, Object>();   
        paramMap.put("opPhone", userPhone);   
        paramMap.put("loginPwd", userPwd);   
        try {   
            // 調用接口   
            SoapObject soapObject = common("userLogin", paramMap, NAME_SPACE_SALE, END_POINT_SALE);   
            return soapObject.getProperty(0).toString();   
        } catch (Exception e) {   
            return null;   
        }   
    }

:hashmap里的key就是web端webservice接口里的@WebParam(name = "opPhone"),此字符串一定要匹配。

 

 


免責聲明!

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



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