移动端与Web端疫情数据展示

1、题目要求

  

2、整体思想

  首先是在前两阶段已经完成的echarts可视化、利用Jsoup爬取疫情数据基础上来进行调用与完善。大致思想是在Android Studio上完成交互去调用ecplise中的Servlet,我新建了两个Servlet为PaquServlet、SearchServlet分别用来接受进行移动端的请求,与Web端的YqServlet分开来,当然也可以不新建Servlet直接调用Web端的YqServlet也是可以的。PaquServlet就是接收到移动端的调用之后开始执行,爬取疫情数据。SearchServlet当接收到移动端的请求调用后开始执行查找功能,这里我分为了两个方法,一个用来查找国内疫情数据,另一个用来查找海外的数据。而国内与海外都存放在同一个数据库表中,所以我又在数据库表中添加了一个Kind的栏位,里面的值为1或2,爬取数据的时候,国内与海外的数据分开爬取,国内的数据Kind等于1,海外的数据Kind等于2,这样查询国内或海外的数据的时候就就方便了,SearchServlet中返回的json数据在Android Studio中解析出来后,我利用的是哈希表来完成分配数据的,使用的是LinearLayout中ListView布局,由于对Android Studio的不熟悉,解析与显示数据以及布局也是在开发过程中最让我头疼的一部分了。注意:本文采用的是ecplise与Android Studio交互远程连接数据库,Android Studio上面并没有直接连取数据库

 3、代码实现

  3.1 Web端(包含前两阶段代码)

   Info.java:

package Bean;

public class Info {
    private int id;
    private String city;
    private String yisi_num;
    private String date;
    private String province;
    private String confirmed_num;
    private String cured_num;
    private String dead_num;
    private String newconfirmed_num;
    public String getNewconfirmed_num() {
        return newconfirmed_num;
    }
    public void setNewconfirmed_num(String newconfirmed_num) {
        this.newconfirmed_num = newconfirmed_num;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    public String getYisi_num() {
        return yisi_num;
    }
    public void setYisi_num(String yisi_num) {
        this.yisi_num = yisi_num;
    }
    public String getDate() {
        return date;
    }
    public void setDate(String date) {
        this.date = date;
    }
    public String getProvince() {
        return province;
    }
    public void setProvince(String province) {
        this.province = province;
    }
    public String getConfirmed_num() {
        return confirmed_num;
    }
    public void setConfirmed_num(String confirmed_num) {
        this.confirmed_num = confirmed_num;
    }
    public String getCured_num() {
        return cured_num;
    }
    public void setCured_num(String cured_num) {
        this.cured_num = cured_num;
    }
    public String getDead_num() {
        return dead_num;
    }
    public void setDead_num(String dead_num) {
        this.dead_num = dead_num;
    }

    
}

   Paqu.java(如同它的名字,用来爬取数据的)

package control;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import Dao.AddService;

 
public class Paqu {
    
    public static void main(String args[]) {
        refesh();
    }

