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

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

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
SAPUI5是一个用于开发企业级Web应用程序的JavaScript库。它提供了一系列的UI控件和工具,用于构建现代、交互式和可扩展的用户界面。而OData是一种用于创建和使用可重复使用的Web API的协议。通过将SAPUI5与OData结合使用,开发者可以轻松地从远程、分布式的数据源中获取数据并将其展示在SAPUI5的应用程序中。 在SAPUI5中,我们可以使用OData模型来管理与远程OData服务的通信。OData模型提供了一系列的API,用于执行数据增删改查等操作。首先,我们需要定义一个数据模型,该模型描述了从OData服务中获取的数据的结构。然后,我们可以使用该模型创建一个绑定到OData服务的控件,例如表格、列表或图表。通过绑定,控件将自动获取并展示来自OData服务的数据。 在SAPUI5的应用程序中,我们可以通过OData模型的方法来对数据进行操作。例如,我们可以使用create()方法向远程OData服务添加新的数据记录,使用read()方法从服务中读取数据记录,使用update()方法更新数据记录,以及使用delete()方法删除数据记录。 SAPUI5还提供了一些内置的UI控件,用于对OData数据进行过滤、排序和分组等操作。开发者可以通过设置这些控件的属性和方法来实现在应用程序中对数据进行筛选、排序和分组的功能。 总之,SAPUI5和OData是一个非常强大的组合,它们使开发者能够轻松地构建现代化的企业级Web应用程序,并与远程的数据进行交互。通过使用SAPUI5的OData模型和相关的API,开发者可以快速地获取、处理和展示来自远程数据源的数据

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值