Ant 快速上手

1  Ant初识  

[html]  view plain copy print ?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <project name="AntDemoProject" default="dist" basedir=".">  
  3.     <!-- 【定义变量】set global properties for this build -->  
  4.     <property name="src" location="src" />  
  5.     <property name="build" location="build" />  
  6.     <property name="dist" location="dist" />  
  7.   
  8.     <!-- 【加载属性文件】 -->  
  9.     <property file="build.properties" />  
  10.     <echo>${container.deploy.dir}</echo>  
  11.   
  12.     <target name="init">  
  13.         <!-- Create the time stamp -->  
  14.         <tstamp />  
  15.         <!-- Create the build directory structure used by compile -->  
  16.         <mkdir dir="${build}" />  
  17.     </target>  
  18.   
  19.     <!-- 【编译】Compile the java code from ${src} into ${build} -->  
  20.     <target name="compile" depends="init">  
  21.         <javac srcdir="${src}" destdir="${build}" />  
  22.     </target>  
  23.   
  24.     <!-- 【打包Jar】 -->  
  25.     <target name="dist" depends="compile">  
  26.         <!-- Create the distribution directory -->  
  27.         <mkdir dir="${dist}/lib" />  
  28.         <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->  
  29.         <jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}" />  
  30.     </target>  
  31.   
  32.     <!-- 【清空】Delete the ${build} and ${dist} directory trees -->  
  33.     <target name="clean">  
  34.         <delete dir="${build}" />  
  35.         <delete dir="${dist}" />  
  36.     </target>  
  37.   
  38.     <!-- 【运行】 -->  
  39.     <target name="run" depends="compile">  
  40.         <java classpath="${build}" classname="HelloJFrame" fork="true">  
  41.         </java>  
  42.     </target>  
  43. </project>  

[html]  view plain copy print ?
  1. <!--  
  2. =================================================================================================================  
  3. 1、安装和配置Ant  
  4.     ①Download Ant binary distribution from:http://ant.apache.org/bindownload.cgi  
  5.       从Apache下载它的zip包,解压到任何本地磁盘上  
  6.     ②Set ANT_HOME to where you installed Ant  
  7.       设置ANT_HOME环境变量,也就是解压后存放的目录  
  8.     ③Include $ANT_HOME/bin in PATH  
  9.       在环境变量中更新Path值,加上%ANT_HOME%/bin  
  10.     ④Make sure JAVA_HOME is set to point to JDK  
  11.       检查JDK的目录,确定JAVA_HOME已加到环境变量中  
  12. =================================================================================================================  
  13. 2、build.xml  
  14.     使用Ant的通常做法是在项目中建立一个XML文件,名字通常取build.xml。当然也可以取任何喜欢的名字  
  15.     每一个build.xml只能有一个<project>标签,每个<project>标签中可以包含若干<tartget>标签  
  16.     每一个target可以独立执行,或依赖于其他target执行完毕才能执行  
  17.     ①<project>标签含以下属性  
  18.         name=====项目名称  
  19.         default==当没有指定target时使用的缺省target  
  20.         basedir==用于计算所有其他路径的基路径  
  21.     ②<target>标签含以下属性  
  22.         name=========target的名字  
  23.         depends======用逗号分隔的target的名字列表,也就是依赖表  
  24.         if===========执行target所需要设定的属性名  
  25.         unless=======执行target需要清除设定的属性名  
  26.         description==关于target功能的简短描述  
  27.     ③举例:  
  28.         <target name="A"/>  
  29.         <target name="B" depends="A"/>  
  30.         <target name="C" depends="B"/>  
  31.         <target name="D" depends="C,B,A"/>  
  32.         其中target A可以独立执行,但是B、C、D则依赖于其他target才可以执行  
  33.         也就是说,执行target D时,Ant就会按照A__B__C这样的顺序先执行其他target  
  34.         从依赖属性来看,你可能认为先执行C,然后B,最后A。错了!C依赖于B,B依赖于A,所以先执行A,然后B,然后C,最后D才会被执行  
  35.         并且一个target只能被执行一次,即时有多个target依赖于它  
  36.         而且还要确保初始化target总是出现在其他target依赖表中的第一个target。初始化target的名字通常是init。  
  37. =================================================================================================================  
  38. 3、定义变量  
  39.     ①如果想使用定义变量,可以在<project>标签下定义<property>标签,如<property name="dist" location="dist" />  
  40.       这样在引用的时候就可以使用${dist}这样的变量了,省得自己去修改每一处需要用到变量的地方  
  41.     ②另外,还可以使用一个外置的属性文件:build.properties,以name=value方式定义变量  
  42.       然后在build.xml中添加<property file="build.properties" />引用这个文件  
  43. =================================================================================================================  
  44. 4、创建目录  
  45.     <target name="init">  
  46.         <mkdir dir="${dist.dir}" />  
  47.         <mkdir dir="${dist.classes.dir}" />  
  48.     </target>  
  49.     ①这里的dist.dir等用${}括起来的,是我们定义的变量  
  50.     ②创建一个目录,如果他的父目录不存在,也会被同时创建  
  51.       <mkdir dir="build/classes"/>  
  52.       说明:如果build目录不存在,也会被同时创建  
  53. =================================================================================================================  
  54. -->  

