работает

This commit is contained in:
2025-02-03 07:28:33 +05:00
parent 07d3be1938
commit 68e938d0d5
5 changed files with 5133 additions and 377 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,46 +0,0 @@
server:
port: 8084
ssl:
key-store: classpath:keystore.jks
key-store-password: QyKtWPZB
key-store-type: JKS
key-alias: weather
servlet:
session:
timeout: 300s
spring:
application:
name: kz_ccalm_sync
datasource:
url: jdbc:postgresql://mcp.kz:5432/mcp
username: postgres
password: 309A86FF65A78FB428F4E38DFE35F730
driver-class-name: org.postgresql.Driver
hikari:
maximum-pool-size: 10
minimum-idle: 5
max-lifetime: 600000
idle-timeout: 60000
connection-timeout: 30000
connection-test-query: SELECT 1
validation-timeout: 30000
cache:
type: none
custom:
config:
data_dir: /data/
db_all:
url: jdbc:postgresql://92.46.48.43:5444/weather?ApplicationName=kz_mcp_weather&sslmode=require
#url: jdbc:postgresql://192.168.0.90:5432/weather?ApplicationName=kz_mcp_weather&sslmode=require
#url: jdbc:postgresql://127.0.0.1:5432/weather?ApplicationName=kz_mcp_weather&sslmode=require
login: postgres
password: PasSecrKey1
db_ru:
url: jdbc:postgresql://92.46.48.43:5444/weather_ru?ApplicationName=kz_mcp_weather&sslmode=require
#url: jdbc:postgresql://192.168.0.90:5432/weather_ru?ApplicationName=kz_mcp_weather&sslmode=require
#url: jdbc:postgresql://127.0.0.1:5432/weather_ru?ApplicationName=kz_mcp_weather&sslmode=require
login: postgres
password: PasSecrKey1

32
org_ccalm_sync.yml Normal file
View File

@ -0,0 +1,32 @@
server:
port: 8084
ssl:
key-store: classpath:keystore.jks
key-store-password: QyKtWPZB
key-store-type: JKS
key-alias: weather
servlet:
session:
timeout: 300s
spring:
application:
name: kz_ccalm_sync
datasource:
url: jdbc:postgresql://127.0.0.1:5432/CCALM?ApplicationName=kz_mcp_sync&sslmode=require
username: postgres
password: PasSecrKey1
#url: jdbc:postgresql://ccalm.org:5432/CCALM?ApplicationName=kz_mcp_sync&sslmode=require
#username: postgres
#password: 309A86FF65A78FB428F4E38DFE35F730
driver-class-name: org.postgresql.Driver
#hikari:
# maximum-pool-size: 10
# minimum-idle: 5
# max-lifetime: 600000
# idle-timeout: 60000
# connection-timeout: 30000
# connection-test-query: SELECT 1
# validation-timeout: 30000
cache:
type: none

View File

@ -72,7 +72,7 @@
<version>2.22.2</version>
<configuration>
<systemPropertyVariables>
<spring.config.location>file:org_ccalm_cync.yml</spring.config.location>
<spring.config.location>file:org_ccalm_sync.yml</spring.config.location>
</systemPropertyVariables>
</configuration>
</plugin>

View File

