Android与ReactNative下使用OData进行数据访问

来源:互联网 发布:蓝光播放器网络排名 编辑:程序博客网 时间:2024/05/19 15:40

Android与ReactNative下使用OData进行数据访问

1.OData定义

    Open Data Protocol (开放数据协议,OData)是用来查询和更新数据的一种Web协议,其提供了把存在于应用程序中的数据暴露出来的方式。OData运用且构建于很多 Web技术之上,比如HTTP、Atom Publishing Protocol(AtomPub)和JSON,提供了从各种应用程序、服务和存储库中访问信息的能力。OData被用来从各种数据源中暴露和访问信息, 这些数据源包括但不限于:关系数据库、文件系统、内容管理系统和传统Web站点。

2.Android下使用OData

1.创建Android应用
2.封装一个OkHttp请求的工具类
    封装一个Http请求是每个网络请求必经的一个步骤,在Android4.4版本之后开始谷歌开始普及OkHttp,创建Android应用后,工程自动导入Okhttp的jar包。
代码如下
public class OkHttpUtil {    public final OkHttpClient client = new OkHttpClient.Builder()            .readTimeout(30, TimeUnit.SECONDS)            .connectTimeout(10, TimeUnit.SECONDS)            .writeTimeout(60, TimeUnit.SECONDS)            .build(); //设置各种超时时间    public static final MediaType JSON            = MediaType.parse("application/json; charset=utf-8");    /**     * OKHttp get请求     * @param url     * @return     */    public Response get(String url, Request.Builder builder){        builder.url(url);        final Request request = builder.build();        Response response = null;        try {            response = client.newCall(request).execute();            System.out.println("===="+response.code());        } catch (IOException e) {            e.printStackTrace();        }        return response;    }    /**     * OKHttp post 请求     * @param url     * @param json     * @return     */    public Response post (String url, String json){        RequestBody requestBody = RequestBody.create(JSON, json);        //创建一个请求对象        Request request = new Request.Builder()                .url(url)                .header("Content-Type","application/json")                .post(requestBody)                .build();        Response response = null;        try {            response = client.newCall(request).execute();        } catch (IOException e) {            e.printStackTrace();        }        return response;    }    /**     * OkHttp put请求     * @param uploadUrl     * @return     * @throws IOException     */    public Response put(Request.Builder builder, String uploadUrl, String json) throws IOException {        builder.url(uploadUrl);        RequestBody body = RequestBody.create(JSON, json);        builder.put(body);        final Request request = builder.build();        Response response = client.newCall(request).execute();        return response;    }    /**     * OkHttp delete请求     * @param url     * @return     * @throws IOException     */    public  Response delete( String url) throws IOException {        Request request = new Request.Builder()                .url(url)                .delete()                .header("Content-Type","application/json")                .build();        Response response = null;        try {            response = client.newCall(request).execute();        } catch (IOException e) {            e.printStackTrace();        }        return response;    }}
3.创建一个请求接口管理类
接口统一管理类本身不难理解,该项目是测试Demo,所用的接口地址是在OData官网上找到的,上面还有一些其他的操作接口,OData官网测试接口地址:http://www.odata.org/odata-services/打开后是这样样子

由于是测试地址,那么增删改查操作会对数据产生影响,OData要求每个用户获取测试所用的key,获取key的具体操作如下:




OData语法规则请参考:https://blogs.msdn.microsoft.com/alexj/2009/11/18/tip-44-how-to-navigate-an-odata-compliant-service/

接口管理类代码如下:
public class UrlService {    //查询所有    public String GetAllURL = "http://services.odata.org/TripPinRESTierService/(S(ttgxui24dxjyngne0nkqgyqi))/People";    //条件查询    public String GetOneByKey = "http://services.odata.org/TripPinRESTierService/(S(ttgxui24dxjyngne0nkqgyqi))/People?$filter=FirstName eq 'Lewis'";    //查询某一个属性    public String GetOneAtt = "http://services.odata.org/TripPinRESTierService/Airports('KSFO')/Name ";    //添加    public String ADDURL = "http://services.odata.org/TripPinRESTierService/(S(ttgxui24dxjyngne0nkqgyqi))/People";    //删除    public String DeleteURL = "http://services.odata.org/TripPinRESTierService/(S(ttgxui24dxjyngne0nkqgyqi))/People('aaa')";    //更新    public String PutURL = "http://services.odata.org/TripPinRESTierService/(S(ttgxui24dxjyngne0nkqgyqi))/People('aaa')";}
4.创建一个请求管理类
创建该管理的目的是为了统一处理请求头及响应(本项目并没有用到),因为之前的项目里有一些请求的批处理操作,所以封装了这么一个管理类,就本项目而言可以不用。
代码如下:
public class ApiService {    OkHttpUtil okHttpUtil = new OkHttpUtil();    public Response read(String url) throws IOException {        Request.Builder builder = new Request.Builder();        requestHeaders(builder);        return okHttpUtil.get(url,builder);    }    public Response create(String url, String json) throws IOException {        return okHttpUtil.post(url,json);    }    public Response update(String uploadUrl, String json) throws IOException {        Request.Builder builder = new Request.Builder();        requestHeaders(builder);        return okHttpUtil.put(builder,uploadUrl,json);    }    public Response delete(String url) throws IOException {        return okHttpUtil.delete(url);    }    public String handleResponse(Response response) throws IOException {        if (response.code()==200){            System.out.println("Succeed"+response.body().string());            return response.body().string();        }else {            return "";        }    }    public Request.Builder requestHeaders(Request.Builder builder){        builder.addHeader("Content-Type", "application/json");        return builder;    }}
5.创建一个MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener {    public Button btnQueryByKey,btnPost,btnPut,btnDelete,btnQueryAll,btnQueryOneAttribute;    public Response response;    public UrlService urlService = new UrlService();    public  String url;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        init();    }    private void init() {        btnPost = (Button) findViewById(R.id.btnPost);        btnPut = (Button) findViewById(R.id.btnPut);        btnDelete = (Button) findViewById(R.id.btnDelete);        btnQueryAll = (Button) findViewById(R.id.btnQueryAll);        btnQueryByKey = (Button) findViewById(R.id.btnQueryByKey);        btnQueryOneAttribute = (Button) findViewById(R.id.btnQueryOneAttribute);        btnQueryOneAttribute.setOnClickListener(this);        btnQueryAll.setOnClickListener(this);        btnQueryByKey.setOnClickListener(this);        btnPost.setOnClickListener(this);        btnPut.setOnClickListener(this);        btnDelete.setOnClickListener(this);    }    @Override    public void onClick(View view) {        switch (view.getId()){            case R.id.btnQueryOneAttribute:                url = urlService.GetOneAtt;                GetRequest getOneAttributeRequest = new GetRequest(MainActivity.this,url);                getOneAttributeRequest.execute();                break;            case R.id.btnQueryAll:                url = urlService.GetAllURL;                GetRequest getAllRequest = new GetRequest(MainActivity.this,url);                getAllRequest.execute();                break;            case R.id.btnQueryByKey :                url = urlService.GetOneByKey;                GetRequest getByKeyRequest = new GetRequest(MainActivity.this,url);                getByKeyRequest.execute();                break;            case R.id.btnPost:                url = urlService.ADDURL;                PostRequest postRequest = new PostRequest(MainActivity.this,url);                postRequest.execute();                break;            case R.id.btnPut:                url = urlService.PutURL;                PutRequest putRequest = new PutRequest(MainActivity.this,url);                putRequest.execute();                break;            case R.id.btnDelete:                url = urlService.DeleteURL;                DeleteRequest deleteRequest = new DeleteRequest(MainActivity.this,url);                deleteRequest.execute();                break;        }    }}
6.创建展示结果的Activity
public class ResultActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_result);        init();    }    private void init() {        Intent intent = getIntent();        String value = intent.getStringExtra("testIntent");        TextView tvBack = (TextView) findViewById(R.id.tvBack);        tvBack.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                ResultActivity.this.finish();            }        });        TextView tvResult = (TextView) findViewById(R.id.tvResult);        tvResult.setText(value);    }}
7.结果展示