[html]  view plain copy print ?
  1. <!--  
  2. =================================================================================================================  
  3. 5、编译Java文件  
  4.     <target name="compile">  
  5.         <javac srcdir="${src.dir}" destdir="${dist.classes.dir}" debug ="true" encoding="GBK">  
  6.             <classpath refid="classpath" />  
  7.         </javac>  
  8.         <jar destfile="${dist.classes.dir}/lib/app.jar" basedir"${dist. classes.dir}"/>  
  9.     </target>  
  10.     这里的<javac>标签中有srcdir、destdir、debug、encoding等属性,还有一个classpath的子标签  
  11.     srcdir==========即目标source,需要编译的源文件  
  12.     destdir=========就是目的地,编译出来的class的存放地  
  13.     debug===========指明source是不是需要把debug信息编译进去。如果不加这个参数,等于在命令行后面加上-g:none参数  
  14.     encoding========指明以何种编码方式编码source文件。对于有中文文字的代码来说这项比较重要  
  15.     classpath子标签==指明需要应用的jar包,或其他class文件的所在地。这也是非常重要的一个选项  
  16.     classpath子标签的使用方式有以下两种:  
  17.         ①作为classpath引用预先定义的jar包位置,refid指明了一个引用变量  
  18.             <property name="lib.dir" value="${basedir}/lib" />  
  19.             <path id="classpath">  
  20.                 <fileset dir="${lib.dir}">  
  21.                     <include name="*.jar"/>  
  22.                 </fileset>  
  23.             </path>  
  24.             <classpath refid="classpath" />  
  25.         ②简单的使用是这样的:<javac srcdir="${src}" destdir="${build}" classpath="xyz.jar" debug="on" />  
  26.         ③<javac srcdir="${src}:${src2}"  
  27.                 destdir="${build}"  
  28.                 includes="mypackage/p1/**,mypackage/p2/**"  
  29.                 excludes="mypackage/p1/testpackage/**"  
  30.                 classpath="xyz.jar"  
  31.                 debug="on"/>  
  32.             表示:编译${src}和${src2}目录及其子目录下的所有Java文件  
  33.                 但是package/p1/**,mypackage/p2/**将被编译,而mypackage/p1/testpackage/**将不会被编译  
  34.                 Class文件将放在${build}指定的目录下  
  35.                 classpath表示需要用到的类文件或者目录  
  36.                 debug设置为on表示输出debug信息  
  37. =================================================================================================================  
  38. 6、打Jar包  
  39.     <jar destfile="${dist}/lib/app.jar" basedir="${dist.classes.dir}"/>  
  40.     这个就是把编译好的文件打成Jar包的Ant脚本,和上面的javac一样,可以放在任意位置  
  41.     destfile==该属性用来指明所要打成的包  
  42.     basedir===该属性用来指明目标class文件  
  43.     ①<jar destfile="${dist}/lib/app.jar">  
  44.           <fileset dir="${build}/classes" excludes="**/Test.class" />  
  45.           <fileset dir="${src}/resources"/>  
  46.       </jar>  
  47.       上面这段脚本很容易理解,就是除了Test.class以外,把一个source的resource目录,连同编译后的class脚本一起打进app.jar包内  
  48.     ②<jar destfile="${dist}/lib/app.jar"  
  49.             basedir="${build}/classes"  
  50.             includes="mypackage/test/**"  
  51.             excludes="**/Test.class"  
  52.             manifest=”my.mf”/>  
  53.             manifest==这个属性用来指定自己的META-INF/MANIFEST.MF文件,而不是由系统生成  
  54.     ③创建ZIP文件<zip destfile="output.zip" basedir="output"/>  
  55.     ④使用GZip压缩文件<gzip src="output.tar" mce_src="output.tar" zipfile="output.tar.gz"/>  
  56.     ⑤解压缩和提取文件<unzip src="output.tar.gz" mce_src="output.tar.gz" dest="extractDir"/>  
  57.     ⑥打Ear包<ear destfile="build/myapp.ear" appxml="src/metadata/application.xml">  
  58.                 <fileset dir="build" includes="*.jar,*.war"/>  
  59.             </ear>  
  60. =================================================================================================================  
  61. -->  

