最近在做一个项目,需要将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)