1、pom.xml
<!--svn上傳文件-->
<dependency>
<groupId>org.tmatesoft.svnkit</groupId>
<artifactId>svnkit</artifactId>
<version>1.10.1</version>
</dependency>
2、SVN連接以及校驗 //1、SVN倉庫的地址(配置文件,有designFileUrl、packageFileUrl、frontFileUrl) String urlType = svnUploadEntity.getUrlType(); String svnUrl = CommonUtil.getSysPara(urlType, "frontFileUrl") ; //如果是程序源碼包上傳,需要增加一層目錄,表示服務名 if(urlType.equals("packageFileUrl")){ svnUrl= svnUrl+ "/"+ svnUploadEntity.getServerName(); } log.info("上傳SVN文件路徑:"+svnUrl );
//2.登錄SVN的用戶名(需要獲取)
String username = svnUploadEntity.getUsername();
//3.登錄SVN的密碼
String passwd = getSvnPassword(username);
//4、本地倉庫的路徑(需要獲取)
String workspace = svnUploadEntity.getWorkspace();
//5、要上傳的文件信息(需要獲取)
String upfile = svnUploadEntity.getUpfile();
//6、提交的日誌信息(需要獲取)
String commitMessage ="提交發包文件:"+ svnUploadEntity.getCommitMessage();
//是否覆蓋SVN上的文件(默認爲true)
Boolean isOverwrite = true;
if(StringUtils.isEs(passwd)){
log.info("沒有登錄權限svn密碼爲空");
map.put("code", "0");
map.put("message", "沒有svn登錄權限svn密碼爲空!");
return map;
}
//第二步:創建SVNUtil對象
SVNUitl svnDeal = new SVNUitl(svnUrl,username, passwd);
//是否有登錄權限
boolean flag = svnDeal.login();
if(flag){
//7、判斷SVN上是否存在該目錄不存在創建目錄
SVNURL svnurl = SVNURL.parseURIDecoded(svnUrl);
if(!svnDeal.isURLExist(svnurl)){
SVNURL [] svnUrls = {svnurl};
svnDeal.createDir(svnUrls);
}
//8、獲取所有要上傳的文件信息
String [] fileArray = upfile.split(",");
//9、遍歷數組判斷要上傳的文件
for(int i=0;i<fileArray.length;i++){
//每個文件信息
String filePath = fileArray[i];
String filename = "";
//獲取上傳的文件名稱
if (filePath.indexOf("/") != -1) {
filename = filePath.substring(filePath.lastIndexOf("/"));
} else {
filename = filePath;
}
//10、進行文件上傳
svnDeal.upload(svnUrl, workspace, filePath, filename,isOverwrite,commitMessage);
}
map.put("code", "1");
map.put("message", "文件上傳svn成功!");
}else{
log.info("沒有登錄權限");
map.put("code", "0");
map.put("message", "沒有svn登錄權限!");
}
2、工具類 public class SVNUitl { // svn版本庫根目錄 private String svnRoot; // svn賬號 private String userName; // svn密碼 private String password; // 版本庫服務 private SVNRepository repository; // 身份認證 private ISVNAuthenticationManager authManager; // 客戶端管理 private SVNClientManager clientManager;
public SVNUitl() {
}
public SVNUitl(String svnRoot, String userName, String password) {
this.svnRoot = svnRoot;
this.userName = userName;
this.password = password;
}
/**
* 不同的協議初始化版本庫
*/
private static void setupLibrary() {
// 對於使用http://和https://
DAVRepositoryFactory.setup();
//對於使用svn:/ /和svn+xxx:/ /
SVNRepositoryFactoryImpl.setup();
//對於使用file://
FSRepositoryFactory.setup();
}
/**
* 登錄驗證
*
* [@return](https://my.oschina.net/u/556800)
*/
public boolean login() {
setupLibrary();
try {
//創建庫連接
repository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(this.svnRoot));
//身份驗證
authManager = SVNWCUtil
.createDefaultAuthenticationManager(this.userName, this.password.toCharArray());
//創建身份驗證管理器
repository.setAuthenticationManager(authManager);
//創建客戶端管理對象
DefaultSVNOptions options = SVNWCUtil.createDefaultOptions(true);
clientManager = SVNClientManager.newInstance(options, authManager);
return true;
} catch (SVNException svne) {
log.info("身份驗證失敗:", svne);
return false;
}
}
/**
* 關閉版本庫
*/
public void closeRepo() {
if (null != this.repository) {
this.repository.closeSession();
log.info("關閉版本庫");
}
}
/**
* 將目錄或者文件添加到版本庫下
*
* [@param](https://my.oschina.net/u/2303379) wcPath
* [@throws](https://my.oschina.net/throws) SVNException
*/
private void addEntry(File wcPath) throws SVNException {
try {
clientManager.getWCClient().doAdd(new File[]{wcPath}, true,
false, false, SVNDepth.INFINITY, false, false, true);
} catch (SVNException e) {
log.info("SVN添加文件到版本控制失敗:", e);
}
}
/**
* 提交到SVN庫中
*
* [@param](https://my.oschina.net/u/2303379) wcPath
* @param keepLocks
* @param commitMessage
* @return
* @throws SVNException
*/
private SVNCommitInfo commit(File wcPath, boolean keepLocks, String commitMessage) throws SVNException {
try {
return clientManager.getCommitClient().doCommit(
new File[]{wcPath}, keepLocks, commitMessage, null,
null, false, false, SVNDepth.INFINITY);
} catch (SVNException e) {
log.info("SVN提交失敗:", e);
}
return null;
}
/**
* 判斷當前的路徑是否是一個工作空間
*
* @param path
* @return
* @throws SVNException
*/
private boolean isWorkingCopy(File path) throws SVNException {
if (!path.exists()) {
return false;
}
try {
if (null == SVNWCUtil.getWorkingCopyRoot(path, false)) {
return false;
}
} catch (SVNException e) {
log.info("當前的path是否是一個工作空間:", e);
}
return true;
}
/**
* 確定URL在SVN上是否存在
*
* @param url
* @return
* @throws SVNException
*/
public boolean isURLExist(SVNURL url) throws SVNException {
try {
SVNRepository svnRepository = SVNRepositoryFactory.create(url);
svnRepository.setAuthenticationManager(authManager);
SVNNodeKind nodeKind = svnRepository.checkPath("", -1);
return nodeKind == SVNNodeKind.NONE ? false : true;
} catch (SVNException e) {
log.info("確定URL在SVN上是否存在:", e);
}
return false;
}
/**
* 在當前目錄下創建一個新的目錄
*/
public boolean createDir(SVNURL[] url) throws SVNException {
try {
clientManager.getCommitClient().doMkDir(url, "創建新的目錄");
} catch (SVNException e) {
log.info("在SVN上創建目錄失敗:", e);
}
return false;
}
/**
* 檢查不在版本庫中的文件添加到版本庫中
*
* @param wc
* @throws SVNException
*/
private void checkVersiondDirectory(File wc) throws SVNException {
if (!SVNWCUtil.isVersionedDirectory(wc)) {
this.addEntry(wc);
}
if (wc.isDirectory()) {
for (File sub : wc.listFiles()) {
if (sub.isDirectory() && sub.getName().equals(".svn")) {
continue;
}
checkVersiondDirectory(sub);
}
}
}
/**
* 刪除單個文件
*
* @param sPath
* @return
*/
private boolean deleteFile(String sPath) {
boolean flag = false;
File file = new File(sPath);
// 路徑爲文件且不爲空則進行刪除
if (file.isFile() && file.exists()) {
file.delete();
flag = true;
}
return flag;
}
/**
* 刪除目錄(文件夾)以及目錄下的文件
*
* @param sPath
* @return
*/
private boolean deleteDirectory(String sPath) {
//如果sPath不以文件分隔符結尾,自動添加文件分隔符
if (!sPath.endsWith(File.separator)) {
sPath = sPath + File.separator;
}
File dirFile = new File(sPath);
//如果dir對應的文件不存在,或者不是一個目錄,則退出
if (!dirFile.exists() || !dirFile.isDirectory()) {
return false;
}
boolean flag = true;
//刪除文件夾下的所有文件(包括子目錄)
File[] files = dirFile.listFiles();
for (int i = 0; i < files.length; i++) {
//刪除子文件
if (files[i].isFile()) {
flag = deleteFile(files[i].getAbsolutePath());
if (!flag) break;
} //刪除子目錄
else {
flag = deleteDirectory(files[i].getAbsolutePath());
if (!flag) break;
}
}
if (!flag) return false;
//刪除當前目錄
if (dirFile.delete()) {
return true;
} else {
return false;
}
}
/**
* 循環刪除.svn目錄
*
* @param spath
*/
private void deletePointSVN(String spath) {
File wc = new File(spath);
for (File sub : wc.listFiles()) {
if (sub.isDirectory() && sub.getName().equals(".svn")) {
this.deleteDirectory(sub.getAbsolutePath());
continue;
}
if (sub.isDirectory()) {
deletePointSVN(sub.getAbsolutePath());
}
}
}
/**
* 上傳文件到對應的SVN庫中
*
* @param svnUrl
* @param workspace
* @param filepath
* @param filename
* @param isOverwrite
* @param commitMessage
* @throws SVNException
*/
public void upload(String svnUrl, String workspace, String filepath, String filename, Boolean isOverwrite, String commitMessage) throws SVNException {
try {
String svnfilePath = svnUrl + "/" + filename;
//開始前刪除以前的.svn文件目錄
deletePointSVN(workspace);
boolean flag = this.isURLExist(SVNURL.parseURIDecoded(svnfilePath));
if (flag) {
if (isOverwrite) {
this.uploadFile(svnUrl, workspace, filepath, filename, commitMessage);
}
} else {
this.uploadFile(svnUrl, workspace, filepath, filename, commitMessage);
}
//結束後刪除當前的.svn文件目錄
deletePointSVN(workspace);
log.info("上傳成功!");
} catch (Exception e) {
log.info("程序異常", e);
}
}
/**
* 更新SVN工作區
*
* @param wcPath
* @param updateToRevision
* @param depth
* @return
* @throws SVNException
*/
private long update(File wcPath, SVNRevision updateToRevision, SVNDepth depth) throws SVNException {
SVNUpdateClient updateClient = clientManager.getUpdateClient();
updateClient.setIgnoreExternals(false);
try {
return updateClient.doUpdate(wcPath, updateToRevision, depth, false, false);
} catch (SVNException e) {
log.info("更新SVN工作區失敗:", e);
}
return -1;
}
/**
* SVN倉庫文件檢出
*
* @param url
* @param revision
* @param destPath
* @param depth
* @return
* @throws SVNException
*/
private long checkout(SVNURL url, SVNRevision revision, File destPath, SVNDepth depth) throws SVNException {
SVNUpdateClient updateClient = clientManager.getUpdateClient();
updateClient.setIgnoreExternals(false);
try {
return updateClient.doCheckout(url, destPath, revision, revision, depth, false);
} catch (SVNException e) {
log.info("檢出SVN倉庫失敗:", e);
}
return -1;
}
private long checkouts(SVNURL url, SVNRevision revision, File destPath, SVNDepth depth) throws SVNException {
SVNUpdateClient updateClient = clientManager.getUpdateClient();
updateClient.setIgnoreExternals(false);
try {
// return updateClient.doCheckout(url, destPath, revision, revision,depth, false); return updateClient.doExport(url, destPath, revision, revision, "", true, false); } catch (SVNException e) { log.info("檢出SVN倉庫失敗:", e); } return -1; }
public void checkWorkCopy(String svnUrl, String workspace, String filepath, String filename) throws SVNException {
SVNURL repositoryURL = null;
try {
repositoryURL = SVNURL.parseURIEncoded(svnUrl);
} catch (SVNException e) {
log.info("解析svnUrl失敗", e);
}
String fPath = "";
if (filepath.indexOf("/") != -1) {
fPath = filepath.substring(0, filepath.lastIndexOf("/"));
}
File wc = new File(workspace + "/" + fPath);
File wc_project = new File(workspace + "/" + fPath);
SVNURL projectURL = null;
try {
projectURL = repositoryURL.appendPath(filename, false);
} catch (SVNException e) {
log.info("解析svnUrl文件失敗:", e);
}
if (!this.isWorkingCopy(wc)) {
if (!this.isURLExist(projectURL)) {
this.checkout(repositoryURL, SVNRevision.HEAD, wc, SVNDepth.EMPTY);
} else {
this.checkout(projectURL, SVNRevision.HEAD, wc_project, SVNDepth.INFINITY);
}
} else {
this.update(wc, SVNRevision.HEAD, SVNDepth.INFINITY);
}
}
public void checkWorkCopys(String svnUrl, String workspace, String filepath, String filename) throws SVNException {
SVNURL repositoryURL = null;
try {
repositoryURL = SVNURL.parseURIEncoded(svnUrl);
} catch (SVNException e) {
log.info("解析svnUrl失敗", e);
}
String fPath = "";
if (filepath.indexOf("/") != -1) {
fPath = filepath.substring(0, filepath.lastIndexOf("/"));
}
// workspace="E:\images"; log.info("解析到的workspace地址爲:", workspace); File wc = new File(workspace); File wc_project = new File(workspace); log.info("文件地址是:", workspace); if (StringUtils.isnEs(fPath)) { wc = new File(workspace + "/" + fPath); wc_project = new File(workspace + "/" + fPath); } if (!wc.exists()) { //建目錄 wc.mkdirs(); } log.info("解析到的地址爲:", wc.getPath()); SVNURL projectURL = null; try { projectURL = repositoryURL.appendPath(filename, false); } catch (SVNException e) { log.info("解析svnUrl文件失敗:", e); }
if (!this.isWorkingCopy(wc)) {
if (!this.isURLExist(projectURL)) {
this.checkouts(repositoryURL, SVNRevision.HEAD, wc, SVNDepth.EMPTY);
} else {
this.checkouts(projectURL, SVNRevision.HEAD, wc_project, SVNDepth.INFINITY);
}
} else {
this.update(wc, SVNRevision.HEAD, SVNDepth.INFINITY);
}
}
/**
* 上傳文件
*
* @param svnUrl
* @param workspace
* @param filepath
* @param filename
* @param commitMessage
* @throws SVNException
*/
private void uploadFile(String svnUrl, String workspace, String filepath, String filename, String commitMessage) throws SVNException {
this.checkWorkCopy(svnUrl, workspace, filepath, filename);
File file = new File(workspace + "/" + filepath);
this.checkVersiondDirectory(file);
this.commit(file, false, commitMessage);
}
}