最近在写一个thymeleaf模板引擎的功能读取模板填充数据生成html文件并导出zip包 本地window是环境下一切都是没有问题的但是在linux环境下导出的 html都是乱码
我用的是SpringTemplateEngine.process(模板名称,内容,FileWriter )这个方法
FileWriter writer = new FileWriter(filePath,true);
一开始(输出路径)用的是 FileWriter 后来发现 Java FileWriter 默认是用(ISO-8859-1 or US-ASCII)西方编码的,而FileWriter类没有setEncoding的方法。希望通过设置编码方式的计划破灭了
后来将FileWriter 换成
BufferedWriter writer = new BufferedWriter (new OutputStreamWriter (new FileOutputStream (filePath,true),"UTF-8"));
就可以了
最后提醒一下 fileWriter.close();一定不要忘了写了。
下面加上我的模板和controller方法
html
动态表格
跨机构进件api接口对接文档
一、文档简介
本文档针对机构对接xxx跨机构进件进行说明。
文档包括了对接流程、对接准备、名词解释、对接接口、异常状态、常见文档等六块内容进行详细说明,便于相关对接人员在对接过程中给出标准化的解释。所涉及的对接事宜相关人员皆可查阅该文档。
二、对接流程
1、参数获取
对接前,需要配置一系列参数,参数含盖合作机构编码、渠道编码、业务编码、准入编码、密钥、消息/通知回调地址及IP白名单地址组成。
参数不全或错误时系统无法正常走单,同时配置参数分为从上方机构获取和自身机构提供两方面进行,具体获取方式及内容详见下方详细说明:
1.1、需从上方机构获取的参数
- (1)合作机构编码
- (2)渠道编码
- (3)业务编码
- (4)准入编码
- (5)密钥
1.2、自身机构需提供的参数
- (1)消息/通知回调地址:需提供测试及生产环境两个地址。
- (2)IP白名单地址:需提供测试及生产环境两个地址。
1.3、参数获取方式
上方机构参数获取需提供对应的邮箱,上方机构或系统技术支持方会通过邮件形式发送对应的参数信息。
自身机构参数发送至上方机构或系统技术支持方的邮箱内(上方机构邮箱:
系统支持方邮箱: [email protected] )。
三、对接准备
1、通讯方式
程序调用时请求接口采用HTTP协议。接口请求参数以及接口请求返回的结果均以#返回值格式,需研发提供下#格式数据为标准。
2、加密方式
程序调用时请求接口采用HTTP协议。接口请求参数以及接口请求返回的结果均以#返回值格式,需研发提供下#格式数据为标准。
四、名词解释
程序调用时请求接口采用HTTP协议。接口请求参数以及接口请求返回的结果均以#返回值格式,需研发提供下#格式数据为标准。
五、对接接口
1、新建订单
1.2、请求参数
参数名 |
名称 |
类型 |
是否必填 |
特殊规则 |
说明 |
---|
code |
|
|
合作机构编码 |
String |
是 |
|
文字 |
data |
orderId |
|
金云汇系统订单号 |
String |
是 |
|
文字 |
businessCode |
|
业务编码 |
String |
是 |
|
文字 |
accessCode |
|
准入编码 |
String |
是 |
|
文字 |
channelCode |
|
渠道编码 |
String |
是 |
|
文字 |
customOrderId |
|
机构唯一标识 |
String |
是 |
|
文字 |
1.3、发送样例
{
"code": "e73f7214de5543be0bb9b72cdae7463c",
"data": {
"accessCode": "",
"businessCode": "",
"channelCode": "",
"orderId": 1,
"customOrderId": ""
}
}
1.4、响应参数
参数名 |
说明 |
---|
code |
状态码(200代表成功, 1XXX代表错误码) |
message |
状态码描述 |
orderId |
订单号 |
status |
订单状态(0:进行中,1:订单完成 ,2:拒绝办理,3:订单终止) |
1.5、返回样例
{
"code":200,
"message":"成功",
"orderId":"15542568760393899",
"status":null
}
2、查询订单状态
2.2、请求参数
参数名 |
名称 |
类型 |
是否必填 |
特殊规则 |
说明 |
---|
code |
|
|
合作机构编码 |
String |
是 |
|
文字 |
data |
orderId |
|
金云汇系统订单号 |
String |
是 |
|
文字 |
businessCode |
|
业务编码 |
String |
是 |
|
文字 |
accessCode |
|
准入编码 |
String |
是 |
|
文字 |
channelCode |
|
渠道编码 |
String |
是 |
|
文字 |
2.3、发送样例
{
"code": "e73f7214de5543be0bb9b72cdae7463c",
"data": {
"accessCode": "",
"businessCode": "",
"channelCode": "",
"orderId": 1
}
}
2.4、响应参数
参数名 |
说明 |
---|
code |
状态码(200代表成功, 1XXX代表错误码) |
message |
状态码描述 |
orderId |
订单号 |
status |
订单状态(0:进行中,1:订单完成 ,2:拒绝办理,3:订单终止) |
2.5、返回样例
{
"code":200,
"message":"成功",
"orderId":"15542568760393899",
"status":null
}
3、流程内取消订单
3.2、请求参数
参数名 |
名称 |
类型 |
是否必填 |
特殊规则 |
说明 |
---|
code |
|
|
合作机构编码 |
String |
是 |
|
文字 |
data |
orderId |
|
金云汇系统订单号 |
String |
是 |
|
文字 |
businessCode |
|
业务编码 |
String |
是 |
|
文字 |
accessCode |
|
准入编码 |
String |
是 |
|
文字 |
channelCode |
|
渠道编码 |
String |
是 |
|
文字 |
3.3、发送样例
{
"code": "e73f7214de5543be0bb9b72cdae7463c",
"data": {
"accessCode": "",
"businessCode": "",
"channelCode": "",
"orderId": 1
}
}
3.4、响应参数
参数名 |
说明 |
---|
code |
状态码(200代表成功, 1XXX代表错误码) |
message |
状态码描述 |
orderId |
订单号 |
status |
订单状态(0:进行中,1:订单完成 ,2:拒绝办理,3:订单终止) |
3.5、返回样例
{
"code":200,
"message":"成功",
"orderId":"15542568760393899",
"status":null
}
4、流程外取消订单
4.2、请求参数
参数名 |
名称 |
类型 |
是否必填 |
特殊规则 |
说明 |
---|
code |
|
|
合作机构编码 |
String |
是 |
|
文字 |
data |
orderId |
|
金云汇系统订单号 |
String |
是 |
|
文字 |
businessCode |
|
业务编码 |
String |
是 |
|
文字 |
accessCode |
|
准入编码 |
String |
是 |
|
文字 |
channelCode |
|
渠道编码 |
String |
是 |
|
文字 |
4.3、发送样例
{
"code": "e73f7214de5543be0bb9b72cdae7463c",
"data": {
"accessCode": "",
"businessCode": "",
"channelCode": "",
"orderId": 1
}
}
4.4、响应参数
参数名 |
说明 |
---|
code |
状态码(200代表成功, 1XXX代表错误码) |
message |
状态码描述 |
orderId |
订单号 |
status |
订单状态(0:进行中,1:订单完成 ,2:拒绝办理,3:订单终止) |
4.5、返回样例
{
"code":200,
"message":"成功",
"orderId":"15542568760393899",
"status":null
}
、
.1、接口说明
接口说明 |
#进件接口管理中对应接口的接口描述+接口类型:补录接口或正常接口# |
---|
接口地址 |
#进件接口管理中对应接口的接口地址+接口的参数名# |
---|
.2、请求参数
参数名 |
名称 |
类型 |
是否必填 |
特殊规则 |
说明 |
---|
code |
|
|
合作机构编码 |
String |
是 |
|
文字 |
data |
orderId |
|
订单号 |
String |
是 |
|
文字 |
businessCode |
|
业务编码 |
String |
是 |
|
文字 |
accessCode |
|
准入编码 |
String |
是 |
|
文字 |
channelCode |
|
渠道编码 |
String |
是 |
|
文字 |
mainBorrower |
|
主借款人信息 |
json |
是 |
|
json对象 |
|
|
String |
String |
String |
Number |
JSONArray |
String |
String |
|
|
图片 |
视频/音频 |
文字 |
数值 |
文件夹 |
PDF |
文字 |
guarantor |
|
反担保人信息 |
json |
是 |
|
JSONArray |
|
|
String |
String |
String |
Number |
JSONArray |
String |
String |
|
|
图片 |
视频/音频 |
文字 |
数值 |
文件夹 |
PDF |
文字 |
coPayer |
|
共同还款人信息 |
json |
是 |
|
JSONArray |
|
|
String |
String |
String |
Number |
JSONArray |
String |
String |
|
|
图片 |
视频/音频 |
文字 |
数值 |
文件夹 |
PDF |
文字 |
order |
|
订单信息 |
json |
是 |
|
json对象 |
|
|
String |
String |
String |
Number |
JSONArray |
String |
String |
|
|
图片 |
视频/音频 |
文字 |
数值 |
文件夹 |
PDF |
文字 |
sign |
|
|
签名 |
String |
是 |
|
文字 |
.3、发送样例
{
"code":200,
"message":"成功",
"orderId":"15542568760393899",
"status":null
}
.4、响应参数
参数名 |
说明 |
---|
code |
状态码(200代表成功, 1XXX代表错误码) |
message |
状态码描述 |
orderId |
订单号 |
status |
订单状态(0:进行中,1:订单完成 ,2:拒绝办理,3:订单终止) |
.5、返回样例
{
"code":200,
"message":"成功",
"orderId":"15542568760393899",
"status":null
}
controller
@RequestMapping(value = "/download")
public void download(HttpServletRequest request, HttpServletResponse response, Integer processId,
Integer basePartnerId) throws ServletException, IOException {
// 查询数据库中各接口的参数
List selectFiledList = apiProcessCodeService.selectFiledList(processId, basePartnerId);
// 错误吗
List errorCode = ergodicEnumData();
Context context = new Context();
context.setVariable("file", selectFiledList);
context.setVariable("formatTime", formatTime);
context.setVariable("apiName", apiName);
context.setVariable("partnerName", partnerName);
context.setVariable("errorCode", errorCode);
File fileExist = (File)new File(path);
if (!fileExist.exists()) {
fileExist.mkdirs();
}
String writerFileName = basePartnerId + "-" + processId + "-" + "example.html";
File writerFile = new File(path + writerFileName);
if (writerFile.exists()) {
boolean delete = writerFile.delete();
log.info(basePartnerId + "-" + processId + "-文件删除是否成功:" + delete);
}
BufferedWriter fileWriter =
new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path + writerFileName, true), "UTF-8"));
templateEngine.process("example", context, fileWriter);
fileWriter.close();
// 设置要导出的文件的名字
String fileName = "接口文档.zip";
String userAgent = request.getHeader("user-agent").toLowerCase();
if (userAgent.contains("msie") || userAgent.contains("trident")) {
// win10 ie edge 浏览器 和其他系统的ie
fileName = URLEncoder.encode(fileName, "UTF-8");
} else {
// 其他的浏览器
fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
}
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition", "attachment;filename=" + fileName);
ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream());
// 本地文件得物理路径
List list = new ArrayList<>();
list.add(writerFileName);
list.add("city.json");
list.add("flow.jpg");
for (String string : list) {
File file = (File)new File(path + string);
if (StringUtils.equals("flow", string.substring(0, string.indexOf(".")))) {
zipFile(file, "系统对接流程图", zipOutputStream);
} else {
zipFile(file, string.substring(0, string.indexOf(".")), zipOutputStream);
}
}
zipOutputStream.close();
}
/**
* 压缩文件
*
* @param inputFile 待压缩的文件
* @param a 区分压缩包文件名相同
* @param identity 借款人类型名称
* @param materialsName 类别,比如身份证正面、反面等
* @param name 借款人姓名
* @param outputstream zip包流
* @throws IOException
* @throws ServletException
*/
private static void zipFile(File inputFile, String name, ZipOutputStream outputstream)
throws IOException, ServletException {
InputStream in = null;
try {
if (inputFile.exists()) {
if (inputFile.isFile()) {
String fileName = inputFile.getName();
String Photoname =
"跨机构进件api接口对接文档" + File.separator + name + fileName.substring(fileName.lastIndexOf("."));
byte[] buff = new byte[1024];
in = new FileInputStream(inputFile);
ZipEntry entry = new ZipEntry(Photoname);
outputstream.putNextEntry(entry);
int len;
while ((len = in.read(buff, 0, 1024)) != -1) {
outputstream.write(buff, 0, len);
}
}
} else {
log.error("文件不存在!" + inputFile);
}
} catch (IOException e) {
log.error("下载出错!", e);
} finally {
if (in != null) {
in.close();
}
}
}