最近在维护OA系统的时候,刚好遇到几个类似的问题。总结了一下大概是下面三种情况。
1.在拼接原生SQL的时候,特殊字符如【'】,破坏了SQL的完整性。
public String escapeExprSpecialWord(String keyword) { if (StringUtils.isNotEmpty(keyword)) { String[] fbsArr = { "\\","$","(",")","*","+",".","[", "]","?","^","{","}","|","'","%" }; for (String key : fbsArr) { if (keyword.contains(key)) { keyword = keyword.replace(key, "\\" + key); } } } return keyword; }
2.返给前端json数据,com.alibaba.fastjson.JSONObject.toJSONString(),如果内容中包含特殊字符\n,\t,\r等,会导致前端json无法正常解析。
public String formatJsonStr(String str){ if(StringUtils.isNotEmpty(str)){ String[] formatStrs = {"\t","\r","\n"}; for(String key:formatStrs){ if(str.contains(key)){ str = str.replace(key, ","); } } } return str; }
3.文件上传及下载,文件名中有【,】也会导致无法下载,或下载内容为空。
/** * 上传文件 * @param files * @return */ public List<AttachmentEntity> upload(File[] files, String[] fileNames) { List<AttachmentEntity> list = new ArrayList<AttachmentEntity>(); Properties prop = new Properties(); FileInputStream fis =null; InputStream in = null; InputStream propertiesIn = null; FileOutputStream out = null ; try { Resource[] resources = RESOLVER .getResources("classpath*:com/**/**/META-INF/upload/*.conf"); if (resources == null || resources.length < 1) { LOGGER.error("上传文件失败,失败原因 : ", "client.conf不存在!"); return list; } else { in = resources[0].getInputStream(); File file = new File("client.conf"); out = new FileOutputStream(file); byte[] buf = new byte[1024]; while (true) { int r = in.read(buf); if (r == -1) { break; } out.write(buf, 0, r); } ClientGlobal.init(file.getAbsolutePath()); LOGGER.info("上传中:" + "客户端配置文件初始化完成 "); // getting connection of FastDFS TrackerClient trackerClient = new TrackerClient(); TrackerServer trackerServer = trackerClient.getConnection(); if (trackerServer != null) { LOGGER.info("上传中:" + "均衡器初始化成功"); } StorageServer storageServer = null; StorageClient storageClient = new StorageClient(trackerServer, storageServer); propertiesIn = new FileInputStream(file.getAbsolutePath()); prop.load(propertiesIn); String iP = trackerServer.getInetSocketAddress().getHostName();//获取fastdfs IP String ipAndPort = iP+":"+prop.getProperty("http.tracker_server_port");//获取fastdfs 对应下载http uri(ip+端口) String fileExtName = ""; for (int i = 0; i < files.length; i++) { AttachmentEntity entity = new AttachmentEntity(); entity.setId(UUIDUtil.generate()); entity.setAttachmentName(fileNames[i]);//这里fileName中,包含特殊符号,比如逗号,在更新到数据库中没有变化 entity.setActive("Y"); entity.setIpAndPort(ipAndPort);//为附件添加http uri; if (fileNames[i].contains(".")) { fileExtName = fileNames[i].substring(fileNames[i] .lastIndexOf(".") + 1); } else { LOGGER.error("上传文件失败,失败原因 : ", "文件名非法"); } fis = new FileInputStream(files[i]); byte[] file_buff = null; if (fis != null) { int len = fis.available(); file_buff = new byte[len]; fis.read(file_buff); } LOGGER.info("file length: " + file_buff.length); // meta data setting fileNameString(fileNames[i]) NameValuePair[] meta_list = new NameValuePair[3]; meta_list[0] = new NameValuePair("fileName", fileNameString(fileNames[i]));//这里将fileNameString(fileNames[i])将原来文件名中逗号替换为空格 meta_list[1] = new NameValuePair("fileExtName", fileExtName); meta_list[2] = new NameValuePair("fileLength", String.valueOf(files[i].length())); String group_name = null; // get store storages StorageServer[] storageServers = trackerClient .getStoreStorages(trackerServer, group_name); if (storageServers == null) { LOGGER.error("访问存储服务器失败,失败原因 : ", storageClient.getErrorCode()); } else { LOGGER.info("store 数目: " + storageServers.length); for (int k = 0; k < storageServers.length; k++) { LOGGER.info(k + 1 + ". " + storageServers[k].getInetSocketAddress() .getAddress().getHostAddress() + ":" + storageServers[k].getInetSocketAddress() .getPort()); } } long startTime = System.currentTimeMillis(); // upload files String[] results = storageClient.upload_file(file_buff, fileExtName, meta_list); LOGGER.info("已上传至服务器,用时 : ", (System.currentTimeMillis() - startTime) + " ms"); if (results == null) { LOGGER.error("上传文件 失败,error code: " + storageClient.getErrorCode()); } // // get groupName and remoteFileName group_name = results[0]; String remote_filename = results[1]; LOGGER.info("group_name: " + group_name + ", remote_filename: " + remote_filename); LOGGER.info(storageClient.get_file_info(group_name, remote_filename).toString()); entity.setPosition(group_name + "/" + remote_filename); // get storage sever of this file ServerInfo[] servers = trackerClient.getFetchStorages( trackerServer, group_name, remote_filename); if (servers == null) { LOGGER.error("获取tracker失败, error code: " + trackerClient.getErrorCode()); } else { LOGGER.info("storage 数目: " + servers.length); for (int k = 0; k < servers.length; k++) { System.err.println(k + 1 + ". " + servers[k].getIpAddr() + ":" + servers[k].getPort()); } } attachmentDao.add(entity); LOGGER.info("附件信息成功插入数据库"); list.add(entity); } return list; } } catch (FileNotFoundException fnfex) { LOGGER.error("文件未找到:" + fnfex.getMessage()); return list; } catch (IOException ioe) { LOGGER.error("IO错误:" + ioe.getMessage()); return list; } catch (MyException mye) { LOGGER.error("FastDFS错误 :" + mye.getMessage()); return list; } catch (Exception e) { LOGGER.error("其他错误 :" + e.getMessage()); return list; } finally{ try { fis.close(); in.close(); propertiesIn.close(); out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
/**
* 文件下载
* @param id
* @param fileName
*/
@Override
public void download(String id, String fileName) {
InputStream in= null;
FileOutputStream out = null;
try {
Resource[] resources = RESOLVER
.getResources("classpath*:com/**/**/META-INF/upload/*.conf");
if (resources == null || resources.length < 1) {
LOGGER.error("下载文件失败,失败原因 : ", "client.conf不存在!");
} else {
in = resources[0].getInputStream();
File file = new File("client.conf");
out = new FileOutputStream(file);
byte[] buf = new byte[1024];
while (true) {
int r = in.read(buf);
if (r == -1) {
break;
}
out.write(buf, 0, r);
}
LOGGER.info("fileName:" + fileName);
ClientGlobal.init(file.getAbsolutePath());
LOGGER.info("下载中:" + "client.conf初始化成功!");
TrackerClient trackerClient = new TrackerClient();
TrackerServer trackerServer = trackerClient.getConnection();
if (trackerServer != null) {
LOGGER.info("下载中:" + "成功获得均衡器");
} else {
LOGGER.error("下载失败:" + "均衡器获取失败");
}
StorageServer storageServer = null;
StorageClient storageClient = new StorageClient(trackerServer,
storageServer);
// groupName and remoteFileName should exist
String group_name = "group1";
AttachmentEntity aEntity = attachmentDao.queryById(id);
String remote_filename = aEntity.getPosition();
String[] paths = remote_filename.split("/");
FileInfo fi = storageClient.get_file_info(paths[0],
remote_filename.replace(paths[0] + "/", ""));
LOGGER.error("下载中..." + "得到文件信息");
HttpServletResponse response = ResponseContext
.geRequestContext().getResponse();
response.reset();
response.setContentType("application/download;charset=UTF-8");
// response.setHeader("Content-Disposition","attachment;" +
// "filename=" + new String(fileName.getBytes("ISO_8859_1"),
// "UTF-8"));
// 如果使用上面编码格式,否则附件名称若为中文,则乱码,下载下来的附件名称,显示不全.或者乱乱码 .应该使用下面的编码格式.
LOGGER.info("fileName(gbk)=[" + new String(fileNameString(fileName).getBytes("gbk"), "ISO8859-1") +"]");
response.setHeader("Content-Disposition", "attachment;"
+ "filename="
+ new String(fileNameString(fileName).getBytes("gbk"), "ISO8859-1"));//无法下载,原因可能是在这里文件名中有逗号,在解析header的时候,逗号导致。这里请求文件名,应该与写入的保持一致
// String basepath =
// System.getProperties().getProperty("user.home");
// String path = basepath + File.separator + new
// String(fileName.getBytes("GBK"), "ISO_8859_1");
ServletOutputStream oOutput = response.getOutputStream();
byte[] inputStream = storageClient.download_file(paths[0],
remote_filename.replace(paths[0] + "/", ""));
try {
oOutput.write(inputStream);
oOutput.flush();
} catch (IOException ioe) {
LOGGER.error("下载失败:" + "写入本地文件失败!");
} finally {
IOUtils.close(oOutput);
}
String sourceIpAddr = fi.getSourceIpAddr();
long size = fi.getFileSize();
LOGGER.info("ip:" + sourceIpAddr + ",size:" + size);
}
} catch (FileNotFoundException fnfex) {
LOGGER.error("下载失败,文件未找到:" + fnfex.getMessage());
} catch (IOException ioex) {
LOGGER.error("下载失败,IO 错误 :" + ioex.getMessage());
} catch (MyException e) {
LOGGER.error("下载失败,其他错误 :" + e.getMessage());
}
finally {
try {
if(in!=null)
in.close();
if(out!=null)
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public String fileNameString(String fileName){ if(fileName.contains(",")){ fileName = fileName.replace(","," "); } return fileName; }
这三个问题,本质都是特殊字符导致的错误。这里提供后台的处理方式,供大家参考