Commit db39106e by jscat

titan cloud project;

1, init project;
parent 2e8a1387
usage: 从baosock|wind同步数据到titan数据库
\ No newline at end of file
# -*- coding: utf-8 -*-
# python环境:python3.7
# apscheduler版本:3.6.1
from apscheduler.schedulers.blocking import BlockingScheduler
from threading import Thread
from datetime import datetime
from datetime import datetime, timedelta
from titan_data_function import Data
from titan_table_structure import Base
import titan_data_settings as settings
class Demo:
def __init__(self):
# 创建请求数据线程
self._thread_data = Thread(target=self.get_data)
self.go = Data(settings.ts_token)
def start(self):
"""
线程启动函数
"""
self._thread_data.start()
def get_calendar(self):
"""
获取数据
"""
self.go.get_AShareCalendar("2010-01-01", "2021-02-30", 0)
print("calendar," + str(datetime.now()))
def get_month_calendar(self):
"""
获取Calendar数据
"""
today = datetime.today()
start_date, end_date = self.go.get_current_month_start_and_end(str(today))
self.go.get_AShareCalendar(start_date=start_date, end_date=end_date, type=1)
print("calendar," + str(datetime.now()))
def get_description(self):
"""
获取Description数据
"""
date = datetime.now()
self.go.get_AShareDescription(date=date, type=0)
print("description," + str(datetime.now()))
def get_data(self):
"""
使用apscheduler定时框架创建定时任务
"""
# 创建调度器对象
scheduler = BlockingScheduler()
# 添加定时任务 每月1号早上8:30 更新当月交易日历
scheduler.add_job(self.get_month_calendar, 'cron', month='1-12', day='1', hour='8', minute='30', name="calendar")
# 添加定时任务 08:00; 09:00;12:30 更新当天A股资料
scheduler.add_job(self.get_description, 'cron', day_of_week='mon-fri', hour=8, minute=0, name="description")
scheduler.add_job(self.get_description, 'cron', day_of_week='mon-fri', hour=9, minute=0, name="description")
scheduler.add_job(self.get_description, 'cron', day_of_week='mon-fri', hour=12, minute=30, name="description")
# 启动调度器,后台监控定时任务,到点执行
scheduler.start()
if __name__== '__main__':
print("start")
demo = Demo()
demo.start()
import pandas as pd
import tushare as ts
import baostock as bs
import pymysql
import traceback
import time
import calendar
from datetime import datetime
import titan_data_settings as settings
from urllib import parse
import logging
from sqlalchemy import create_engine
from titan_table_structure import Base
from dateutil.relativedelta import relativedelta
from sqlalchemy import text
import re
'''
author: jscat 2021/02/02
'''
'''
初始化函数
:param token:tushare pro的token
'''
class Data:
def __init__(self, token):
# 创建请求数据线程
self.token = token
self.engine = create_engine(settings.mysql_url, encoding='utf-8', echo=False)
# delete数据并且append
def delete_append(self, data, table_name, info):
"""删除mysql表所有数据,to_sql追加新数据"""
try:
with self.engine.begin() as conn:
conn.execute('DELETE FROM ' + table_name)
# rollback sql
data.to_sql(table_name, conn, if_exists='append', index=False)
self.update_log(table_name, conn, info)
except Exception as ee:
logging.error('delete_append failed: '+info, ee)
self.error_log(table_name, self.engine, info, ee.args)
# keep数据并且append
def keep_append(self, data, table_name, info):
"""保留mysql表所有数据,to_sql追加新数据"""
try:
with self.engine.begin() as conn:
# rollback sql
data.to_sql(table_name, conn, if_exists='append', index=False)
self.update_log(table_name, conn, info)
except Exception as ee:
logging.error('keep_append failed: '+info, ee)
self.error_log(table_name, self.engine, info, ee.args)
# 同步更新日志表
def update_log(self, table_name, conn, info):
df = pd.DataFrame({'TARGET_TABLE': table_name, 'UPDATE_INFO': info, 'CREATE_DT': str(datetime.now())}, index=[0])
df.to_sql("tbl_update_log", conn, if_exists='append', index=False)
# 同步更新错误日志表
def error_log(self, table_name, conn, info, log):
df = pd.DataFrame({'TARGET_TABLE': table_name, 'UPDATE_INFO': info, 'ERROR_INFO': str(log), 'CREATE_DT': str(datetime.now())}, index=[0])
df.to_sql("tbl_error_log", conn, if_exists='append', index=False)
'''
start_date='20210101', end_date='20311231'
FieldType Comment
OBJECT_ID varchar(100) NULL对象ID
TRADE_DAYS varchar(8) NOT NULL Trading Day, 20210201
S_INFO_EXCHMARKET varchar(40) NOT NULL Exchange Name (English), SSE:上海交易所 | SZSE:深圳交易所
SOURCE_TYPE varchar(10) NULL BS: baostock | WD: wind
'''
def get_AShareCalendar(self, start_date, end_date, type):
# 此方法连接数据库,密码可以输入特殊字符串
print('bs连接成功')
lg = bs.login()
# 显示登陆返回信息
print('login respond error_code:' + lg.error_code)
print('login respond error_msg:' + lg.error_msg)
#### 获取交易日信息 ####
rs = bs.query_trade_dates(start_date=start_date, end_date=end_date)
print('query_trade_dates respond error_code:' + rs.error_code)
print('query_trade_dates respond error_msg:' + rs.error_msg)
#### 打印结果集 ####
data_list = []
while (rs.error_code == '0') & rs.next():
# 获取一条记录,将记录合并在一起
data_list.append(rs.get_row_data())
df_all = pd.DataFrame(data_list, columns=rs.fields)
# 删选数据
df_all = df_all[df_all['is_trading_day'] == '1']
df_all = df_all.drop('is_trading_day', axis=1)
# 本地储存前一定要先转化成Wind-Compatible日期格式先
df_all['calendar_date'] = df_all['calendar_date'].str.replace('-', '')
# 对获取的数据列名称进行重命名适应Wind format
df_all = df_all.rename(columns={'calendar_date': 'TRADE_DAYS'})
# 补全其他字段
df_all['OBJECT_ID'] = ""
df_all['SOURCE_TYPE'] = "BS"
df_all['S_INFO_EXCHMARKET'] = "SSE"
# data operation
info = "update record: "+str(start_date)+"_"+str(end_date)
if type == 0:
self.delete_append(df_all, 'tbl_AShareCalendar', info)
else:
self.keep_append(df_all, 'tbl_AShareCalendar', info)
'''
start_date='20210101', end_date='20311231'
OBJECT_ID varchar(100) NULL对象ID
S_INFO_CODE varchar(40) NOT NULL交易代码
S_INFO_NAME varchar(50) NULL 证券简称
S_INFO_COMPNAME varchar(100) NULL 公司中文名字
S_INFO_COMPNAMEENG varchar(100) NULL 公司英文名字
S_INFO_ISINCODE varchar(40) NULL ISIN CODE
S_INFO_EXCHMARKET varchar(40) NULL 交易所, SSE: 上交所; SZSE:深交所
S_INFO_LISTBOARD varchar(10) NULL 上市板类型; 434004000:主板; 434003000:中小企业板; 434001000:创业板
S_INFO_LISTBOARDNAME varchar(10) NULL 上市板, 主板, 创业板, 中小企业板
'''
def get_AShareDescription(self, date, type):
# 登陆系统
lg = bs.login()
# 显示登陆返回信息
print('login respond error_code:' + lg.error_code)
print('login respond error_msg:' + lg.error_msg)
# 获取证券基本资料
rs = bs.query_stock_basic()
# rs = bs.query_stock_basic(code_name="浦发银行") # 支持模糊查询
print('query_stock_basic respond error_code:' + rs.error_code)
print('query_stock_basic respond error_msg:' + rs.error_msg)
# 打印结果集
data_list = []
while (rs.error_code == '0') & rs.next():
# 获取一条记录,将记录合并在一起
data_list.append(rs.get_row_data())
df = pd.DataFrame(data_list, columns=rs.fields)
# 结果集输出到csv文件
# 筛选出type=='1'(股票)和status=='1'(可用)的数据
print(len(df))
df = df[(df['type'] == '1') & (df['status'] == '1')]
print(len(df))
#
df['S_INFO_CODE'] = df['code'].apply(lambda x: x.split('.')[1])
df['S_INFO_EXCHMARKET'] = df['code'].apply(lambda x: x.split('.')[0])
df['S_INFO_EXCHMARKET'] = df['S_INFO_EXCHMARKET'].map(lambda x: re.sub('sh', 'SSE', x))
df['S_INFO_EXCHMARKET'] = df['S_INFO_EXCHMARKET'].map(lambda x: re.sub('sz', 'SZSE', x))
df['S_INFO_NAME'] = df['code_name']
df = df.drop(['code', 'code_name', 'ipoDate', 'outDate', 'type', 'status'], axis=1)
# data operation
info = "update record: "+str(date)
if type == 0:
self.delete_append(df, 'tbl_AShareDescription', info)
else:
self.keep_append(df, 'tbl_AShareDescription', info)
# Deprecated
def get_all_stockdata(self, start_date, end_date):
# 此方法连接数据库,密码可以输入特殊字符串
engine = create_engine(settings.mysql_url)
print('数据库连接成功')
ts.set_token(self.token)
pro = ts.pro_api()
trade_d = pro.trade_cal(exchange='SSE', is_open='1',start_date=start_date,end_date=end_date, fields='cal_date')
for date in trade_d['cal_date'].values:
df_basic = pro.stock_basic(exchange='', list_status='L') #再获取所有股票的基本信息
df_daily = pro.daily(trade_date=date) # 先获得所有股票的行情数据,成交额单位是千元,成交量是手
df_daily_basic = pro.daily_basic(ts_code='', trade_date=date,fields='ts_code, turnover_rate, turnover_rate_f,'
' volume_ratio, pe, pe_ttm, pb, ps, ps_ttm,'
' dv_ratio, dv_ttm, total_share, float_share,'
' free_share, total_mv, circ_mv ') #获取每日指标,单位是万股,万元
df_first = pd.merge(left=df_basic, right=df_daily, on='ts_code', how='outer') # on='ts_code'以ts_code为索引,合并数据,how='outer',取并集
df_all = pd.merge(left=df_first, right=df_daily_basic, on='ts_code', how='outer')
# 数据清洗,删除symbol列数据,跟ts_code数据重复
df_all = df_all.drop('symbol', axis=1)
for w in ['name', 'area', 'industry', 'market']: # 在'name', 'area', 'industry', 'market'列内循环填充NaN值
df_all[w].fillna('问题股', inplace=True)
#df_all['amount'] = df_all['amount'] / 100000 # 千转亿
#df_all['circ_mv'] = df_all['circ_mv'] / 10000 # 万转亿
#df_all['total_mv'] = df_all['total_mv'] / 10000 # 万转亿
df_all['ts_code'] = df_all['ts_code'].astype(str) # 强制转换成str字符串格式
df_all['listart_date'] = pd.to_datetime(df_all['listart_date']) # 本地储存前一定要先转化成日期格式先
df_all['trade_date'] = pd.to_datetime(df_all['trade_date'])
#对获取的股票数据列名称进行重命名以方便阅读
df_all = df_all.rename(columns={'ts_code': '股票代码', 'name': '股票名称', 'area': '所在地域', 'industry': '行业'
, 'market': '市场类型', 'listart_date': '上市日期', 'trade_date': '交易日期', 'change': '涨跌额'
, 'pct_chg': '涨跌幅', 'vol': '成交量(手)', 'amount': '成交额(千元)', 'turnover_rate': '换手率(%)'
, 'turnover_rate_f': '流通换手率', 'volume_ratio': '量比', 'pe': '市盈率', 'pe_ttm': '滚动市盈率'
, 'pb': '市净率', 'ps': '市销率', 'ps_ttm': '滚动市销率', 'dv_ratio': '股息率'
, 'dv_ttm': '滚动股息率', 'total_share': '总股本(万股)', 'float_share': '流通股本 (万股)'
, 'free_share': '自由流通股本(万股)', 'total_mv': '总市值 (万元)', 'circ_mv': '流通市值(万元)'})
#亏损的为空值
engine.execute('drop table if exists {}_ts;'.format(date)) #删除重复的数据表
print('%s is downloading....' % (str(date)))
df_all.to_sql('{}_ts'.format(date),engine,index=False)
print('{}成功导入数据库'.format(date))
# 获取当月起止日期
def get_current_month_start_and_end(self, date):
"""
年份 date(2017-09-08格式)
:param date:
:return:本月第一天日期和本月最后一天日期
"""
date = str(date)
if date.count('-') != 2:
raise ValueError('- is error')
year, month = str(date).split('-')[0], str(date).split('-')[1]
end = calendar.monthrange(int(year), int(month))[1]
start_date = '%s-%s-01' % (year, month)
end_date = '%s-%s-%s' % (year, month, end)
return start_date, end_date
if __name__=='__test__':
data = Data(settings.ts_token)
start = "2020-02-01"
for i in range(1):
date = pd.to_datetime(start) + relativedelta(months=+i) # 当前日期往后推i个月
date_str = date.strftime("%Y-%m-%d")
start_date, end_date = data.get_current_month_start_and_end(date)
print(start_date, end_date)
data.get_AShareCalendar(start_date=start_date, end_date=end_date, type=1)
time.sleep(10)
print("finish")
if __name__=='__main__':
data = Data(settings.ts_token)
date = datetime.now()
data.get_AShareDescription(date=date, type=0)
print("finish")
import pandas as pd
import tushare as ts
import baostock as bs
import pymysql
from urllib import parse
from sqlalchemy import create_engine
ts_token = "33261e14a0f45680d6afdc86b85bc0c4c80ba6b8dc199d7313a30838"
mysql_url = "mysql+pymysql://sharpe_dev:123456@47.99.110.89:3306/sharpe?charset=utf8"
ip_address = "47.99.110.89"
ip_port = 3306
db_name = "sharpe"
user_name = "sharpe_dev"
password ="123456"
\ No newline at end of file
# coding=utf-8
from sqlalchemy import Column, String, Float
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
import titan_data_settings as settings
# 创建连接
engine = create_engine(settings.mysql_url, encoding='utf-8', echo=False)
# 生成orm基类
Base = declarative_base()
class AShareCalendar(Base):
"""交易日历
"""
__tablename__ = 'tbl_AShareCalendar'
OBJECT_ID = Column(String(100), comment="对象ID") # 对象ID
TRADE_DAYS = Column(String(8), primary_key=True, comment="Trading Day, 20210201") # Trading Day, 20210201
S_INFO_EXCHMARKET = Column(String(40), primary_key=True, comment="Exchange Name (English), SSE:上海交易所 | SZSE:深圳交易所") # Exchange Name (English), SSE:上海交易所 | SZSE:深圳交易所
SOURCE_TYPE = Column(String(10), comment="BS: baostock | WD: wind") # BS: baostock | WD: wind
#
Base.metadata.create_all(engine)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>eureka</artifactId>
<groupId>cn.com.titan</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>eureka-api</artifactId>
<properties>
<spring-security.version>5.1.6.RELEASE</spring-security.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Junit依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!--
MyBatis-Spring-Boot-Starter will:
* Autodetect an existing DataSource.
* Will create and register an instance of a SqlSessionFactory passing that DataSource as an input using the SqlSessionFactoryBean.
* Will create and register an instance of a SqlSessionTemplate got out of the SqlSessionFactory.
* Autoscan your mappers, link them to the SqlSessionTemplate and register them to Spring context so they can be injected into your beans.
-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>${mapper.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.kafka/spring-kafka -->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<!--<version>${spring.boot.version}</version>-->
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.yaml/snakeyaml -->
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.23</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mortbay.jetty/jetty-util -->
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>6.1.26</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.aliyun.oss/aliyun-sdk-oss -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.8.0</version>
</dependency>
<!--二维码-->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Package as an executable jar -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package cn.com.titan.eureka.api;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* Created by jscat on 2020-11-04.
*/
@ComponentScan(basePackages={"cn.com.titan"})
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
@EnableSwagger2
@EnableEurekaServer
public class EurekaServerApplication {
private static final Logger LOGGER = LoggerFactory.getLogger(EurekaServerApplication.class);
@Bean
protected ServletContextListener listener() {
return new ServletContextListener() {
@Override
public void contextInitialized(ServletContextEvent sce) {
LOGGER.debug("ServletContext initialized");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
LOGGER.debug("ServletContext destroyed");
}
};
}
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
@Configuration
public static class ApplicationWebMvcConfiger extends WebMvcConfigurerAdapter {
/**
* 支持跨域访问
*
* @see org.springframework.web.servlet.config.annotation.WebMvcConfigurer#addCorsMappings
*
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT")
.maxAge(3600);
}
}
}
package cn.com.titan.eureka.api.common;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* Created by jscat on 2017-05-24.
*/
public class Constants {
public static final String DATE_PATTERN = "yyyy-MM-dd";
public static final String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
public static final String DATE_LABEL_PATTERN = "MM.dd";
public static final String TOP_NAME_UNKNOWN = "未知";
public static final String DEFAULT_NOT_EXISTS = "无";
public static final int T_SUBTRAHEND_2 = 2;
public static String BASE_PATH;
public static String LOGIN_SESSION_KEY = "Favorites_user";
public static String PASSWORD_KEY = "@#$%^&*()OPG#$%^&*(HG";
public static String DES3_KEY = "9964DYByKL967c3308imytCB";
public static String default_logo="img/logo.jpg";
public static String userAgent="Mozilla";
public static String default_Profile=BASE_PATH+"/img/logo.jpg";
public static String LAST_REFERER = "LAST_REFERER";
public static int COOKIE_TIMEOUT= 30*24*60*60;
public enum DataSetEnum {
OPENHIGH("日期", "093000", "早盘高开"),
NOONHIGH("日期", "130000", "午盘高开"),
OPENTEXT("日期", "093000", "早盘黑嘴文本"),
NOONTEXT("日期", "130000", "午盘黑嘴文本");
private String eventDate;
private String eventTime;
private String eventType;
DataSetEnum(String eventDate, String eventTime, String eventType) {
this.eventDate = eventDate;
this.eventTime = eventTime;
this.eventType = eventType;
}
public String eventDate() {
return eventDate;
}
public String eventTime() {
return eventTime;
}
public String eventType() {
return eventType;
}
}
}
package cn.com.titan.eureka.api.common;
/**
* Created by jscat on 2017-05-24.
*/
public enum CronJobType
{
/// <summary>
/// 理财 浏览量
/// </summary>
financing_browser_stat_pv,
/// <summary>
/// 理财 浏览量 按员工号分类
/// </summary>
financing_browser_stat_purchase,
/// <summary>
/// 理财 购买量 按员工号分类
/// </summary>
financing_browser_stat_ryxx_purchase,
/// <summary>
/// 个股 访问统计 PV浏览量 Purchase购买量
/// </summary>
stock_browser_stat,
/// <summary>
/// 理财 每日0时将ryxx stat表清空
/// </summary>
truncate_ryxx_table_perday
}
package cn.com.titan.eureka.api.common;
public enum ExceptionMsg {
SUCCESS("000000", "操作成功"),
FAILED("999999","操作失败"),
ParamError("000001", "参数为空错误!"),
LoginNameOrPassWordError("000100", "用户名或者密码错误!"),
EmailUsed("000101","该邮箱已被注册"),
UserNameUsed("000102","该登录名称已存在"),
EmailNotRegister("000103","该邮箱地址未注册"),
LinkOutdated("000104","该链接已过期,请重新请求"),
PassWordError("000105","密码输入错误"),
UserNameLengthLimit("000106","用户名长度超限"),
LoginNameNotExists("000107","该用户未注册"),
UserNameSame("000108","新用户名与原用户名一致"),
FavoritesNameIsNull("000200","收藏夹名称不能为空"),
FavoritesNameUsed("000201","收藏夹名称已被创建"),
CollectExist("000300","该文章已被收藏"),
FileEmpty("000400","上传文件为空"),
LimitPictureSize("000401","图片大小必须小于2M"),
LimitPictureType("000402","图片格式必须为'jpg'、'png'、'jpge'、'gif'、'bmp'"),
OSSTokenNameIsBlack("000501", "cardNumber或tokenName不能为空!"),
OSSServerInternalError("000502", "获取阿里oss token失败,服务器内部错误!"),
ResubmitError("000601", "重复提交错误!"),
EditMemberError("000701", "更新商家信息错误!"),
AddAddressError("000701", "新增地址信息错误!")
;
private ExceptionMsg(String code, String msg) {
this.code = code;
this.msg = msg;
}
private String code;
private String msg;
public String getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
package cn.com.titan.eureka.api.common;
import java.util.List;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.naming.event.ObjectChangeListener;
/**
* @Title: LeeJSONResult.java
* @Package com.lee.utils
* @Description: 自定义响应数据结构
* 这个类是提供给门户,ios,安卓,微信商城用的
* 门户接受此类数据后需要使用本类的方法转换成对于的数据类型格式(类,或者list)
* 其他自行处理
* 200:表示成功
* 500:表示错误,错误信息在resultMsg字段中
* 501:bean验证错误,不管多少个错误都以map形式返回
* 502:拦截器拦截到用户token出错
* 555:异常抛出信息
* Copyright: Copyright (c) 2016
* Company:Nathan.Lee.Salvatore
* @author leechenxiang
* @date 2016年4月22日 下午8:33:36
* @version V1.0
*/
public class JSONResult {
// 定义jackson对象
private static final ObjectMapper MAPPER = new ObjectMapper();
// 响应业务状态
private String resultCode;
// 总数
private Integer totalCount;
// 响应消息
private String resultMsg;
// 响应中的数据
private Object data;
public static JSONResult build(String resultCode, String resultMsg, Integer totalCount, Object data) {
return new JSONResult(resultCode, resultMsg, totalCount, data);
}
public static JSONResult errorException(String resultMsg) {
return new JSONResult("555", resultMsg, 0, null);
}
public JSONResult() {
}
public JSONResult(String resultCode, String resultMsg, Integer totalCount, Object data) {
this.resultCode = resultCode;
this.resultMsg = resultMsg;
this.totalCount = totalCount;
this.data = data;
}
public JSONResult(Integer totalCount, Object data) {
this.resultCode = "200";
this.resultMsg = "OK";
this.totalCount = totalCount;
this.data = data;
}
public JSONResult(ExceptionMsg exceptionMsg) {
this.resultCode = exceptionMsg.getCode();
this.resultMsg = exceptionMsg.getMsg();
this.totalCount = 0;
this.data = null;
}
//如果有额外的错误信息
public JSONResult(ExceptionMsg exceptionMsg, String errorInfo) {
this.resultCode = exceptionMsg.getCode();
this.resultMsg = exceptionMsg.getMsg() + errorInfo;
this.totalCount = 0;
this.data = null;
}
public JSONResult(ExceptionMsg exceptionMsg, Object data) {
this.resultCode = exceptionMsg.getCode();
this.resultMsg = exceptionMsg.getMsg();
this.totalCount = 1;
this.data = data;
}
public String getresultCode() {
return resultCode;
}
public void setresultCode(String resultCode) {
this.resultCode = resultCode;
}
public String getresultMsg() {
return resultMsg;
}
public void setresultMsg(String resultMsg) {
this.resultMsg = resultMsg;
}
public Integer getTotalCount() {
return totalCount;
}
public void setTotalCount(Integer totalCount) {
this.totalCount = totalCount;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
/**
* @Description: 将json结果集转化为LeeJSONResult对象
* 需要转换的对象是一个类
* @param jsonData
* @param clazz
* @return
* @author leechenxiang
* @date 2016年4月22日 下午8:34:58
*/
public static JSONResult formatToPojo(Integer totalCount, String jsonData, Class<?> clazz) {
try {
if (clazz == null) {
return MAPPER.readValue(jsonData, JSONResult.class);
}
JsonNode jsonNode = MAPPER.readTree(jsonData);
JsonNode data = jsonNode.get("data");
Object obj = null;
if (clazz != null) {
if (data.isObject()) {
obj = MAPPER.readValue(data.traverse(), clazz);
} else if (data.isTextual()) {
obj = MAPPER.readValue(data.asText(), clazz);
}
}
return build(jsonNode.get("resultCode").toString(), jsonNode.get("resultMsg")
.asText(), totalCount, obj);
} catch (Exception e) {
return null;
}
}
/**
* @Description: 没有object对象的转化
* @param json
* @return
* @author leechenxiang
* @date 2016年4月22日 下午8:35:21
*/
public static JSONResult format(String json) {
try {
return MAPPER.readValue(json, JSONResult.class);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* @Description: Object是集合转化
* 需要转换的对象是一个list
* @param jsonData
* @param clazz
* @return
* @author leechenxiang
* @date 2016年4月22日 下午8:35:31
*/
public static JSONResult formatToList(Integer totalCount, String jsonData, Class<?> clazz) {
try {
JsonNode jsonNode = MAPPER.readTree(jsonData);
JsonNode data = jsonNode.get("data");
Object obj = null;
if (data.isArray() && data.size() > 0) {
obj = MAPPER.readValue(
data.traverse(),
MAPPER.getTypeFactory().constructCollectionType(
List.class, clazz));
}
return build(jsonNode.get("resultCode").toString(), jsonNode.get("resultMsg")
.asText(), totalCount, obj);
} catch (Exception e) {
return null;
}
}
}
package cn.com.titan.eureka.api.common;
/**
* Created by jscat on 2017-05-24.
* 语句1:select * from student limit 9(offset),4(size)
* 语句2:select * from student limit 4(size) offset 9(offset)
* // 语句1和2均返回表student的第10、11、12、13行 ,第一个参数表示从该参数的下一条数据开始,第二个参数表示每次返回的数据条数。
* //语句2中的4表示返回4行,9表示从表的第十行开始
*/
public class Pagination {
private Long offset;
private Integer page; // 表示页码
private Integer size; // 表示每页要显示的条数
public Pagination(Integer limit) {
this(Integer.valueOf(1), limit);
}
public Pagination(Integer page, Integer size) {
setPage(page);
setSize(size);
setOffset(Long.valueOf(size * (page-1)));
}
public Long getOffset() {
return offset;
}
public void setOffset(Long offset) {
if (offset == null || offset < 0) {
this.offset = Long.valueOf(0);
} else {
this.offset = offset;
}
}
public Integer getPage() {
return page;
}
public void setPage(Integer page) {
if (page == null || page < 1) {
this.page = Integer.valueOf(0);
} else {
this.page = page;
}
}
public Integer getSize() {
return size;
}
public void setSize(Integer size) {
if (size == null || size < 1) {
this.size = Integer.valueOf(5);
} else {
this.size = size;
}
}
@Override
public String toString() {
return "Pagination{" +
"offset=" + offset +
", page=" + page +
", size=" + size +
'}';
}
}
package cn.com.titan.eureka.api.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// /eureka路径忽略csrf
http.csrf().ignoringAntMatchers("/eureka/**");
super.configure(http);
}
}
\ No newline at end of file
package cn.com.titan.eureka.api.utils;
/**
* Created by jscat on 2020/3/5
*/
import java.io.UnsupportedEncodingException;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidParameterSpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.management.openmbean.InvalidKeyException;
import org.apache.commons.codec.binary.Base64;
/**
* <p>User: qrn
* <p>Date: 14-1-28
* <p>Version: 1.0
* 描述: 解密
*/
public class AesCbcUtil {
/**
* AES解密
*
* @param encryptedData 包括敏感数据在内的完整用户信息的加密数据,
* @param key 秘钥
* @param iv 加密算法的初始向量,
* @param encodingFormat 解密后的结果需要进行的编码
* @return String
* @see Exception
*/
public static String decrypt(String encryptedData,String key, String iv, String encodingFormat) throws Exception {
// initialize();
//被加密的数据
byte[] dataByte = Base64.decodeBase64(encryptedData);
//加密秘钥
byte[] keyByte = Base64.decodeBase64(key);
//偏移量
byte[] ivByte = Base64.decodeBase64(iv);
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
parameters.init(new IvParameterSpec(ivByte));
cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
byte[] resultByte = cipher.doFinal(dataByte);
if (null != resultByte && resultByte.length > 0) {
String result = new String(resultByte, encodingFormat);
return result;
}
return null;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidParameterSpecException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
}
\ No newline at end of file
package cn.com.titan.eureka.api.utils;
/**
* Created by jscat on 2020/4/10
*/
import java.io.UnsupportedEncodingException;
public class Base64 {
/**
* Chunk size per RFC 2045 section 6.8.
*
* <p>
* The {@value} character limit does not count the trailing CRLF, but counts
* all other characters, including any equal signs.
* </p>
*
* @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section
* 6.8</a>
*/
static final int CHUNK_SIZE = 76;
/**
* Chunk separator per RFC 2045 section 2.1.
*
* @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section
* 2.1</a>
*/
static final byte[] CHUNK_SEPARATOR = "\r\n".getBytes();
/**
* The base length.
*/
static final int BASELENGTH = 255;
/**
* Lookup length.
*/
static final int LOOKUPLENGTH = 64;
/**
* Used to calculate the number of bits in a byte.
*/
static final int EIGHTBIT = 8;
/**
* Used when encoding something which has fewer than 24 bits.
*/
static final int SIXTEENBIT = 16;
/**
* Used to determine how many bits data contains.
*/
static final int TWENTYFOURBITGROUP = 24;
/**
* Used to get the number of Quadruples.
*/
static final int FOURBYTE = 4;
/**
* Used to test the sign of a byte.
*/
static final int SIGN = -128;
/**
* Byte used to pad output.
*/
static final byte PAD = (byte) '=';
// Create arrays to hold the base64 characters and a
// lookup for base64 chars
private static byte[] base64Alphabet = new byte[BASELENGTH];
private static byte[] lookUpBase64Alphabet = new byte[LOOKUPLENGTH];
// Populating the lookup and character arrays
static {
for (int i = 0; i < BASELENGTH; i++) {
base64Alphabet[i] = (byte) -1;
}
for (int i = 'Z'; i >= 'A'; i--) {
base64Alphabet[i] = (byte) (i - 'A');
}
for (int i = 'z'; i >= 'a'; i--) {
base64Alphabet[i] = (byte) (i - 'a' + 26);
}
for (int i = '9'; i >= '0'; i--) {
base64Alphabet[i] = (byte) (i - '0' + 52);
}
base64Alphabet['+'] = 62;
base64Alphabet['/'] = 63;
for (int i = 0; i <= 25; i++) {
lookUpBase64Alphabet[i] = (byte) ('A' + i);
}
for (int i = 26, j = 0; i <= 51; i++, j++) {
lookUpBase64Alphabet[i] = (byte) ('a' + j);
}
for (int i = 52, j = 0; i <= 61; i++, j++) {
lookUpBase64Alphabet[i] = (byte) ('0' + j);
}
lookUpBase64Alphabet[62] = (byte) '+';
lookUpBase64Alphabet[63] = (byte) '/';
}
private static boolean isBase64(byte octect) {
if (octect == PAD) {
return true;
} else if (base64Alphabet[octect] == -1) {
return false;
} else {
return true;
}
}
public static void main(String[] args) {
String decodestr = new String(decode("MTE2LjQ2Mzg0NzU1MDg0".getBytes()));
System.out.println(decodestr);
}
/**
* Tests a given byte array to see if it contains only valid characters
* within the Base64 alphabet.
*
* @param arrayOctect
* byte array to test
* @return true if all bytes are valid characters in the Base64 alphabet or
* if the byte array is empty; false, otherwise
*/
public static boolean isArrayByteBase64(byte[] arrayOctect) {
arrayOctect = discardWhitespace(arrayOctect);
int length = arrayOctect.length;
if (length == 0) {
// shouldn't a 0 length array be valid base64 data?
// return false;
return true;
}
for (int i = 0; i < length; i++) {
if (!isBase64(arrayOctect[i])) {
return false;
}
}
return true;
}
/**
* Encodes binary data using the base64 algorithm but does not chunk the
* output.
*
* @param binaryData
* binary data to encode
* @return Base64 characters
*/
public static byte[] encodeBase64(byte[] binaryData) {
return encodeBase64(binaryData, false);
}
/**
* Encodes binary data using the base64 algorithm and chunks the encoded
* output into 76 character blocks
*
* @param binaryData
* binary data to encode
* @return Base64 characters chunked in 76 character blocks
*/
public static byte[] encodeBase64Chunked(byte[] binaryData) {
return encodeBase64(binaryData, true);
}
/**
* Decodes a byte[] containing containing characters in the Base64 alphabet.
*
* @param pArray
* A byte array containing Base64 character data
* @return a byte array containing binary data
*/
public static byte[] decode(byte[] pArray) {
return decodeBase64(pArray);
}
/**
* Encodes binary data using the base64 algorithm, optionally chunking the
* output into 76 character blocks.
*
* @param binaryData
* Array containing binary data to encode.
* @param isChunked
* if isChunked is true this encoder will chunk the base64 output
* into 76 character blocks
* @return Base64-encoded data.
*/
public static byte[] encodeBase64(byte[] binaryData, boolean isChunked) {
int lengthDataBits = binaryData.length * EIGHTBIT;
int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
byte encodedData[] = null;
int encodedDataLength = 0;
int nbrChunks = 0;
if (fewerThan24bits != 0) {
// data not divisible by 24 bit
encodedDataLength = (numberTriplets + 1) * 4;
} else {
// 16 or 8 bit
encodedDataLength = numberTriplets * 4;
}
// If the output is to be "chunked" into 76 character sections,
// for compliance with RFC 2045 MIME, then it is important to
// allow for extra length to account for the separator(s)
if (isChunked) {
nbrChunks = (CHUNK_SEPARATOR.length == 0 ? 0 : (int) Math
.ceil((float) encodedDataLength / CHUNK_SIZE));
encodedDataLength += nbrChunks * CHUNK_SEPARATOR.length;
}
encodedData = new byte[encodedDataLength];
byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
int encodedIndex = 0;
int dataIndex = 0;
int i = 0;
int nextSeparatorIndex = CHUNK_SIZE;
int chunksSoFar = 0;
// log.debug("number of triplets = " + numberTriplets);
for (i = 0; i < numberTriplets; i++) {
dataIndex = i * 3;
b1 = binaryData[dataIndex];
b2 = binaryData[dataIndex + 1];
b3 = binaryData[dataIndex + 2];
// log.debug("b1= " + b1 +", b2= " + b2 + ", b3= " + b3);
l = (byte) (b2 & 0x0f);
k = (byte) (b1 & 0x03);
byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
: (byte) ((b1) >> 2 ^ 0xc0);
byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4)
: (byte) ((b2) >> 4 ^ 0xf0);
byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6)
: (byte) ((b3) >> 6 ^ 0xfc);
encodedData[encodedIndex] = lookUpBase64Alphabet[val1];
// log.debug( "val2 = " + val2 );
// log.debug( "k4 = " + (k<<4) );
// log.debug( "vak = " + (val2 | (k<<4)) );
encodedData[encodedIndex + 1] = lookUpBase64Alphabet[val2
| (k << 4)];
encodedData[encodedIndex + 2] = lookUpBase64Alphabet[(l << 2)
| val3];
encodedData[encodedIndex + 3] = lookUpBase64Alphabet[b3 & 0x3f];
encodedIndex += 4;
// If we are chunking, let's put a chunk separator down.
if (isChunked) {
// this assumes that CHUNK_SIZE % 4 == 0
if (encodedIndex == nextSeparatorIndex) {
System.arraycopy(CHUNK_SEPARATOR, 0, encodedData,
encodedIndex, CHUNK_SEPARATOR.length);
chunksSoFar++;
nextSeparatorIndex = (CHUNK_SIZE * (chunksSoFar + 1))
+ (chunksSoFar * CHUNK_SEPARATOR.length);
encodedIndex += CHUNK_SEPARATOR.length;
}
}
}
// form integral number of 6-bit groups
dataIndex = i * 3;
if (fewerThan24bits == EIGHTBIT) {
b1 = binaryData[dataIndex];
k = (byte) (b1 & 0x03);
// log.debug("b1=" + b1);
// log.debug("b1<<2 = " + (b1>>2) );
byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
: (byte) ((b1) >> 2 ^ 0xc0);
encodedData[encodedIndex] = lookUpBase64Alphabet[val1];
encodedData[encodedIndex + 1] = lookUpBase64Alphabet[k << 4];
encodedData[encodedIndex + 2] = PAD;
encodedData[encodedIndex + 3] = PAD;
} else if (fewerThan24bits == SIXTEENBIT) {
b1 = binaryData[dataIndex];
b2 = binaryData[dataIndex + 1];
l = (byte) (b2 & 0x0f);
k = (byte) (b1 & 0x03);
byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
: (byte) ((b1) >> 2 ^ 0xc0);
byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4)
: (byte) ((b2) >> 4 ^ 0xf0);
encodedData[encodedIndex] = lookUpBase64Alphabet[val1];
encodedData[encodedIndex + 1] = lookUpBase64Alphabet[val2
| (k << 4)];
encodedData[encodedIndex + 2] = lookUpBase64Alphabet[l << 2];
encodedData[encodedIndex + 3] = PAD;
}
if (isChunked) {
// we also add a separator to the end of the final chunk.
if (chunksSoFar < nbrChunks) {
System.arraycopy(CHUNK_SEPARATOR, 0, encodedData,
encodedDataLength - CHUNK_SEPARATOR.length,
CHUNK_SEPARATOR.length);
}
}
return encodedData;
}
/**
* Decodes Base64 data into octects
*
* @param base64Data
* Byte array containing Base64 data
* @return Array containing decoded data.
*/
public static byte[] decodeBase64(byte[] base64Data) {
// RFC 2045 requires that we discard ALL non-Base64 characters
base64Data = discardNonBase64(base64Data);
// handle the edge case, so we don't have to worry about it later
if (base64Data.length == 0) {
return new byte[0];
}
int numberQuadruple = base64Data.length / FOURBYTE;
byte decodedData[] = null;
byte b1 = 0, b2 = 0, b3 = 0, b4 = 0, marker0 = 0, marker1 = 0;
// Throw away anything not in base64Data
int encodedIndex = 0;
int dataIndex = 0;
{
// this sizes the output array properly - rlw
int lastData = base64Data.length;
// ignore the '=' padding
while (base64Data[lastData - 1] == PAD) {
if (--lastData == 0) {
return new byte[0];
}
}
decodedData = new byte[lastData - numberQuadruple];
}
for (int i = 0; i < numberQuadruple; i++) {
dataIndex = i * 4;
marker0 = base64Data[dataIndex + 2];
marker1 = base64Data[dataIndex + 3];
b1 = base64Alphabet[base64Data[dataIndex]];
b2 = base64Alphabet[base64Data[dataIndex + 1]];
if (marker0 != PAD && marker1 != PAD) {
// No PAD e.g 3cQl
b3 = base64Alphabet[marker0];
b4 = base64Alphabet[marker1];
decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
decodedData[encodedIndex + 1] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
decodedData[encodedIndex + 2] = (byte) (b3 << 6 | b4);
} else if (marker0 == PAD) {
// Two PAD e.g. 3c[Pad][Pad]
decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
} else if (marker1 == PAD) {
// One PAD e.g. 3cQ[Pad]
b3 = base64Alphabet[marker0];
decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
decodedData[encodedIndex + 1] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
}
encodedIndex += 3;
}
return decodedData;
}
/**
* Discards any whitespace from a base-64 encoded block.
*
* @param data
* The base-64 encoded data to discard the whitespace from.
* @return The data, less whitespace (see RFC 2045).
*/
static byte[] discardWhitespace(byte[] data) {
byte groomedData[] = new byte[data.length];
int bytesCopied = 0;
for (int i = 0; i < data.length; i++) {
switch (data[i]) {
case (byte) ' ':
case (byte) '\n':
case (byte) '\r':
case (byte) '\t':
break;
default:
groomedData[bytesCopied++] = data[i];
}
}
byte packedData[] = new byte[bytesCopied];
System.arraycopy(groomedData, 0, packedData, 0, bytesCopied);
return packedData;
}
/**
* Discards any characters outside of the base64 alphabet, per the
* requirements on page 25 of RFC 2045 - "Any characters outside of the
* base64 alphabet are to be ignored in base64 encoded data."
*
* @param data
* The base-64 encoded data to groom
* @return The data, less non-base64 characters (see RFC 2045).
*/
static byte[] discardNonBase64(byte[] data) {
byte groomedData[] = new byte[data.length];
int bytesCopied = 0;
for (int i = 0; i < data.length; i++) {
if (isBase64(data[i])) {
groomedData[bytesCopied++] = data[i];
}
}
byte packedData[] = new byte[bytesCopied];
System.arraycopy(groomedData, 0, packedData, 0, bytesCopied);
return packedData;
}
/**
* Encodes a byte[] containing binary data, into a byte[] containing
* characters in the Base64 alphabet.
*
* @param pArray
* a byte array containing binary data
* @return A byte array containing only Base64 character data
*/
public static byte[] encode(byte[] pArray) {
return encodeBase64(pArray, false);
}
// public static String encode(String str) throws
// UnsupportedEncodingException {
// String baseStr = new String(encode(str.getBytes("UTF-8")));
// String tempStr = Digest.digest(str).toUpperCase();
// String result = tempStr + baseStr;
// return new String(encode(result.getBytes("UTF-8")));
// }
public static String decode(String cryptoStr)
throws UnsupportedEncodingException {
if (cryptoStr.length() < 40)
return "";
try {
String tempStr = new String(decode(cryptoStr.getBytes("UTF-8")));
String result = tempStr.substring(40, tempStr.length());
return new String(decode(result.getBytes("UTF-8")));
} catch (ArrayIndexOutOfBoundsException ex) {
ex.printStackTrace();
return "";
}
}
}
package cn.com.titan.eureka.api.utils;
import cn.com.titan.eureka.api.common.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
* Created by jscat on 2020/4/10
*/
public class BaseUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(BaseUtils.class);
public static HttpServletRequest getRequest() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
}
public static HttpSession getSession() {
return getRequest().getSession();
}
public static String getUserIp() {
String value = getRequest().getHeader("X-Real-IP");
if (StringUtils.isNotBlank(value) && !"unknown".equalsIgnoreCase(value)) {
return value;
} else {
return getRequest().getRemoteAddr();
}
}
public static String getPwd(String password){
try {
String pwd = MD5Util.encrypt(password+Constants.PASSWORD_KEY);
return pwd;
} catch (Exception e) {
LOGGER.error("密码加密异常:",e);
}
return null;
}
public static String cookieSign(String value){
try{
value = value + Constants.PASSWORD_KEY;
String sign = Des3EncryptionUtil.encode(Constants.DES3_KEY,value);
return sign;
}catch (Exception e){
LOGGER.error("cookie签名异常:",e);
}
return null;
}
}
package cn.com.titan.eureka.api.utils;
/**
* Created by jscat on 2017/8/1.
*/
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.BeanUtils;
/**
* 文件操作
*/
public class CSVUtils {
/**
* 生成为CVS文件
* @param exportData
* 源数据List
* @param map
* csv文件的列表头map
* @param outPutPath
* 文件路径
* @param fileName
* 文件名称
* @return
*/
@SuppressWarnings("rawtypes")
public static File createCSVFile(List exportData, LinkedHashMap map, String outPutPath,
String fileName) {
File csvFile = null;
BufferedWriter csvFileOutputStream = null;
try {
File file = new File(outPutPath);
if (!file.exists()) {
file.mkdir();
}
//定义文件名格式并创建
csvFile = File.createTempFile(fileName, ".csv", new File(outPutPath));
System.out.println("csvFile:" + csvFile);
// UTF-8使正确读取分隔符","
csvFileOutputStream = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(
csvFile), "UTF-8"), 1024);
System.out.println("csvFileOutputStream:" + csvFileOutputStream);
// 写入文件头部
csvFileOutputStream.write(new String(new byte[] { (byte) 0xEF, (byte) 0xBB,(byte) 0xBF }));
for (Iterator propertyIterator = map.entrySet().iterator(); propertyIterator.hasNext();) {
java.util.Map.Entry propertyEntry = (java.util.Map.Entry) propertyIterator.next();
csvFileOutputStream
.write("" + (String) propertyEntry.getValue() != null ? (String) propertyEntry
.getValue() : "" + "");
if (propertyIterator.hasNext()) {
csvFileOutputStream.write(",");
}
}
csvFileOutputStream.newLine();
// 写入文件内容
for (Iterator iterator = exportData.iterator(); iterator.hasNext();) {
Object row = (Object) iterator.next();
for (Iterator propertyIterator = map.entrySet().iterator(); propertyIterator
.hasNext();) {
java.util.Map.Entry propertyEntry = (java.util.Map.Entry) propertyIterator
.next();
csvFileOutputStream.write((String) BeanUtils.getProperty(row,
(String) propertyEntry.getKey()));
if (propertyIterator.hasNext()) {
csvFileOutputStream.write(",");
}
}
if (iterator.hasNext()) {
csvFileOutputStream.newLine();
}
}
csvFileOutputStream.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
csvFileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return csvFile;
}
/**
* 下载文件
* @param response
* @param csvFilePath
* 文件路径
* @param fileName
* 文件名称
* @throws IOException
*/
public static void exportFile(HttpServletResponse response, String csvFilePath, String fileName)
throws IOException {
response.setContentType("application/csv;charset=UTF-8");
response.setHeader("Content-Disposition",
"attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
InputStream in = null;
try {
in = new FileInputStream(csvFilePath);
int len = 0;
byte[] buffer = new byte[1024];
response.setCharacterEncoding("UTF-8");
OutputStream out = response.getOutputStream();
while ((len = in.read(buffer)) > 0) {
out.write(new byte[] { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF });
out.write(buffer, 0, len);
}
} catch (FileNotFoundException e) {
System.out.println(e);
} finally {
if (in != null) {
try {
in.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
/**
* 删除该目录filePath下的所有文件
* @param filePath
* 文件目录路径
*/
public static void deleteFiles(String filePath) {
File file = new File(filePath);
if (file.exists()) {
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isFile()) {
files[i].delete();
}
}
}
}
/**
* 删除单个文件
* @param filePath
* 文件目录路径
* @param fileName
* 文件名称
*/
public static void deleteFile(String filePath, String fileName) {
File file = new File(filePath);
if (file.exists()) {
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isFile()) {
if (files[i].getName().equals(fileName)) {
files[i].delete();
return;
}
}
}
}
}
/**
* 生成content
* @param exportData
* 源数据List
* @param map
* csv文件的列表头map
* @return
*/
@SuppressWarnings("rawtypes")
public static String genContent(List exportData, LinkedHashMap map) {
String content = "";
try {
// 写入文件头部
for (Iterator propertyIterator = map.entrySet().iterator(); propertyIterator.hasNext();) {
java.util.Map.Entry propertyEntry = (java.util.Map.Entry) propertyIterator.next();
content += "" + (String) propertyEntry.getValue() != null ? (String) propertyEntry
.getValue() : "" + "";
if (propertyIterator.hasNext()) {
content += ",";
}
}
content += "\n";
// 写入文件内容
for (Iterator iterator = exportData.iterator(); iterator.hasNext();) {
Object row = (Object) iterator.next();
for (Iterator propertyIterator = map.entrySet().iterator(); propertyIterator
.hasNext();) {
java.util.Map.Entry propertyEntry = (java.util.Map.Entry) propertyIterator
.next();
content += (String) BeanUtils.getProperty(row, (String) propertyEntry.getKey());
if (propertyIterator.hasNext()) {
content += ",";
}
}
if (iterator.hasNext()) {
content += "\n";
}
}
} catch (Exception e) {
e.printStackTrace();
}
return content;
}
/**
* 测试数据
* @param args
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static void main(String[] args) {
List exportData = new ArrayList<Map>();
Map row1 = new LinkedHashMap<String, String>();
row1.put("1", "11");
row1.put("2", "12");
row1.put("3", "13");
row1.put("4", "14");
exportData.add(row1);
row1 = new LinkedHashMap<String, String>();
row1.put("1", "21");
row1.put("2", "22");
row1.put("3", "23");
row1.put("4", "24");
exportData.add(row1);
LinkedHashMap map = new LinkedHashMap();
map.put("1", "第一列");
map.put("2", "第二列");
map.put("3", "第三列");
map.put("4", "第四列");
String path = "c:/export/";
String fileName = "文件导出";
File file = CSVUtils.createCSVFile(exportData, map, path, fileName);
String fileName2 = file.getName();
System.out.println("文件名称:" + fileName2);
}
}
package cn.com.titan.eureka.api.utils;
import java.util.Date;
/**
* Created by jscat on 2017-05-08.
*/
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
public static Date max(Date d1, Date d2) {
if (d1 == null && d2 == null) {
return null;
} else if (d1 == null) {
return d2;
} else if (d2 == null) {
return d1;
}
return d1.after(d2) ? d1 : d2;
}
}
package cn.com.titan.eureka.api.utils;
/**
* Created by jscat on 2020/4/10
*/
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
public class Des3EncryptionUtil {
public static final String CHAR_ENCODING = "UTF-8";
public static byte[] encode(byte[] key, byte[] data) throws Exception {
final String Algorithm = "DESede";
SecretKey deskey = new SecretKeySpec(key, Algorithm);
Cipher c1 = Cipher.getInstance(Algorithm);
c1.init(Cipher.ENCRYPT_MODE, deskey);
return c1.doFinal(data);
}
public static byte[] decode(byte[] key, byte[] value) throws Exception {
final String Algorithm = "DESede";
SecretKey deskey = new SecretKeySpec(key, Algorithm);
Cipher c1 = Cipher.getInstance(Algorithm);
c1.init(Cipher.DECRYPT_MODE, deskey);
return c1.doFinal(value);
}
public static String encode(String key, String data) {
try {
byte[] keyByte = key.getBytes(CHAR_ENCODING);
byte[] dataByte = data.getBytes(CHAR_ENCODING);
byte[] valueByte = encode(keyByte, dataByte);
String value = new String(Base64.encode(valueByte), CHAR_ENCODING);
return value;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String decode(String key, String value) {
try {
byte[] keyByte = key.getBytes(CHAR_ENCODING);
byte[] valueByte = Base64.decode(value.getBytes(CHAR_ENCODING));
byte[] dataByte = decode(keyByte,valueByte);
String data = new String(dataByte, CHAR_ENCODING);
return data;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String encryptToHex(String key, String data) {
try {
byte[] keyByte = key.getBytes(CHAR_ENCODING);
byte[] dataByte = data.getBytes(CHAR_ENCODING);
byte[] valueByte = encode(keyByte, dataByte);
String value = toHex(valueByte);
return value;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String decryptFromHex(String key, String value) {
try {
byte[] keyByte = key.getBytes(CHAR_ENCODING);
byte[] valueByte = fromHex(value);
byte[] dataByte = decode(keyByte,valueByte);
String data = new String(dataByte, CHAR_ENCODING);
return data;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String udpEncrypt(String key, String data) {
try {
Key k = updGenerateKey(key);
IvParameterSpec IVSpec = new IvParameterSpec(new byte[8]);
Cipher c = Cipher.getInstance("DESede/CBC/PKCS5Padding");
c.init(1, k, ((IVSpec)));
byte output[] = c.doFinal(data.getBytes("UTF-8"));
return new String(Base64.encode(output), "UTF-8");
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static Key updGenerateKey(String key) {
try {
DESedeKeySpec KeySpec = new DESedeKeySpec(UdpHexDecode(key));
SecretKeyFactory KeyFactory = SecretKeyFactory
.getInstance("DESede");
Key k = ((KeyFactory.generateSecret(((KeySpec)))));
return k;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String udpDecrypt(String key, String data) {
try {
byte[] input = Base64.decode(data.getBytes("UTF-8"));
Key k = updGenerateKey(key);
IvParameterSpec IVSpec = new IvParameterSpec(new byte[8]);
Cipher c = Cipher.getInstance("DESede/CBC/PKCS5Padding");
c.init(2, k, ((IVSpec)));
byte output[] = c.doFinal(input);
return new String(output, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static byte[] UdpHexDecode(String s) {
byte abyte0[] = new byte[s.length() / 2];
String s1 = s.toLowerCase();
for (int i = 0; i < s1.length(); i += 2) {
char c = s1.charAt(i);
char c1 = s1.charAt(i + 1);
int j = i / 2;
if (c < 'a')
abyte0[j] = (byte) (c - 48 << 4);
else
abyte0[j] = (byte) ((c - 97) + 10 << 4);
if (c1 < 'a')
abyte0[j] += (byte) (c1 - 48);
else
abyte0[j] += (byte) ((c1 - 97) + 10);
}
return abyte0;
}
public static String toHex(byte input[]) {
if (input == null)
return null;
StringBuffer output = new StringBuffer(input.length * 2);
for (int i = 0; i < input.length; i++) {
int current = input[i] & 0xff;
if (current < 16)
output.append("0");
output.append(Integer.toString(current, 16));
}
return output.toString();
}
public static byte[] fromHex(String input) {
if (input == null)
return null;
byte output[] = new byte[input.length() / 2];
for (int i = 0; i < output.length; i++)
output[i] = (byte) Integer.parseInt(
input.substring(i * 2, (i + 1) * 2), 16);
return output;
}
}
\ No newline at end of file
package cn.com.titan.eureka.api.utils;
/**
* Created by jscat on 2020/4/10
*/
import java.security.MessageDigest;
public class MD5Util {
public static String encrypt(String dataStr) {
try {
MessageDigest m = MessageDigest.getInstance("MD5");
m.update(dataStr.getBytes("UTF8"));
byte s[] = m.digest();
String result = "";
for (int i = 0; i < s.length; i++) {
result += Integer.toHexString((0x000000FF & s[i]) | 0xFFFFFF00)
.substring(6);
}
return result;
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}
package cn.com.titan.eureka.api.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Locale;
@Configuration
public class SpringContextUtil implements ApplicationContextAware
{
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext contex)
throws BeansException
{
System.out.println("--------------------contex---------"+contex);
SpringContextUtil.context = contex;
}
public static ApplicationContext getApplicationContext() {
return context;
}
public static Object getBean(String beanName) {
return context.getBean(beanName);
}
public static boolean containsBean(String name) {
return context.containsBean(name);
}
public static String getMessage(String key) {
return context.getMessage(key, null, Locale.getDefault());
}
}
package cn.com.titan.eureka.api.utils;
import java.text.NumberFormat;
/**
* Created by jscat on 2017-05-09.
*/
public class StringUtils extends org.apache.commons.lang3.StringUtils {
public static String formatPercent(Number value) {
return formatPercent(value, 1);
}
public static String formatPercent(Number value, int maximumFractionDigits) {
if (value == null) {
return "0%";
}
NumberFormat instance = NumberFormat.getPercentInstance();
instance.setMaximumFractionDigits(maximumFractionDigits);
return instance.format(value);
}
public static String formatCurrencyHumanReadable(Double value) {
return formatCurrencyHumanReadable(value, 0);
}
public static String formatCurrencyHumanReadable(Double value, int maximumFractionDigits) {
return formatCurrencyHumanReadable(value, maximumFractionDigits, true, CurrencyUnit.TT, true);
}
public static String formatCurrencyHumanReadable(Double value, int maximumFractionDigits, boolean grouping,
CurrencyUnit currencyUnit, boolean appendUnit) {
if (value == null) {
return "0";
}
NumberFormat format = NumberFormat.getInstance();
format.setMaximumFractionDigits(maximumFractionDigits);
format.setGroupingUsed(grouping);
CurrencyUnit current = currencyUnit;
do {
if (Math.abs(value) >= current.value()) {
return appendUnit ? format.format(value / current.value()) + current.unit() : format.format(value / current.value());
}
} while((current = currencyUnit.next(current)) != null);
return format.format(value);
}
public enum CurrencyUnit {
// 亿 hundred million
HM(0, 1E8, "亿"),
// 万 ten thousand
TT(1, 1E4, "万");
private static final CurrencyUnit[] CURRENCY_UNIT = new CurrencyUnit[]{HM, TT};
private int index;
private double value;
private String unit;
CurrencyUnit(int index, double value, String unit) {
this.index = index;
this.value = value;
this.unit = unit;
}
public int index() {
return index;
}
public double value() {
return value;
}
public String unit() {
return unit;
}
public CurrencyUnit next(CurrencyUnit current) {
int nextIndex = current.index() + 1;
if (nextIndex >= CURRENCY_UNIT.length) {
return null;
}
return CURRENCY_UNIT[nextIndex];
}
}
}
package cn.com.titan.eureka.api.web.common;
import cn.com.titan.eureka.api.common.Constants;
import cn.com.titan.eureka.api.utils.DateUtils;
import cn.com.titan.eureka.api.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.beans.PropertyEditorSupport;
import java.text.ParseException;
/**
* Created by jscat on 2017-05-09.
*/
public class DateEditor extends PropertyEditorSupport {
private static final Logger LOGGER = LoggerFactory.getLogger(DateEditor.class);
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (StringUtils.isBlank(text)) {
setValue(null);
} else {
try {
setValue(DateUtils.parseDate(text, Constants.DATE_PATTERN, Constants.DATETIME_PATTERN));
} catch (ParseException e) {
LOGGER.error("error parsing text to date. [{}]", text, e);
setValue(null);
}
}
}
}
package cn.com.titan.eureka.api.web.common;
/**
* Created by jscat on 2020-02-17.
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
public class HttpRequest {
public static void main(String[] args) {
//发送 GET 请求
String s=HttpRequest.sendGet("http://v.qq.com/x/cover/kvehb7okfxqstmc.html?vid=e01957zem6o", "");
System.out.println(s);
// //发送 POST 请求
// String sr=HttpRequest.sendPost("http://www.toutiao.com/stream/widget/local_weather/data/?city=%E4%B8%8A%E6%B5%B7", "");
// JSONObject json = JSONObject.fromObject(sr);
// System.out.println(json.get("data"));
}
/**
* 向指定URL发送GET方法的请求
*
* @param url
* 发送请求的URL
* @param param
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return URL 所代表远程资源的响应结果
*/
public static String sendGet(String url, String param) {
String result = "";
BufferedReader in = null;
try {
String urlNameString = url + "?" + param;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
/**
* 向指定 URL 发送POST方法的请求
*
* @param url
* 发送请求的 URL
* @param param
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public static String sendPost(String url, String param) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送 POST 请求出现异常!"+e);
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOException ex){
ex.printStackTrace();
}
}
return result;
}
}
package cn.com.titan.eureka.api.web.common;
/**
* Created by jscat on 2016-12-28.
*/
public enum ResponseCode {
OK(0, "success"),
FAILED(100, "failed")
;
private Integer code;
private String message;
ResponseCode(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer code() {
return code;
}
public String message() {
return message;
}
}
package cn.com.titan.eureka.api.web.common;
/**
* Created by jscat on 2017-05-05.
*/
public class ResponseHelper {
public static <T> ResponseWrapper<T> newResponseWrapper(T instance, Class<T> type) {
ResponseWrapper<T> response = new ResponseWrapper<>();
response.setData(instance);
return response;
}
}
package cn.com.titan.eureka.api.web.common;
/**
* Created by jscat on 2016-12-28.
*/
public class ResponseWrapper<T> {
private Integer code;
private String message;
private String reason;
private T data;
public ResponseWrapper() {
updateResponseState(ResponseCode.OK);
}
public ResponseWrapper(ResponseCode responseCode) {
updateResponseState(responseCode);
}
public ResponseWrapper(Integer code, String message) {
this.code = code;
this.message = message;
}
public ResponseWrapper(Integer code, String message, String reason) {
this.code = code;
this.message = message;
this.reason = reason;
}
public ResponseWrapper(Integer code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
public void updateResponseState(ResponseCode responseCode) {
setCode(responseCode.code());
setMessage(responseCode.message());
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
spring:
application:
name: eureka-server
security:
user:
name: admin
password: pass
server:
port: ${EUREKA_PORT:48761}
maxPostSize: -1
maxHttpHeaderSize: 4048576
eureka:
instance:
hostname: ${HOST_IP_ADDR:127.0.0.1}
prefer-ip-address: true
server:
enable-self-preservation: false
client:
registerWithEureka: false
fetch-registry: false
serviceUrl:
defaultZone: http://admin:pass@${HOST_IP_ADDR:127.0.0.1}:${EUREKA_PORT:48761}/eureka
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds">
<property name="LOG_HOME" value="tplus_log" />
<appender name="LOG_HOME" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/test.log</file>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<Pattern> %d [%thread] %-5level [%logger{0}] - %msg%n </Pattern>
</encoder>
</appender>
<!-- appender for server.log, time and size based rolling -->
<appender name="FILE-SERVER-LOG"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/server.log</file>
<encoder>
<Pattern> %d [%thread] %-5level [%logger{0}] - %msg%n </Pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern> ${LOG_HOME}/archived/server.%d{yyyy-MM-dd}.%i.log.zip </fileNamePattern>
<!-- each file should be at most 100MB, keep 30 days worth of history, but at most 20GB -->
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
</appender>
<!-- add loggers here -->
<logger name="cn.com.titan.eureka.api" level="debug" additivity="false">
<appender-ref ref="FILE-SERVER-LOG" />
</logger>
<logger name= "cn.com.titan.eureka.api.repository.KeyMapper" level="TRACE" />
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE-SERVER-LOG" />
<appender-ref ref="LOG_HOME" />
</root>
</configuration>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.com.titan</groupId>
<artifactId>eureka</artifactId>
<version>1.0-SNAPSHOT</version>
<name>eureka</name>
<packaging>pom</packaging>
<modules>
<module>api</module>
</modules>
<properties>
<java.version>1.8</java.version>
<spring.boot.version>2.1.10.RELEASE</spring.boot.version>
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
<spring-framework.version>5.1.11.RELEASE</spring-framework.version>
<spring-security.version>5.1.6.RELEASE</spring-security.version>
<mapper.version>4.1.5</mapper.version>
</properties>
<!-- Inherit defaults from Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.10.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<!-- Add typical dependencies for a web application -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring.boot.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>27.0.1-jre</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-core -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>9.0.16</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-jdbc -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
<version>9.0.16</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<!-- 版本号可以不用指定,Spring Boot会选用合适的版本 -->
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>${mapper.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<!--pageHelper-->
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<!-- Package as an executable jar -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
</project>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论