文档章节

Eclispe下集成JFinal中jetty包作为开发环境

魔法王者安琪拉
 魔法王者安琪拉
发布于 2014/03/26 15:25
字数 1368
阅读 3959
收藏 26

一、下载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类的实现

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("..\path\abc.txt") 中的三个方法获取路径的方法
 * 1: getPath() 获取相对路径,例如   ..\path\abc.txt
 * 2: getAbslutlyPath() 获取绝对路径,但可能包含 ".." 或 "." 字符,例如  D:\otherPath\..\path\abc.txt
 * 3: getCanonicalPath() 获取绝对路径,但不包含 ".." 或 "." 字符,例如  D:\path\abc.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

 

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

<?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.启动类

 

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,这里找不到上传文件地方,好吧,我太菜了


 


 

 

 

© 著作权归作者所有

魔法王者安琪拉

魔法王者安琪拉

粉丝 81
博文 109
码字总数 48920
作品 0
深圳
程序员
私信 提问
加载中

评论(2)

魔法王者安琪拉
魔法王者安琪拉 博主

引用来自“maiyang”的评论

直接引入jfinal就好了!难道你还用其他的?

嗯, 是的,用源码自己可以定制,稍微改改,打个包封装成符合自己的习惯jar调用挺好,http://my.oschina.net/u/136848/blog/213008这个就是直接引用的,现在JFinal还不够大众,最近换工作中就发现很多都用SpringMVC,JFinal的这个jetty集成的好用,可以封装成jar包在其它框架中使用
maiyang
maiyang
直接引入jfinal就好了!难道你还用其他的?
JBolt-JFinal开发利器,新官网上线

JBolt,诞生于2016年8月,以Eclipse插件的形式提供给JFinal开发者无偿下载使用。(Idea版还在捣鼓...) 今天JBolt新版官网正式上线,欢迎访问学习交流和使用,有什么问题,在社区提问@我即可,...

山东-小木
2019/07/21
288
0
在Intellij IDEA中Jfinal不能自动重新加载

@JFinal 你好,想跟你请教个问题:我使用的开发环境不是标准的Eclipse,我使用的是Intellij IDEA,我把File-> Project Structure->Project compiler output中输出的路径设置为:G:\Work\jfina...

糖豆
2013/05/24
3.3K
6
JFinal Undertow 1.3 发布,从极速开发到极速上线

从 JFinal 3.0 重新定义模板引擎实现了 MVC + ORM 各层的极速开发(3.0 发布盛况传送门),到 JFinal 3.4 将极速贯彻到 UI 层,实现了 UI 层的极速开发 (3.4 发布盛况传送门),“开发过程” 的...

JFinal
2018/12/12
10.7K
89
jfinal-weixin maven导出war包问题

@JFinal 你好,想跟你请教个问题: 今天试着在MyEclipse开发环境中集成Mavn,保持与你开发时的环境一致, 当使用"Mavn install"生成war时,项目中出现了一个target子目录,目录结构如下: ---targ...

andying
2014/11/11
1K
4
Jfinal在开发环境中用Jetty,在应用环境中用tomcat好不好

@Jfinal Jfinal在开发环境中用Jetty,在应用环境中用tomcat好不好

圣杰是也
2013/07/26
1K
7

没有更多内容

加载失败,请刷新页面

加载更多

How to find table in a database with HeidiSQL

In this article I want to show you how you can find table by name with HeidiSQL. Find table by typing One of the options to find table is to having focus in the object explorer ......

Ciet
10分钟前
4
0
基于SWIG跨平台开发的C++编码规范

1、数组定义 使用数组不建议采用指针方式eg double *,或者 double test[4] 直接采用std::vector或list即可。对于固定长度的数组定义为一个结构体 double test[4]instead ofstruct Vec...

洋碱
12分钟前
2
0
用Markdown编程之布局

基本就是用Markdown的布局方式。 \:是转义符号,最高优先级。 行首+# :用于空间布局,1-6分别标明:模式根、子模式、子模式内。 行首+> :用于标注和通信,1个标明标注,2个标明分类,3个标...

dwcz
19分钟前
3
0
SpringBoot定时器多线程解决方案

@Scheduled 作用:spring定时器(定时执行一次或定时轮询执行一段代码) 使用场景:注解在方法上 参数说明:常用参数 @Scheduled 参数说明 String cron:cron表达式定义了方法执行的时间规则(网...

whoisliang
19分钟前
4
0
3.01、Spring AOP的理解

注:转 https://mp.weixin.qq.com/s/PsgTLn8cdTxdd542XgVkUA 什么是AOP AOP(Aspect-Oriented Programming), 即 面向切面编程 , 它与 OOP( Object-Oriented Programming, 面向对象编程) 相辅相......

追忆2025
25分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部