    public static void refesh() {
        // TODO Auto-generated method stub
        String sheng="";
        String xinzeng="";
        String leiji="";
        String zhiyu="";
        String siwang="";
        String country="";
        char kind;
         String url = "https://wp.m.163.com/163/page/news/virus_report/index.html?_nw_=1&_anw_=1";
        
        int i=0;
        
        try {
            //构造一个webClient 模拟Chrome 浏览器
            WebClient webClient = new WebClient(BrowserVersion.CHROME);
            //支持JavaScript
            webClient.getOptions().setJavaScriptEnabled(true);
            webClient.getOptions().setCssEnabled(false);
            webClient.getOptions().setActiveXNative(false);
            webClient.getOptions().setCssEnabled(false);
            webClient.getOptions().setThrowExceptionOnScriptError(false);
            webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
            webClient.getOptions().setTimeout(8000);
            HtmlPage rootPage = webClient.getPage(url);
            //设置一个运行JavaScript的时间
            webClient.waitForBackgroundJavaScript(6000);
            String html = rootPage.asXml();
            Document doc = Jsoup.parse(html);
            //System.out.println(doc);
        //爬取国内各省数据
Element listdiv1 = doc.select(".wrap").first(); Elements listdiv2 = listdiv1.select(".province"); for(Element s:listdiv2) { Elements span = s.getElementsByTag("span"); Elements real_name=span.select(".item_name"); Elements real_newconfirm=span.select(".item_newconfirm"); Elements real_confirm=span.select(".item_confirm"); Elements real_dead=span.select(".item_dead"); Elements real_heal=span.select(".item_heal"); sheng=real_name.text(); xinzeng=real_newconfirm.text(); leiji=real_confirm.text(); zhiyu=real_heal.text(); siwang=real_dead.text(); System.out.println(sheng+" 新增确诊:"+xinzeng+" 累计确诊:"+leiji+" 累计治愈:"+zhiyu+" 累计死亡:"+siwang); Date currentTime=new Date(); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm"); String time = formatter.format(currentTime);//获取当前时间 kind='1';//1代表国内省份,2代表海外,为国内外分开查询做基础 AddService dao=new AddService(); dao.add("myinfo", sheng, xinzeng, leiji, zhiyu, siwang,time,kind);//将爬取到的数据添加至数据库,注意需将“myinfo”修改为你的表名 }
        //爬取海外数据 Element listdiv11
= doc.getElementById("world_block"); Elements listdiv22 =listdiv11.select(".chart_table_nation"); for(Element s:listdiv22) { Elements real_name=s.select(".chart_table_name"); Elements real_newconfirm=s.select(".chart_table_today_confirm"); Elements real_confirm=s.select(".chart_table_confirm"); Elements real_dead=s.select(".chart_table_dead"); Elements real_heal=s.select(".chart_table_heal"); country=real_name.text(); xinzeng=real_newconfirm.text(); leiji=real_confirm.text(); zhiyu=real_heal.text(); siwang=real_dead.text(); System.out.println(country+" 新增确诊:"+xinzeng+" 累计确诊:"+leiji+" 累计治愈:"+zhiyu+" 累计死亡:"+siwang); Date currentTime=new Date(); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm"); String time = formatter.format(currentTime);//获取当前时间 kind='2';//1代表国内省份,2代表海外,为国内外分开查询做基础 AddService dao=new AddService(); dao.add("myinfo", country, xinzeng, leiji, zhiyu, siwang,time,kind);//将爬取到的数据添加至数据库,注意需将“myinfo”修改为你的表名 } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); System.out.println("爬取失败"); } } }

   AddService.java(上面的Paqu.java在爬取中调用了该类,将数据添加到数据库中)

package Dao;

import java.sql.Connection;
import java.sql.Statement;

import utils.DBUtil;

public class AddService {
    public void add(String table,String sheng,String xinzeng,String leiji,String zhiyu,String dead,String time,char kind) {
        String sql = "insert into "+table+" (Province,Newconfirmed_num ,Confirmed_num,Cured_num,Dead_num,Time,Kind) values('" + sheng + "','" + xinzeng +"','" + leiji +"','" + zhiyu + "','" + dead+ "','" + time+ "','" + kind+ "')";
        System.out.println(sql);
        Connection conn = DBUtil.getConn();
        Statement state = null;
        int a = 0;
        try {
            state = conn.createStatement();
            a=state.executeUpdate(sql);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            DBUtil.close(state, conn);
        }        
    }
}

    DeleteService.java(按需删除数据库中的数据,当重新爬取更新今日数据时调用)

package Dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import utils.DBUtil;

public class DeleteService {
    public boolean delete(String table,String value)
    {
        boolean c=false;
        Connection conn=DBUtil.getConn();
        PreparedStatement state=null;
        String sql="delete from "+table+" where date(Time) =?";//date(Time)将数据库表中Time转换为只有日期的形式
        try {
            state=conn.prepareStatement(sql);
            state.setString(1,value);
            int num = state.executeUpdate();
            if(num!=0)
            {
                c= true;
            }
            state.close();
            conn.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return c;
    }
}

   Get.java(SearchServlet查询表中数据时调用并以List形式返回)

package Dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import Bean.Info;
import utils.DBUtil;

public class Get {
  //查询国内各省数据
public List<Info> listAll(String date1,String date2) { ArrayList<Info> list = new ArrayList<>(); Connection conn=DBUtil.getConn(); PreparedStatement pstmt = null; ResultSet rs = null; String sql="select * from myinfo where Kind ='1' and Time between ? and ?"; try { pstmt = conn.prepareStatement(sql); pstmt.setString(1, date1); pstmt.setString(2, date2); rs = pstmt.executeQuery(); while (rs.next()) { Info yq = new Info(); yq.setId(rs.getInt(1)); yq.setDate(rs.getString(8)); yq.setProvince(rs.getString(2)); yq.setNewconfirmed_num(rs.getString(3)); yq.setConfirmed_num(rs.getString(4)); yq.setCured_num(rs.getString(6)); yq.setDead_num(rs.getString(7)); list.add(yq); } } catch (Exception e) { e.printStackTrace(); } finally { try { conn.close(); } catch (Exception e) { e.printStackTrace(); } } return list; } //查询海外数据 public List<Info> listAll2(String date1,String date2) { ArrayList<Info> list = new ArrayList<>(); Connection conn=DBUtil.getConn(); PreparedStatement pstmt = null; ResultSet rs = null; String sql="select * from myinfo where Kind ='2' and Time between ? and ?"; try { pstmt = conn.prepareStatement(sql); pstmt.setString(1, date1); pstmt.setString(2, date2); System.out.println(sql); rs = pstmt.executeQuery(); while (rs.next()) { Info yq = new Info(); yq.setId(rs.getInt(1)); yq.setDate(rs.getString(8)); yq.setProvince(rs.getString(2)); yq.setNewconfirmed_num(rs.getString(3)); yq.setConfirmed_num(rs.getString(4)); yq.setCured_num(rs.getString(6)); yq.setDead_num(rs.getString(7)); list.add(yq); } } catch (Exception e) { e.printStackTrace(); } finally { try { conn.close(); } catch (Exception e) { e.printStackTrace(); } } return list; } }

   Select.java(查询表中是否有今日数据从而判断是否删除.....现在发现根本不需要该方法,直接删除即可,不需要判断表中有没有数据)

package Dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;


import utils.DBUtil;


public class Select {
    public boolean select(String time) {
        // TODO Auto-generated method stub
        Connection conn=DBUtil.getConn();
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        boolean b=false;
        String sql="select * from myinfo where date(Time) = ?";
        System.out.println(sql);
        try {
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, time);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                b=true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return b;
    }
}

   PaquServlet.java(这阶段新建的,专门用来接收移动端爬取请求的)

package Servlet;


import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import com.google.gson.Gson;

import Dao.DeleteService;
import control.Paqu;
import utils.DBUtil;

@WebServlet("/PaquServlet")//移动端爬取用到了该Servlet
public class PaquServlet extends HttpServlet {
 
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("request--->"+request.getRequestURL()+"===="+request.getParameterMap().toString());
        response.setContentType("text/html;charset=utf-8");
        Date currentTime=new Date();
        SimpleDateFormat formatter_date = new SimpleDateFormat("yyyy-MM-dd");
        String date=formatter_date.format(currentTime);
        DeleteService ds=new DeleteService();
        ds.delete("myinfo", date);
        Paqu pq=new Paqu();
        pq.refesh();
    }
    

}

  SearchServlet.java(也是这阶段新建的,用来接收移动端的查找请求)

package Servlet;


import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import com.google.gson.Gson;

import Bean.Info;
import Dao.DeleteService;
import Dao.Get;
import Dao.Select;
import control.Paqu;
import utils.DBUtil;

@WebServlet("/SearchServlet")//移动端用到了该Servlet
public class SearchServlet extends HttpServlet {


    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("request--->"+request.getRequestURL()+"===="+request.getParameterMap().toString());
        response.setContentType("text/html;charset=utf-8");
        String method = request.getParameter("method");
        String date1 = request.getParameter("username"); // 获取客户端传过来的参数,移动端的参数叫username与password,我没有修改,可以修改为易于理解的date1,date2,但移动端也要对应修改
        String date2 = request.getParameter("password");
        Get get=new Get();
        List<Info> list=null;
        if(method.equals("province")) {//查询中国省份疫情数据
            list = get.listAll(date1,date2); 
        }else
            if(method.equals("country")) {//查询海外疫情数据
                list = get.listAll2(date1, date2);
            }             
        request.setAttribute("list",list);
        Gson gson = new Gson();
        String json = gson.toJson(list);
        try {
            response.getWriter().println(json);
            // 将json数据传给客户端
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            response.getWriter().close(); // 关闭这个流,不然会发生错误的
        }
    }
}

   YqSearch.java(前两个阶段中Web端使用的,移动端没有调用该Servlet)

package Servlet;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.google.gson.Gson;

import Bean.Info;
import Dao.DeleteService;
import Dao.Get;
import Dao.Select;
import control.Paqu;


/**
 * Servlet implementation class SearchConfirmedServlet
 */
@WebServlet("/YqServlet")
public class YqServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    Get get=new Get();
    /**
     * @see HttpServlet#HttpServlet()
     */
    public YqServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String method = request.getParameter("method");
        if(method.equals("getAllProvince")) {
            try {
                getAllProvince(request, response);
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }else if(method.equals("getAllConfirmed")) {
            getAllConfirmed(request, response);
        }
    }
    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }
    protected void getAllProvince(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, ParseException {
        response.setCharacterEncoding("UTF-8");
        Select s=new Select();
        Date currentTime=new Date();
        SimpleDateFormat formatter_date = new SimpleDateFormat("yyyy-MM-dd");
        String date=formatter_date.format(currentTime);
        String date1 = request.getParameter("date1");
        String date2 = request.getParameter("date2");
        Date today=formatter_date.parse(date);//将现在的date转为日期,方便比较
        Date date22=formatter_date.parse(date2);//将date2转为日期,方便比较
        if(today.before(date22)) {//如果今天日期today比查询后边的date2日期早,需要用到今天的数据
            //不管数据库中有没有今天的数据,运行到这都需要重新爬取一遍,防止官方更新今日数据
            boolean b=s.select(date);//查找数据库中是否存在今天的数据.............黄色部分可删除,前面说到了,用不到查询判断表中是否有今日数据,直接删除就好,反正下面会重新爬取存到数据库
            if(b) {//如果有今日数据已存在,先删除
                DeleteService ds=new DeleteService();
                ds.delete("myinfo", date);
            }
            Paqu pq=new Paqu();//不管数据库是否存在今日数据都会爬取;如果存在,前面已经删除过了,这里的爬取就相当于更新了
            pq.refesh();
        }        
        List<Info> list = get.listAll(date1,date2);
        request.setAttribute("list",list);
        request.setAttribute("date1",date1);
        request.setAttribute("date2",date2);
        request.getRequestDispatcher("bar.jsp").forward(request, response);
    }
    
    protected void getAllConfirmed(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setCharacterEncoding("UTF-8");
        String date1 = request.getParameter("date1");
        String date2 = request.getParameter("date2");
        System.out.println(date1);
        System.out.println(date2);
        List<Info> list = get.listAll(date1,date2);
        HttpSession session = request.getSession();
        session.setAttribute("list",list);
        Gson gson = new Gson();
        String json = gson.toJson(list);
        response.getWriter().write(json);
    }
}

  DBUtil.java

package utils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class DBUtil {
    
    public static String db_url = "jdbc:mysql://localhost:3306/test?useSSL=false&characterEncoding=UTF-8&serverTimezone=GMT";//如果发布到云服务器就将localhost改为云服务器的ip
    public static String db_user = "root";
    public static String db_pass = "root";
    
    public static Connection getConn () {
        Connection conn = null;
        
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(db_url, db_user, db_pass);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return conn;
    }

    public static void close (Statement state, Connection conn) {
        if (state != null) {
            try {
                state.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    
    public static void close (ResultSet rs, Statement state, Connection conn) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        
        if (state != null) {
            try {
                state.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

}

  index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Insert title here</title>
<link href="${pageContext.request.contextPath }/bootstrap-3.3.7-dist/css/bootstrap.min.css"  rel="stylesheet">
<script src="${pageContext.request.contextPath }/js/jquery-3.3.1.min.js"></script>
<script src="${pageContext.request.contextPath }/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>

<style type="text/css">
    .skyblue{
        background:skyblue;
    }
    .pink{
        background:pink;
    }
    *{
        margin:0px;
        padding:0px;
    }
    a{
        font-size:15px;
    }
    
</style>
</head>
<body>
    <div class="container">
        <form action="YqServlet?method=getAllProvince" method="post">
            <div class="row" style="padding-top: 20px">
                <div class="col-xs-4">
                    <h4>起始时间:</h4>
                    <input type="text" class="form-control" name="date1">
                </div>
                <div class="col-xs-4">
                    <h4>终止时间:</h4>
                    <input type="text" class="form-control" name="date2">
                </div>
                <div class="col-xs-2">
                    <input type="submit" class="btn btn-default" value="查询">
                </div>
            </div>
        </form>

    </div>
</body>
</html>

  bar.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link href="${pageContext.request.contextPath }/bootstrap-3.3.7-dist/css/bootstrap.min.css"  rel="stylesheet">
<script src="${pageContext.request.contextPath }/js/jquery.min.js"></script>
<script src="${pageContext.request.contextPath }/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/echarts.min.js"></script>
</head>
<script type="text/javascript">
var dt;
function getAllConfirmed(){
    
    var date1 = "${date1}";
    var date2 = "${date2}";
$.ajax({
    url:"YqServlet?method=getAllConfirmed",
    async:false,
    type:"POST",
    data:{"date1":date1,
          "date2":date2
         },
    success:function(data){
        dt = data;
        //alert(dt);
    },
    error:function(){
        alert("请求失败");
    },
    dataType:"json"
});
    
    var myChart = echarts.init(document.getElementById('yiqingchart'));
    var xd = new Array(0)//长度为33
    var yd = new Array(0)//长度为33
    for(var i=0;i<32;i++){
        xd.push(dt[i].province);
        yd.push(dt[i].confirmed_num);
    }
        // 指定图表的配置项和数据
       var option = {
        title: {
            text: '全国各省的确诊人数'
        },
        tooltip: {
            show: true,
            trigger: 'axis'
            
        },
        legend: {
            data: ['确诊人数']
        },
        grid: {
            left: '3%',
            right: '4%',
            bottom: '3%',
            containLabel: true
        },
        toolbox: {
            feature: {
                saveAsImage: {}
            }
        },
        xAxis: {
            type: 'category',
            boundaryGap: false,
            axisLabel:{
                                        //横坐标上的文字斜着显示 文字颜色 begin 
                                             interval:0,
                                             rotate:45,
                                             margin:60,
                                             textStyle:{color:"#ec6869" }
                                        //横坐标上的文字换行显示 文字颜色end
                                             },
            data: xd
        },
        yAxis: {
            type: 'value'
        },
        series: [
            {
                name: '确诊人数',
                type: 'bar',
                stack: '总量',
                data: yd,
                barWidth:20,
                barGap:'10%'
            }
        ]
    };
        // 使用刚指定的配置项和数据显示图表。
        myChart.setOption(option);
}
</script>
<body>
    <button class="btn btn-default" onclick="getAllConfirmed()" style="padding-top:20px;font-size:20px">柱状图</button>
    <div id="yiqingchart" style="900px; height: 600px;">
        
    </div>
    <table class="table table-striped" style="font-size:20px">
        <tr>
            <td>编号</td>
            <td>时间</td>
            <td>省份</td>
            <td>新增人数</td>
            <td>确诊人数</td>
            <td>治愈人数</td>
            <td>死亡人数</td>
        </tr>
        <c:forEach items="${list}" var="info">
        <tr>
            <td>${info.id}</td>
            <td>${info.date}</td>
            <td>${info.province}</td>
            <td>${info.newconfirmed_num}</td>
            <td>${info.confirmed_num}</td>
            <td>${info.cured_num}</td>
            <td>${info.dead_num}</td>
        </tr>
        </c:forEach>
    </table>
</body>
</html>

  3.2 移动端

  activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.testnet.MainActivity">


<!--    <EditText-->
<!--    android:id="@+id/et_data_uname"-->
<!--    android:layout_width="match_parent"-->
<!--    android:layout_height="wrap_content"-->
<!--    android:hint="请输入开始时间:"-->
<!--    android:text="2020-03-18"/>-->

<!--    <EditText-->
<!--        android:id="@+id/et_data_upass"-->
<!--        android:layout_width="match_parent"-->
<!--        android:layout_height="wrap_content"-->
<!--        android:hint="请输入截止时间:"-->
<!--        android:text="2020-03-19" />-->

    <TextView
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:text="请选择开始时间"
        android:textSize="50sp" />

    <DatePicker
        android:id="@+id/et_data_uname"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_margin="4dp"
        android:datePickerMode="spinner"
        android:calendarViewShown="false"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:text="请选择截止时间"
        android:textSize="50sp" />

    <DatePicker
        android:id="@+id/et_data_upass"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_margin="4dp"
        android:datePickerMode="spinner"
        android:calendarViewShown="false"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="loginGet"
        android:text="爬取(只可获取当天数据)" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="loginPOST"
        android:text="查询国内疫情信息" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="loginPOST2"
        android:text="查询海外疫情信息" />

</LinearLayout>

  content_main.xml(大的表单)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="50dp">
        <TextView
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_marginLeft="10dp"
            android:ellipsize="marquee"
            android:gravity="center"
            android:singleLine="true"
            android:text="省份"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/tv_date"
            android:layout_width="95dp"
            android:layout_height="wrap_content"
            android:text="时间"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/tv_confirmed"
            android:layout_width="55dp"
            android:layout_height="80dp"
            android:text="确诊"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/tv_cured"
            android:layout_width="55dp"
            android:layout_height="80dp"
            android:text="治愈"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/tv_dead"
            android:layout_width="55dp"
            android:layout_height="80dp"
            android:text="死亡"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/tv_new"
            android:layout_width="55dp"
            android:layout_height="80dp"
            android:text="新增"
            android:textSize="15sp" />
    </LinearLayout>
    <ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/lv_main"/>
</LinearLayout>

  list_item.xml(显示具体的一条一条数据)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/tv_province"
        android:layout_width="60dp"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_marginLeft="10dp"
        android:ellipsize="marquee"
        android:gravity="center"
        android:singleLine="true"
        android:text="省份"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tv_date"
        android:layout_width="95dp"
        android:layout_height="wrap_content"
        android:text="时间"
        android:textSize="15sp" />

    <TextView
        android:id="@+id/tv_confirmed"
        android:layout_width="55dp"
        android:layout_height="80dp"
        android:text="67799"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tv_cured"
        android:layout_width="55dp"
        android:layout_height="80dp"
        android:text="56002"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tv_dead"
        android:layout_width="55dp"
        android:layout_height="80dp"
        android:text="3"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tv_new"
        android:layout_width="55dp"
        android:layout_height="80dp"
        android:text="5"
        android:textSize="20sp" />

</LinearLayout>

 只需用到info和两个activity即可,另外两个用不到

  Info.java

package com.example.testnet;

public class Info {
    private String id;
    private String city;
    private String yisi_num;
    private String date;
    private String province;
    private String confirmed_num;
    private String cured_num;
    private String dead_num;
    private String newconfirmed_num;
    public String getNewconfirmed_num() {
        return newconfirmed_num;
    }
    public void setNewconfirmed_num(String newconfirmed_num) {
        this.newconfirmed_num = newconfirmed_num;
    }
    public String  getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    public String getYisi_num() {
        return yisi_num;
    }
    public void setYisi_num(String yisi_num) {
        this.yisi_num = yisi_num;
    }
    public String getDate() {
        return date;
    }
    public void setDate(String date) {
        this.date = date;
    }
    public String getProvince() {
        return province;
    }
    public void setProvince(String province) {
        this.province = province;
    }
    public String getConfirmed_num() {
        return confirmed_num;
    }
    public void setConfirmed_num(String confirmed_num) {
        this.confirmed_num = confirmed_num;
    }
    public String getCured_num() {
        return cured_num;
    }
    public void setCured_num(String cured_num) {
        this.cured_num = cured_num;
    }
    public String getDead_num() {
        return dead_num;
    }
    public void setDead_num(String dead_num) {
        this.dead_num = dead_num;
    }
}

  MainActivity.java

package com.example.testnet;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.DatePicker;

import androidx.appcompat.app.AppCompatActivity;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;


public class MainActivity extends AppCompatActivity {

    String TAG = MainActivity.class.getCanonicalName();
//    private EditText et_data_uname;
//    private EditText et_data_upass;
    private DatePicker et_data_uname;
    private DatePicker et_data_upass;
    private HashMap<String, String> stringHashMap;
    private String t;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et_data_uname = (DatePicker) findViewById(R.id.et_data_uname);
        et_data_upass = (DatePicker) findViewById(R.id.et_data_upass);
        stringHashMap = new HashMap<>();
    }

    public void loginPOST(View view) {
        stringHashMap.put("username",et_data_uname.getYear()+"-"+(et_data_uname.getMonth()+1)+"-"+et_data_uname.getDayOfMonth());
        stringHashMap.put("password", et_data_upass.getYear()+"-"+(et_data_upass.getMonth()+1)+"-"+et_data_upass.getDayOfMonth());

        new Thread(postRun).start();
    }
    public void loginPOST2(View view) {
        stringHashMap.put("username",et_data_uname.getYear()+"-"+(et_data_uname.getMonth()+1)+"-"+et_data_uname.getDayOfMonth());
        stringHashMap.put("password", et_data_upass.getYear()+"-"+(et_data_upass.getMonth()+1)+"-"+et_data_upass.getDayOfMonth());

        new Thread(postRun2).start();
    }
    public void loginGet(View view) {
        stringHashMap.put("username", et_data_uname.getYear()+"-"+(et_data_uname.getMonth()+1)+"-"+et_data_uname.getDayOfMonth());
        stringHashMap.put("password", et_data_upass.getYear()+"-"+(et_data_upass.getMonth()+1)+"-"+et_data_upass.getDayOfMonth());
        new Thread(getRun).start();
    }

    /**
     * get请求线程
     */
    Runnable getRun = new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            requestGet(stringHashMap);
        }
    };
    /**
     * post请求线程
     */
    Runnable postRun = new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            requestPost(stringHashMap);
        }
    };
    Runnable postRun2 = new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            requestPost2(stringHashMap);
        }
    };

    /**
     * get提交数据
     *
     * @param paramsMap
     */
    private void requestGet(HashMap<String, String> paramsMap) {
        try {
            String baseUrl = "http://10.0.2.2:8080/YiQing/PaquServlet?";//如果发布到云端,将黄色部分修改为云服务器ip
            StringBuilder tempParams = new StringBuilder();
            int pos = 0;
            for (String key : paramsMap.keySet()) {
                if (pos > 0) {
                    tempParams.append("&");
                }
                tempParams.append(String.format("%s=%s", key, URLEncoder.encode(paramsMap.get(key), "utf-8")));
                pos++;
            }

            Log.e(TAG,"params--get-->>"+tempParams.toString());
            String requestUrl = baseUrl + tempParams.toString();
            // 新建一个URL对象
            URL url = new URL(requestUrl);
            // 打开一个HttpURLConnection连接
            HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
            // 设置连接主机超时时间
            urlConn.setConnectTimeout(5 * 1000);
            //设置从主机读取数据超时
            urlConn.setReadTimeout(5 * 1000);
            // 设置是否使用缓存  默认是true
            urlConn.setUseCaches(true);
            // 设置为Post请求
            urlConn.setRequestMethod("GET");
            //urlConn设置请求头信息
            //设置请求中的媒体类型信息。
            urlConn.setRequestProperty("Content-Type", "application/json");
            //设置客户端与服务连接类型
            urlConn.addRequestProperty("Connection", "Keep-Alive");
            // 开始连接
            urlConn.connect();
            // 判断请求是否成功
            if (urlConn.getResponseCode() == 200) {
                // 获取返回的数据
                String result = streamToString(urlConn.getInputStream());
                Log.e(TAG, "Get方式请求成功,result--->" + result);
            } else {
                Log.e(TAG, "Get方式请求失败");
            }
            // 关闭连接
            urlConn.disconnect();
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
    }

    /**
     * post提交数据
     *
     * @param paramsMap
     */
    private void requestPost(HashMap<String, String> paramsMap) {
        try {
            String baseUrl = "http://10.0.2.2:8080/YiQing/SearchServlet?method=province";//如若发布到云端,将黄色部分修改为云端ip 
            //合成参数
            StringBuilder tempParams = new StringBuilder();
            int pos = 0;
            for (String key : paramsMap.keySet()) {
                if (pos >0) {
                    tempParams.append("&");
                }
                tempParams.append(String.format("%s=%s", key, URLEncoder.encode(paramsMap.get(key), "utf-8")));
                pos++;
            }
            String params = tempParams.toString();
            Log.e(TAG,"params--post-->>"+params);
            // 请求的参数转换为byte数组
//            byte[] postData = params.getBytes();
            // 新建一个URL对象
            URL url = new URL(baseUrl);
            // 打开一个HttpURLConnection连接
            HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
            // 设置连接超时时间
            urlConn.setConnectTimeout(5 * 1000);
            //设置从主机读取数据超时
            urlConn.setReadTimeout(5 * 1000);
            // Post请求必须设置允许输出 默认false
            urlConn.setDoOutput(true);
            //设置请求允许输入 默认是true
            urlConn.setDoInput(true);
            // Post请求不能使用缓存
            urlConn.setUseCaches(false);
            // 设置为Post请求
            urlConn.setRequestMethod("POST");
            //设置本次连接是否自动处理重定向
            urlConn.setInstanceFollowRedirects(true);
            //配置请求Content-Type
//            urlConn.setRequestProperty("Content-Type", "application/json");//post请求不能设置这个
            // 开始连接
            urlConn.connect();

            // 发送请求参数
            PrintWriter dos = new PrintWriter(urlConn.getOutputStream());
            dos.write(params);
            dos.flush();
            dos.close();
            // 判断请求是否成功
            if (urlConn.getResponseCode() == 200) {
                // 获取返回的数据
                String result = streamToString(urlConn.getInputStream());
                Log.e(TAG, "Post方式请求成功,result--->" + result);
                t=result;
                Intent intent = new Intent(MainActivity.this,MainActivity2.class);
                System.out.println(t);
                intent.putExtra("data",t);
                startActivity(intent);
            } else {
                Log.e(TAG, "Post方式请求失败");
            }
            // 关闭连接
            urlConn.disconnect();
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
    }

    private void requestPost2(HashMap<String, String> paramsMap) {
        try {
            String baseUrl = "http://10.0.2.2:8080/YiQing/SearchServlet?method=country";//如若发布到云端,将黄色部分修改为云端ip
            //合成参数
            StringBuilder tempParams = new StringBuilder();
            int pos = 0;
            for (String key : paramsMap.keySet()) {
                if (pos >0) {
                    tempParams.append("&");
                }
                tempParams.append(String.format("%s=%s", key, URLEncoder.encode(paramsMap.get(key), "utf-8")));
                pos++;
            }
            String params = tempParams.toString();
            Log.e(TAG,"params--post-->>"+params);
            // 请求的参数转换为byte数组
//            byte[] postData = params.getBytes();
            // 新建一个URL对象
            URL url = new URL(baseUrl);
            // 打开一个HttpURLConnection连接
            HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
            // 设置连接超时时间
            urlConn.setConnectTimeout(5 * 1000);
            //设置从主机读取数据超时
            urlConn.setReadTimeout(5 * 1000);
            // Post请求必须设置允许输出 默认false
            urlConn.setDoOutput(true);
            //设置请求允许输入 默认是true
            urlConn.setDoInput(true);
            // Post请求不能使用缓存
            urlConn.setUseCaches(false);
            // 设置为Post请求
            urlConn.setRequestMethod("POST");
            //设置本次连接是否自动处理重定向
            urlConn.setInstanceFollowRedirects(true);
            //配置请求Content-Type
//            urlConn.setRequestProperty("Content-Type", "application/json");//post请求不能设置这个
            // 开始连接
            urlConn.connect();

            // 发送请求参数
            PrintWriter dos = new PrintWriter(urlConn.getOutputStream());
            dos.write(params);
            dos.flush();
            dos.close();
            // 判断请求是否成功
            if (urlConn.getResponseCode() == 200) {
                // 获取返回的数据
                String result = streamToString(urlConn.getInputStream());
                Log.e(TAG, "Post方式请求成功,result--->" + result);
                t=result;
                Intent intent = new Intent(MainActivity.this,MainActivity2.class);
                System.out.println(t);
                intent.putExtra("data",t);
                startActivity(intent);
            } else {
                Log.e(TAG, "Post方式请求失败");
            }
            // 关闭连接
            urlConn.disconnect();
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
    }


    /**
     * 将输入流转换成字符串
     *
     * @param is 从网络获取的输入流
     * @return
     */
    public String streamToString(InputStream is) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = is.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            baos.close();
            is.close();
            byte[] byteArray = baos.toByteArray();
            return new String(byteArray);
        } catch (Exception e) {
            Log.e(TAG, e.toString());
            return null;
        }
    }

    /**
     * 文件下载
     *
     * @param fileUrl
     */
    private void downloadFile(String fileUrl) {
        try {
            // 新建一个URL对象
            URL url = new URL(fileUrl);
            // 打开一个HttpURLConnection连接
            HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
            // 设置连接主机超时时间
            urlConn.setConnectTimeout(5 * 1000);
            //设置从主机读取数据超时
            urlConn.setReadTimeout(5 * 1000);
            // 设置是否使用缓存  默认是true
            urlConn.setUseCaches(true);
            // 设置为Post请求
            urlConn.setRequestMethod("GET");
            //urlConn设置请求头信息
            //设置请求中的媒体类型信息。
            urlConn.setRequestProperty("Content-Type", "application/json");
            //设置客户端与服务连接类型
            urlConn.addRequestProperty("Connection", "Keep-Alive");
            // 开始连接
            urlConn.connect();
            // 判断请求是否成功
            if (urlConn.getResponseCode() == 200) {
                String filePath = "";//下载文件保存在本地的地址
                File descFile = new File(filePath);
                FileOutputStream fos = new FileOutputStream(descFile);
                ;
                byte[] buffer = new byte[1024];
                int len;
                InputStream inputStream = urlConn.getInputStream();
                while ((len = inputStream.read(buffer)) != -1) {
                    // 写到本地
                    fos.write(buffer, 0, len);
                }
            } else {
                Log.e(TAG, "文件下载失败");
            }
            // 关闭连接
            urlConn.disconnect();
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
    }

    /**
     * 文件上传
     *
     * @param filePath
     * @param paramsMap
     */
    private void upLoadFile(String filePath, HashMap<String, String> paramsMap) {
        try {
            String baseUrl = "http://xxx.com/uploadFile";
            File file = new File(filePath);
            //新建url对象
            URL url = new URL(baseUrl);
            //通过HttpURLConnection对象,向网络地址发送请求
            HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
            //设置该连接允许读取
            urlConn.setDoOutput(true);
            //设置该连接允许写入
            urlConn.setDoInput(true);
            //设置不能适用缓存
            urlConn.setUseCaches(false);
            //设置连接超时时间
            urlConn.setConnectTimeout(5 * 1000);   //设置连接超时时间
            //设置读取超时时间
            urlConn.setReadTimeout(5 * 1000);   //读取超时
            //设置连接方法post
            urlConn.setRequestMethod("POST");
            //设置维持长连接
            urlConn.setRequestProperty("connection", "Keep-Alive");
            //设置文件字符集
            urlConn.setRequestProperty("Accept-Charset", "UTF-8");
            //设置文件类型
            urlConn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + "*****");
            String name = file.getName();
            DataOutputStream requestStream = new DataOutputStream(urlConn.getOutputStream());
            requestStream.writeBytes("--" + "*****" + "
");
            //发送文件参数信息
            StringBuilder tempParams = new StringBuilder();
            tempParams.append("Content-Disposition: form-data; name="" + name + ""; filename="" + name + ""; ");
            int pos = 0;
            int size = paramsMap.size();
            for (String key : paramsMap.keySet()) {
                tempParams.append(String.format("%s="%s"", key, paramsMap.get(key), "utf-8"));
                if (pos < size - 1) {
                    tempParams.append("; ");
                }
                pos++;
            }
            tempParams.append("
");
            tempParams.append("Content-Type: application/octet-stream
");
            tempParams.append("
");
            String params = tempParams.toString();
            requestStream.writeBytes(params);
            //发送文件数据
            FileInputStream fileInput = new FileInputStream(file);
            int bytesRead;
            byte[] buffer = new byte[1024];
            DataInputStream in = new DataInputStream(new FileInputStream(file));
            while ((bytesRead = in.read(buffer)) != -1) {
                requestStream.write(buffer, 0, bytesRead);
            }
            requestStream.writeBytes("
");
            requestStream.flush();
            requestStream.writeBytes("--" + "*****" + "--" + "
");
            requestStream.flush();
            fileInput.close();
            int statusCode = urlConn.getResponseCode();
            if (statusCode == 200) {
                // 获取返回的数据
                String result = streamToString(urlConn.getInputStream());
                Log.e(TAG, "上传成功,result--->" + result);
            } else {
                Log.e(TAG, "上传失败");
            }
        } catch (IOException e) {
            Log.e(TAG, e.toString());
        }
    }


}

  MainActivity2.java(当点击查询后,会从MainActivity跳转到该MainActivity2)  

package com.example.testnet;

import android.content.Intent;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;

import androidx.appcompat.app.AppCompatActivity;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MainActivity2 extends AppCompatActivity {

    private List<Info> list ;
    private YqAdapter mAdapter;
    Info yq=new Info();
    int n=0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content_main);
        Intent m =getIntent();
        String result=m.getStringExtra("data");
        List<Map<String, Object>> listitem = new ArrayList<Map<String, Object>>();
        String[] province=new String[1000];
        String[] date=new String[1000];
        String[] now=new String[1000];
        String[] cured=new String[1000];
        String[] dead=new String[1000];
        String[] today=new String[1000];
        try {
            JSONArray json = new JSONArray(result);
            for (int i = 0;i<json.length();i++){
                JSONObject jb=json.getJSONObject(i);
                date[i]=jb.getString("date");
                province[i]=jb.getString("province");
                now[i]=jb.getString("confirmed_num");
                cured[i]=jb.getString("cured_num");
                dead[i]=jb.getString("dead_num");
                today[i]=jb.getString("newconfirmed_num");
                n=i+1;
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        for (int i = 0; i <n; i++)
        {
            Map<String,Object> map = new HashMap<String, Object>();
            map.put("province",province[i]);
            map.put("date",date[i]);
            map.put("now",now[i]);
            map.put("cured",cured[i]);
            map.put("dead",dead[i]);
            map.put("today",today[i]);
            listitem.add(map);
        }
//        for (int i=0;i<n;i++){
//            System.out.println(province[i]);
//        }
        SimpleAdapter adapter = new SimpleAdapter(this
                , listitem
                , R.layout.list_item
                , new String[]{"province","date","now","cured","dead","today"}
                ,new int[]{R.id.tv_province,R.id.tv_date,R.id.tv_confirmed,R.id.tv_cured,R.id.tv_dead,R.id.tv_new});
        ListView listView =(ListView) findViewById(R.id.lv_main);
        listView.setAdapter(adapter);
    }
}

4、移动端与Web端的交互(上面的代码已经实现了交互)

  移动端只是向Web端发送请求,调用相应的Servlet,一些复杂的运算还是ecplise中进行完成的。

  刚开始可以参考该篇博客了解交互过程https://blog.csdn.net/qq_34317125/article/details/80533685

5、云服务器配置与部署

  可以参考我的另一篇博客https://www.cnblogs.com/xhj1074376195/p/12318178.html 

  新获得的云服务要像一台新电脑一样,同样需要下载配置jdk,mysql,Tomcat....

6、运行测试结果

  Web端

   移动端

7、开发过程中出现的问题 

  1.在Android Studio中将localhost:8080修改为云端服务器ip时,没有把:8080去掉,导致连接不上云端服务器。

  2.Listview的布局中,没有弄清楚绑定的是哪一个页面,导致一直报空指针,应该修改为ListView控件所在的xml页面。

  3.在AndroidMainifresh.xml中添加联网设置

<uses-permission android:name="android.permission.INTERNET" />

  4.新建一个MainActivity2.java之后,在AndroidMainifest.xml中添加Activity活动

<activity android:name=".MainActivity2"/>

  5.在虚拟机上可以正常运行,但打包apk至真机无法运行,请教同学以及百度后得知,Android 9.0之后 的应用程序,将要求默认使用加密连接,这意味着 Android P(9.0) 将禁止 App 使用所有未加密的连接,因此运行 Android P(9.0) 系统的安卓设备无论是接收或者发送流量,未来都不能明码传输,需要使用下一代(Transport Layer Security)传输层安全协议,而 Android Nougat 和 Oreo 则不受影响。简单来说就是,系统为了安全起见,Android 9.0之后禁止使用不加密的连接。解决办法,在AndroidMainifresh.xml中<application></application>下添加语句允许不加密连接

        android:usesCleartextTraffic="true"

8、PSP0级时间记录日志

 9、资源分享

  项目所需要的jar包   链接:https://pan.baidu.com/s/1z4eqP3Gpa0EqudogM-a-lw    提取码:tr06

     疫情数据显示Web端源代码已上传至GitHub      https://github.com/xhj1074376195/YiQing_Web

     疫情数据显示移动端源代码已上传至GitHub  https://github.com/xhj1074376195/YiQing_App

原文地址:https://www.cnblogs.com/xhj1074376195/p/12523452.html