3.ReactNative下使用OData

1.创建ReactNative应用
2.封装Fetch请求工具类
var HTTPUtil = {};  import {    ToastAndroid} from 'react-native';/**  * 基于 fetch 封装的 GET请求  * @param url  * @param params {}  * @param headers  * @returns {Promise}  */  HTTPUtil.get = function(url) {       return new Promise(        function (resolve, reject) {          fetch(url, {              method: 'GET',            }).then(              (response) => {                    return response;             })          .then((response) => {                resolve(response);            })            .catch((err)=> {              reject({status:-1});            })      })  }  /**  * 基于 fetch 封装的 POST请求  FormData 表单数据  * @param url  * @param formData    * @param headers  * @returns {Promise}  */  HTTPUtil.post = function(url, formData) {      return new Promise(function (resolve, reject) {        fetch(url, {              method: 'POST',              headers: {              'Accept': 'application/json',              'Content-Type': 'application/json'            },            body: JSON.stringify(formData)           })            .then((response) => {                  return response;              })            .then((response) => {                resolve(response);            })            .catch((err)=> {                reject({status:-1});            })      })  }/**  * 基于 fetch 封装的 POST请求 Json文件数据  * @param url  * @param data    * @param callback  * @returns {Promise}  */  HTTPUtil.postJson = function(url, data) {    var fetchOptions = {      method: 'POST',      headers: {        'Accept': 'application/json',        'Content-Type': 'application/json'      },      body: JSON.stringify(data)    };  fetch(url, fetchOptions)    .then((response) =>{          return response;         }).done();  }  /**  * 基于 fetch 封装的 PUT请求 Json文件数据  * @param url  * @param data    * @param callback  * @returns {Promise}  */  HTTPUtil.putJson = function(url, data) {    return new Promise(function (resolve, reject) {        fetch(url, {            method: 'PUT',          headers: {            'Accept': 'application/json',            'content-Type': 'application/json'          },          body: JSON.stringify(data)        }) .then((response) => {                 return response;              })            .then((response) => {              resolve(response);            })            .catch((err)=> {                reject({status:-1});            })      })}   /**  * 基于 fetch 封装的 DELETE请求  * @param url  * @param params {}  * @returns {Promise}  */  HTTPUtil.delete = function(url) {      return new Promise(function (resolve, reject) {        fetch(url, {              method: 'DELETE'           }).then((response) => {            ToastAndroid.show("=1!="+ response.status, ToastAndroid.SHORT);                    return response;             })            .then((response) => {                resolve(response);            })            .catch((err)=> {              reject({status:-1});            })      })  }  export default HTTPUtil;  
3.创建请求管理类RequestManager
let RequestManager = {};  import {    ToastAndroid,    AsyncStorage} from 'react-native';import HttpUtil from './HttpUtil';import RequsetURL from './RequsetURL';import AsyncStorageUtil from '../AsyncStorageUtil';import MainView from '../../View/MainView';let json = {    "UserName":"fang",    "FirstName":"Lewis",    "LastName":"Black",    "Emails":[        "lewisblack@example.com"    ],    "AddressInfo": [        {          "Address": "187 Suffolk Ln.",          "City": {            "Name": "Boise",            "CountryRegion": "United States",            "Region": "ID"          }        }    ]};let jsonUpdata = {            "FirstName": "Gao",             "LastName": "Xiuyang"            }RequestManager.state;RequestManager.getAll = function() {         return  HttpUtil.get(RequsetURL.GetAllURL).then(RequestManager.handleResponse);}  RequestManager.getByKey = function() {     return  HttpUtil.get(RequsetURL.GetBuKey).then(RequestManager.handleResponse); };RequestManager.postCreat = function() {      return HttpUtil.post(RequsetURL.PostCreat,json).then(RequestManager.handleResponse);}RequestManager.putUpdata = function() {      return HttpUtil.putJson(RequsetURL.PutUpdata,jsonUpdata).then(RequestManager.handleResponse);}RequestManager.delete = function() {      return HttpUtil.delete(RequsetURL.DeleteURL).then(RequestManager.handleResponse);}RequestManager.handleResponse= function(response) {    console.log(response.url, response.statusText);    if (response.ok) {            if(response.status==204){                AsyncStorageUtil.set('Content', "成功!!!!");             }else{                response.text().then(function(text){                    AsyncStorageUtil.set('Content', text);                   });              }        return response;     }else {        console.error('An error occurred', response);    }}export default RequestManager;  
4.创建URL管理类
var RequsetURL = {};   RequsetURL.GetAllURL = 'http://services.odata.org/TripPinRESTierService/(S(ttgxui24dxjyngne0nkqgyqi))/People'; RequsetURL.GetBuKey = "http://services.odata.org/TripPinRESTierService/(S(ttgxui24dxjyngne0nkqgyqi))/People?$filter=FirstName eq 'Lewis'"; RequsetURL.PostCreat = 'http://services.odata.org/TripPinRESTierService/(S(ttgxui24dxjyngne0nkqgyqi))/People'; RequsetURL.PutUpdata = "http://services.odata.org/TripPinRESTierService/(S(ttgxui24dxjyngne0nkqgyqi))/People('fang')" RequsetURL.DeleteURL = "http://services.odata.org/TripPinRESTierService/(S(ttgxui24dxjyngne0nkqgyqi))/People('fang')"export default RequsetURL;  
5.创建AsyncStorageUtil进行本地存储
var AsyncStorageUtil = {};  import {    AsyncStorage,    ToastAndroid} from 'react-native';AsyncStorageUtil.set = function(key, value){    AsyncStorage.setItem(key, value, () => {        AsyncStorage.mergeItem(key, value, () => {            AsyncStorage.getItem(key, (err, result) => {                 if(result!==null){                  return true;                }else{                   return false;                }            });        });    });}AsyncStorageUtil.get = function(key){     Result=''     AsyncStorage.getItem(key, (err, result) => {        return result      });}export default AsyncStorageUtil;
6.创建MainView
'use strict';import React,{Component} from 'react'import {    AppRegistry,    StyleSheet,    Text,    View,    Image,    TextInput,    Alert,    Dimensions,    AsyncStorage,    Platform,    NativeModules,    ToastAndroid,    TouchableOpacity} from 'react-native';import AsyncStorageUtil from '../Utils/AsyncStorageUtil';import RequestManager from '../Utils/RequestApiUtils/RequestManager';import HttpUtil from '../Utils/RequestApiUtils/HttpUtil';import RequsetURL from '../Utils/RequestApiUtils/RequsetURL';import ApiSevice from '../Utils/RequestApiUtils/ApiSevice';import Result from './ResultView';export default class page1 extends React.Component {    constructor(props) {        super(props);             this.state = {          content:""            };    }    getByKey(){         let thiz = this;        RequestManager.getByKey().then(x => {            if(x.ok){                thiz.props.navigator.push({                    component:Result                });             }else{                ToastAndroid.show('请重试', ToastAndroid.SHORT);             }        });     }    getAll(){        let thiz = this;         RequestManager.getAll().then(x => {            if(x.ok){                thiz.props.navigator.push({                    component:Result                });             }else{                ToastAndroid.show('请重试', ToastAndroid.SHORT);             }        });        }    postCreat(){        let thiz = this;         RequestManager.postCreat().then(x => {            if(x.ok){                thiz.props.navigator.push({                    component:Result                });             }else{                ToastAndroid.show('请重试', ToastAndroid.SHORT);             }        });      }    putUpdata(){        let thiz = this;         RequestManager.putUpdata().then(x => {            if(x.ok){                thiz.props.navigator.push({                    component:Result                });             }else{                ToastAndroid.show('请重试', ToastAndroid.SHORT);             }        });     }    delete(){        let thiz = this;         RequestManager.delete().then(x => {            if(x.ok){                thiz.props.navigator.push({                    component:Result                });             }else{                ToastAndroid.show('请重试', ToastAndroid.SHORT);             }        });     }    render() {        return (           <View style = {styles.containers}>                <TouchableOpacity style={styles.btn} onPress={this.postCreat.bind(this)} >                    <Text style={styles.btnText}>Post(增加)</Text>                </TouchableOpacity>                <TouchableOpacity style={styles.btn} onPress={this.getAll.bind(this)} >                    <Text style={styles.btnText}>Get(查询全部)</Text>                </TouchableOpacity>                <TouchableOpacity style={styles.btn} onPress={this.getByKey.bind(this)} >                    <Text style={styles.btnText}>Get(条件查询)</Text>                </TouchableOpacity>                <TouchableOpacity style={styles.btn} onPress={this.putUpdata.bind(this)} >                    <Text style={styles.btnText}>Put(修改)</Text>                </TouchableOpacity>                <TouchableOpacity style={styles.btn} onPress={this.delete.bind(this)} >                    <Text style={styles.btnText}>Delete(删除)</Text>                </TouchableOpacity>           </View>        )    }}let styles = StyleSheet.create({   containers: {       backgroundColor: '#f1f1f1',       height: Dimensions.get('window').height   },   btn: {        backgroundColor: "#0066cc",        height: 40,        borderRadius: 4,        marginLeft: 20,        marginRight: 20,        marginTop: 20,           justifyContent: 'center',    },    btnText: {        textAlign: 'center',        color: '#fff',        fontSize: 16    }})  
7.创建ResultView用于展示结果
'use strict';import React,{Component} from 'react'import {    AppRegistry,    StyleSheet,    Text,    View,    Image,    TextInput,    Alert,    Dimensions,    AsyncStorage,    Platform,    NativeModules,    ToastAndroid,    ScrollView,    TouchableOpacity} from 'react-native';import AsyncStorageUtil from '../Utils/AsyncStorageUtil';import RequestManager from '../Utils/RequestApiUtils/RequestManager';export default class page1 extends React.Component {    constructor(props) {        super(props);        AsyncStorage.getItem('Content', (err, result) => {                   this.setState({content:result})                        AsyncStorage.mergeItem('Content', result);                 });        this.state = {          content:""        };    }    onBack(){        const { navigator } = this.props;        if(navigator) {            navigator.pop();        }    }    render() {        return (           <View style = {styles.containers}>                <View style = {styles.titleView}>                    <TouchableOpacity onPress={this.onBack.bind(this)} >                        <Text style={styles.loginBtn}>返回</Text>                    </TouchableOpacity>                </View>                <ScrollView style={styles.scrollView}>                    <Text style = {styles.textView}>                        {this.state.content}                    </Text>                </ScrollView>           </View>        )    }}let styles = StyleSheet.create({    scrollView: {        height: Dimensions.get('window').height-50,    },   containers: {       backgroundColor: '#f1f1f1',       height: Dimensions.get('window').height-25,   },   titleView: {       backgroundColor: '#4799e5',       height: 45,       flexDirection: 'row',        alignItems: 'center'    },   textView:{       margin: 20,       color: '#666666',       fontSize: 14   },   loginBtn: {       fontSize: 16,       marginLeft: 20,       color: '#fff',       alignSelf: 'flex-end'   },})
8.结果展示


4.源码地址

1.PostMan(接口测试工具)

http://download.csdn.net/detail/lanye11/9685964

2.Android下使用OData进行数据访问源码

http://download.csdn.net/detail/lanye11/9689924

3.ReactNative下使用OData进行数据访问源码

http://download.csdn.net/detail/lanye11/9689929

2 0
原创粉丝点击