Java项目内置Jetty
想要在一个Java项目中自启动一个jetty容器,可以打开站点,显示自定义内容,而不需要引入jetty插件或者Ide支持或者类似tomcat那样启动。并且将项目打成jar包,可以在其他项目中引用。
在使用中碰到一些问题,主要是:
- jetty包对jsp页面不支持,需要额外引入包,且去掉冲突包;
- 当项目被打成jar包、被其他项目引用时,要注意jetty Server webAppContext的路径问题
现记录如下:
引入Jetty包:
1
2
3
4
5
6
7
8
9
10<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>9.3.7.v20160115</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>9.3.7.v20160115</version>
</dependency>是为了让jetty站点支持jsp和jstl,还需要引入:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jsp</artifactId>
<version>9.2.15.v20160210</version>
<exclusions>
<exclusion>
<groupId>org.eclipse.jetty.orbit</groupId>
<artifactId>javax.servlet.jsp.jstl</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>javax.servlet.jsp.jstl-api</artifactId>
<version>1.2.1</version>
</dependency>在
main
文件夹下创建webapp
文件夹,类似于标准web项目,创建webapp\WEB-INF\web.xml
文件;由于项目使用了springMVC框架,所以resource
文件夹下要创建applicationContext.xml
文件,并引入相应的springMVC包,其他jsp/js/css/images等参考标准web项目目录。Main函数启动Jetty,加载web.xml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30private static final int port = 8080;
private static final String CONTEXT = "/";
public static Server createServer(int port) throws MalformedURLException, URISyntaxException {
Server server = new Server();
server.setStopAtShutdown(true); //JVM退出时关闭Jetty
ServerConnector connector = new ServerConnector(server);
connector.setPort(port);
connector.setReuseAddress(false); //重复启动Jetty居然报端口冲突
server.setConnectors(new Connector[]{connector});
WebAppContext webContext = new WebAppContext("src/main/webapp", CONTEXT);
webContext.setDescriptor("src/main/webapp/WEB-INF/web.xml");
webContext.setResourceBase("src/main/webapp");
webContext.setClassLoader(ApiWebSite.class.getClassLoader());
server.setHandler(webContext);
return server;
}
public static void main(String[] args) throws Exception {
Server server = ApiWebSite.createServer(ApiWebSite.port);
try {
server.stop();
server.start();
server.join();
} catch (Exception e) {
e.printStackTrace();
}
}
完成其他spring bean代码和jsp代码编写,运行main函数,浏览器访问localhost:8080/index.htm
(自己在web.xml
和applicationContext.xml
配置)就可以访问web页面了。
但是
将项目打成jar包,在其他工程中引用,运行main函数,试图启动jetty站点时,WebAppContext的路径,会在当前项目的src目录下找,当然是找不到的,所以加载xml文件失败。需要对上面的内容做一点修改:
将
web
文件夹,从src
目录移动到resources
目录下,这样做的目的是为了打包时将网站内容也打进jar包(因为这不是一个标准的web工程);修改代码:
1
2
3WebAppContext webContext = new WebAppContext("webapp", CONTEXT);
webContext.setBaseResource(Resource.newResource(new URL(ApiWebSite.class.getResource("/webapp/WEB-INF"), ".")));
webContext.setClassLoader(ApiWebSite.class.getClassLoader());此时,webAppContext就会从依赖的jar包中找到配置文件的实际路径进行加载,而不是从当前项目的文件夹中找。
要注意的是,这里没有
setDescriptor("src/main/webapp/WEB-INF/web.xml")
。因为在使用时,不管我怎么设置这个web.xml
的地址,总是找不到。在丁哥帮助下,发现jetty源码中,如果不设置Descriptor,他会默认寻找webapp目录下的WEB-INF/web.xml
文件:1
2
3
4
5
6
7
8/**
* @return the web.xml descriptor to use. If set to null, WEB-INF/web.xml is used if it exists.
*/
public String getDescriptor()
{
return _descriptor;
}去掉
webContext.setDescriptor(...);
后,重新install,启动成功。