Gradle:创建web应用

       Gradle是一个优秀的自动化构建工具,你只需遵循一定的规则,就能够非常轻松地构建出你想要的项目,不仅可以轻松地让构建好的项目跑在任何机器上,而且还可以轻松地和其他同学一起开发软件,听了之后是不是感觉超级神奇?下面我们来看看到底是怎么回事。

一. 创建一个java项目

1. 手动创建

       让我们先从手写一个HelloWorld项目开始,这个项目只干一件事,在屏幕上打印出”HelloWorld”。注意这里是要构建一个项目,所以不单单只是编写一个java文件,编译成class运行就行了,我们还需要一些目录结构。

这里假设你已经知道了java里package的概念,即package和文件目录一一对应,假设我们的HelloWorld文件如下:

package com.wzt;

public class HelloWorld{

public static void main(String args[]){

           System.out.println("Hello World!");

          }

}

我们的这个HelloWorld类属于com.wzt这个包,那么我们最基本的目录结构应该是图1红色部分的样子

图1

假设你刚好看过一点点工程目录的样子,知道还有一个src的目录,好的,我们就在工程的根目录下建立了这样一个目录结构。现在我们开始编译这个HelloWorld.java,使用javac命令,好的,我们顺利的在wzt目录下生成的对应的class文件,然后运行,没问题。但是总感觉乱乱的,class和java文件放在一起,分开好不好,javac倒是有一个-d的参数能够重新安置class,但是放在哪呢,随便吧,放在src目录下,于是我们在src目录下增加了一个class文件夹,里面放了我们的class文件,像是下图2的样子,


图2


图3

这样的目录结构是不是看起来就好多了。这时候跟你一起学java的小明也做好了,他给你看他的demo,如图3的样子,这时候你们开始争吵,后来经验丰富的老王来了,他告诉你们生成的class路径也要和package一一对应,你就和小明说,这个规矩太麻烦了,我要在编译的时候指定这么多级的文件夹,万一漏了一级就不好了,而且就这么个简单的工程我和同桌小明都不同,我和他的编译命令都不一样,我的是这样的:

javac src/com/wzt/HelloWorld.java -d classes

而他的是这样的:

javac src/com/wzt/HelloWorld.java -d src/classes

就连这个都不能复用,后面我们还要把这个工程打成一个jar包,肯定也会有不同,蝴蝶效应啊,这真是个悲伤的故事。

老王说,那我们规定一个目录结构吧,然后把编译和打包的命令写成一个脚本,构建好了基本目录一运行脚本就行了。于是我们又做了一遍,果然不错,还是老王有经验。这时候老王跟你们说有一个工具叫Gradle,可以做上面说的这些事,并且做得更好,更多,这么神奇?等不了了,快上车。

2. Gradle构建

       既然用别人的给的工具,到了别人的地盘上,就要守别人的规矩,好在所有人都遵循同一套规范,大家都一样的时候就会感觉没有区别了。好,我们现在建立图示这样一种目录结构,红色部


图4

分依旧是由源文件的package决定的目录结构。绿色的部分是Gradle新增的文件,里面记录了工程的所有信息,让我们来看看这个工程需要哪些信息:

1. apply plugin : 'java'

2. jar {

3.manifest{

4.attributes 'Main-Class' : 'com.wzt.HelloWorld'

5.}

6. }

简单的第一行非常好用,意思是用了java这个插件,我们可以用gradle tasks看一下这个插件增加了哪些task,这里就不一一列举了。假设我们先就只在build.gradle中写第一行,然后运行gradle build命令,得到了很多任务的反馈信息,再看一下目录结构,发现在src平级的地方多了一个build文件夹,打开看看吧,发现里面有classes、libs等,我们就说这两个文件夹,classes里面是按照package名组织好的文件目录,libs里面是打包好的jar包。让我们来运行一下jar包,发生了这样的错误:

no main manifest attribute, in build/libs/jartest.jar

找不到manifest的参数,哪痛打哪,我们在build.gradle加上了2-4行,很好理解,我们在jar包中给manifest一个Main-Class的参数,即我们的类名,重新build之后运行jar包,发现成功打印除了HelloWorld!成功了!那我们现在来写一个web应用吧。

二. 创建一个java web项目

1. 手动创建

我们以一个简单的数据采集应用为例,网页让用户填写相关信息,用户填写完毕后保存到数据库。让我们先手动创建上述项目。首先手动建立一个标准的java web应用的目录结构,如图5,src目录下


图5

