Maven 打包jsp/js/jsp静态资源到 JAR 包中(Servlet3.0模块化特性与Maven结合应用)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhangxin09/article/details/79268056

先吐槽一下,本人踩过很多坑,泪流满面啊,有因为不熟悉 maven 的,有 eclipse bug 的,有网上文章信息不对称的……
好吧,回到正题,我们需求是这样子滴:

  • 一个项目由多个工程组成。因为项目是复杂的,大的,所以划分为多个子项目(或者说工程)比较好一点
  • 那么问题来了,父与子工程的依赖怎么处理?打包构建怎么处理?
  • 怎么破?用 maven 呗;
  • 我们都知道 maven 强大,可是伴随着强大的同义词是复杂!这也就是我之前喜欢用 ant 而不是 maven 的缘故。
  • 我们都知道,工程最终要打包为 jar/war 部署的。对于 IDE 而言,从它的方面去理解的话,其实还存在一个隐含的内建环境:就是我们开发时候,敲代码、测试、改 bug 的 IDE 环境,是我们开发者主要花时间的环境,这时 IDE 可以检查依赖的包是否导入了,能否提供代码联想功能……等等——这两个环境是不同的于是处理起来也是不一样的——这也就是为什么敲代码时候 IDE 依赖正确,看不出什么问题,但是运行时候却报错出现 Class Not Found 的原因;下面我们逐一分析;
  • 首先是开发环境。我们希望,各个项目的依赖的自动的、同步的。啥意思?就是子工程 B 依赖父工程 A,我修改了 A 的代码,B 那里会有所反应,知晓的。谁也不想手动 build A一下 B 工程才能用,这应该 maven/eclipse 后台自动帮我们做的。
  • 这需求很普遍是吧,没问题,maven 可以这样子做,只要在 pom.xml 声明依赖就可以了(当然前提都是本地的工程)
  • 如下图所示,依赖了 ajaxjs-base/data 两个工程,代码可以自动同步的
    这里写图片描述
  • 可见那不是 jar 包。但如果在 eclipse 里面 close 了 ajaxjs-base/data 工程,那么 maven 就不依赖本地工程,而是提供 jar 包;
  • 嗯,到目前为止一切很好是吧!?
  • 不过~只是 for 纯 java 项目而论的!web 工程就不行,不能自动同步!!!
  • 这里多说一句,没接触 maven 之前,我用 eclipse link resource 功能,build war 也可以,也蛮不错,同步啥文件都可以。

打包失败!

苦思良久,神农氏般尝试百草的方法都试过,无甚所获!maven 会把整个 web 项目打成 jar 而非标准的 java jar 包!
后来皇天不负有心人,正确的操作姿势是依赖 war 包:

“dependency type war 就可以实现war包依赖,B依赖A,打包的时候就会把A的classes以及文件打进去”

<dependency>
<groupId>com.handlecode</groupId>
<artifactId>diy-biz</artifactId>
<version>${diy.version}</version>
<type>war</type>
</dependency>

http://blog.csdn.net/sxhong/article/details/72869359

当然依赖的工程类型是 war。
这里写图片描述
这样 WEB-INF 会有包含 war 的包,这是 eclipse 调试时的临时目录。
别问为什么可以是 war,人家都是 jar?我也不知道,反正可以读到里面的 class……

然后 build 的时候走的是 maven-war-plugin 插件。再次强调,问题分两个方面的,一个是满足开发环境的匹配,一个是最终打包环境的匹配。解决了一个问题不等于解决另外一个问题,而且有时候会两个问题是矛盾的。
上述这个方法仅限于 java 代码复用、同步。

打包 jsp/html/js/jpg 资源

将项目依赖 war 包就可以了导入父工程的 class。可是1、那不是 jar 包,而且包含其他没用的 jsp 等;2、不能导入静态资源;3、父工程必须为 war 类,而我要 build 一份 jar 给别人用的,改 pom.xml 是可以但很麻烦。

有朋友问,为啥 jsp/html/js/jpg 资源导入 jar?复用呗、重用呗~都是公用的资源。请君看看 Servlet 3.0 新特性:

在Servlet3.0协议规范中指出:${jar}/META-INF/resources/被视为根目录。那么将jsp等静态资源打入META-INF/resources/目录下就与实际项目没有区别了。

也就是说 jsp 在 jar 是可以运行的。还有 webfragment.xml 也应该要支持。
我觉得这很有价值,尤其全栈的 js 代码当然想一块拉进来。你懂的~
具体操作请接着看。

启用 webfragment 项目

标准的东西 eclispe 肯定支持,只不过很少用而已。
这里写图片描述
webfragment 项目特点是不能放在 tomcat 里运行,其他与标准 DynamicWeb项目 无异。
你不想新建project 也可以,改 project fact 呗~
这里写图片描述
eclipse 死活不能在ui里改,改配置呗,
找到 org.eclipse.wst.common.project.facet.core.xml

<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
  <fixed facet="wst.jsdt.web"/>
  <installed facet="java" version="1.7"/>
  <installed facet="wst.jsdt.web" version="1.0"/>
  <installed facet="jst.webfragment" version="3.0"/>
</faceted-project>

好了

转为 Maven 项目

当然你也可以新建 maven 项目再转 porject fact,顺序无所谓。pom.xml 一定要设置 jar 类型的
这里写图片描述

Deployment Assembly 设置

其实就算是 DynamicWeb工程也可以,因为关键设置是 Deployment Assembly,设置对了就行。
不过我们先明确下需求,欲生成的 jar 包是这样的。
这里写图片描述
MEA-INF 目录下有 web-fragment.xml;resources 是像 WebContent ,都是 jsp/js 你喜欢放啥都行;tags 是放 tld 自定义标签的(吐槽一句不支持 tag files!)
必须按这样的结构来放到 web-inf/lib 下 tomcat 或者 jetty 等的 servlet 容器才能读取。
重头戏来了!Deployment Assembly 必须是这样子滴:
这里写图片描述

  • 指定 /META-INF 对应根目录。其实 WebContent 目录没必要存在了,都放到 META-INF 下面好了
  • /src/main 是指定 java 文件的,都给我放到根目录下去~

很好,这就是 jar 里面的结构了。每当你修改了一些东西包括 jsp,B工程也会同步知晓。eclispe/mavne 会在后面辛勤地劳作,打包成这样:
这里写图片描述

最后补充

  • 到目前为止只是说了 开发环境的打包,没说构建的打包。之前我弄过,也不能难,肯定比 eclipse 下灵活、自由。
  • 我的不是标准 Maven项目的目录结构,而是传统的DynamicWeb项目结构,有些不同但不影响,关键配置对就行(这里插一句,之前尼玛报错 出现 “Updating status for Tomcat v6.0 Server at localhost…”. java.lang.NullPointerException 莫名其妙的,后来升级 eclipse 就行)
  • 至于 idea,很好,能自动识别 pom 的 resources 配置,能设置好 maven 等于能设置对 IDE 了,非常智能的话,不愧为 idea

参考:
http://blog.csdn.net/sxhong/article/details/72869359
http://blog.csdn.net/u011666411/article/details/77160907
http://blog.csdn.net/mafan121/article/details/51862933
https://segmentfault.com/a/1190000007166005

猜你喜欢

转载自blog.csdn.net/zhangxin09/article/details/79268056
今日推荐