利用aether api实现从指定maven仓库下载jar包

最近公司做项目遇到一个需求,通过用户提供的groupId和artifactId以及version到指定maven库中下载jar包。平时的maven项目中,依赖的jar包都是通过pom文件设置,然后maven通过<dependency></dependency>去下载jar包,现在要做的就是maven下载的这一功能。

通过上网去查阅,知道了可以在命令行利用mvn dependency:copy -Dartifact=groupId:artifactId:version -DoutputDirectory=? -Dmdep.stripVerison=true的命令下载到本地仓库。但是有一个问题,利用mvn可能涉及到maven环境的问题,这样程序移植的时候会有很多问题。最好是由一个api借口,以jar包的形式引入,完全脱离本地的maven环境。

这个问题在网上搜索了好久,终于利用google找到了答案。它就是Aether。官方网址是http://wiki.eclipse.org/Aether     上面有相关的说明和API 文档。下面就来说一说具体的实现流程。

依据官方文档,首先应引入jar包,创建一个maven项目,在pom文件中添加如下依赖:

 

<properties>
    <aetherVersion>1.0.0.v20140518</aetherVersion>
    <mavenVersion>3.1.0</mavenVersion>
    <wagonVersion>1.0</wagonVersion>
  </properties>
  <dependencies>
  <dependency>
      <groupId>org.eclipse.aether</groupId>
      <artifactId>aether-api</artifactId>
      <version>${aetherVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.aether</groupId>
      <artifactId>aether-util</artifactId>
      <version>${aetherVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.aether</groupId>
      <artifactId>aether-impl</artifactId>
      <version>${aetherVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.aether</groupId>
      <artifactId>aether-connector-basic</artifactId>
      <version>${aetherVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.aether</groupId>
      <artifactId>aether-transport-file</artifactId>
      <version>${aetherVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.aether</groupId>
      <artifactId>aether-transport-http</artifactId>
      <version>${aetherVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.aether</groupId>
      <artifactId>aether-transport-wagon</artifactId>
      <version>${aetherVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-aether-provider</artifactId>
      <version>${mavenVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.maven.wagon</groupId>
      <artifactId>wagon-ssh</artifactId>
      <version>${wagonVersion}</version>
    </dependency>
  
  </dependencies>

 

 

然后建立RepositorySystem,这个是用来操作maven仓库的主要接口:

 

/**
	 * 建立RepositorySystem
	 * @return RepositorySystem
	 */
	private static RepositorySystem newRepositorySystem()
    {
        DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
        locator.addService( RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class );
        locator.addService( TransporterFactory.class, FileTransporterFactory.class );
        locator.addService( TransporterFactory.class, HttpTransporterFactory.class );
 
        return locator.getService( RepositorySystem.class );
    }

然后建立RepositorySystemSession对象:

 

 

/**
	 *  create a repository system session
	 * @param system RepositorySystem
	 * @return RepositorySystemSession
	 */
	private static RepositorySystemSession newSession( RepositorySystem system,String target )
    {
        DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
 
        LocalRepository localRepo = new LocalRepository( /*"target/local-repo" */target);
        session.setLocalRepositoryManager( system.newLocalRepositoryManager( session, localRepo ) );
 
        return session;
    }


接下来实现的是从指定maven仓库下载指定的jar包:

/**
	 *  从指定maven地址下载指定jar包
	 * @param artifact maven-jar包的三围定位(groupId:artifactId:version)
	 * @param repositoryURL maven库的URL地址
	 * @param username 若需要权限,则需使用此参数添加用户名,否则设为null
	 * @param password 同上
	 * @throws ArtifactResolutionException
	 */
	public static void DownLoad(Params params) throws ArtifactResolutionException 
	{
		String groupId=params.getGroupId();
		String artifactId=params.getArtifactId();
		String version=params.getVersion();
		String repositoryUrl=params.getRepository();
		String target=params.getTarget();
		String username=params.getUsername();
		String password=params.getPassword();
		
		
		RepositorySystem repoSystem = newRepositorySystem();
        RepositorySystemSession session = newSession( repoSystem ,target);
        RemoteRepository central=null;
        if(username==null&&password==null)
        {
        	central = new RemoteRepository.Builder( "central", "default", repositoryUrl ).build();
        }else{
        	 Authentication authentication=new AuthenticationBuilder().addUsername(username).addPassword(password).build();
        	 central = new RemoteRepository.Builder( "central", "default", repositoryUrl ).setAuthentication(authentication).build();
        }
        /**
         * 下载一个jar包
         */
        Artifact artifact=new DefaultArtifact(groupId+":"+artifactId+":"+version);
        ArtifactRequest artifactRequest=new ArtifactRequest();
        artifactRequest.addRepository(central);
        artifactRequest.setArtifact(artifact);
        repoSystem.resolveArtifact(session, artifactRequest);
        System.out.println("success");
        

        /**
         * 下载该jar包及其所有依赖jar包
         */
        /*
         *
       	Dependency dependency =
            new Dependency( new DefaultArtifact( artifact ),null);
        CollectRequest collectRequest = new CollectRequest();
        collectRequest.setRoot( dependency );
        collectRequest.addRepository( central );
        DependencyNode node = repoSystem.collectDependencies( session, collectRequest ).getRoot();
 
        DependencyRequest dependencyRequest = new DependencyRequest();
        dependencyRequest.setRoot( node );
 
        repoSystem.resolveDependencies( session, dependencyRequest  );
 
        PreorderNodeListGenerator nlg = new PreorderNodeListGenerator();
        node.accept( nlg );
        System.out.println( nlg.getClassPath() );*/
	}
	
	

}


其中Params对象是相关的一些参数,包括groupId,artifactId,version,远程maven仓库的URL地址repository,下载后存放的路径target,访问maven仓库的username和password:

 

 

public class Params {
	
	/**
	 * jar包在maven仓库中的groupId
	 */
	private String groupId;
	/**
	 * jar包在maven仓库中的artifactId
	 */
	private String artifactId;
	/**
	 * jar包在maven仓库中的version
	 */
	private String version;
	/**
	 * 远程maven仓库的URL地址,默认使用bw30的远程maven-public库
	 */
	private String repository="http://ae.mvn.bw30.com/repository/maven-public/";
	/**
	 * 下载的jar包存放的目标地址,默认为./target/repo
	 */
	private String target="temp";
	/**
	 * 登录远程maven仓库的用户名,若远程仓库不需要权限,设为null,默认为null
	 */
	private String username=null;
	/**
	 * 登录远程maven仓库的密码,若远程仓库不需要权限,设为null,默认为null
	 */
	private String password=null;
	
	
	public Params() {
		super();
	}



	public Params(String groupId, String artifactId) {
		super();
		this.groupId = groupId;
		this.artifactId = artifactId;
	}
	
	
	
	public Params(String groupId, String artifactId, String username,
			String password) {
		super();
		this.groupId = groupId;
		this.artifactId = artifactId;
		this.username = username;
		this.password = password;
	}



	public Params(String groupId, String artifactId, String version,
			String repository, /*String target,*/ String username, String password) {
		super();
		this.groupId = groupId;
		this.artifactId = artifactId;
		this.version = version;
		this.repository = repository;
		/*this.target = target;*/
		this.username = username;
		this.password = password;
	}



	public Params(String groupId, String artifactId, String version,
			String username, String password) {
		super();
		this.groupId = groupId;
		this.artifactId = artifactId;
		this.version = version;
		this.username = username;
		this.password = password;
	}



	public String getGroupId() {
		return groupId;
	}
	public void setGroupId(String groupId) {
		this.groupId = groupId;
	}
	public String getArtifactId() {
		return artifactId;
	}
	public void setArtifactId(String artifactId) {
		this.artifactId = artifactId;
	}
	public String getVersion() {
		return version;
	}
	public void setVersion(String version) {
		this.version = version;
	}
	public String getRepository() {
		return repository;
	}
	public void setRepository(String repository) {
		this.repository = repository;
	}
	public String getTarget() {
		return target;
	}
	/*public void setTarget(String target) {
		this.target = target;
	}*/
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
	
}


上面是根据三围来下载jar包,但是jar包的版本会有很多,所以有如下需求:给定groupId和artifactId,列出所有的version,用户选择某一version后再利用上面的方法下载,那么怎么列出所有的version呢?Aether API给出了一些借口,稍加组合即可:

 

 

	/**
	 * 根据groupId和artifactId获取所有版本列表
	 * @param params Params对象,包括基本信息
	 * @return version列表
	 * @throws VersionRangeResolutionException
	 */
	public static List<Version> getAllVersions(Params params) throws VersionRangeResolutionException
	{
		String groupId=params.getGroupId();
		String artifactId=params.getArtifactId();
		String repositoryUrl=params.getRepository();
		String target=params.getTarget();
		String username=params.getUsername();
		String password=params.getPassword();
		
		RepositorySystem repoSystem = newRepositorySystem();
        RepositorySystemSession session = newSession( repoSystem ,target);
        RemoteRepository central=null;
        if(username==null&&password==null)
        {
        	central = new RemoteRepository.Builder( "central", "default", repositoryUrl ).build();
        }else{
        	 Authentication authentication=new AuthenticationBuilder().addUsername(username).addPassword(password).build();
        	 central = new RemoteRepository.Builder( "central", "default", repositoryUrl ).setAuthentication(authentication).build();
        }
        Artifact artifact = new DefaultArtifact( groupId+":"+artifactId+":[0,)" );
        VersionRangeRequest rangeRequest = new VersionRangeRequest();
        rangeRequest.setArtifact( artifact );
        rangeRequest.addRepository( central );
        VersionRangeResult rangeResult = repoSystem.resolveVersionRange( session, rangeRequest );
        List<Version> versions = rangeResult.getVersions();
        System.out.println( "Available versions " + versions );
        return versions;
	}


在这里面最令人恶心的是由于之前是三围坐标,创建Artifact对象的时候传进去groupId:artifactId:verison的字符串就行了,现在没有verison了,找了好久的API都是必带verison的,甚至试了一下通配符也不成。后来找到了官方的example的源码,才发现原来是用[0,)来表示所有的verison,就是数学中的0到正无穷呀,想改成啥区间的version都可以了。

 

后面的需求就是解压下载下来的jar包,然后将其中的js文件夹再压缩供用户下载引用,压缩、解压的方法网上好多,就不再说明了。

另外,Aether官方提供的示例代码还实现很多其他的功能,有需要的可以下载来参考。

示例代码官方git地址:git://git.eclipse.org/gitroot/aether/aether-demo.git   或

ssh://git.eclipse.org/gitroot/aether/aether-demo.git  或

http://git.eclipse.org/gitroot/aether/aether-demo.git

我的源代码地址:git@git.oschina.net:xiaosiyuan/maven-download-jar.git 或

https://git.oschina.net/xiaosiyuan/maven-download-jar.git

posted @ 2016-09-20 09:46  浅夏丶未央  阅读(2802)  评论(0编辑  收藏  举报