[html]  view plain copy print ?
  1. <!--  
  2. =================================================================================================================  
  3. 7、复制文件  
  4.     <copy todir="${dist.webapps.dir}/WEB-INF/lib" overwrite="true" flatten="true">  
  5.         <fileset dir="${lib.dir}">  
  6.             <include name="*.jar" />  
  7.             <exclude name="j2ee.jar" />  
  8.         </fileset>  
  9.     </copy>  
  10.     todir======指定需要拷贝的地点  
  11.     overwrite==是否需要覆盖  
  12.     【flatten====是否忽略目的目录结构,不管是什么目录,直接拷贝文件到目的地,丢弃其所在结构】  
  13. =================================================================================================================  
  14. 8、其他拷贝  
  15.     ①单个文件的拷贝<copy file="myfile.txt" tofile="mycopy.txt"/>或者  
  16.                  <copyfile src="test.java" mce_src="test.java" dest="subdir/test.java"/>  
  17.     ②文件到目录拷贝<copy file="myfile.txt" todir="../some/other/dir"/>  
  18.     ③目录到目录拷贝<copy todir="../new/dir">  
  19.                     <fileset dir="src_dir"/>  
  20.                  </copy>  
  21.     ④拷贝一批文件到指定目录下  
  22.                 <copy todir="../dest/dir">  
  23.                     <fileset dir="src_dir">  
  24.                         <exclude name="**/*.java"/>  
  25.                     </fileset>  
  26.                 </copy>  
  27.                 或者  
  28.                 <copy todir="../dest/dir">  
  29.                     <fileset dir="src_dir" excludes="**/*.java"/>  
  30.                 </copy>  
  31.     ⑤拷贝一批文件到指定目录下,并将文件名后增加.Bak后缀  
  32.                 <copy todir="../backup/dir">  
  33.                     <fileset dir="src_dir"/>  
  34.                     <mapper type="glob" from="*" to="*.bak"/>  
  35.                 </copy>  
  36.     ⑥拷贝一个文件集合到一个目录,同时建立备份文件  
  37.                 <copy todir="../backup/dir">  
  38.                     <fileset dir="src_dir"/>  
  39.                     <globmapper from="*" to="*.bak"/>  
  40.                 </copy>  
  41.     ⑦拷贝sr_dir目录到backup/dir目录,并把所有文件中的@TITLE@替换成Foo Bar  
  42.                 <copy todir="../backup/dir">  
  43.                     <fileset dir="src_dir"/>  
  44.                     <filterset>  
  45.                         <filter token="TITLE" value="Foo Bar"/>  
  46.                     </filterset>  
  47.                  </copy>  
  48.     ⑧拷贝一个目录下的东西到另一个目录下(includes加入,excludes排除)  
  49.                 <copydir src="${src}/resources" mce_src="${src}/resources"  
  50.                          dest="${dist}"  
  51.                          includes="**/*.java"  
  52.                          excludes="**/Test.java"/>  
  53. =================================================================================================================  
  54. -->  

