1. 程式人生 > >JAVA對特殊字元的處理

JAVA對特殊字元的處理

最近在維護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;
    }

這三個問題,本質都是特殊字元導致的錯誤。這裡提供後臺的處理方式,供大家參考