diff --git a/.gitignore b/.gitignore
index 8ec80db..a0166ac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -98,3 +98,5 @@ code/java/天气灾害预警/target/
code/java/天气灾害预警/out/
*.jar
*.iws
+*.log
+*.lck
diff --git a/code/java/DisasterWarning/.gitignore b/code/java/DisasterWarning/.gitignore
index 569855c..612c062 100644
--- a/code/java/DisasterWarning/.gitignore
+++ b/code/java/DisasterWarning/.gitignore
@@ -133,4 +133,7 @@ $RECYCLE.BIN/
# Windows shortcuts
*.lnk
-target/*
\ No newline at end of file
+target/*
+
+logs/*
+logs
\ No newline at end of file
diff --git a/code/java/DisasterWarning/config.json b/code/java/DisasterWarning/config.json
index 014224c..3795a43 100644
--- a/code/java/DisasterWarning/config.json
+++ b/code/java/DisasterWarning/config.json
@@ -3,6 +3,7 @@
"key": "fe9fa8eeeb6f4301a92541eed565dd15",
"query_url": "https://devapi.qweather.com/v7/warning/now?",
"wechat_officalaccount_url": "https://cxxmwx.cpic.com.cn/app/index.php?i=2&c=entry&do=send_group_tpl_api&m=ok_tplmessage",
+ "query_interval": 10,
"cities": [
{
"city_name": "厦门",
diff --git a/code/java/DisasterWarning/db.json b/code/java/DisasterWarning/db.json
index 7d27945..a8f5ddd 100644
--- a/code/java/DisasterWarning/db.json
+++ b/code/java/DisasterWarning/db.json
@@ -1,12 +1,14 @@
{
"tns_name": "xmcx1",
"ip_addr": "10.39.0.86",
- "user_name": "",
- "password": "",
+ "jdbc_url": "jdbc:oracle:thin:@10.39.0.86:1521:xmcx1",
+ "table_space": "wechat",
+ "user_name": "wechat",
+ "password": "@rn7Q+t5zeyKIZ~s",
"tables": [
{
- "table_name": "",
- "table_description": ""
+ "table_name": "weather_disaster_notify",
+ "table_description": "天气预警消息表"
}
]
-}
\ No newline at end of file
+}
diff --git a/code/java/DisasterWarning/logging.properties b/code/java/DisasterWarning/logging.properties
new file mode 100644
index 0000000..f82b56f
--- /dev/null
+++ b/code/java/DisasterWarning/logging.properties
@@ -0,0 +1,10 @@
+
+handlers = java.util.logging.ConsoleHandler, java.util.logging.FileHandler
+
+.level = INFO
+
+java.util.logging.FileHandler.pattern = ./logs/log_%u.log
+java.util.logging.FileHandler.limit = 50000
+java.util.logging.FileHandler.count = 1
+java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
+java.util.logging.FileHandler.append = true;
diff --git a/code/java/DisasterWarning/pom.xml b/code/java/DisasterWarning/pom.xml
index f2ef2b1..bc67e03 100644
--- a/code/java/DisasterWarning/pom.xml
+++ b/code/java/DisasterWarning/pom.xml
@@ -5,6 +5,13 @@
disaster_warning
1.0-SNAPSHOT
+
+ com.oracle
+ ojdbc8
+ 1.0
+ system
+ ${project.basedir}/lib/ojdbc8.jar
+
org.apache.httpcomponents
httpclient
@@ -16,7 +23,7 @@
4.13.2
test
-
+
com.fasterxml.jackson.core
jackson-core
@@ -72,6 +79,40 @@
compile
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0-M6
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+ jar-with-dependencies
+
+
+
+ AppMain
+
+
+
+
+
+ make-assmenbly
+ package
+
+ single
+
+
+
+
+
diff --git a/code/java/DisasterWarning/src/main/java/AppMain.java b/code/java/DisasterWarning/src/main/java/AppMain.java
index 1b52676..9373c01 100644
--- a/code/java/DisasterWarning/src/main/java/AppMain.java
+++ b/code/java/DisasterWarning/src/main/java/AppMain.java
@@ -2,41 +2,62 @@
* @Author: Kane
* @Date: 2022-04-22 10:53:49
* @LastEditors: Kane
- * @LastEditTime: 2022-04-23 23:22:57
+ * @LastEditTime: 2022-05-10 16:28:07
* @FilePath: \DisasterWarning\src\main\java\AppMain.java
* @Description: 和风天气预警推送厦门太保公众号主程序!
*
* Copyright (c) ${2022} by Kane, All Rights Reserved.
*/
+import com.cpic.xim.config.AppConfigManager;
import com.cpic.xim.config.City;
import com.cpic.xim.notify.disaster.QWeatherDisasterWarning;
import com.cpic.xim.notify.disaster.WeatherDisasterWarningGrabber;
-import com.cpic.xim.config.WeatherDisasterNotifyConfig;
import com.cpic.xim.wechat.officalAccount.sendMessage;
-
+import com.cpic.xim.config.WeatherDisasterNotifyConfig;
+import java.io.FileInputStream;
import java.io.IOException;
+import java.sql.SQLException;
import java.util.Vector;
+import java.util.logging.*;
+
public class AppMain
{
- private static final String CONFIG_FILE_PATH = "./config.json";
+ // private final static String LOG_FILE_PATH = "./logs/app%u.log";
public static void main( String[] args )
{
String json;
WeatherDisasterNotifyConfig config = null;
QWeatherDisasterWarning warning = null;
+ Logger logger = null;
+
+ // 配置logger
+ try
+ {
+ setRootLogger();
+
+ logger = Logger.getLogger( "com.cpicxim" );
+ }
+ catch ( IOException error )
+ {
+ System.out.println( "配置logger失败,原因:" + error.getMessage() );
+
+ return;
+ }
// 读取配置
try
{
- config = WeatherDisasterNotifyConfig.load( CONFIG_FILE_PATH );
+ config = AppConfigManager.getConfig();
}
- catch (IOException error)
+ catch ( IOException error )
{
System.out.println( "读取配置文件失败!" );
System.out.println( error.getMessage() );
+ logger.log( Level.SEVERE, "读取配置文件失败:{0}", error.getMessage() );
+
return;
}
@@ -45,30 +66,91 @@ public class AppMain
String userKey = config.getKey();
// 遍历所有城市,查询是否有警报,有则推送。
- for ( City city : cities)
+ while (true)
{
+ for ( City city : cities )
+ {
+ try
+ {
+ json = WeatherDisasterWarningGrabber.getWeatherDisasterWarningJSON( queryURL,
+ userKey, city.getCityCode() );
+ warning = WeatherDisasterWarningGrabber.convertWeatherDisasterWarning( json );
+
+ logger.log( Level.INFO, "查询{0}天气预警,结果:{1}。", new Object[]
+ { city.getCityName(), json} );
+
+ // 判断是否有警报
+ if ( warning.getWarning().isEmpty() == true)
+ {
+ logger.log( Level.INFO, "查询{0}天气预警,无警报!。", new Object[]
+ { city.getCityName()} );
+ continue;
+ }
+
+ logger.log( Level.INFO, "查询{0}天气预警,发送日志。", new Object[]
+ { city.getCityName()} );
+
+ sendMessage.sendWeatherDisasterWarning( config.getWechatOfficalAccountURL(),
+ warning );
+
+ logger.log( Level.INFO, "{0}天气预警,日志发送成功。", new Object[]
+ { city.getCityName()} );
+
+ sendMessage.saveWeatherDisasterWarning( city.getCityName(), warning );
+ }
+ catch ( IOException error )
+ {
+ System.out.println( "查询" + city.getCityName() + "出现异常!" );
+ System.out.println( error.getMessage() );
+
+ logger.log( Level.SEVERE, "查询 {0} 出现异常:{1}。", new Object[]
+ { city.getCityName(), error.getMessage()} );
+ }
+ catch ( SQLException error )
+ {
+ logger.log( Level.SEVERE, "查询 {0} 写入数据库失败:{1}。", new Object[]
+ { city.getCityName(), error.getMessage()} );
+ }
+ catch ( ClassNotFoundException error )
+ {
+ logger.log( Level.SEVERE, "查询 {0} 加载oracle驱动失败:{1}。", new Object[]
+ { city.getCityName(), error.getMessage()} );
+
+ }
+ catch ( Exception error )
+ {
+ logger.log( Level.SEVERE, "查询 {0} 出现未知错误:{1}。", new Object[]
+ { city.getCityName(), error.getMessage()} );
+ }
+ }
+
try
{
- json = WeatherDisasterWarningGrabber.getWeatherDisasterWarningJSON( queryURL,
- userKey, city.getCityCode() );
- warning = WeatherDisasterWarningGrabber.convertWeatherDisasterWarning( json );
-
- // 判断是否有警报
- if ( warning.getWarning().isEmpty() == true)
- {
- continue;
- }
-
- sendMessage.sendWeatherDisasterWarning( config.getWechatOfficalAccountURL(),
- warning );
+ logger.log( Level.INFO, "查询结束,休眠{0}分钟。", config.getQueryInterval() );
+ Thread.sleep( config.getQueryInterval() * 1000 * 60 );
}
- catch (IOException error)
+ catch ( InterruptedException error )
{
- System.out.println( "查询" + city.getCityName() + "出现异常!" );
- System.out.println( error.getMessage() );
-
- continue;
+ logger.log( Level.SEVERE, "线程休眠异常,错误信息:{0}", new Object[]
+ { error.getMessage()} );
}
}
}
+
+ /**
+ * 设置JUL的logger。
+ */
+ private static void setRootLogger() throws IOException
+ {
+ LogManager logManager = LogManager.getLogManager();
+ // 使用外部的配置文件。
+ FileInputStream configFile = new FileInputStream( "./logging.properties" );
+ // 使用jar中的配置文件。
+ // InputStream configFile =
+ // AppMain.class.getClassLoader().getResourceAsStream( "logging.properties" );
+
+ logManager.readConfiguration( configFile );
+
+ Logger.getLogger( "com.cpicxim" );
+ }
}
diff --git a/code/java/DisasterWarning/src/main/java/com/cpic/xim/config/AppConfigManager.java b/code/java/DisasterWarning/src/main/java/com/cpic/xim/config/AppConfigManager.java
new file mode 100644
index 0000000..69fcfa0
--- /dev/null
+++ b/code/java/DisasterWarning/src/main/java/com/cpic/xim/config/AppConfigManager.java
@@ -0,0 +1,79 @@
+/*
+ * @Author: Kane
+ * @Date: 2022-05-10 16:06:14
+ * @LastEditors: Kane
+ * @LastEditTime: 2022-05-10 16:09:07
+ * @FilePath: \DisasterWarning\src\main\java\com\cpic\xim\config\AppConfigManager.java
+ * @Description:
+ *
+ * Copyright (c) ${2022} by Kane, All Rights Reserved.
+ */
+
+package com.cpic.xim.config;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.FileInputStream;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.PropertyNamingStrategy;
+
+public class AppConfigManager
+{
+ private static final int BUFFER_SIZE = 1024;
+ private static final String CONFIG_FILE_CHARSET = "UTF-8";
+ private static final String CONFIG_FILE_PATH = "./config.json";
+ private static WeatherDisasterNotifyConfig appConfig = null;
+
+ public static WeatherDisasterNotifyConfig getConfig() throws IOException
+
+ {
+ if ( appConfig != null)
+ {
+ return appConfig;
+ }
+
+ ObjectMapper mapper = new ObjectMapper();
+ FileInputStream configFile = null;
+ InputStreamReader in = null;
+ StringBuffer json = null;
+ char[] buffer = new char[BUFFER_SIZE];
+
+ // 设置json属性
+ mapper.setPropertyNamingStrategy( PropertyNamingStrategy.SNAKE_CASE );
+
+ try
+ {
+ configFile = new FileInputStream( CONFIG_FILE_PATH );
+ in = new InputStreamReader( configFile, CONFIG_FILE_CHARSET );
+ json = new StringBuffer();
+
+ int length = in.read( buffer );
+
+ while (length != -1)
+ {
+ json.append( buffer );
+
+ length = in.read( buffer );
+ }
+
+ appConfig = mapper.readValue( json.toString(), WeatherDisasterNotifyConfig.class );
+ }
+ finally
+ {
+ if ( configFile != null)
+ {
+ try
+ {
+ configFile.close();
+ }
+ catch ( IOException e )
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ return appConfig;
+ }
+}
diff --git a/code/java/DisasterWarning/src/main/java/com/cpic/xim/config/WeatherDisasterNotifyConfig.java b/code/java/DisasterWarning/src/main/java/com/cpic/xim/config/WeatherDisasterNotifyConfig.java
index f3bdeaf..dd1892d 100644
--- a/code/java/DisasterWarning/src/main/java/com/cpic/xim/config/WeatherDisasterNotifyConfig.java
+++ b/code/java/DisasterWarning/src/main/java/com/cpic/xim/config/WeatherDisasterNotifyConfig.java
@@ -1,62 +1,22 @@
+/*
+ * @Author: Kane
+ * @Date: 2022-04-24 10:21:46
+ * @LastEditors: Kane
+ * @LastEditTime: 2022-05-10 16:16:28
+ * @FilePath: \DisasterWarning\src\main\java\com\cpic\xim\config\WeatherDisasterNotifyConfig.java
+ * @Description:
+ *
+ * Copyright (c) ${2022} by Kane, All Rights Reserved.
+ */
package com.cpic.xim.config;
-import java.io.FileReader;
-import java.io.IOException;
import java.util.Vector;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.PropertyNamingStrategy;
+
public class WeatherDisasterNotifyConfig
{
- private static final int BUFFER_SIZE = 1024;
-
- public static WeatherDisasterNotifyConfig load( String filePath ) throws IOException
-
- {
- WeatherDisasterNotifyConfig config = null;
- ObjectMapper mapper = new ObjectMapper();
- FileReader configFile = null;
- StringBuffer json = null;
- char[] buffer = new char[BUFFER_SIZE];
-
- // 设置json属性
- mapper.setPropertyNamingStrategy( PropertyNamingStrategy.SNAKE_CASE );
-
- try
- {
- configFile = new FileReader( filePath );
- json = new StringBuffer();
-
- int length = configFile.read( buffer );
-
- while (length != -1)
- {
- json.append( buffer );
-
- length = configFile.read( buffer );
- }
-
- config = mapper.readValue( json.toString(), WeatherDisasterNotifyConfig.class );
- }
- finally
- {
- if ( configFile != null)
- {
- try
- {
- configFile.close();
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- }
- }
-
- return config;
- }
public WeatherDisasterNotifyConfig()
{};
@@ -96,6 +56,18 @@ public class WeatherDisasterNotifyConfig
return cities;
}
+
+ public int getQueryInterval()
+ {
+ return queryInterval;
+ }
+
+ public void setQueryInterval( int queryInterval )
+ {
+ this.queryInterval = queryInterval;
+ }
+
+
public void setCities( Vector cities )
{
this.cities = cities;
@@ -121,14 +93,24 @@ public class WeatherDisasterNotifyConfig
this.wechatOfficalAccountURL = wechatOfficalAccountURL;
}
+ @JsonProperty( "title")
private String title;
+
+ @JsonProperty( "key")
private String key;
+
+ @JsonProperty( "query_url")
private String queryUrl;
+ @JsonProperty( "query_interval")
+ private int queryInterval;
+
@JsonProperty( "wechat_officalaccount_url")
private String wechatOfficalAccountURL;
+
+ @JsonProperty( "cities")
private Vector cities;
+
+ @JsonProperty( "notify_stuffs")
private Vector notifyStuffs;
-
-
}
diff --git a/code/java/DisasterWarning/src/main/java/com/cpic/xim/config/db/DBTable.java b/code/java/DisasterWarning/src/main/java/com/cpic/xim/config/db/DBTable.java
index 2c5a8e1..a41c6a8 100644
--- a/code/java/DisasterWarning/src/main/java/com/cpic/xim/config/db/DBTable.java
+++ b/code/java/DisasterWarning/src/main/java/com/cpic/xim/config/db/DBTable.java
@@ -2,7 +2,7 @@
* @Author: Kane
* @Date: 2022-04-22 17:33:30
* @LastEditors: Kane
- * @LastEditTime: 2022-04-23 23:50:20
+ * @LastEditTime: 2022-04-27 16:53:13
* @FilePath: \DisasterWarning\src\main\java\com\cpic\xim\config\db\DBTable.java
* @Description:
*
@@ -12,6 +12,8 @@ package com.cpic.xim.config.db;
import java.util.Objects;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
public class DBTable
{
public DBTable()
@@ -59,6 +61,9 @@ public class DBTable
return Objects.hash( tableName, tableDescription );
}
+ @JsonProperty( "table_name")
private String tableName;
+
+ @JsonProperty( "table_description")
private String tableDescription;
}
diff --git a/code/java/DisasterWarning/src/main/java/com/cpic/xim/config/db/OracleConfig.java b/code/java/DisasterWarning/src/main/java/com/cpic/xim/config/db/OracleConfig.java
index 4caaccd..ff6c3ca 100644
--- a/code/java/DisasterWarning/src/main/java/com/cpic/xim/config/db/OracleConfig.java
+++ b/code/java/DisasterWarning/src/main/java/com/cpic/xim/config/db/OracleConfig.java
@@ -2,7 +2,7 @@
* @Author: Kane
* @Date: 2022-04-22 17:33:30
* @LastEditors: Kane
- * @LastEditTime: 2022-04-23 23:51:46
+ * @LastEditTime: 2022-04-25 21:33:07
* @FilePath: \DisasterWarning\src\main\java\com\cpic\xim\config\db\OracleConfig.java
* @Description:
*
@@ -11,7 +11,11 @@
package com.cpic.xim.config.db;
import java.util.Vector;
+import com.fasterxml.jackson.annotation.JsonProperty;
+/**
+ * @Description oracle数据库相关参数对象。
+ */
public class OracleConfig
{
@@ -45,6 +49,17 @@ public class OracleConfig
this.jdbcURL = jdbcURL;
}
+
+ public String getTableSpace()
+ {
+ return tableSpace;
+ }
+
+ public void setTableSpace( String tableSpace )
+ {
+ this.tableSpace = tableSpace;
+ }
+
public String getUserName()
{
return userName;
@@ -75,10 +90,24 @@ public class OracleConfig
this.tables = tables;
}
+ @JsonProperty( "tns_name")
private String tnsName;
+
+ @JsonProperty( "ip_addr")
private String ipAddr;
+
+ @JsonProperty( "jdbc_url")
private String jdbcURL;
+
+ @JsonProperty( "table_space")
+ private String tableSpace;
+
+ @JsonProperty( "user_name")
private String userName;
+
+ @JsonProperty( "password")
private String password;
+
+ @JsonProperty( "tables")
private Vector tables;
}
diff --git a/code/java/DisasterWarning/src/main/java/com/cpic/xim/config/db/OracleConfigManager.java b/code/java/DisasterWarning/src/main/java/com/cpic/xim/config/db/OracleConfigManager.java
new file mode 100644
index 0000000..3a32004
--- /dev/null
+++ b/code/java/DisasterWarning/src/main/java/com/cpic/xim/config/db/OracleConfigManager.java
@@ -0,0 +1,77 @@
+/*
+ * @Author: Kane
+ * @Date: 2022-04-25 21:45:12
+ * @LastEditors: Kane
+ * @LastEditTime: 2022-05-03 22:34:37
+ * @FilePath: \DisasterWarning\src\main\java\com\cpic\xim\config\db\OracleConfigManager.java
+ * @Description: oracle数据库配置文件加载类
+ *
+ * Copyright (c) ${2022} by Kane, All Rights Reserved.
+ */
+package com.cpic.xim.config.db;
+
+import java.io.*;
+
+import com.fasterxml.jackson.databind.*;
+
+public class OracleConfigManager
+{
+ private static final String CONFIG_FILE_PATH = "./db.json";
+ private static final String CONFIG_FILE_CHARSET = "UTF-8";
+ private static final int BUFFER_SIZE = 1024;
+ private static OracleConfig dbConfig = null;
+
+ private OracleConfigManager()
+ {}
+
+ public static OracleConfig getOracleConfig() throws IOException
+ {
+ FileInputStream file = null;
+ InputStreamReader in = null;
+ StringBuffer json = null;
+ char[] buffer = new char[BUFFER_SIZE];
+
+ if ( dbConfig != null)
+ {
+ return dbConfig;
+ }
+
+ try
+ {
+ file = new FileInputStream( CONFIG_FILE_PATH );
+ in = new InputStreamReader( file, CONFIG_FILE_CHARSET );
+ json = new StringBuffer();
+
+ int count = in.read( buffer );
+
+ while (count != -1)
+ {
+ json.append( buffer );
+
+ count = in.read( buffer );
+ }
+
+ ObjectMapper mapper = new ObjectMapper();
+
+ dbConfig = mapper.readValue( json.toString(), OracleConfig.class );
+ }
+ catch ( IOException error )
+ {
+ throw error;
+ }
+ finally
+ {
+ try
+ {
+ file.close();
+ }
+ catch ( Exception error )
+ {
+ error.printStackTrace();
+ }
+
+ }
+
+ return dbConfig;
+ }
+}
diff --git a/code/java/DisasterWarning/src/main/java/com/cpic/xim/notify/disaster/QWeatherDisasterWarning.java b/code/java/DisasterWarning/src/main/java/com/cpic/xim/notify/disaster/QWeatherDisasterWarning.java
index e527a88..ec911b6 100644
--- a/code/java/DisasterWarning/src/main/java/com/cpic/xim/notify/disaster/QWeatherDisasterWarning.java
+++ b/code/java/DisasterWarning/src/main/java/com/cpic/xim/notify/disaster/QWeatherDisasterWarning.java
@@ -1,23 +1,24 @@
+/*
+ * @Author: Kane
+ * @Date: 2022-04-24 10:21:46
+ * @LastEditors: Kane
+ * @LastEditTime: 2022-04-24 11:28:58
+ * @FilePath: \DisasterWarning\src\main\java\com\cpic\xim\notify\disaster\QWeatherDisasterWarning.java
+ * @Description:
+ *
+ * Copyright (c) ${2022} by Kane, All Rights Reserved.
+ */
package com.cpic.xim.notify.disaster;
+import java.util.Date;
import java.util.Vector;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonProperty;
public class QWeatherDisasterWarning
{
- public QWeatherDisasterWarning( String code,
- String updateTime,
- String fxLink,
- Vector warning,
- QWeatherDisasterWarningRefer refer )
- {
- this.code = code;
- this.updateTime = updateTime;
- this.fxLink = fxLink;
- this.warning = warning;
- this.refer = refer;
- }
-
- public QWeatherDisasterWarning() {}
+ public QWeatherDisasterWarning()
+ {}
public String getCode()
{
@@ -29,12 +30,12 @@ public class QWeatherDisasterWarning
this.code = code;
}
- public String getUpdateTime()
+ public Date getUpdateTime()
{
return updateTime;
}
- public void setUpdateTime( String updateTime )
+ public void setUpdateTime( Date updateTime )
{
this.updateTime = updateTime;
}
@@ -69,9 +70,19 @@ public class QWeatherDisasterWarning
this.refer = refer;
}
- private String code;
- private String updateTime;
- private String fxLink;
+ @JsonProperty( "code")
+ private String code;
+
+ @JsonProperty( "updateTime")
+ @JsonFormat( pattern = "yyyy-MM-dd\'T\'HH:mmXXX")
+ private Date updateTime;
+
+ @JsonProperty( "fxLink")
+ private String fxLink;
+
+ @JsonProperty( "warning")
private Vector warning;
- private QWeatherDisasterWarningRefer refer;
+
+ @JsonProperty( "refer")
+ private QWeatherDisasterWarningRefer refer;
}
diff --git a/code/java/DisasterWarning/src/main/java/com/cpic/xim/notify/disaster/QWeatherDisasterWarningItem.java b/code/java/DisasterWarning/src/main/java/com/cpic/xim/notify/disaster/QWeatherDisasterWarningItem.java
index ad4ba37..53397ea 100644
--- a/code/java/DisasterWarning/src/main/java/com/cpic/xim/notify/disaster/QWeatherDisasterWarningItem.java
+++ b/code/java/DisasterWarning/src/main/java/com/cpic/xim/notify/disaster/QWeatherDisasterWarningItem.java
@@ -1,79 +1,61 @@
package com.cpic.xim.notify.disaster;
+import java.util.Date;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonProperty;
//import com.fasterxml.jackson.annotation.JsonIgnore;
public class QWeatherDisasterWarningItem
{
- public QWeatherDisasterWarningItem() {}
- public QWeatherDisasterWarningItem( String id,
- String sender,
- String pubTime,
- String title,
- String status,
- String level,
- String type,
- String typeName,
- String text,
- String related,
- String urgency, String certainty )
+ public QWeatherDisasterWarningItem()
+ {}
+
+ public QWeatherDisasterWarningItem( String id, String sender, Date pubTime, String title,
+ String status, String level, String type, String typeName, String text, String related,
+ String urgency, String certainty)
{
- this.id = id;
- this.sender = sender;
- this.pubTime = pubTime;
- this.title = title;
- this.status = status;
- this.level = level;
- this.type = type;
+ this.id = id;
+ this.sender = sender;
+ this.pubTime = pubTime;
+ this.title = title;
+ this.status = status;
+ this.level = level;
+ this.type = type;
this.typeName = typeName;
- this.text = text;
- this.related = related;
- this.urgency = urgency;
+ this.text = text;
+ this.related = related;
+ this.urgency = urgency;
this.certainty = certainty;
}
@Override
public boolean equals( Object o )
{
- if ( this == o )
+ if ( this == o)
{
return true;
}
- if ( o == null || getClass() != o.getClass() )
+ if ( o == null || getClass() != o.getClass())
{
return false;
}
QWeatherDisasterWarningItem that = (QWeatherDisasterWarningItem) o;
- return id.equals( that.id ) && Objects.equals( sender, that.sender ) && Objects.equals( pubTime,
- that.pubTime ) && Objects.equals(
- title,
- that.title ) && Objects.equals( status, that.status ) && Objects.equals( level,
- that.level ) && Objects.equals(
- type,
- that.type ) && Objects.equals( typeName, that.typeName ) && Objects.equals( text,
- that.text ) && Objects.equals(
- related,
- that.related ) && Objects.equals( urgency, that.urgency ) && Objects.equals( certainty,
- that.certainty );
+ return id.equals( that.id ) && Objects.equals( sender, that.sender )
+ && Objects.equals( pubTime, that.pubTime ) && Objects.equals( title, that.title )
+ && Objects.equals( status, that.status ) && Objects.equals( level, that.level )
+ && Objects.equals( type, that.type ) && Objects.equals( typeName, that.typeName )
+ && Objects.equals( text, that.text ) && Objects.equals( related, that.related )
+ && Objects.equals( urgency, that.urgency )
+ && Objects.equals( certainty, that.certainty );
}
@Override
public int hashCode()
{
- return Objects.hash( id,
- sender,
- pubTime,
- title,
- status,
- level,
- type,
- typeName,
- text,
- related,
- urgency,
- certainty );
+ return Objects.hash( id, sender, pubTime, title, status, level, type, typeName, text,
+ related, urgency, certainty );
}
public String getId()
@@ -96,12 +78,12 @@ public class QWeatherDisasterWarningItem
this.sender = sender;
}
- public String getPubTime()
+ public Date getPubTime()
{
return pubTime;
}
- public void setPubTime( String pubTime )
+ public void setPubTime( Date pubTime )
{
this.pubTime = pubTime;
}
@@ -198,8 +180,11 @@ public class QWeatherDisasterWarningItem
private String id;
private String sender;
- @JsonFormat(pattern="yyyy-MM-dd'T'HH:mm")
- private String pubTime;
+
+ @JsonProperty( "pubTime")
+ @JsonFormat( shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd\'T\'HH:mmXXX")
+ private Date pubTime;
+
private String title;
private String status;
private String level;
diff --git a/code/java/DisasterWarning/src/main/java/com/cpic/xim/wechat/officalAccount/sendMessage.java b/code/java/DisasterWarning/src/main/java/com/cpic/xim/wechat/officalAccount/sendMessage.java
index 221f4ca..198e768 100644
--- a/code/java/DisasterWarning/src/main/java/com/cpic/xim/wechat/officalAccount/sendMessage.java
+++ b/code/java/DisasterWarning/src/main/java/com/cpic/xim/wechat/officalAccount/sendMessage.java
@@ -2,7 +2,7 @@
* @Author: Kane
* @Date: 2022-04-22 10:53:49
* @LastEditors: Kane
- * @LastEditTime: 2022-04-23 23:46:54
+ * @LastEditTime: 2022-05-06 11:14:32
* @FilePath: \DisasterWarning\src\main\java\com\cpic\xim\wechat\officalAccount\sendMessage.java
* @Description: 用来推送公众号消息的程序库。
*
@@ -10,13 +10,20 @@
*/
package com.cpic.xim.wechat.officalAccount;
+import com.cpic.xim.config.db.OracleConfigManager;
+import com.cpic.xim.config.db.OracleConfig;
import com.fasterxml.jackson.annotation.JsonProperty;
-
+import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Vector;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
import com.cpic.xim.notify.disaster.*;
import com.cpic.xim.httpUtil.HttpUtils;
@@ -31,7 +38,7 @@ public class sendMessage
/**
* 推送天气灾害预警!接口文档参考 彭奕洁 编写《消息发送接口调用文档》
- *
+ * 使用 post 方式,请求体内容以最基础的 post 格式。
* @param officalAccountURL 产险厦门分公司公众号接口网址
* @param warning 灾害预警对象
*/
@@ -49,7 +56,7 @@ public class sendMessage
headers.put( "Content-Type", "application/x-www-form-urlencoded;charset=UTF-8" );
// 遍历消息,将消息推送出去。
- for ( QWeatherDisasterWarningItem item : warningItems)
+ for ( QWeatherDisasterWarningItem item : warningItems )
{
// 拼接消息内容
String title = item.getTitle();
@@ -57,7 +64,6 @@ public class sendMessage
String color = warningLevel.keySet().contains( item.getLevel() )
? warningLevel.get( item.getLevel() )
: "#000000";
-
requestBody = new StringBuilder();
requestBody.append( "tplid=57&groupid=1&first=尊敬的#realname#,您好!&" );
@@ -69,13 +75,188 @@ public class sendMessage
{
HttpUtils.postHttpRequest( officalAccountURL, headers, requestBody.toString() );
}
- catch (MalformedURLException error)
+ catch ( MalformedURLException error )
{
error.printStackTrace();
}
}
}
+ /**
+ * 检查预警是否已经推送过,通过 QWeatherDisasterWarningItem 对象的 id 属性。
+ * 查询 oracle xmcx1 数据库 wechat 表空间下 weather_disaster_notify 表,
+ * 统计 warningID 的数量,如果不为0,说明该预警已经保存过,视为已经推送过。
+ * @param warningID 预警的id
+ * @return 如果推送过,返回false,否则返回 true。
+ */
+ public static boolean checkWarningHasSended( String warningID )
+ throws ClassNotFoundException, SQLException, IOException
+ {
+ boolean result = false;
+
+ OracleConfig dbConfig = OracleConfigManager.getOracleConfig();;
+
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+
+ String jdbcURL = dbConfig.getJdbcURL();
+ String userName = dbConfig.getUserName();
+ String password = dbConfig.getPassword();
+ String sql = "select count(*) from weather_disaster_notify where notify_id = ?";
+
+ // Logger logger = Logger.getLogger( "com.cpicxim.wechat.officalAccount.sendMessage" );
+
+ try
+ {
+ Class.forName( "oracle.jdbc.driver.OracleDriver" );
+
+ conn = DriverManager.getConnection( jdbcURL, userName, password );
+ stmt = conn.prepareStatement( sql );
+ stmt.setString( 1, warningID );
+
+ rs = stmt.executeQuery();
+
+ if ( rs.next() && rs.getInt( 1 ) == 0)
+ {
+ result = true;
+ }
+ }
+ finally
+ {
+ try
+ {
+ if ( rs != null)
+ {
+ rs.close();
+ }
+ }
+ catch ( Exception error )
+ {
+ error.printStackTrace();
+ }
+
+ try
+ {
+ if ( stmt != null)
+ {
+ stmt.close();
+ }
+ }
+ catch ( Exception error )
+ {
+ error.printStackTrace();
+ }
+
+ try
+ {
+ if ( conn != null)
+ {
+ conn.close();
+ }
+ }
+ catch ( Exception error )
+ {
+ error.printStackTrace();
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * 保存天气预警警报数据。
+ * 保存至 oracle xmcx1 数据库 wechat 表空间下 weather_disaster_notify 表。
+ * 保存的数据用来判断预警是否已经推送过,以防止反复推送数据。
+ * @param city 城市名称
+ * @param warning 预警数据,为 QWeatherDisasterWarningItem 对象。
+ * @throws SQLException 执行sql时可能抛出的异常。出现sql异常,就回滚事务。
+ * @throws IOException 读取数据库配置文件时可能抛出的异常。
+ * @throws ClassNotFoundException 加载oracle jdbc驱动时可能抛出的异常。
+ */
+ public static void saveWeatherDisasterWarning( String city, QWeatherDisasterWarning warnings )
+ throws SQLException, IOException, ClassNotFoundException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+
+ String sql = "insert into weather_disaster_notify(notify_id, sender, city,"
+ + "warning_level, warning_type_code, warning_type_name, title,"
+ + "text, pub_time) values( ?,?,?,?,?,?,?,?,?)";
+
+ OracleConfig dbConfig = OracleConfigManager.getOracleConfig();
+
+ String jdbcURL = dbConfig.getJdbcURL();
+ String userName = dbConfig.getUserName();
+ String password = dbConfig.getPassword();
+
+ try
+ {
+ Class.forName( "oracle.jdbc.driver.OracleDriver" );
+
+ conn = DriverManager.getConnection( jdbcURL, userName, password );
+ stmt = conn.prepareStatement( sql );
+
+ for ( QWeatherDisasterWarningItem warning : warnings.getWarning() )
+ {
+ java.sql.Timestamp pubTime =
+ new java.sql.Timestamp( warning.getPubTime().getTime() );
+
+ stmt.setString( 1, warning.getId() );
+ stmt.setString( 2, warning.getSender() );
+ stmt.setString( 3, city );
+ stmt.setString( 4, warning.getLevel() );
+ stmt.setString( 5, warning.getType() );
+ stmt.setString( 6, warning.getTypeName() );
+ stmt.setString( 7, warning.getTitle() );
+ stmt.setString( 8, warning.getText() );
+ stmt.setTimestamp( 9, pubTime );
+
+ stmt.execute();
+ }
+
+ // 没有问题就提交
+ conn.commit();
+ }
+ catch ( SQLException error )
+ {
+ // 出现sql错误,就回滚!
+ if ( conn != null)
+ {
+ conn.rollback();
+ }
+
+ throw error;
+ }
+ finally
+ {
+ try
+ {
+ if ( stmt != null)
+ {
+ stmt.close();
+ }
+ }
+ catch ( Exception error )
+ {
+ error.printStackTrace();
+ }
+
+ try
+ {
+ if ( conn != null)
+ {
+ conn.close();
+ }
+ }
+ catch ( Exception error )
+ {
+ error.printStackTrace();
+ }
+ }
+ }
+
+
static
{
// 预警级别色彩
diff --git a/code/java/DisasterWarning/src/main/resources/assembly.xml b/code/java/DisasterWarning/src/main/resources/assembly.xml
new file mode 100644
index 0000000..e69de29
diff --git a/code/java/DisasterWarning/src/main/resources/logging.properties b/code/java/DisasterWarning/src/main/resources/logging.properties
new file mode 100644
index 0000000..707450e
--- /dev/null
+++ b/code/java/DisasterWarning/src/main/resources/logging.properties
@@ -0,0 +1,10 @@
+
+handlers = java.util.logging.ConsoleHandler, java.util.logging.FileHandler
+
+.level = INFO
+
+java.util.logging.FileHandler.pattern = ./logs/log_%u.log
+java.util.logging.FileHandler.limit = 50000
+java.util.logging.FileHandler.count = 10
+java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
+java.util.logging.FileHandler.append = true;
diff --git a/code/java/DisasterWarning/src/test/java/com/cpic/xim/wechat/officalAccount/sendMessageTest.java b/code/java/DisasterWarning/src/test/java/com/cpic/xim/wechat/officalAccount/sendMessageTest.java
index 2cda05e..90078f6 100644
--- a/code/java/DisasterWarning/src/test/java/com/cpic/xim/wechat/officalAccount/sendMessageTest.java
+++ b/code/java/DisasterWarning/src/test/java/com/cpic/xim/wechat/officalAccount/sendMessageTest.java
@@ -2,7 +2,7 @@
* @Author: Kane
* @Date: 2022-04-22 10:53:49
* @LastEditors: Kane
- * @LastEditTime: 2022-04-23 23:44:54
+ * @LastEditTime: 2022-05-10 11:33:41
* @FilePath: \DisasterWarning\src\test\java\com\cpic\xim\wechat\officalAccount\sendMessageTest.java
* @Description:
*
@@ -12,10 +12,10 @@ package com.cpic.xim.wechat.officalAccount;
import com.cpic.xim.notify.disaster.QWeatherDisasterWarning;
-import org.junit.Test;
import static org.junit.Assert.*;
import com.cpic.xim.httpUtil.*;
import java.io.IOException;
+
import java.util.*;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -32,7 +32,7 @@ public class sendMessageTest
{
// sendMessage.postNotifyMessageJSON( url, "警报", "警报标题", "警报内容!" );
}
- catch (Exception error)
+ catch ( Exception error )
{
fail( "测试失败!" );
}
@@ -54,13 +54,13 @@ public class sendMessageTest
{
HttpUtils.postHttpRequest( url, headers, param );
}
- catch (Exception error)
+ catch ( Exception error )
{
}
}
- @Test
+ // @Test
public void testSendWeatherDisasterWarning() throws IOException
{
String warningJSON =
@@ -72,11 +72,29 @@ public class sendMessageTest
QWeatherDisasterWarning warning =
mapper.readValue( warningJSON, QWeatherDisasterWarning.class );
- sendMessage.sendWeatherDisasterWarning( url, warning );
+ String city = "东山县";
+
+
+ sendMessage.saveWeatherDisasterWarning( city, warning );
}
- catch (Exception error)
+ catch ( Exception error )
{
fail( error.getMessage() );
}
}
+
+ // @Test
+ public void testCheckWarningHasSended()
+ {
+ String warningID = "10123060820220422061200476313081";
+
+ try
+ {
+ sendMessage.checkWarningHasSended( warningID );
+ }
+ catch ( Exception error )
+ {
+ error.printStackTrace();
+ }
+ }
}
diff --git a/应用/1.0/config.json b/应用/1.0/config.json
new file mode 100644
index 0000000..3795a43
--- /dev/null
+++ b/应用/1.0/config.json
@@ -0,0 +1,19 @@
+{
+ "title": "天气灾害预警配置文件",
+ "key": "fe9fa8eeeb6f4301a92541eed565dd15",
+ "query_url": "https://devapi.qweather.com/v7/warning/now?",
+ "wechat_officalaccount_url": "https://cxxmwx.cpic.com.cn/app/index.php?i=2&c=entry&do=send_group_tpl_api&m=ok_tplmessage",
+ "query_interval": 10,
+ "cities": [
+ {
+ "city_name": "厦门",
+ "city_code": "101230201"
+ }
+ ],
+ "notify_stuffs": [
+ {
+ "stuff_name": "王炜",
+ "mobile_phone": "15959215339"
+ }
+ ]
+}
diff --git a/应用/1.0/db.json b/应用/1.0/db.json
new file mode 100644
index 0000000..a8f5ddd
--- /dev/null
+++ b/应用/1.0/db.json
@@ -0,0 +1,14 @@
+{
+ "tns_name": "xmcx1",
+ "ip_addr": "10.39.0.86",
+ "jdbc_url": "jdbc:oracle:thin:@10.39.0.86:1521:xmcx1",
+ "table_space": "wechat",
+ "user_name": "wechat",
+ "password": "@rn7Q+t5zeyKIZ~s",
+ "tables": [
+ {
+ "table_name": "weather_disaster_notify",
+ "table_description": "天气预警消息表"
+ }
+ ]
+}
diff --git a/应用/1.0/logging.properties b/应用/1.0/logging.properties
new file mode 100644
index 0000000..f82b56f
--- /dev/null
+++ b/应用/1.0/logging.properties
@@ -0,0 +1,10 @@
+
+handlers = java.util.logging.ConsoleHandler, java.util.logging.FileHandler
+
+.level = INFO
+
+java.util.logging.FileHandler.pattern = ./logs/log_%u.log
+java.util.logging.FileHandler.limit = 50000
+java.util.logging.FileHandler.count = 1
+java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
+java.util.logging.FileHandler.append = true;