[html]  view plain copy print ?
  1. <!--  
  2. =================================================================================================================  
  3. 9、删除操作  
  4.     <target name="clean">  
  5.         <delete dir="${dest.dir}"/>  
  6.         <delete file="${dest2.dir}"/>  
  7.     </target>  
  8.     ①删除一个文件<delete file="/lib/ant.jar"/>  
  9.     ②删除指定目录及其子目录<delete dir="lib"/>  
  10.     ③删除指定的一组文件<delete>  
  11.                         <fileset dir="." includes="**/*.bak"/>  
  12.                     </delete>  
  13.     ④删除当前目录下所有的文件和目录,不包括当前目录<delete includeEmptyDirs="true">  
  14.                                                 <fileset dir="build"/>  
  15.                                             </delete>  
  16.     ⑤删除当前目录下所有的文件和目录,不包括当前目录<delete includeEmptyDirs="true">  
  17.                                                 <fileset dir="build" includes="**/*"/>  
  18.                                             </delete>  
  19.     ⑥删除当前目录下所有的svn相关文件(因为svn文件默认是excludes的,所以这里要设置一下)  
  20.                                             <delete defaultexcludes="false">  
  21.                                                 <fileset dir="src" includes="**/.svn"/>  
  22.                                             </delete>  
  23.     ⑦删除文件目录树<deltree dir="dist"/>  
  24. =================================================================================================================  
  25. 10、移动操作  
  26.     ①移动或重命名一个文件<move file="file.orig" tofile="file.moved"/>  
  27.     ②移动或重命名一个文件到另一个文件夹下面<move file="file.orig" todir="dir/to/move/to"/>  
  28.     ③将一个目录移到另外一个目录下<move todir="new/dir/to/move/to">  
  29.                                 <fileset dir="src/dir"/>  
  30.                             </move>  
  31.     ④将一组文件移动到另外的目录下<move todir="some/new/dir">  
  32.                                 <fileset dir="my/src/dir">  
  33.                                     <include name="**/*.jar"/>  
  34.                                     <exclude name="**/ant.jar"/>  
  35.                                 </fileset>  
  36.                             </move>  
  37.     ⑤移动文件过程中增加.Bak后缀<move todir="my/src/dir">  
  38.                                 <fileset dir="my/src/dir">  
  39.                                     <exclude name="**/*.bak"/>  
  40.                                 </fileset>  
  41.                                 <mapper type="glob" from="*" to="*.bak"/>  
  42.                             </move>  
  43. =================================================================================================================  
  44. 11、其它操作  
  45.     ①重命名文件<rename src="foo.jar" mce_src="foo.jar" dest="ant-${version}.jar"/>  
  46.     ②建立临时文件<tempfile property="temp.file" destDir="build" suffix=".xml"/>  
  47.                 即在build目录下,建立文件名为temp.file,后缀为.xml的文件  
  48.     ③输出信息<echo message="xxx"/>或者<echo>yyy</echo>  
  49.     ④输出一段XML<echoxml file="subbuild.xml">  
  50.                     <project default="foo">  
  51.                         <target name="foo">  
  52.                             <echo>foo</echo>  
  53.                         </target>  
  54.                     </project>  
  55.                 </echoxml>  
  56.     ⑤引入一个XML文件<import file="../common-targets.xml"/>  
  57. =================================================================================================================  
  58. -->  

2 Ant 的其他应用

[html]  view plain copy print ?
  1. <!--  
  2. =================================================================================================================  
  3. 1、Touch的使用  
  4.     ①若文件不存在,则创建文件;如果存在,则更改最后访问时间为当前系统时间  
  5.                 <touch file="myfile"/>  
  6.     ②若文件不存在,则创建文件,并更改最后访问时间为10/15/2010 2:02 pm  
  7.                 <touch file="myfile" datetime="10/15/2010 2:02 pm"/>  
  8.     ③更改目录下所有文件的最后访问时间为10/15/2010 2:02 pm  
  9.                 <touch datetime="10/15/2010 2:02 pm">  
  10.                     <fileset dir="src_dir"/>  
  11.                 </touch>  
  12. =================================================================================================================  
  13. 2、Condition的使用  
  14.     有<and><or><not>等tag  
  15.     <condition property="isMacOsButNotMacOsX">  
  16.         <and>  
  17.             <os family="mac"/>  
  18.             <not>  
  19.                 <os family="unix"/>  
  20.             </not>  
  21.         </and>  
  22.     </condition>  
  23. =================================================================================================================  
  24. 3、替换replace  
  25.     <replace file="configure.sh" value="defaultvalue" propertyFile="source/name.properties">  
  26.         <replacefilter token="@token1@"/>  
  27.         <replacefilter token="@token2@" value="value2"/>  
  28.         <replacefilter token="@token3@" property="property.key"/>  
  29.     </replace>  
  30. =================================================================================================================  
  31. 4、调用chmod  
  32.     <chmod perm="go-rwx" type="file">  
  33.         <fileset dir="/web">  
  34.             <include name="**/*.cgi"/>  
  35.             <include name="**/*.old"/>  
  36.         </fileset>  
  37.         <dirset dir="/web">  
  38.             <include name="**/private_*"/>  
  39.         </dirset>  
  40.     </chmod>  
  41. =================================================================================================================  
  42. -->  

