Jetty 啓動spring項目


一、簡介

  傳統的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後進行配置



直接運行該項目即可了,由於目前還處於自己學習的階段,沒有部署到服務器上,具體服務器怎麼啓動還沒有去研究,等之後會繼續完善。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章