一、下载jetty包,
1.如果是gradle 或是maven项目地址在这,jetty-server包http://maven.oschina.net/index.html#nexus-search;quick~com.jfinal
二、引入JettyServer类(核心类),Scanner类(定时任务,热启动),工具类,PathKit,StringKit,FileKit(这些类都来自JFinal中源码)
测试工程目录
1.JettryServer类的实现
代码语言:javascript复制 package com.jetty;
import java.io.File;
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.ServerSocket;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.SessionManager;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.server.session.HashSessionManager;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.webapp.WebAppContext;
import com.kit.FileKit;
import com.kit.PathKit;
import com.kit.StringKit;
/**
* JettyServer is used to config and start jetty web server.
* Jetty version 8.1.8
*/
public class JettyServer {
private String webAppDir;
private int port;
private String context;
private int scanIntervalSeconds;
private boolean running = false;
private Server server;
private WebAppContext webApp;
public JettyServer(String webAppDir, int port, String context, int scanIntervalSeconds) {
if (webAppDir == null)
throw new IllegalStateException("Invalid webAppDir of web server: " webAppDir);
if (port < 0 || port > 65536)
throw new IllegalArgumentException("Invalid port of web server: " port);
if (StringKit.isBlank(context))
throw new IllegalStateException("Invalid context of web server: " context);
this.webAppDir = webAppDir;
this.port = port;
this.context = context;
this.scanIntervalSeconds = scanIntervalSeconds;
}
public void start() {
if (!running) {
try {doStart();} catch (Exception e) {e.printStackTrace();}
running = true;
}
}
public void stop() {
if (running) {
try {server.stop();} catch (Exception e) {e.printStackTrace();}
running = false;
}
}
private void doStart() {
if (!available(port))
throw new IllegalStateException("port: " port " already in use!");
deleteSessionData();
//System.out.println("Starting JFinal " Const.JFINAL_VERSION);
server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(port);
server.addConnector(connector);
webApp = new WebAppContext();
webApp.setContextPath(context);
webApp.setResourceBase(webAppDir); // webApp.setWar(webAppDir);
webApp.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false");
webApp.setInitParameter("org.eclipse.jetty.servlet.Default.useFileMappedBuffer", "false"); // webApp.setInitParams(Collections.singletonMap("org.mortbay.jetty.servlet.Default.useFileMappedBuffer", "false"));
persistSession(webApp);
server.setHandler(webApp);
// configureScanner
if (scanIntervalSeconds > 0) {
Scanner scanner = new Scanner(PathKit.getRootClassPath(), scanIntervalSeconds) {
public void onChange() {
try {
System.err.println("nLoading changes ......");
webApp.stop();
webApp.start();
System.err.println("Loading complete.");
} catch (Exception e) {
System.err.println("Error reconfiguring/restarting webapp after change in watched files");
e.printStackTrace();
}
}
};
System.out.println("Starting scanner at interval of " scanIntervalSeconds " seconds.");
scanner.start();
}
try {
System.out.println("Starting web server on port: " port);
server.start();
System.out.println("Starting Complete. Welcome To The Jetty World :)");
server.join();
} catch (Exception e) {
e.printStackTrace();
System.exit(100);
}
return;
}
private void deleteSessionData() {
try {
FileKit.delete(new File(getStoreDir()));
}
catch (Exception e) {
}
}
private String getStoreDir() {
String storeDir = PathKit.getWebRootPath() "/../../session_data" context;
if ("\".equals(File.separator))
storeDir = storeDir.replaceAll("/", "\\");
return storeDir;
}
private void persistSession(WebAppContext webApp) {
String storeDir = getStoreDir();
SessionManager sm = webApp.getSessionHandler().getSessionManager();
if (sm instanceof HashSessionManager) {
((HashSessionManager)sm).setStoreDirectory(new File(storeDir));
return ;
}
HashSessionManager hsm = new HashSessionManager();
hsm.setStoreDirectory(new File(storeDir));
SessionHandler sh = new SessionHandler();
sh.setSessionManager(hsm);
webApp.setSessionHandler(sh);
}
private static boolean available(int port) {
if (port <= 0) {
throw new IllegalArgumentException("Invalid start port: " port);
}
ServerSocket ss = null;
DatagramSocket ds = null;
try {
ss = new ServerSocket(port);
ss.setReuseAddress(true);
ds = new DatagramSocket(port);
ds.setReuseAddress(true);
return true;
} catch (IOException e) {
} finally {
if (ds != null) {
ds.close();
}
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
// should not be thrown, just detect port available.
}
}
}
return false;
}
}
2.Sanner类的实现
package com.jetty;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import com.kit.StringKit;
/**
* Scanner.
*/
public abstract class Scanner {
private Timer timer;
private TimerTask task;
private File rootDir;
private int interval;
private boolean running = false;
private final Map<String,TimeSize> preScan = new HashMap<String,TimeSize> ();
private final Map<String,TimeSize> curScan = new HashMap<String,TimeSize> ();
public Scanner(String rootDir, int interval) {
if (StringKit.isBlank(rootDir))
throw new IllegalArgumentException("The parameter rootDir can not be blank.");
this.rootDir = new File(rootDir);
if (!this.rootDir.isDirectory())
throw new IllegalArgumentException("The directory " rootDir " is not exists.");
if (interval <= 0)
throw new IllegalArgumentException("The parameter interval must more than zero.");
this.interval = interval;
}
public abstract void onChange();
private void working() {
scan(rootDir);
compare();
preScan.clear();
preScan.putAll(curScan);
curScan.clear();
}
private void scan(File file) {
if (file == null || !file.exists())
return ;
if (file.isFile()) {
try {
curScan.put(file.getCanonicalPath(), new TimeSize(file.lastModified(),file.length()));
} catch (IOException e) {
e.printStackTrace();
}
}
else if (file.isDirectory()) {
File[] fs = file.listFiles();
if (fs != null)
for (File f : fs)
scan(f);
}
}
private void compare() {
if (preScan.size() == 0)
return;
if (!preScan.equals(curScan))
onChange();
}
public void start() {
if (!running) {
timer = new Timer("JFinal-Scanner", true);
task = new TimerTask() {public void run() {working();}};
timer.schedule(task, 1010L * interval, 1010L * interval);
running = true;
}
}
public void stop() {
if (running) {
timer.cancel();
task.cancel();
running = false;
}
}
}
class TimeSize {
final long time;
final long size;
public TimeSize(long time, long size) {
this.time = time;
this.size = size;
}
public int hashCode() {
return (int)(time ^ size);
}
public boolean equals(Object o) {
if (o instanceof TimeSize) {
TimeSize ts = (TimeSize)o;
return ts.time == this.time && ts.size == this.size;
}
return false;
}
public String toString() {
return "[t=" time ", s=" size "]";
}
}
3,工具类
package com.kit;
import java.io.File;
/**
* FileKit.
*/
public class FileKit {
public static void delete(File file) {
if (file != null && file.exists()) {
if (file.isFile()) {
file.delete();
}
else if (file.isDirectory()) {
File files[] = file.listFiles();
for (int i=0; i<files.length; i ) {
delete(files[i]);
}
}
file.delete();
}
}
}
package com.kit;
import java.io.File;
/**
* new File("..pathabc.txt") 中的三个方法获取路径的方法
* 1: getPath() 获取相对路径,例如 ..pathabc.txt
* 2: getAbslutlyPath() 获取绝对路径,但可能包含 ".." 或 "." 字符,例如 D:otherPath..pathabc.txt
* 3: getCanonicalPath() 获取绝对路径,但不包含 ".." 或 "." 字符,例如 D:pathabc.txt
*/
public class PathKit {
private static String webRootPath;
private static String rootClassPath;
public static String getRootClassPath() {
if (rootClassPath == null) {
try {
String path = PathKit.class.getClassLoader().getResource("").toURI().getPath();
rootClassPath = new File(path).getAbsolutePath();
}
catch (Exception e) {
String path = PathKit.class.getClassLoader().getResource("").getPath();
rootClassPath = new File(path).getAbsolutePath();
}
}
return rootClassPath;
}
public static String getWebRootPath() {
if (webRootPath == null)
webRootPath = detectWebRootPath();;
return webRootPath;
}
public static void setWebRootPath(String webRootPath) {
if (webRootPath == null)
return ;
if (webRootPath.endsWith(File.separator))
webRootPath = webRootPath.substring(0, webRootPath.length() - 1);
PathKit.webRootPath = webRootPath;
}
private static String detectWebRootPath() {
try {
String path = PathKit.class.getResource("/").toURI().getPath();
return new File(path).getParentFile().getParentFile().getCanonicalPath();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
package com.kit;
/**
* StringKit.
*/
public class StringKit {
/**
* 首字母变小写
*/
public static String firstCharToLowerCase(String str) {
Character firstChar = str.charAt(0);
String tail = str.substring(1);
str = Character.toLowerCase(firstChar) tail;
return str;
}
/**
* 首字母变大写
*/
public static String firstCharToUpperCase(String str) {
Character firstChar = str.charAt(0);
String tail = str.substring(1);
str = Character.toUpperCase(firstChar) tail;
return str;
}
/**
* 字符串为 null 或者为 "" 时返回 true
*/
public static boolean isBlank(String str) {
return str == null || "".equals(str.trim()) ? true : false;
}
/**
* 字符串不为 null 而且不为 "" 时返回 true
*/
public static boolean notBlank(String str) {
return str == null || "".equals(str.trim()) ? false : true;
}
public static boolean notBlank(String... strings) {
if (strings == null)
return false;
for (String str : strings)
if (str == null || "".equals(str.trim()))
return false;
return true;
}
public static boolean notNull(Object... paras) {
if (paras == null)
return false;
for (Object obj : paras)
if (obj == null)
return false;
return true;
}
}
三,准备工作完成,见证奇迹的时刻来了
1,新建一个Servlet
代码语言:javascript复制 package com;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@SuppressWarnings("serial")
public class FisrtServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) {
System.out.println("jetty我来了");
}
}
2.web.xml
代码语言:javascript复制 <?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0" metadata-complete="true">
<servlet>
<servlet-name>servletTest</servlet-name>
<servlet-class>com.FisrtServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servletTest</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
</web-app>
3.启动类
代码语言:javascript复制 package com;
import com.jetty.JettyServer;
public class JettyTest {
public static void main(String[] args) {
new JettyServer("WebRoot", 80, "/", 5).start();;
}
}
测试启动,结果如下
localhost/test访问后
需要demo可发邮箱451671299@qq.com,这里找不到上传文件地方,好吧,我太菜了