@ -2,12 +2,19 @@ package org.ccalm.sync;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.LogManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.ServletContextAware;
import org.json.JSONObject;
import org.json.JSONArray;
@ -18,6 +25,7 @@ import tctable.TCTable;
import tctable.TCTableTools;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
@ -46,6 +54,19 @@ public class MainController implements ServletContextAware {
this.context = servletContext;
}
// Метод для извлечения имени файла из заголовка Content-Disposition
private String extractFileName(String contentDisposition) {
if (contentDisposition != null && contentDisposition.contains("filename=")) {
String[] elements = contentDisposition.split(";");
for (String element : elements) {
if (element.trim().startsWith("filename=")) {
return element.split("=")[1].trim().replace("\"", "");
}
}
}
return "unknown"; // Если имя не указано
}
@RequestMapping(value = "/",method = {RequestMethod.POST,RequestMethod.GET},produces = "application/json;charset=utf-8")
@ResponseBody
public String index(Model model, @RequestParam(required=false,name="lng",defaultValue = "1") String language_id) {
@ -78,24 +99,48 @@ public class MainController implements ServletContextAware {
return json.toString();
}
//Скачать с удалённого сервера
@RequestMapping(value = "/download/",params = {"fn"},method = { RequestMethod.GET, RequestMethod.POST })
@ResponseBody
public Object download(HttpServletResponse response, @RequestHeader(required=false,name="Content-Type") String contentType, @RequestBody(required=false) String reqData, @RequestParam(required=false,name="file") MultipartFile file, @RequestParam(required=false,name="fn") String fn, @RequestParam(required=false,name="r") String reqR, @RequestParam(required=false,name="n") String reqN, @RequestParam(required=false,name="s") String reqS, @RequestParam(required=false,name="l") String reqL, @RequestParam(required=false,name="days",defaultValue = "0") int days, @RequestParam(required=false,name="country_id",defaultValue = "0") int country_id, @RequestParam(required=false,name="android_id",defaultValue = "") String device_id) {
System.out.println("/asdc/tctable/");
public long getMaxSeq(String table_name) {
long result = 1;
JSONObject result = new JSONObject();
result.put("error_code", 0);
result.put("error_message", "");
byte[] reqData=null;
if(file!=null) {
Connection conn = null;
try {
reqData = file.getBytes();
} catch (IOException e) {
throw new RuntimeException(e);
Class.forName("org.postgresql.Driver");
conn = DriverManager.getConnection(db_url, db_login, db_password);
try {
Statement sttTZ = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
sttTZ.executeUpdate("SET TIME ZONE 'UTC';");
sttTZ.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
String sql = "select max(seq) from " + table_name;
boolean exists = false;
try (PreparedStatement st = conn.prepareStatement(sql)) {
st.setString(1, tbl.getRowByName("uid").getStrVal());
try (ResultSet rs = st.executeQuery()) {
if (rs != null && rs.next()) {
result = rs.getLong(1);
}
}
} catch (SQLException e) {
logger.error("Error:",e);
result = 1;
}
} catch (Exception e) {
logger.error("Error:",e);
result = 1;
}finally {
if(conn!=null) { try { conn.close(); } catch (SQLException e) { } }
}
return result;
}
//Обновить таблицу в соответствии с пришедшими данными (вставить/обновить) TODO перенести в отдельный файл данную функцию для postgresql TCTableToolsPostgreSQL
public String updateData(byte[] reqData){
String result = "";
if(reqData==null)
return "OK";
@ -111,311 +156,216 @@ public class MainController implements ServletContextAware {
ex.printStackTrace();
}
InputStream isRaw = null;
isRaw = new ByteArrayInputStream(reqData);
InputStream isRaw = new ByteArrayInputStream(reqData);
TCTable tbl = new TCTable("", 0);
try {
if (tbl.OpenTableH(isRaw)) {
if(tbl.name.equals("frmlocustdel_locations")) {
while (tbl.ReadNextRecord()) {
String uid=tbl.fields.get(0).getStrVal();
if(uid==null || uid.isEmpty()) continue; //Для не пропуска переходных записей...
boolean exists = false; //Is there a record.
Statement st;
try {
ResultSet rs = null;
st = conn.createStatement();
try {
String sql = "select 1 from main.frmlocustdel_locations where uid=main.strtouuid('"+uid+"')";
rs = st.executeQuery(sql);
} catch (SQLException ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
}
if (rs != null) {
if (rs.next())
exists = true;
}
st.close();
PreparedStatement stmt = null;
String sql = "";
if (exists) {
sql = """
update main.frmlocustdel_locations set
del=?,
seq=?,
frmlocustdel_uid=main.strtouuid(?),
pos=?,
lon=?,
lat=?
where
uid=main.strtouuid(?)
""";
try {
stmt = conn.prepareStatement(sql);
} catch (SQLException ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
}
} else {
sql = """
insert into main.frmlocustdel_locations(
del,
seq,
frmlocustdel_uid,
pos,
lon,
lat,
uid
)values(
?,
?,
main.strtouuid(?),
?,
?,
?,
main.strtouuid(?)
)
""";
try {
stmt = conn.prepareStatement(sql);
} catch (SQLException ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
}
}
try {
stmt.setBoolean(1, tbl.fields.get(1).getBoolVal());
stmt.setLong(2, tbl.fields.get(2).getUIntVal());
stmt.setString(3, tbl.fields.get(3).getStrVal());
stmt.setInt(4, tbl.fields.get(4).getIntVal());
stmt.setDouble(5, tbl.fields.get(5).getDoubleVal());
stmt.setDouble(6, tbl.fields.get(6).getDoubleVal());
stmt.setString(7, tbl.fields.get(0).getStrVal());
} catch (SQLException ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
}
//Выпоняю запрос на свтавку либо обновление
try {
stmt.execute();
} catch (SQLException ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
}
} catch (SQLException ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
}
}
}else{
//Если это универсальная функция по обновлению данных (похожая функция есть в андроид приложении)
//Проверка на существование полей в обеих таблицах
ExistsType[] fb=new ExistsType[tbl.fields.size()];
Map<String, String> col = TCTableTools.getTableSchema(conn, "main", tbl.name);
Map<String, String> col = TCTableTools.getTableSchema(conn, tbl.name);
for(int i=0;i<tbl.fields.size();i++)
{
Iterator<Map.Entry<String, String>> iterator = col.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
if (entry.getKey().equalsIgnoreCase(col.get(i))) {
fb[i].exists=true;
fb[i].type=entry.getValue();
if(tbl.fields.get(i).name.equalsIgnoreCase(entry.getKey())){
tbl.fields.get(i).u_exists=true;
tbl.fields.get(i).u_type=entry.getValue();
break;
}
}
}
//Формирую SQL запрос для обновления и для вставки (можно также вынести в отдельную функцию)
String sqlI = TCTableTools.getSQLInsert(tbl);
String sqlU = TCTableTools.getSQLUpdate(tbl);
//Переписываем значения существующих полей и выполняем запросы
while(tbl.ReadNextRecord())
{
String sql=null;
String[] par=null;
if(tbl.getRowByName("id")!=null && tbl.getRowByName("id").getStrVal()!=null){
sql="select 1 from main."+tbl.name+" where id = ?";
par = new String[] { tbl.getRowByName("id").getStrVal() };
}else if(tbl.getRowByName("uid")!=null && tbl.getRowByName("id").getStrVal()!=null){
sql="select 1 from main."+tbl.name+" where uid = main.strtouuid(?)";
par = new String[] { tbl.getRowByName("uid").getStrVal() };
}
if(sql==null)
continue;
String sql = "select 1 from " + tbl.name + " where uid = main.strtouuid(?)";
boolean exists = false;
ResultSet rs = null;
Statement st = conn.createStatement();
try {
rs = st.executeQuery(sql);
} catch (SQLException ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
}
if (rs != null) {
if (rs.next())
try (PreparedStatement st = conn.prepareStatement(sql)) {
st.setString(1, tbl.getRowByName("uid").getStrVal());
try (ResultSet rs = st.executeQuery()) {
if (rs != null && rs.next()) {
exists = true;
}
st.close();
}
} catch (SQLException e) {
logger.error("Error:",e);
return "Error";
}
PreparedStatement stmt = null;
sql = "";
if (exists) {
sql="update main."+tbl.name+" set ";
for(int i=0;i<tbl.fields.size();i++)
{
if(fb[i].exists){
if(!tbl.fields.get(i).name.equals("uid"))
sql+=tbl.fields.get(i).name+"=?,";
}
}
sql=sql.substring(0, sql.length() - 1);
sql+="where uid=main.strtouuid(?)";
sql=sqlU;
} else {
sql="insert into main."+tbl.name+"(";
String subSql1=" ";
String subSql2=" ";
sql=sqlI;
}
try (PreparedStatement stmt = conn.prepareStatement(sql)) { //TODO для оптимизации вынести из цикла
int pos=0;
String uid="";
for(int i=0;i<tbl.fields.size();i++)
{
if(fb[i].exists){
if(!tbl.fields.get(i).name.equals("uid")) {
subSql1 += tbl.fields.get(i).name + ",";
subSql2 += "?,";
}
}
}
subSql1 += "uid,";
subSql2 += "?,";
subSql1=subSql1.substring(0, subSql1.length() - 1);
subSql2=subSql1.substring(0, subSql2.length() - 1);
sql+=subSql1+")values("+subSql2+");";
}
try {
stmt = conn.prepareStatement(sql);
} catch (SQLException ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
}
try {
for(int i=0;i<tbl.fields.size();i++)
{
if(fb[i].exists){
if(!tbl.fields.get(i).name.equals("uid")) {
if(tbl.fields.get(i).u_exists){
if(tbl.fields.get(i).name.equals("uid")) {
uid = tbl.fields.get(i).getStrVal();
}else{
pos++;
if(tbl.fields.get(i).isNull()){
stmt.setNull(i, Types.NULL);
stmt.setNull(pos, Types.NULL);
}else{
switch (tbl.fields.get(i).type){
case TCField.BD_UINT1_B:
stmt.setBoolean(pos, tbl.fields.get(i).getBoolVal());
break;
case TCField.BD_UINT1, TCField.BD_UINT2, TCField.BD_UINT4:
stmt.setLong(i, tbl.fields.get(i).getLongVal());
stmt.setLong(pos, tbl.fields.get(i).getLongVal());
break;
case TCField.BD_UINT8:
stmt.setLong(i, tbl.fields.get(i).getLongVal());
stmt.setLong(pos, tbl.fields.get(i).getLongVal());
break;
case TCField.BD_SUINT8:
stmt.setLong(i, tbl.fields.get(i).getLongVal());
stmt.setLong(pos, tbl.fields.get(i).getLongVal());
break;
case TCField.BD_INT1, TCField.BD_INT2, TCField.BD_INT4:
stmt.setInt(i, tbl.fields.get(i).getIntVal());
stmt.setInt(pos, tbl.fields.get(i).getIntVal());
break;
case TCField.BD_INT8:
stmt.setLong(i, tbl.fields.get(i).getLongVal());
stmt.setLong(pos, tbl.fields.get(i).getLongVal());
break;
case TCField.BD_SINT8:
stmt.setLong(i, tbl.fields.get(i).getLongVal());
stmt.setLong(pos, tbl.fields.get(i).getLongVal());
break;
case TCField.BD_FLOAT4:
stmt.setFloat(i, tbl.fields.get(i).getFloatVal());
stmt.setFloat(pos, tbl.fields.get(i).getFloatVal());
break;
case TCField.BD_FLOAT8:
stmt.setDouble(i, tbl.fields.get(i).getDoubleVal());
stmt.setDouble(pos, tbl.fields.get(i).getDoubleVal());
break;
case TCField.BD_SFLOAT8:
stmt.setBigDecimal(i, tbl.fields.get(i).getBigDecimalVal());
stmt.setBigDecimal(pos, tbl.fields.get(i).getBigDecimalVal());
break;
case TCField.BD_UTF8_1,TCField.BD_UTF8_2,TCField.BD_UTF8_4:
stmt.setString(i, tbl.fields.get(i).getStrVal());
case TCField.BD_UTF8_1,TCField.BD_UTF8_1_UUID,TCField.BD_UTF8_1_TIMESTAMP,TCField.BD_UTF8_2,TCField.BD_UTF8_4,TCField.BD_UTF8_4_JSONB:
stmt.setString(pos, tbl.fields.get(i).getStrVal());
break;
}
}
}
}
}
/*stmt.setBoolean(1, tbl.fields.get(1).getBoolVal());
stmt.setLong(2, tbl.fields.get(2).getUIntVal());
stmt.setString(3, tbl.fields.get(3).getStrVal());
stmt.setInt(4, tbl.fields.get(4).getIntVal());
stmt.setDouble(5, tbl.fields.get(5).getDoubleVal());
stmt.setDouble(6, tbl.fields.get(6).getDoubleVal());
stmt.setString(7, tbl.fields.get(0).getStrVal());*/
} catch (SQLException ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
pos++;
stmt.setString(pos, uid);
stmt.executeUpdate();
} catch (SQLException e) {
logger.error("Error:",e);
return "Error";
}
}
}
} catch (IOException e) {
logger.error("Error:",e);
return "Error";
}
}
}
}
} catch (IOException ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
}
} catch (Exception ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
} catch (Exception e) {
logger.error("Error:",e);
return "Error";
}finally {
if(conn!=null) { try { conn.close(); } catch (SQLException e) { } }
}
return result.toString();
return result;
}
//отдать с текущего сервера
@RequestMapping(value = "/upload/",params = {"fn"},method = { RequestMethod.GET, RequestMethod.POST })
//Скачать с удалённого сервера данные согласно настройке из json файла
@RequestMapping(value = "/download",method = { RequestMethod.GET, RequestMethod.POST })
@ResponseBody
public Object upload(HttpServletResponse response, @RequestHeader(required=false,name="Content-Type") String contentType, @RequestBody(required=false) String reqData, @RequestParam(required=false,name="file") MultipartFile file, @RequestParam(required=false,name="fn") String fn, @RequestParam(required=false,name="r") String reqR, @RequestParam(required=false,name="n") String reqN, @RequestParam(required=false,name="s") String reqS, @RequestParam(required=false,name="l") String reqL, @RequestParam(required=false,name="days",defaultValue = "0") int days, @RequestParam(required=false,name="country_id",defaultValue = "0") int country_id, @RequestParam(required=false,name="android_id",defaultValue = "") String device_id) {
public ResponseEntity<String> download(
// HttpServletResponse response
// @RequestHeader(required=false,name="Content-Type") String contentType,
// @RequestBody(required=false) String reqData,
// @RequestParam(required=false,name="file") MultipartFile file,
// @RequestParam(required=false,name="fn") String fn,
// @RequestParam(required=false,name="r") String reqR,
// @RequestParam(required=false,name="n") String reqN,
// @RequestParam(required=false,name="s") String reqS,
// @RequestParam(required=false,name="l") String reqL,
// @RequestParam(required=false,name="days",defaultValue = "0") int days,
// @RequestParam(required=false,name="country_id",defaultValue = "0") int country_id,
// @RequestParam(required=false,name="android_id",defaultValue = "") String device_id
) {
long seq = getMaxSeq("main.commands");
String fileUrl = "https://ccalm.org/api/synchronization/v01/upload?name=main.commands&seq="+String.valueOf(seq); // Замените на URL вашего файла
RestTemplate restTemplate = new RestTemplate();
String result;
String sql="select * from main.commands where seq>0";
try {
// Создаем свой обработчик ошибок, чтобы работать с заголовками ответа
restTemplate.setErrorHandler(new ResponseErrorHandler() {
@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
return response.getStatusCode().isError();
}
@Override
public void handleError(ClientHttpResponse response) throws IOException {
System.out.println("Ошибка при запросе: " + response.getStatusCode());
}
});
// Получаем заголовки и данные файла
ResponseEntity<byte[]> response = restTemplate.getForEntity(fileUrl, byte[].class);
if (response.getStatusCode() != HttpStatus.OK) {
return new ResponseEntity<>("Ошибка при скачивании файла", HttpStatus.BAD_REQUEST);
}
// Получаем заголовки
HttpHeaders headers = response.getHeaders();
String contentDisposition = headers.getFirst(HttpHeaders.CONTENT_DISPOSITION);
String contentLength = headers.getFirst(HttpHeaders.CONTENT_LENGTH);
// Извлекаем имя файла из заголовка Content-Disposition
String fileName = extractFileName(contentDisposition);
// Получаем размер файла из заголовка Content-Length
long fileSize = contentLength != null ? Long.parseLong(contentLength) : response.getBody().length;
// Выводим информацию о файле в консоль
System.out.println("Название файла: " + fileName);
System.out.println("Размер файла: " + fileSize + " байт");
System.out.println("Содержимое файла (в первом байте): " + response.getBody()[0]);
if(fileSize>5 && response.getBody()[0]==-36){
updateData(response.getBody());
}
// Возвращаем сообщение с информацией о файле
String responseMessage = String.format("Файл '%s' загружен, размер: %d байт.", fileName, fileSize);
return new ResponseEntity<>(responseMessage, HttpStatus.OK);
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>("Ошибка при загрузке файла", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
//отдать с текущего сервера (отдаём только авторизованным пользователям)
@RequestMapping(value = "/upload",method = { RequestMethod.GET, RequestMethod.POST })
@ResponseBody
public ResponseEntity<byte[]> upload(
// HttpServletResponse response,
// @RequestHeader(required=false,name="Content-Type") String contentType,
// @RequestBody(required=false) String reqData,
// @RequestParam(required=false,name="file") MultipartFile file,
@RequestParam(required=false,name="name") String tblName,
@RequestParam(required=false,name="seq") String seq
// @RequestParam(required=false,name="days",defaultValue = "0") int days,
// @RequestParam(required=false,name="country_id",defaultValue = "0") int country_id,
) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
String sql="select * from "+tblName+" where seq>"+seq;
//Connect to database
Connection conn = null;
@ -428,8 +378,6 @@ public class MainController implements ServletContextAware {
logger.info("An error occurred while connecting to the database!");
}
try {
Statement st = conn.createStatement();
ResultSet rs=null;
try {
@ -440,8 +388,8 @@ public class MainController implements ServletContextAware {
if(rs!=null)
{
TCTable tbl=new TCTable(pN,123456);
logger.info("*** "+pN+" ***");
TCTable tbl=new TCTable(tblName,123456);
logger.info("*** "+tblName+" ***");
ResultSetMetaData rsmd = rs.getMetaData();
for(int i=1;i<=rsmd.getColumnCount();i++)
@ -452,7 +400,7 @@ public class MainController implements ServletContextAware {
tbl.addField(field);
}
tbl.getHeader(response.getOutputStream());
tbl.getHeader(outputStream);
while (rs.next())
{
for(int i=1;i<=rsmd.getColumnCount();i++)
@ -465,24 +413,27 @@ public class MainController implements ServletContextAware {
}
}
//Save binary data to stream
tbl.getCol(response.getOutputStream());
tbl.getCol(outputStream);
}
}
st.close();
//response.getOutputStream();
response.flushBuffer();
} catch (IOException e) {
logger.error("Error",e);
}
} catch (Exception ex) {
logger.error("Error",ex);
}finally {
if(conn!=null) {try { conn.close(); } catch (SQLException e) {} }
}
return result;
// Получаем массив байтов
byte[] data = outputStream.toByteArray();
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Length", String.valueOf(data.length));
headers.add("Content-Disposition", "attachment; filename=" + tblName);
return new ResponseEntity<>(data, headers, HttpStatus.OK);
}
}