是按package组织的java源文件。web文件夹是整个web应用,下面包括一个jsp页面(或jsp、css目录),WEB-INF文件夹,在WEB-INF下的classes存放class文件,lib下是外部依赖库。还需要一个web.xml来记录配置信息。

所有目录和源文件都准备和组织好之后,还有一个问题,还需要准备外部依赖的jar包,好了,这时候我们开始想办法弄这些jar包,好在这个项目需要的外部依赖只有两个,一个mysql相关,


图6

另外一个servlet相关,经过拷贝和下载之后,我们终于把这些jar包放在lib文件夹中了。现在我们谢了一个脚本,编译源文件,指定输出的class目录,然后打包,生成war包。所以整个过程如图6。其中建立目录是个细活,不能出错,准备jar包是个力气活,如果项目里需要很多外部依赖的jar包,你就需要到每个jar包相关的网站上下载,是不是很麻烦。

最后当别人拿到你的war包之后,想要扩展,发现目录结构又不一样,又发生了我们之前说的那些问题。

2. Gradle构建


图7

与构建java项目类似,我们要遵循一定的规则构建目录,并编写build.gradle文件,当然,文件中的东西是不一样的,先给出目录结构,可以看到发生了些许变化,web应用文件夹被放在了src/main下面,web变成了webapp,并且不用在WEB-INF下手动创建classes和lib文件夹了。(见图7)

接下来我们来做最后一步。什么?最后一步,这就最后一步了,我手动构建时的jar包都准备好了,你跟我说不要了?对的,最后一步就是编写build.gradle文件,我们来看看这个build.gradle该怎么写:

1. apply plugin : 'java'

2. apply plugin : 'war'

3. repositories {

4.mavenCentral()

5. }

6. dependencies {

7.providedCompile 'javax.servlet:servlet-api:2.5'

8.runtime 'javax.servlet:jstl:1.1.2'

9.compile 'mysql:mysql-connector-java:5.1.6'

10.}

我们来一步步解释这个文件:

1. 插件 首先我们在第二行加了一个插件’war’,顾名思义,这个插件就是跟war包有关。

2. 代码仓库 接下来3-10行就是来解决jar包的,gradle提供的你想要的jar包也不是凭空来的,也不是gradle自动编写生成的,gradle也是通过代码仓库下载下来,gradle是基于Maven的,所以你需要3-5行的声明,告诉gradle你的仓库是什么,这里用的是Maven,如果你非常牛,经常开发一些自己的jar包并持续应用到项目中,那么你也可以提供一个本地的仓库或是其他仓库。

3. 配置依赖 6-10行配置项目中需要的依赖,也就是具体需要从第2步的代码仓库中下载哪些依赖包,这里因为不同的依赖需要的时间段不一样,有的是运行,有的是编译,所以你会看到dependencies里面不同的声明。

到此,这个应用的build.gradle文件就写完了,我们运行gradle build。我们发现在src平级目录下多了一个build文件夹,里面有classes、lib文件夹,classes里按照源文件的package名组织好了class文件,而整个项目打包好的war包就放在libs文件夹里,拷贝到Tomcat下就可以运行了。

那这个用构建好的Gradle工程怎么交给被人开发呢,毕竟一个项目是大家一起工作的,你不可能一个人完成所有的工作然后只提交war包。当你需要把自己的项目给其他人的时候,我们可以在gradle.build文件里加上这个:

task createWrapper(type: Wrapper) {

gradleVersion = '0.9'

}

意思是给gradle加了一个task,运行这个task:

gradle createWrapper

你就会发现生成了3个新的文件:

1.gradle文件夹

2.gradlew

3.gradlew.bat

这些个文件的意思就是,任何机器都可以运行这个build即使没有装gradle,linux用户直接运行gradlew,windows用户运行gradlew.bat,如果没有装就会根据gradle文件夹里面的配置下载特定版本。

我觉得这个是至关重要的,因为可以在一个:项目组内统一gradle版本。

好啦,这样大家就可以一起愉快的开发软件啦!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,018评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,046评论 2 372
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,215评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,303评论 1 266
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,181评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,171评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,577评论 3 384
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,260评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,546评论 1 292
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,630评论 2 311
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,390评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,260评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,633评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,920评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,210评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,569评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,767评论 2 335

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,497评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,085评论 25 707
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,679评论 6 342
  • 说到自己的生日是怎么过的,没有太多的印象。 但印象一直很深的是,多年前,在工作坊里一个朋友的生日。 当时是发明老师...
    石艳华阅读 127评论 0 2
  • django框架的admin模块,通过list_filter提供给用户自定义分类查询的接口,并且我们可以在原有类的...
    Jerakrs阅读 11,028评论 2 10