本次任务要求:结合之前的数据可视化,数据爬取,配合服务器实现外网访问,并做出一个手机app实现访问数据。!!!【由于写该博客时插入图片出现问题,因此效果无法展示,部分地方会进行文字描述】
思路分析:数据可视化和数据爬取沿用前两周任务代码即可,问题在于服务器搭建和app的制作。服务器我在阿里云以学生价租用了一个, app使用Android Studio制作即可,需要解决的问题是Android访问远程MySQL数据库。
关于使用服务器实现外网访问Web项目:要实现外网访问Web项目,需要在服务器上搭建jdk和Tomcat,将本机上相应Web项目打包成war文件后,复制到远程服务器上Tomcat中webapps文件夹下。随后要在服务器上配置信息:找到服务器实例的安全组,在配置规则里加入端口8080/8080的自定义TCP,入方向和出方向我都设置了一次。在一切配置完之后,即可通过【http://+你的公网ip地址+/项目名/项目名下xx.html或xx.jsp】格式外网访问你的项目。
要实现实时更新数据信息,数据爬取入库和读取MySQL数据库操作需要在远程服务器上实现,因此要在远程服务器上下载MySQL和Python相关应用,我使用的是Navicat for MySQL配合MySQL数据库进行使用。在配置时会出现连接数据库失败的情况,解决方法如下:在服务器实例安全组的配置规则中加入端口3306/3306(Navicat 里可以从连接属性上看端口)的自定义TCP。设置后数据库连接成功。python爬取操作没有变化。使用java实现读取数据并将其可视化操作也没有变化,由于你将其打包成war文件并复制进远程桌面的Tomcat的webapps文件夹下,它所访问的数据库不是本地数据库,而是远程服务器下的数据库。
app搭建:这里是重头戏,一般的搜索,跳转页面之类的不用再说,问题在于app访问远程服务器的MySQL数据库,从而拿到数据显示。一开始我在思考怎么能连接上数据库,以前写的记账本连接的是SQLite数据库,是不一样的。后来查阅发现可以使用HttpURLConnection访问java文件的Servlet,从中拿到数据即可(因为实现可视化需要在后台遍历查询之后通过Servlet将值传到前端),代码如下:
1 package com.example.yiqing;
2
3 import androidx.appcompat.app.AppCompatActivity;
4
5 import android.content.Intent;
6 import android.os.Bundle;
7 import android.os.Handler;
8 import android.os.Message;
9 import android.text.method.ScrollingMovementMethod;
10 import android.view.View;
11 import android.widget.Button;
12 import android.widget.TextView;
13
14 import org.json.JSONArray;
15 import org.json.JSONObject;
16
17 import java.io.BufferedReader;
18 import java.io.DataOutputStream;
19 import java.io.IOException;
20 import java.io.InputStreamReader;
21 import java.io.OutputStream;
22 import java.net.HttpURLConnection;
23 import java.net.URL;
24 import java.net.URLEncoder;
25
26 public class Watch extends AppCompatActivity {
27 private TextView show;
28 private Button see;
29
30 //利用Handler实现更改页面
31 private Handler handler=new Handler(){
32 public void handleMessage(android.os.Message msg){
33 Bundle bundle=new Bundle();
34 bundle=msg.getData();
35 String ans=bundle.getString("result");
36 if(ans!=null){
37 show.setText(ans);
38 }
39 }
40 };
41 @Override
42 protected void onCreate(Bundle savedInstanceState) {
43 super.onCreate(savedInstanceState);
44 setContentView(R.layout.activity_watch);
45 show=(TextView)findViewById(R.id.show);
46 show.setMovementMethod(ScrollingMovementMethod.getInstance());
47 see=(Button)findViewById(R.id.see);
48
49 see.setOnClickListener(new View.OnClickListener(){
50 @Override
51 public void onClick(View view){
52 //写下要访问的servlet路径
53 final String path="http://47.98.228.220:8080/PaQu/ChartServlet";
54 //使用HttpURLConnection需要子线程
55 new Thread(new Runnable() {
56 @Override
57 public void run() {
58 Intent intentdata=getIntent();
59 //从上一个页面拿到输入的日期数据
60 String date=intentdata.getStringExtra("date");
61 String msg="";
62 HttpURLConnection conn=null;
63 try{
64 URL url=new URL(path);
65 conn=(HttpURLConnection)url.openConnection();
66 //设置post格式,这里格式要跟servlet里一致
67 conn.setRequestMethod("POST");
68 //设置超时时间
69 conn.setConnectTimeout(5000);
70 conn.setReadTimeout(5000);
71 //post格式不能用缓存
72 conn.setUseCaches(false);
73 conn.setDoInput(true);
74 String data="date="+date;
75 //将传给servlet的数据写入传输
76 OutputStream out=conn.getOutputStream();
77 //这里注意要更改传输数据的格式,getBytes()
78 out.write(data.getBytes());
79 out.flush();
80 out.close();
81 conn.connect();
82
83 //这里开始接收从servlet里传回来的数据
84 BufferedReader reader=new BufferedReader(new InputStreamReader(conn.getInputStream()));
85 String line=null;
86 //传回来的是一个JSONArray类型的数据,需要对其进行解析
87 if((line=reader.readLine())!=null){
88 //开始解析
89 JSONArray jsonArray=new JSONArray(line);
90 for(int i=0;i<jsonArray.length();i++){
91 JSONObject jsonObject=jsonArray.getJSONObject(i);
92 String province=jsonObject.getString("Province");
93 String confirmed=jsonObject.getString("Confirmed");
94 String cured=jsonObject.getString("Cured");
95 String dead=jsonObject.getString("Dead");
96 msg=msg+"省份:"+province+" 确诊:"+confirmed+" 治愈:"+cured+" 死亡:"+dead+"\n";
97 }
98 }
99 //将信息使用bundle封装,传给handler
100 Bundle bundle=new Bundle();
101 bundle.putString("result",msg);
102 Message msg1=new Message();
103 msg1.setData(bundle);
104 handler.sendMessage(msg1);
105 conn.disconnect();
106 }catch(Exception e){
107 e.printStackTrace();
108 }
109 }
110 }).start();
111 }
112 });
113 }
114
115 }
使用HttpURLConnection需要用到线程,需要注意servlet路径,还有接收servlet传回来的信息时,由于我这里是json数据,需要进行解析。子线程中为了能够进行页面更改,使用handler实现操作。
最后给出psp表格:
|
PSP2.1 |
Personal Software Process Stages |
Time/Real time |
|
Planning |
计划 |
|
|
·Estimate |
·估计这个任务需要多长时间 |
2天/1天 |
|
Development |
开发 |
|
|
·Analysis |
·需求分析(包括学习新技术) |
1天/7-8小时 |
|
·Design Spec |
·生成设计文档 |
0/0 |
|
·Design Review |
·设计复审(和同事审核设计文档) |
0/0 |
|
·Coding Standard |
·代码规范(为目前的开发制定合适的规范) |
0/0 |
|
·Design |
·具体设计 |
12小时/6小时 |
|
·Coding |
·具体编码 |
12小时/12小时 |
|
·Code Review |
·代码复审 |
0/0 |
|
·Test |
·测试(自我测试,修改代码,提交修改) |
3-6小时/3-6小时 |
|
Reporting |
报告 |
|
|
·Test Report |
·测试报告 |
1小时/1小时 |
|
·Size Measurement |
·计算工作量 |
30分钟/30分钟 |
|
·Postmortem&Process Improvement Plan |
·事后总结,并提出过程改进计划 |
20分钟/20分钟 |
|
|
合计 |
2天/1天 |
来源:https://www.cnblogs.com/20183711PYD/p/12547654.html