文章目录
在文件的传输的使用中常常用到两系统之间的文件交互,使用的方式有两种,一种是通过二进制流的方式实现,一种是通过转码编译的方式。下面是三中使用场景
一、文件转存
当系统A要把文件传个系统B用来保存,这样的可以使用两钟方式
1. 二进制流
在文件的读写过程中长用的就是二进制流的方式,下面一个简单的思路
// 创建一个File对象,这里可以通过其他方式获取到我们使用的文件
File file = new File(fileName);
if (file.exists()) {
response.addHeader("Content-Disposition", "attachment;filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
response.setContentType(fileType + ";charset=" + "UTF-8");
response.setHeader("Accept-Ranges", "bytes");
int fileLength = (int) file.length();
response.setContentLength(fileLength);
if (fileLength > 0) {
this.writeFileToResp(response, file);
}
} else {
throw new AttachmentException("msg.warning.download.file.error", "msg.warning.download.file.error", new Object[0]);
}
private void writeFileToResp(HttpServletResponse response, File file) throws Exception {
byte[] buf = new byte[BUFFER_SIZE];
InputStream inStream = new FileInputStream(file);
Throwable var5 = null;
try {
ServletOutputStream outputStream = response.getOutputStream();
Throwable var7 = null;
try {
int readLength;
while ((readLength = inStream.read(buf)) != -1) {
outputStream.write(buf, 0, readLength);
}
outputStream.flush();
} catch (Throwable var30) {
var7 = var30;
throw var30;
} finally {
if (outputStream != null) {
if (var7 != null) {
try {
outputStream.close();
} catch (Throwable var29) {
var7.addSuppressed(var29);
}
} else {
outputStream.close();
}
}
}
} catch (Throwable var32) {
var5 = var32;
throw var32;
} finally {
if (inStream != null) {
if (var5 != null) {
try {
inStream.close();
} catch (Throwable var28) {
var5.addSuppressed(var28);
}
} else {
inStream.close();
}
}
}
}
一般使用这样的方式来完成数据的下载接口
然后另一个系统通过http
请求获取到文件的流数据
public void downloadFile(HttpServletResponse response, String fileId) {
HttpHeaders headers = new HttpHeaders();
String url = ptpProperties.getUri() + ptpProperties.getFileApi() + fileId;
// 获取认证信息
String token = "bearer " + this.sendToken();
headers.add("Authorization", token);
//请求PTP获取要下载的文件流
ResponseEntity<byte[]> responseNew = RestTemplateSingleton.INSTANCE.getRestTemplate().exchange(url, HttpMethod.GET, new HttpEntity<byte[]>(headers), byte[].class);
// 下载文件
this.saveFile(response, responseNew);
}
private void saveFile(HttpServletResponse response, ResponseEntity<byte[]> responseNew) {
//获取PTP返回报文中文件字节码,从ResponseEntity对象中我们可以解析到文件的名称和类型,编码规则等
byte[] result = responseNew.getBody();
// 然后就可以通过这个二进制流来完成文件的转移保存了。
}
2. 转码编译
但是有的时候上述的方式会出现文件损坏的情况
这个时候我们就要考虑编码问题或者其他的文件格式的问题,为了解决这个问题我们可以把文件当作字符串参数传给接收的系统
public class NewFile {
private String fileName;
private String fileStr;
private String fileId;
private String fileType;
private String charset;
private boolean exist = false;
public NewFile() {
}
public NewFile(boolean isExist) {
this.exist = isExist;
}
public NewFile(SysFile sysFile, String fileId) throws IOException {
File file = new File(sysFile.getFilePath());
if (file.exists()) {
this.fileId = fileId;
this.fileName = sysFile.getFileName();
this.charset = "UTF-8";
this.fileType = sysFile.getFileType();
byte[] readFileToByteArray = FileUtils.readFileToByteArray(file);
this.fileStr = Base64.encodeBase64String(readFileToByteArray);
this.exist = true;
}
}
// getter and setter
}
public NewFile detailFile(HttpServletRequest request, String fileId) {
try {
IRequest requestContext = this.createRequestContext(request);
// 这里是获取到文件的信息,可以使用其他的方式
SysFile sysFile = this.fileService.selectByPrimaryKey(requestContext, Long.valueOf(fileId));
return new PtpFile(sysFile, fileId);
} catch (IOException e) {
LOGGER.error("文件异常:", e);
}
return new NewFile(false);
}
这样就可以把文件信息传出去了,接收方通过http
请求获取这个对象,然后反编译就可以了。
public void downloadFile(HttpServletResponse response, String fileId) {
HttpHeaders headers = new HttpHeaders();
String url = properties.getUri() + properties.getFileApi() + fileId;
String token = "bearer " + this.sendToken();
headers.add("Authorization", token);
ResponseEntity<NewFile> responseNew = RestTemplateSingleton.INSTANCE.getRestTemplate().exchange(url, HttpMethod.GET, new HttpEntity<NewFile>(headers), NewFile.class);
try {
this.saveFile(response, responseNew);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
NewFile newFile = responseNew.getBody();
byte[] result = Base64.decodeBase64(newFile.getFileStr());
这样就可以获取到二进制流文件了。
二、文件下载接口穿透
如果要实现文件的下载穿透,就要修改上述方式中的saveFile
方法
1. 二进制流
private void saveFile(HttpServletResponse response, ResponseEntity<byte[]> responseNew) {
//获取PTP返回报文中文件字节码
byte[] result = responseNew.getBody();
//将数据回写到HBPM返回参数
response.setHeader("content-type", String.valueOf(responseNew.getHeaders().getContentType()));
response.setHeader("Content-Disposition", String.valueOf(responseNew.getHeaders().getContentDisposition()));
response.setHeader("Accept-Ranges", "bytes");
response.setContentType(String.valueOf(responseNew.getHeaders().getContentType()));
try (InputStream inputStream = new ByteArrayInputStream(result); OutputStream outputStream = response.getOutputStream()) {
byte[] buff = new byte[result.length];
// 读取字节流
inputStream.read(buff);
//通过while循环写入到指定了的文件夹中
outputStream.write(buff);
} catch (IOException e) {
e.printStackTrace();
throw new CommonException(MessagesConstant.PTP_COMMON_FILE_DOWNLOAD_ERROR);
}
}
2. 转码编译
private void saveFile(HttpServletResponse response, ResponseEntity<NewFile> responseNew) throws UnsupportedEncodingException {
NewFile newFile = responseNew.getBody();
if (Boolean.TRUE.equals(newFile.isExist())) {
byte[] result = Base64.decodeBase64(newFile.getFileStr());
//获取PTP返回报文中文件字节码
//将数据回写到HBPM返回参数
response.addHeader("Content-Disposition", "attachment;filename=\"" + URLEncoder.encode(newFile.getFileName(), "UTF-8") + "\"");
response.setContentType(newFile.getFileType() + ";charset=" + newFile.getCharset());
response.setHeader("Accept-Ranges", "bytes");
response.setContentType(String.valueOf(responseNew.getHeaders().getContentType()));
try (InputStream inputStream = new ByteArrayInputStream(result); OutputStream outputStream = response.getOutputStream()) {
byte[] buff = new byte[result.length];
// 读取字节流
inputStream.read(buff);
//通过while循环写入到指定了的文件夹中
outputStream.write(buff);
} catch (IOException e) {
e.printStackTrace();
throw new CommonException(MessagesConstant.PTP_COMMON_FILE_DOWNLOAD_ERROR);
}
}
}
三、Hzero系统下文件的穿透下载
面对Hzero的接口穿透,要知道这些关系
- Hzero的接口穿透通过将请求参数转成字符串传递,这就要保证数据转成字符串不能有转码的问题
- Hzero的穿透是接口服务的功能,这样就可以保证数据请求时的校验和认证不用开发者去反复编码
- Hzero的接口请求都是默认UTF-8的编码格式
面对上面的情况,我们知道不能使用二进制流的方式实现,这里提倡用base64转码编译后传输,使用时解码就可以了。
这里就不用案例说明,具体使用和上述的转码编译的下载基本一样。# 两系统文件传输
在文件的传输的使用中常常用到两系统之间的文件交互,使用的方式有两种,一种是通过二进制流的方式实现,一种是通过转码编译的方式。下面是三中使用场景
一、文件转存
当系统A要把文件传个系统B用来保存,这样的可以使用两钟方式
1. 二进制流
在文件的读写过程中长用的就是二进制流的方式,下面一个简单的思路
// 创建一个File对象,这里可以通过其他方式获取到我们使用的文件
File file = new File(fileName);
if (file.exists()) {
response.addHeader("Content-Disposition", "attachment;filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
response.setContentType(fileType + ";charset=" + "UTF-8");
response.setHeader("Accept-Ranges", "bytes");
int fileLength = (int) file.length();
response.setContentLength(fileLength);
if (fileLength > 0) {
this.writeFileToResp(response, file);
}
} else {
throw new AttachmentException("msg.warning.download.file.error", "msg.warning.download.file.error", new Object[0]);
}
private void writeFileToResp(HttpServletResponse response, File file) throws Exception {
byte[] buf = new byte[BUFFER_SIZE];
InputStream inStream = new FileInputStream(file);
Throwable var5 = null;
try {
ServletOutputStream outputStream = response.getOutputStream();
Throwable var7 = null;
try {
int readLength;
while ((readLength = inStream.read(buf)) != -1) {
outputStream.write(buf, 0, readLength);
}
outputStream.flush();
} catch (Throwable var30) {
var7 = var30;
throw var30;
} finally {
if (outputStream != null) {
if (var7 != null) {
try {
outputStream.close();
} catch (Throwable var29) {
var7.addSuppressed(var29);
}
} else {
outputStream.close();
}
}
}
} catch (Throwable var32) {
var5 = var32;
throw var32;
} finally {
if (inStream != null) {
if (var5 != null) {
try {
inStream.close();
} catch (Throwable var28) {
var5.addSuppressed(var28);
}
} else {
inStream.close();
}
}
}
}
一般使用这样的方式来完成数据的下载接口
然后另一个系统通过http
请求获取到文件的流数据
public void downloadFile(HttpServletResponse response, String fileId) {
HttpHeaders headers = new HttpHeaders();
String url = ptpProperties.getUri() + ptpProperties.getFileApi() + fileId;
// 获取认证信息
String token = "bearer " + this.sendToken();
headers.add("Authorization", token);
//请求PTP获取要下载的文件流
ResponseEntity<byte[]> responseNew = RestTemplateSingleton.INSTANCE.getRestTemplate().exchange(url, HttpMethod.GET, new HttpEntity<byte[]>(headers), byte[].class);
// 下载文件
this.saveFile(response, responseNew);
}
private void saveFile(HttpServletResponse response, ResponseEntity<byte[]> responseNew) {
//获取PTP返回报文中文件字节码,从ResponseEntity对象中我们可以解析到文件的名称和类型,编码规则等
byte[] result = responseNew.getBody();
// 然后就可以通过这个二进制流来完成文件的转移保存了。
}
2. 转码编译
但是有的时候上述的方式会出现文件损坏的情况
这个时候我们就要考虑编码问题或者其他的文件格式的问题,为了解决这个问题我们可以把文件当作字符串参数传给接收的系统
public class NewFile {
private String fileName;
private String fileStr;
private String fileId;
private String fileType;
private String charset;
private boolean exist = false;
public NewFile() {
}
public NewFile(boolean isExist) {
this.exist = isExist;
}
public NewFile(SysFile sysFile, String fileId) throws IOException {
File file = new File(sysFile.getFilePath());
if (file.exists()) {
this.fileId = fileId;
this.fileName = sysFile.getFileName();
this.charset = "UTF-8";
this.fileType = sysFile.getFileType();
byte[] readFileToByteArray = FileUtils.readFileToByteArray(file);
this.fileStr = Base64.encodeBase64String(readFileToByteArray);
this.exist = true;
}
}
// getter and setter
}
public NewFile detailFile(HttpServletRequest request, String fileId) {
try {
IRequest requestContext = this.createRequestContext(request);
SysFile sysFile = this.fileService.selectByPrimaryKey(requestContext, Long.valueOf(fileId));
return new PtpFile(sysFile, fileId);
} catch (IOException e) {
LOGGER.error("文件异常:", e);
}
return new NewFile(false);
}
这样就可以把文件信息传出去了,接收方通过http
请求获取这个对象,然后反编译就可以了。
public void downloadFile(HttpServletResponse response, String fileId) {
HttpHeaders headers = new HttpHeaders();
String url = properties.getUri() + properties.getFileApi() + fileId;
String token = "bearer " + this.sendToken();
headers.add("Authorization", token);
ResponseEntity<NewFile> responseNew = RestTemplateSingleton.INSTANCE.getRestTemplate().exchange(url, HttpMethod.GET, new HttpEntity<NewFile>(headers), NewFile.class);
try {
this.saveFile(response, responseNew);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
NewFile newFile = responseNew.getBody();
byte[] result = Base64.decodeBase64(newFile.getFileStr());
这样就可以获取到二进制流文件了。
二、文件下载接口穿透
如果要实现文件的下载穿透,就要修改上述方式中的saveFile
方法
1. 二进制流
private void saveFile(HttpServletResponse response, ResponseEntity<byte[]> responseNew) {
//获取PTP返回报文中文件字节码
byte[] result = responseNew.getBody();
//将数据回写到HBPM返回参数
response.setHeader("content-type", String.valueOf(responseNew.getHeaders().getContentType()));
response.setHeader("Content-Disposition", String.valueOf(responseNew.getHeaders().getContentDisposition()));
response.setHeader("Accept-Ranges", "bytes");
response.setContentType(String.valueOf(responseNew.getHeaders().getContentType()));
try (InputStream inputStream = new ByteArrayInputStream(result); OutputStream outputStream = response.getOutputStream()) {
byte[] buff = new byte[result.length];
// 读取字节流
inputStream.read(buff);
//通过while循环写入到指定了的文件夹中
outputStream.write(buff);
} catch (IOException e) {
e.printStackTrace();
throw new CommonException(MessagesConstant.PTP_COMMON_FILE_DOWNLOAD_ERROR);
}
}
2. 转码编译
private void saveFile(HttpServletResponse response, ResponseEntity<NewFile> responseNew) throws UnsupportedEncodingException {
NewFile newFile = responseNew.getBody();
if (Boolean.TRUE.equals(newFile.isExist())) {
byte[] result = Base64.decodeBase64(newFile.getFileStr());
//获取PTP返回报文中文件字节码
//将数据回写到HBPM返回参数
response.addHeader("Content-Disposition", "attachment;filename=\"" + URLEncoder.encode(newFile.getFileName(), "UTF-8") + "\"");
response.setContentType(newFile.getFileType() + ";charset=" + newFile.getCharset());
response.setHeader("Accept-Ranges", "bytes");
response.setContentType(String.valueOf(responseNew.getHeaders().getContentType()));
try (InputStream inputStream = new ByteArrayInputStream(result); OutputStream outputStream = response.getOutputStream()) {
byte[] buff = new byte[result.length];
// 读取字节流
inputStream.read(buff);
//通过while循环写入到指定了的文件夹中
outputStream.write(buff);
} catch (IOException e) {
e.printStackTrace();
throw new CommonException(MessagesConstant.PTP_COMMON_FILE_DOWNLOAD_ERROR);
}
}
}
三、Hzero系统下文件的穿透下载
面对Hzero的接口穿透,要知道这些关系
- Hzero的接口穿透通过将请求参数转成字符串传递,这就要保证数据转成字符串不能有转码的问题
- Hzero的穿透是接口服务的功能,这样就可以保证数据请求时的校验和认证不用开发者去反复编码
- Hzero的接口请求都是默认UTF-8的编码格式
面对上面的情况,我们知道不能使用二进制流的方式实现,这里提倡用base64转码编译后传输,使用时解码就可以了。
这里就不用案例说明,具体使用和上述的转码编译的下载基本一样。