JAVA對特殊字元的處理
阿新 • • 發佈:2019-01-06
最近在維護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;
}
這三個問題,本質都是特殊字元導致的錯誤。這裡提供後臺的處理方式,供大家參考