最近在做这样的一个需求: 我们有几套相似的后台,其中的表结构还不是完全一致,但是后台的菜单功能基本相同,我们想把这几个后台合并到一个后台中,通过下拉菜单进行后台的切换。以下简称总后台和子后台。
缕清楚需求后,我首先想到的是使用多数据源的切换,但是表结构和一些其他业务上的原因并不能完全行的通。由于项目中都是使用前后端分离做的开发,所以我想到的是直接使用拦截器,首先所有的请求都是发送到总后台,总后台根据带过来的参数判断是发往那个子后台的请求,然后去子后台发起请求。
所以这里在总后台上加上了一个拦截器,用于拦截所有的请求,然后做出判断,使用httpclient工具,将请求发送到对应的子后台,得到数据后,返回到response中,实现需求。
String businessId = request.getHeader("businessId");
HttpResponse resp = sendRequestByBusinessId(request, businessId, re, paramMap);//封装好的httpclient
String result = EntityUtils.toString(resp.getEntity(), "UTF-8");
log.debug("返回结果:"+result);
//将调用其他平台返回的参数转成map: 直接返回可能会出错。
Map<String, Object> resMap = JSON.parseObject(result);
log.debug("请求参数Map===== {}",resMap);
//将返回结果封装到response
response.addHeader(CONTENT_TYPE, JS_TYPE);
response.setContentType("application/json");
response.setCharacterEncoding(CODE_UTF8);
OutputStreamWriter out = null;
try {
out = new OutputStreamWriter(response.getOutputStream(), "UTF-8");
} catch (UnsupportedEncodingException e) {
log.error(e.getMessage(), e);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
JsonUtil.write(out,resMap);
但是有一类需求发现使用这种方式做处理无法得到预期结果。那就是系统中还存在部分excel导出功能,都是使用poi做实现的。由于poi中自动实现了对于response和输出流的处理,使用上面的方式是没有办法实现的。那么我使用httpclient如何调用另一个系统写好的poi导出功能呢。
我们先看一下子系统中poi的实现方式。
@RequestMapping(value = "/test/export.htm")
public void urgeLogExport(@RequestParam(value = "searchParams", required = false) String searchParams)
throws Exception {
Map<String, Object> params = JsonUtil.parse(searchParams, Map.class);
List list = urgeRepayOrderService.listUrgeLog(params);
SysUser user = (SysUser) request.getSession().getAttribute("SysUser");
response.setContentType("application/msexcel;charset=UTF-8");
// 记录取得
String title = "导出Excel表";
String[] hearders = ExportConstant.EXPORT_URGELOG_LIST_HEARDERS;
String[] fields = ExportConstant.EXPORT_URGELOG_LIST_FIELDS;
JsGridReportBase report = new JsGridReportBase(request, response);
report.exportExcel(list, title, hearders, fields, user.getName());
}
//report.exportExcel方法如下:
/**
* hj
* Excel报表导出通用方法(含多个sheet导出)
* @throws Exception
*/
public void exportExcel(List<Object> list,String title,String[] hearders,String[] fields,String operatorName) throws Exception{
List<List<Object>> listResult = new ArrayList<List<Object>>(); //保存每页List的二维数组
String excelTitle = title+"_"+DateUtil.dateStr3(DateUtil.getNow());
if (list.size()>5000) {
int excelSize = 5000; //每个Excel文件条数
int totalCount = list.size(); //查询结果总条数
int pageCount = 0;
int numPage = totalCount%excelSize; //是否整页数
if (numPage > 0) {
pageCount = totalCount/excelSize + 1;
}else{
pageCount = totalCount/excelSize;
}
for (int i = 1; i <= pageCount; i++) {
if (numPage == 0) {
listResult.add(list.subList((i-1)*excelSize,excelSize*i));
}
else{
if (i == pageCount) {
listResult.add(list.subList((i-1)*excelSize,totalCount));
}
else{
listResult.add(list.subList((i-1)*excelSize,excelSize*(i)));
}
}
}
}
TableData td = null;
if (listResult.size()>0) {
List<TableData> tableDataLst = new ArrayList<TableData>();
for (int i = 0; i < listResult.size(); i++) {
td = ExcelUtil.createTableData(listResult.get(i), ExcelUtil.createTableHeader(hearders), fields);
td.setSheetTitle(title + "_("+(i+1)+")");
tableDataLst.add(td);
}
exportToExcel(excelTitle, operatorName, tableDataLst);
}else{
td = ExcelUtil.createTableData(list, ExcelUtil.createTableHeader(hearders), fields);
exportToExcel(excelTitle, operatorName, td);
}
}
exportToExcel方法如下:
HSSFWorkbook wb = new HSSFWorkbook();// 创建新的Excel 工作簿
HashMap<String, HSSFCellStyle> styles = initStyles(wb);// 根据模板文件,初始化表头样式
wb = writeSheet(wb, title, styles, creator, tableData);// 写入工作表
String sFileName = title + ".xls";
/*response.setHeader("Content-Disposition",
"attachment;filename=".concat(String.valueOf(URLEncoder.encode(sFileName, "UTF-8"))));*/
// 火狐浏览器导出excel乱码
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String agent = request.getHeader("User-Agent");
// 判断是否火狐浏览器
boolean isFirefox = (agent != null && agent.contains("Firefox"));
if (isFirefox) {
sFileName = new String(sFileName.getBytes("UTF-8"), "ISO-8859-1");
} else {
sFileName = URLEncoder.encode(sFileName, "UTF8");
}
response.setHeader("Content-Disposition", "attachment; filename=".concat(sFileName));
response.setHeader("Connection", "close");
response.setHeader("Content-Type", "application/vnd.ms-excel");
wb.write(response.getOutputStream());
发现最终是使用wb.write写出数据,那么我们使用httpclient还怎么调用呢,这里我们先通过httpclient调用返回HttpResponse,在把他转换成InputStream ,然后穿件一个HSSFWorkbook 对象,按照上面的方式写出去即可:
HttpResponse resp = sendRequestByBusinessId(request, businessId, re, paramMap);//封装的httpclient
String fileName = "导出文件_"+System.nanoTime();//默认名字
InputStream input = resp.getEntity().getContent();//转成InputStream
HSSFWorkbook wb = new HSSFWorkbook(input);// 创建新的Excel 工作簿
response.setHeader("Content-Disposition", "attachment; filename=".concat(fileName));
response.setHeader("Connection", "close");
response.setHeader("Content-Type", "application/vnd.ms-excel");
wb.write(response.getOutputStream());
完成