[html]  view plain copy print ?
  1. <!--  
  2. =================================================================================================================  
  3. 5、checksum MD5运算  
  4.     ①md5文件,然后把值放入foo.bar.MD5属性<checksum file="foo.bar"/>  
  5.     ②md5文件,然后把值放入foobarMD5属性    <checksum file="foo.bar" property="foobarMD5"/>  
  6.     ③Md5目录下的所有文件,然后建立一个.md5文件,把所有的md5值放入  
  7.                                     <checksum>  
  8.                                         <fileset dir=".">  
  9.                                             <include name="foo*"/>  
  10.                                         </fileset>  
  11.                                     </checksum>  
  12. =================================================================================================================  
  13. 6、Available的使用  
  14.     ①如果类存在,则设置属性Myclass.present为true,如果没有就false  
  15.                 <available classname="org.whatever.Myclass" property="Myclass.present"/>  
  16.     ②若文件存在,则设置属性jaxp.jar.presen为true,否则为false  
  17.                 <property name="jaxp.jar" value="./lib/jaxp11/jaxp.jar"/>  
  18.                 <available file="${jaxp.jar}" property="jaxp.jar.present"/>  
  19.     ③若目录存在,则设置属性local.lib.present为true,否则为false  
  20.                 <available file="/usr/local/lib" type="dir" property="local.lib.present"/>  
  21. =================================================================================================================  
  22. 7、设置property  
  23.     ①设置属性<property name="foo.dist" value="dist"/>  
  24.     ②读取属性文件中的属性配置<property file="foo.properties"/>  
  25.     ③读取网络中的属性文件<property url="http://www.mysite.com/bla/props/foo.properties"/>  
  26.     ④读取文件中的属性配置<property resource="foo.properties"/>  
  27.     ⑤读取环境变量<property environment="env"/>  
  28.     ⑥读取属性文件中的属性,并作为全局引用<property file="/Users/antoine/ant-global.properties"/>  
  29. =================================================================================================================  
  30. 8、显示错误  
  31.     ①方式一<fail>Something wrong here.</fail>  
  32.     ②方式二<fail message="${属性}"/>  
  33.     ③如果这个属性不存在显示错误<fail unless="failCondition" message="unless Condition"/>  
  34.     ④如果这个属性存在显示错误<fail if="failCondition" message="if Condition"/>  
  35.     ⑤如果符合条件显示错误,这里的条件是(没有设置属性)  
  36.                         <fail message="tag condition">  
  37.                             <condition>  
  38.                                 <not>  
  39.                                     <isset property=" failConditon "/>  
  40.                                 </not>  
  41.                             </condition>  
  42.                         </fail>  
  43. =================================================================================================================  
  44. -->  

