前言: 源于需要四天实现的Java课设,之前完全没有学过Java,实现起来非常多的问题(痛苦面具)。Java爬虫到服务器的Mysql数据库组员实现,从一个方法类将Mysql数据库的数据返回了一个JSON数据,html网页也有组员修改过后的模板,所以按html模板所需要的JSON文件来修改,但是由于爬取的数据只有四项(省名,死亡病例,疑似病例,确诊病例),而模板用的JSON文件数据复杂,所以只修改这三个数据的绑定与展示,提取方法类返回的JSON文件的数据,使用Java类接收数据再实现数据转移,并且返回一个源于Mysql数据库数据的html可用的JSON文件,再由html调用即可实现爬取数据的展示。(疫情新闻的爬取其他组员实现)
数据库提取数据实现(服务器ID已屏蔽)
package test1;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.mysql.cj.xdevapi.JsonArray;
// JSON读取与转换
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.sql.*;
public class Conn {
//private static String url ="jdbc:mysql://localhost:3306/mynews";
//解决乱码的问题
private static String url ="jdbc:mysql://***.**.**.***:****/***?useUnicode=true&characterEncoding=UTF-8";
private static String userName ="*****";
private static String password ="*******";
//静态代码块,在类加载时候执行,只会执行一次
static {
try {
//1、加载驱动,交给DriverManager管理
Class.forName("com.mysql.jdbc.Driver");
}catch (Exception ex){
ex.printStackTrace();
}
}
//获取connection
public static Connection getConnection(){
//Class.forName("com.mysql.jdbc.Driver");//放这里是有问题的。
try {
return DriverManager.getConnection(url,userName,password);
}catch (SQLException ex){
ex.printStackTrace();
return null;
}
}
public static void close(Connection conn){
try {
if(conn !=null)
conn.close();
}catch(SQLException ex){
ex.printStackTrace();
}
}
public static void close(Statement stmt){
try {
if(stmt !=null)
stmt.close();
}catch(SQLException ex){
ex.printStackTrace();
}
}
public static void close(ResultSet rs){
try {
if(rs !=null)
rs.close();
}catch(SQLException ex){
ex.printStackTrace();
}
}
public static void close(ResultSet rs,Statement stmt,Connection conn){
close(rs);
close(stmt);
close(conn);
}
/**
* 将resultSet转化为JSONObject
* @param rs
* @return
* @throws SQLException
* @throws JSONException
*/
/**
* 将resultSet转化为JSON数组
* @param rs
* @return
* @throws SQLException
* @throws JSONException
*/
public static JSONArray resultSetToJsonArry(ResultSet rs) throws SQLException,JSONException
{
// json数组
JSONArray array = new JSONArray();
// 获取列数
ResultSetMetaData metaData = rs.getMetaData();
int columnCount = metaData.getColumnCount();
// 遍历ResultSet中的每条数据
while (rs.next()) {
JSONObject jsonObj = new JSONObject();
// 遍历每一列
for (int i = 1; i <= columnCount; i++) {
String columnName =metaData.getColumnLabel(i);
String value = rs.getString(columnName);
jsonObj.put(columnName, value);
}
array.add(jsonObj);
}
return array;
}
public static void insert_convid19(String name,int nowConfirm,int suspect,int dead) throws Exception{
Connection conn = getConnection();
Statement stmt = conn.createStatement();
String sql="insert into convid19(name,dead,nowConfirm,suspect) value(\"%s\",%d,%d,%d);";
//System.out.println(sql);
sql=String.format(sql,name,nowConfirm,suspect,dead);
stmt.execute(sql);
close(stmt);
}
public static void insert_news(String title,String img,String content,String link) throws Exception{
Connection conn = getConnection();
Statement stmt = conn.createStatement();
String sql="insert into news(title,img,content,link) value(\"%s\",\"%s\",\"%s\",\"%s\");";
sql=String.format(sql,title,img,content,link);
stmt.execute(sql);
close(stmt);
}
public static JSONArray select_convid19() throws Exception{
Connection conn = getConnection();
Statement stmt = conn.createStatement();
ResultSet rs=stmt.executeQuery("select * from convid19;");
JSONArray jsonArray=new JSONArray();
jsonArray=resultSetToJsonArry(rs);
close(rs,stmt,conn);
return jsonArray;
}
public static JSONArray select_news() throws Exception{
Connection conn = getConnection();
Statement stmt = conn.createStatement();
ResultSet rs=stmt.executeQuery("select * from news;");
JSONArray jsonArray=new JSONArray();
jsonArray=resultSetToJsonArry(rs);
close(rs,stmt,conn);
return jsonArray;
}
public static void main(String[] args) throws Exception {
// JSONArray test=new JSONArray();
// test=select_convid19();
// System.out.println(test.toJSONString());
// for(int i=0;i<test.size();i++){
// System.out.print(test.getJSONObject(i).getString("name")+",");
// System.out.print(test.getJSONObject(i).getInteger("dead")+",");
// System.out.print(test.getJSONObject(i).getInteger("nowConfirm")+",");
// System.out.print(test.getJSONObject(i).getInteger("suspect")+"\n");
// }
//insert_news("asdas","asdsad","asdasdasd","asdasda");
}
}
select_news(); //返回新闻数据的JSON文件
select_convid19(); //返回疫情数据的JSON文件
数据在JSON文件间的转移(返回html可用JSON文件)
package com.hc.app.DAO;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import java.io.*;
import static com.hc.app.DAO.Conn.select_convid19;
public class turnjson {
//读取json数据文件
public static String readJsonData(String data) throws IOException {
String result = "";
InputStreamReader isr = new InputStreamReader(new FileInputStream(data), "UTF-8");
BufferedReader br = new BufferedReader(isr);
String temporaryStringLine = null;
while ((temporaryStringLine = br.readLine()) != null) {
result += temporaryStringLine;
result += "\r\n"; // 补上换行符
}
return result;
}
//data1 JSON -> java class
public static class pro {
private String name;
private String dead;
private String nowConfirm;
private String suspect;
public pro() {}
public pro(String name,String dead,String nowConfirm,String suspect) {
this.name = name;
this.dead = dead;
this.nowConfirm = nowConfirm;
this.suspect = suspect;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDead() {
return dead;
}
public void setDead(String dead) {
this.dead = dead;
}
public String getNowConfirm() {
return nowConfirm;
}
public void setNowConfirm(String nowf) {
this.nowConfirm = nowf;
}
public String getSuspect() {
return suspect;
}
public void setSuspect(String suspect) {
this.suspect = suspect;
}
}
//data2 class
public static class protwo {
private long id;
private long createTime;
private long modifyTime;
private String tags;
private long countryType;
private String continents;
private String provinceId;
private String provinceName;
private String provinceShortName;
private String cityName;
private long currentConfirmedCount;
private long confirmedCount;
private long suspectedCount;
private long curedCount;
private long deadCount;
private String comment;
private long sort;
private String operator;
private long locationId;
private String countryShortCode;
public protwo() {}
public protwo(long id,long createTime,long modifyTime,String tags,long countryType,String continents,String provinceId,String provinceName,String provinceShortName,String cityName,long currentConfirmedCount,long confirmedCount,long suspectedCount,long curedCount,long deadCount,String comment,long sort,String operator,long locationId,String countryShortCode) {
this.id = id;
this.createTime = createTime;
this.modifyTime = modifyTime;
this.tags = tags;
this.countryType = countryType;
this.continents = continents;
this.provinceId = provinceId;
this.provinceName = provinceName;
this.provinceShortName = provinceShortName;
this.provinceShortName = provinceShortName;
this.cityName = cityName;
this.currentConfirmedCount = currentConfirmedCount;
this.confirmedCount = confirmedCount;
this.suspectedCount = suspectedCount;
this.curedCount = curedCount;
this.deadCount = deadCount;
this.comment = comment;
this.sort = sort;
this.operator = operator;
this.locationId = locationId;
this.countryShortCode = countryShortCode;
}
//String
public String getTags() { return tags; }
public void setTags(String tags) { this.tags = tags; }
public String getContinents() { return continents; }
public void setcontinents(String continents) { this.continents = continents; }
public String getProvinceId() { return provinceId; }
public void setProvinceId(String provinceId) { this.provinceId = provinceId; }
public String getProvinceName() { return provinceName; }
public void setProvinceName(String provinceName) { this.provinceName = provinceName; }
public String getProvinceShortName() { return provinceShortName; }
public void setprovinceShortName(String provinceShortName) { this.provinceShortName = provinceShortName; }
public String getCityName() { return cityName; }
public void setCityName(String cityName) { this.cityName = cityName; }
public String getComment() { return comment; }
public void setcomment(String comment) { this.comment = comment; }
public String getCountryShortCode() { return countryShortCode; }
public void setCountryShortCode(String countryShortCode) { this.countryShortCode = countryShortCode; }
public String getOperator() { return operator; }
public void setOperator(String operator) { this.operator = operator; }
// long
public long getId() { return id; }
public void setId(long id) { this.id = id; }
public long getCreateTime() { return createTime; }
public void setCreateTime(long createTime) { this.createTime = createTime; }
public long getModifyTime() { return modifyTime; }
public void setModifyTime(long modifyTime) { this.modifyTime = modifyTime; }
public long getCountryType() { return countryType; }
public void setCountryType(long countryType) { this.countryType = countryType; }
public long getCurrentConfirmedCount() { return currentConfirmedCount; }
public void setCurrentConfirmedCount(long currentConfirmedCount) { this.currentConfirmedCount = currentConfirmedCount; }
public long getConfirmedCount() { return confirmedCount; }
public void setConfirmedCount(long confirmedCount) { this.confirmedCount = confirmedCount; }
public long getSuspectedCount() { return suspectedCount; }
public void setSuspectedCount(long suspectedCount) { this.suspectedCount = suspectedCount; }
public long getCuredCount() { return curedCount; }
public void setCuredCount(long curedCount) { this.curedCount = curedCount; }
public long getDeadCount() { return deadCount; }
public void setDeadCount(long deadCount) { this.deadCount = deadCount; }
public long getSort() { return sort; }
public void setSort(long sort) { this.sort = sort; }
public long getLocationId() { return locationId; }
public void setLocationId(long locationId) { this.locationId = locationId; }
}
//json数据的转换,返回html可用的json文件(实现数据源于数据库。
public static String select_turn() throws Exception {
//d1:数据库获取数据,d2:html使用的json板块
JSONArray Js = select_convid19();
String d1 = Js.toJSONString();
String d2 = readJsonData("data2.json");
//data1 解析
List<pro> pros = JSON.parseArray(d1,pro.class);
//data2 解析
JSONObject jsonObject = JSONObject.parseObject(d2);
String getFirstNodesss = jsonObject.getString("getListByCountryTypeService1");
List<protwo> protwos = JSON.parseArray(getFirstNodesss,protwo.class);
//绑定数据
for(protwo i : protwos) {
String proname = i.provinceShortName;
int tmp1 = 0,tmp2 = 0,tmp3 = 0;
for(pro j : pros) {
if(j.name.equals(proname)) {
tmp1 = Integer.parseInt(j.nowConfirm);
tmp2 = Integer.parseInt(j.dead);
tmp3 = Integer.parseInt(j.suspect);
break;
}
}
i.currentConfirmedCount = tmp1;
i.deadCount = tmp2;
i.suspectedCount = tmp3;
i.tags = ("确诊" + (Integer.toString((int)i.currentConfirmedCount)) + "例");
}
//基于数据库修改完毕的JSON数据
String ListproJSON = JSON.toJSONString(protwos);
//获取新JSON
StringBuilder tmpOne = new StringBuilder();
tmpOne.append("{\"getListByCountryTypeService1\":");
tmpOne.append(ListproJSON);
tmpOne.append(",\"getAreaStat\":");
tmpOne.append(jsonObject.getString("getAreaStat"));
tmpOne.append(",\"getStatisticsService\":");
tmpOne.append(jsonObject.getString("getStatisticsService"));
tmpOne.append("}");
return tmpOne.toString();
}
public static void main(String[] args) throws Exception {
String tmp = select_turn();
System.out.println(tmp);
//写String到文件(UTF-8)
File distFile = new File("data3.json");
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(distFile), "UTF8"));
out.write(tmp);
out.close();
}
}
Echarts的对数据的实现板块
主要实现数据显示
chinamap.js,chinamap1.js,chinamap2.js:
var myChart = echarts.init(document.querySelector('#chinamap'))
// fetch xmlhttprequest
// fetchfetch(请求url)不需要引入任何的文件
fetch('1.json')
.then(res => res.json()) // 把可读数据流转为json格式
.then(res => {
console.log(res) // 获取到的疫情数据
var getListByCountryTypeService = res.getListByCountryTypeService1
// 将接口返回的数据进行处理 转为echarts认可的数据
var filterData = []
getListByCountryTypeService.forEach(item => {
filterData.push({
name: item.provinceShortName,
value:item.currentConfirmedCount
}) })
myChart.setOption({
title:{
text:'现有确诊病例'
},
tooltip: {
formatter:function(params){
return `地区:${params.name}<br/>现有确诊:${params.value || 0}人<br/>`
}//数据格式化
},
visualMap: [
{
type: 'piecewise', // continuous连续的 piecewise分段
pieces: [
{ gte: 10000 }, // (10000, Infinity]
{ gte: 1000, lte: 9999 }, // (1000, 9999]
{ gte: 100, lte: 999 }, // (100, 999]
{ gte: 10, lte: 99 }, // (10, 99]
{ gte: 0, lte: 9 }, // (0, 9]
{value:0}
],
inRange: {
color: ['#ffffff','#fdebcf', '#f59e83', '#e55a4e', '#cb2a2f', '#811c24']
}
}
],
geo: {
map: 'china',
roam: false,
zoom:1.23,
label: {
normal: {
show: true,
fontSize:'10',
color: 'rgba(0,0,0,0.7)'
}
},
itemStyle: {
normal:{
borderColor: 'rgba(0, 0, 0, 0.2)'
},
emphasis:{
areaColor: '#F3B329',
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 20,
borderWidth: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
},
series : [
{
name: '确诊人数',
type: 'map',
geoIndex: 0,
data:filterData
}
]
})
})
var myChart2 = echarts.init(document.querySelector('#chinamap2'))
// fetch xmlhttprequest
// fetchfetch(请求url)不需要引入任何的文件
fetch('1.json')
.then(res => res.json()) // 把可读数据流转为json格式
.then(res => {
console.log(res) // 获取到的疫情数据
var getListByCountryTypeService1 = res.getListByCountryTypeService1
// 将接口返回的数据进行处理 转为echarts认可的数据
var filterData2 = []
getListByCountryTypeService1.forEach(item => {
filterData2.push({
name: item.provinceShortName,
value: item.deadCount
}) })
myChart2.setOption({
title:{
text:'累计死亡病例'
},
tooltip: {
formatter:function(params){
return `地区:${params.name}<br/>累计死亡:${params.data?.value || 0}人<br/>`
}//数据格式化
},
visualMap: [
{
type: 'piecewise', // continuous连续的 piecewise分段
pieces: [
{ gte: 10000 }, // (10000, Infinity]
{ gte: 1000, lte: 9999 }, // (1000, 9999]
{ gte: 100, lte: 999 }, // (100, 999]
{ gte: 10, lte: 99 }, // (10, 99]
{ gte: 0, lte: 9 }, // (0, 9]
{value:0}
],
inRange: {
color: ['#ffffff','#fdebcf', '#f59e83', '#e55a4e', '#cb2a2f', '#811c24']
}
}
],
geo: {
map: 'china',
roam: false,//不开启缩放和平移
zoom:1.23,//视角缩放比例
label: {
normal: {
show: true,
fontSize:'10',
color: 'rgba(0,0,0,0.7)'
}
},
itemStyle: {
normal:{
borderColor: 'rgba(0, 0, 0, 0.2)'
},
emphasis:{
areaColor: '#F3B329',//鼠标选择区域颜色
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 20,
borderWidth: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
},
series : [
{
name: '死亡人数',
type: 'map',
geoIndex: 0,
data:filterData2
}
]
})
})
var myChart1 = echarts.init(document.querySelector('#chinamap1'))
// fetch xmlhttprequest
// fetchfetch(请求url)不需要引入任何的文件
fetch('1.json')
.then(res => res.json()) // 把可读数据流转为json格式
.then(res => {
console.log(res) // 获取到的疫情数据
var getListByCountryTypeService1 = res.getListByCountryTypeService1
// 将接口返回的数据进行处理 转为echarts认可的数据
var filterData1 = []
getListByCountryTypeService1.forEach(item => {
filterData1.push({
name: item.provinceShortName,
value: item.suspectedCount,
}) })
myChart1.setOption({
title:{
text:'疑似确诊病例'
},
tooltip: {
formatter:function(params){
return `地区:${params.name}<br/>疑似确诊:${params.value || 0}人`
}//数据格式化
},
visualMap: [
{
type: 'piecewise', // continuous连续的 piecewise分段
pieces: [
{ gte: 10000 }, // (10000, Infinity]
{ gte: 1000, lte: 9999 }, // (1000, 9999]
{ gte: 100, lte: 999 }, // (100, 999]
{ gte: 10, lte: 99 }, // (10, 99]
{ gte: 0, lte: 9 }, // (0, 9]
{value:0}
],
inRange: {
color: ['#ffffff','#fdebcf', '#f59e83', '#e55a4e', '#cb2a2f', '#811c24']
}
}
],
geo: {
map: 'china',
roam: false,//不开启缩放和平移
zoom:1.23,//视角缩放比例
label: {
normal: {
show: true,
fontSize:'10',
color: 'rgba(0,0,0,0.7)'
}
},
itemStyle: {
normal:{
borderColor: 'rgba(0, 0, 0, 0.2)'
},
emphasis:{
areaColor: '#F3B329',//鼠标选择区域颜色
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 20,
borderWidth: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
},
series : [
{
name: '确诊人数',
type: 'map',
geoIndex: 0,
data:filterData1
}
]
})
})
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>新冠肺炎实时数据统计</title>
<link rel="stylesheet" type="text/css" href="CSS/daohanglan.css">
<link rel="stylesheet" type="text/css" href="CSS/zhengti.css">
<link rel="stylesheet" type="text/css" href="CSS/zuoyoulan.css">
<link rel="stylesheet" type="text/css" href="CSS/dibu.css">
<link rel="stylesheet" type="text/css" href="CSS/biaoge.css">
<link rel="stylesheet" type="text/css" href="CSS/shurukuang.css">
<link rel="stylesheet" type="text/css" href="CSS/xiangying.css">
<link rel="stylesheet" type="text/css" href="CSS/huandengpian.css">
<style>
img {
position:absolute;
}
</style>
</head>
<body>
<div class="header">
<div id="times"></div>
<h1 style="text-shadow: 2px 2px #8888ff;">新冠肺炎实时热点新闻</h1>
</div>
<div class="topnav">
<a href="index.html">首页</a>
<a href="news1.html">新闻1</a>
<a href="news2.html">新闻2</a>
<a href="news3.html">新闻3</a>
<a href="news4.html">新闻4</a>
<a href="news5.html">新闻5</a>
<a href="news6.html">新闻6</a>
<a href="news7.html">新闻7</a>
<a href="news8.html">新闻8</a>
</div>
<div class="row">
<div class="leftcolumn">
<div class="slideshow-container">
<div class="mySlides fade">
<div class="numbertext">1 / 3</div>
<img src="p1.jpg" style="width:100%">
</div>
<div class="mySlides fade">
<div class="numbertext">2 / 3</div>
<img src="p2.jpg" style="width:100%">
</div>
<div class="mySlides fade">
<div class="numbertext">3 / 3</div>
<img src="p3.jpg" style="width:100%">
</div>
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<br>
<div style="text-align:center">
<span class="dot" onclick="currentSlide(1)"></span>
<span class="dot" onclick="currentSlide(2)"></span>
<span class="dot" onclick="currentSlide(3)"></span>
</div>
<div class="card">
<h2>疫情</h2>
<h5 id="显示日期"></h5>
<table>
<tr>
<tr>
<td>现有确诊病例</td>
<td id="现有确诊病例"></td>
</tr>
<tr>
<td>现有疑似病例</td>
<td id="现有疑似病例"></td>
</tr>
<tr>
<td>死亡病例</td>
<td id="死亡病例"></td>
</tr>
</tr>
</table>
</div>
</div>
<div class="rightcolumn">
<div class="card">
<h2>疫情地图</h2>
<div id="chinamap" style="width: 600px;height: 450px;margin: 0px auto"> </div>
<div id="chinamap1" style="display: none;width: 600px;height: 450px;margin: 0px auto"> </div>
<div id="chinamap2" style="display: none;width: 600px;height: 450px;margin: 0px auto"> </div>
<script src="JS/echarts.min.js"></script>
<script src="JS/china.js"></script>
<script src="JS/chinamap.js"></script>
<script src="JS/chinamap1.js"></script>
<script src="JS/chinamap2.js"></script>
<button type="button" onclick="divSW()">现有确诊病例</button>
<button type="button" onclick="divSW1()">疑似确诊病例</button>
<button type="button" onclick="divSW2()">累计死亡病例</button>
<script>
var dv = document.getElementById( "chinamap" );
var dv1 = document.getElementById( "chinamap1" );
var dv2 = document.getElementById( "chinamap2" );
function divSW() {
dv.style.display = "block";
dv1.style.display = "none";
dv2.style.display = "none";
}
function divSW1() {
dv.style.display = "none";
dv1.style.display = "block";
dv2.style.display = "none";
}
function divSW2() {
dv.style.display = "none";
dv1.style.display = "none";
dv2.style.display = "block";
}
</script>
</div>
</div>
</div>
<script src="JS/huandengpian.js" type="text/javascript"></script>
<script src="JS/qgbg.js" type="text/javascript"></script>
<script>
//得到时间并写入div
function getDate(){
//获取当前时间
var date = new Date();
//格式化为本地时间格式
var date1 = date.toLocaleString();
//获取div
document.getElementById("times").innerHTML=date1;
}
//使用定时器每秒向div写入当前时间
setInterval("getDate()",1000);
</script>
</body>
</html>
可视化结果显示: