一、简介
传统的Web开发大部分是开发好web程序,通过打成war等程序包发布到web容器中部署。
Jetty其实也可以像tomcat那样作为容器,将程序打包放在其中进行启动,但是我们这里主要是为了简化开发的操作,直接嵌入jetty 启动项目。
二、开发环境
1、由于分布式的兴起,代码复用变得很重要,我这边会把Jetty启动项目的代码做一个module,最后打包成jar包,方便其他使用它的项目依赖使用。
2、 项目结构,该结构是项目的模块化,可以参考一下http://juvenshun.iteye.com/blog/305865
我也正在学习分布式的项目,还没开始多久,项目的地址https://github.com/lili1990/learning.git
3、learning-common-jetty的依赖pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>learning-common</artifactId>
<groupId>com.app</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<name>learning-common-jetty</name>
<groupId>com.app</groupId>
<artifactId>learning-common-jetty</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.app</groupId>
<artifactId>learning-common-main</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jsp</artifactId>
<version>9.2.9.v20150224</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>9.2.9.v20150224</version>
</dependency>
<!-- 使用jstp 不知道jetty为啥非得和这个一起才不会报错-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
</dependencies>
</project>
4、JettyServer的具体代码
package app.server;
import app.utils.ServerProperties;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
/**
* Created by lili19289 on 2016/8/4.
*/
public class JettyServer {
private static final Logger LOGGER = Logger.getLogger(JettyServer.class);
private static final String PROP_NAME__PREFIX = "jetty.";
private static final String PROP_NAME_CONTEXT_PATH = PROP_NAME__PREFIX + "contextPath";
private static final String PROP_NAME_WEBAPP_PATH = PROP_NAME__PREFIX + "webappPath";
private static final String PROP_NAME_HOST = PROP_NAME__PREFIX + "host";
private static final String PROP_NAME_PORT = PROP_NAME__PREFIX + "port";
private static int port;
private String contextPath;
private String webappPath;
private Server server;
private WebAppContext webapp;
/**
* 创建用于开发运行调试的Jetty Server, 以src/main/webapp为Web应用目录.
*/
public static void main(String[] args) {
String contextPath = System.getProperty(PROP_NAME_CONTEXT_PATH);
if (StringUtils.isBlank(contextPath)) {//项目启动后 直接IP:port/就可以访问,因此在这里不进行配置
contextPath = ServerProperties.getProperty(PROP_NAME_CONTEXT_PATH);
}
String webappPath = System.getProperty(PROP_NAME_WEBAPP_PATH);
if (StringUtils.isBlank(webappPath)) {//web.xml的路径,在idea中设置
webappPath = ServerProperties.getProperty(PROP_NAME_WEBAPP_PATH);
}
String portString = System.getProperty(PROP_NAME_PORT);
if (StringUtils.isBlank(portString)) {//项目的端口,在每个项目的conf文件夹下的配置文件中设置
portString = ServerProperties.getProperty(PROP_NAME_PORT);
}
int port = 0;
try {
port = Integer.parseInt(portString);
} catch (Exception e) {
e.printStackTrace();
throw new IllegalArgumentException(PROP_NAME_PORT + " should be an integer between 1 and 65535");
}
JettyServer jettyServer = new JettyServer(contextPath, webappPath, port);
jettyServer.start();
}
public JettyServer(String contextPath, String webappPath, int port) {
if (StringUtils.isBlank(contextPath)) {
this.contextPath = "";
}else{
this.contextPath = contextPath;
}
if (StringUtils.isBlank(webappPath)) {
throw new IllegalArgumentException("webappPath is required");
}else{
this.webappPath = webappPath;
}
this.port = port;
}
public void start() {
if (null == server || server.isStopped()) {
doStart();
} else {
throw new IllegalStateException("JettyServer already started.");
}
}
private void doStart() {
if (!checkServerPortAvailable()) {
throw new IllegalStateException("Server port already in use: " + port);
}
webapp = new WebAppContext(webappPath, contextPath);
server = new Server(port);
server.setHandler(webapp);
try {
long st = System.currentTimeMillis();
server.start();
long sp = System.currentTimeMillis() - st;
System.out.println("JettyServer started: " + String.format("%.2f sec", sp / 1000D)+",the port is ==="+port+"");
server.join();
}catch (Exception e){
e.printStackTrace();
LOGGER.error("JettyServer started failed!");
}
}
private boolean checkServerPortAvailable() {
if (0 < port) {
ServerSocket ss = null;
try {
ss = new ServerSocket(port, 0, null);
} catch (Exception e) {
LOGGER.error("check serverPort failed", e);
return false;
} finally {
if (null != ss) {
try {
ss.close();
} catch (IOException e) {
LOGGER.error("close ServerSocket failed", e);
}
}
}
} else {
throw new IllegalArgumentException("Invalid port " + port);
}
return true;
}
}
package app.utils;
import app.utils.EnvivironmentUtil;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Properties;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//读取配置文件
public class ServerProperties {
private static final Logger LOGGER = LoggerFactory.getLogger(ServerProperties.class);
private static final String FILE_NAME = "/conf/server.properties";
private static Properties prop;
public ServerProperties() {
}
private static void init() {
String filePath = EnvivironmentUtil.getClassPath() + "/conf/server.properties";
FileInputStream ins = null;
try {
ins = new FileInputStream(filePath);
prop = new Properties();
prop.load(ins);
} catch (FileNotFoundException var7) {
LOGGER.error("Can not find server properties, it may result working problem. path: " + filePath, var7);
} catch (Exception var8) {
LOGGER.error("init server properties failed", var8);
} finally {
IOUtils.closeQuietly(ins);
}
}
public static String getProperty(String key) {
return null != prop?prop.getProperty(key):null;
}
static {
init();
}
}
5、在项目中使用该Server,下面以spring这个项目为例子
其他的配置与正常的spring项目一样,只是需要在idea中配置才能正常启动
配置文件 conf/server.properties 中配置
jetty.port=9001,这个端口你可以随意修改
在idea中配置,
创建一个Application后进行配置
直接运行该项目即可了,由于目前还处于自己学习的阶段,没有部署到服务器上,具体服务器怎么启动还没有去研究,等之后会继续完善。