[html]  view plain copy print ?
  1. <!--  
  2. =================================================================================================================  
  3. 9、时间戳  
  4.     ①在生成环境中使用当前时间和日期,以某种方式标记某个生成任务的输出,以便记录它是何时生成的,这经常是可取的  
  5.       这可能涉及编辑一个文件,以便插入一个字符串来指定日期和时间,或将这个信息合并到JAR或zip文件的文件名中  
  6.       这种需要是通过简单但是非常有用的tstamp任务来解决的  
  7.       这个任务通常在某次生成过程开始时调用,比如在一个init目标中。这个任务不需要属性,许多情况下只需<tstamp/>就足够了  
  8.       tstamp不产生任何输出;相反,它根据当前系统时间和日期设置Ant属性  
  9.     ②下面是tstamp设置的一些属性、对每个属性的说明,以及这些属性可被设置到的值的例子  
  10.       DSTAMP==设置为当前日期,默认格式为yyyymmdd==如20031217  
  11.       TSTAMP==设置为当前时间,默认格式为hhmm======如1603  
  12.       TODAY===设置为当前日期,带完整的月份========如2010年10月15日  
  13.     ③比如我们按该方式创建了一个JAR文件:<jar destfile="package.jar" basedir="classes"/>  
  14.       在调用tstamp任务之后,我们能够根据日期命名该JAR文件:<jar destfile="package-${DSTAMP}.jar" basedir="classes"/>  
  15.       因此,如果这个任务在2010年10月15日调用,则该JAR文件将被命名为package-20101015.jar  
  16.     ④另外,还可以配置tstamp任务来设置不同的属性,应用一个当前时间之前或之后的时间偏移,或以不同的方式格式化该字符串  
  17.       所有这些都是使用一个嵌套的format元素来完成的,如下所示:  
  18.       <tstamp>  
  19.           <format property="OFFSET_TIME" pattern="HH:mm:ss" offset="10" unit="minute"/>  
  20.       </tstamp>  
  21.       上面的清单将OFFSET_TIME属性设置为距离当前时间10分钟之后的小时数、分钟数和秒数  
  22.       用于定义格式字符串的字符与java.text.SimpleDateFormat类所定义的那些格式字符相同  
  23. =================================================================================================================  
  24. 10、通过JDBC执行SQL语句  
  25.     <sql driver="org.gjt.mm.mysql.Driver"  
  26.          url="jdbc:mysql://localhost:3306/mydb"  
  27.          userid="root"  
  28.          password="root"  
  29.          src="data.sql" mce_src="data.sql"/>  
  30. =================================================================================================================  
  31. 11、使用SMTP服务器发送邮件  
  32.     <mail mailhost="smtp.myisp.com" mailport="1025" subject="Test build">  
  33.         <from address="me@myisp.com"/>  
  34.         <to address="all@xyz.com"/>  
  35.         <message>The ${buildname} nightly build has completed</message>  
  36.         <fileset dir="dist">  
  37.             <includes name="**/*.zip"/>  
  38.         </fileset>  
  39.     </mail>  
  40.     mailhost==SMTP服务器地址  
  41.     mailport==服务器端口  
  42.     subject===主题  
  43.     from======发送人地址  
  44.     to========接收人地址  
  45.     message===发送的消息  
  46.     fileset===设置附件   
  47. =================================================================================================================  
  48. -->  

[html]  view plain copy print ?
  1. <!--  
  2. =================================================================================================================  
  3. 12、配合JUnit实现单元测试  
  4.     ①把junit.jar拷入ANT_HOME/lib下,并确认在这个目录下有optional.jar,因为JUnit是Ant的扩展任务,需要引用这个扩展包  
  5.     ②在build.xml中加入JUnit的任务  
  6.         <target name="run" depends="client">  
  7.             <junit printsummary="yes" fork="yes" haltonfailure="yes">  
  8.                 <classpath>  
  9.                     <pathelement location="client.jar" />  
  10.                 </classpath>  
  11.                 <formatter type="plain" />  
  12.                 <test name="com.ascenttech.HelloWorldTest" />  
  13.             </junit>  
  14.         </target>  
  15. =================================================================================================================  
  16. -->  

[html]  view plain copy print ?
  1. <!--  
  2. =================================================================================================================  
  3. 13、使用Ant调用native2ascii转换中文  
  4.        在src下建立一个名为build.xml的文件,代码如下  
  5.        <project>  
  6.             <target name="I18N">  
  7.                 <native2ascii dest="com//jadyer//test"  
  8.                               src="com//jadyer//temp" mce_src="com//jadyer//temp"  
  9.                               includes="*.properties"  
  10.                               encoding="UTF-8">  
  11.                 </native2ascii>  
  12.             </target>  
  13.         </project>  
  14.         src表示所要转换的资源文件的路径  
  15.         dest表示目标路径。路径若为空则代表当前根目录  
  16. =================================================================================================================  
  17. -->  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值