使用Java通过Nginx反向代理服务器操作PostgreSQL数据库

最近在做一个项目,需要将Android App和服务器上的PostgreSQL进行连接,但是Android Studio不能够直接通过JDBC进行连接,所以选择通过Nginx作为中间服务器对PostgreSQL进行操作,这篇文章紧接Nginx以及ngx_postgres安装以及配置

更新:后来发现使用nginx的效果并不好,更好的方法可能是使用PostgREST+Nginx反向代理对数据库进行操作,因为PostgREST直接提供了处理PostgreSQL数据库的RESTful接口,更加方便。详细教程可以去网上搜一搜。

我们的数据库中的数据主要存储的是Android app中的使用信息,定义app_usage_info表拥有以下字段

day date,
app_name text,
package_name text,
app_usage_time interval,
app_usage_count integer

首先,我们需要对nginx的配置文件进行配置,nginx的配置文件一般是在nginx的安装目录下的/conf/nginx.conf,比如在我的系统中就是/opt/nginx/conf/nginx.conf,打开配置文件我们就可以进行配置。Nginx的配置文件结构可以在Nginx 配置详解 | 菜鸟教程 (runoob.com)中简单学习一下。

worker_processes 1;

events {
    worker_connections  1024;
}


http {
        include         mime.types;
        default_type    application/octet-stream;
    	sendfile        on;
        keepalive_timeout  65;

    upstream database {
        postgres_server 172.29.118.77 dbname=postgres user=postgres password=511668;
    }

    server {

        charset utf-8;
        listen 80;
        server_name localhost;

        location /insert {
            postgres_pass database;
            rds_json on;
            postgres_query "insert into app_usage_info VALUES ('$arg_day', '$arg_app_name', '$arg_package_name', '$arg_time', '$arg_count');
            postgres_rewrite no_changes 410;
        }

        location /query-all {
            postgres_pass database;
            rds_json on;
            postgres_query "select * from app_usage_info";
        }

        location /query-day {
            postgres_pass database;
            rds_json on;

            postgres_query      HEAD GET "SELECT * FROM app_usage_info WHERE day='$arg_day'";
            postgres_rewrite    HEAD GET no_rows 410;


        }

        location / {
               root   html;
               index  index.html index.htm;
        }
	   	# 错误页面 
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
                root    html;
        }

这是我的一个简单的配置,为了对数据库做不同的处理,我定义了insert页面,query-day(查询指定天数)页面,query-all(查询整个表)页面。这里面还涉及到关于Nginx中变量的使用,可以看这一篇Nginx变量使用方法详解 - 简书 (jianshu.com),讲得还是非常的清楚的。这里我使用了$arg_XXX变量,就可以直接通过http网址进行参数的设定了,也就很方便的可以通过JAVA的Http请求执行对应的数据库操作。

下面是用来实现Http请求的Java类,参考这篇文章实现 JAVA发送HTTP请求的四种方式总结_java_脚本之家 (jb51.net)

public class HttpUtils {

    private String uri;

    public HttpUtils(String hostname) {
        uri = hostname;
    }

    public static void sendRequest(String url, Callback callback) {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url(url).build();
        client.newCall(request).enqueue(callback);
    }


    public static String sendRequestWithHttpURL(String urlParam,String requestType) {

        HttpURLConnection con = null;

        BufferedReader buffer = null;
        StringBuffer resultBuffer = null;

        try {
            URL url = new URL(urlParam);
            //得到连接对象
            con = (HttpURLConnection) url.openConnection();
            //设置请求类型
            con.setRequestMethod(requestType);
            //设置请求需要返回的数据类型和字符集类型
            con.setRequestProperty("Content-Type", "application/json;charset=utf-8");
            //允许写出
            con.setDoOutput(true);
            //允许读入
            con.setDoInput(true);
            //不使用缓存
            con.setUseCaches(false);
            //得到响应码
            int responseCode = con.getResponseCode();
            System.out.println(urlParam + ": " + responseCode);
            if(responseCode == HttpURLConnection.HTTP_OK){
                //得到响应流
                InputStream inputStream = con.getInputStream();
                //将响应流转换成字符串
                resultBuffer = new StringBuffer();
                String line;
                buffer = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
                while ((line = buffer.readLine()) != null) {
                    resultBuffer.append(line);
                }
                return resultBuffer.toString();
            }
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "Failed!";
    }

    public void insert(String day, String app_name, String package_name, String interval, int count) {
        String responseData = sendRequestWithHttpURL(uri+"/insert?"+"day="+day+"&app_name="+app_name+"&package_name="+package_name+"&time="+interval+"&count="+count, "POST");
        System.out.println(responseData);
    }

    public void queryAll() {
        String responseData = sendRequestWithHttpURL(uri+"/query-all", "GET");
        System.out.println(responseData);
    }

    public void queryDay(String day) {
        String responseData = sendRequestWithHttpURL(uri+"/query-day?day="+day, "GET");
        System.out.println(responseData);
    }
}

main函数所在类

public static void main(String[] args) {
        String url ="your host address";
        HttpUtils http = new HttpUtils(url);
        http.queryAll();
        http.queryDay("2021-07-07");
        http.insert("2021-07-08", "华为桌面", "com.huawei.android.launcher",
                "00:18:41", 63);
}

程序运行结果
在这里插入图片描述

参考资料

[1] Nginx 配置详解 | 菜鸟教程 (runoob.com)

[2] Nginx变量使用方法详解 - 简书 (jianshu.com)

[3] [JAVA发送HTTP请求的四种方式总结_java_脚本之家 (jb51.net)](https://www.jb51.net/article/206762.htm#:~:text=JAVA发送HTTP请求的四种方式总结 1 HttpURLConnection 2,URLConnection 3 HttpClient 4 Socket)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值