jetty9内嵌到应用,并在启动后加载WebApplicationInitializer,可运行jsp
声明:本文所介绍的两功能都已经测试通过。
第一步先确保你用的是java 8,并依赖需要的相关jar包,以下是用gradle进行依赖的信息:
ext {
taglibsStandardVersion = "1.2.5"
ecjVersion = "4.4.2"
apacheJspVersion = "6.9.10"
asmVersion = "5.0.1"
tomcatVersion = "8.0.30"
annotationApiVersion = "1.2"
jettySchemasVersion = "3.1"
jettyVersion = "9.3.7.v20160115"
servletApiVersion = "3.1.0"
hamcrestCoreVersion = "5.0.1"
commonsLoggingVersion = "1.2"
springVersion = "4.2.3.RELEASE"
}
dependencies {
compile("spring-web:spring-web:${springVersion}")
compile("spring-aop:spring-aop:${springVersion}")
compile("spring-beans:spring-beans:${springVersion}")
compile("spring-context:spring-context:${springVersion}")
compile("spring-expression:spring-expression:${springVersion}")
compile("spring-core:spring-core:${springVersion}")
compile("commons-logging:commons-logging:${commonsLoggingVersion}")
compile("javax.servlet-api:javax.servlet-api:${servletApiVersion}")
compile("hamcrest-core:hamcrest-core:${hamcrestCoreVersion}")
compile("jetty-annotations:jetty-annotations:${jettyVersion}")
compile("jetty-plus:jetty-plus:${jettyVersion}")
compile("jetty-jndi:jetty-jndi:${jettyVersion}")
compile("jetty-webapp:jetty-webapp:${jettyVersion}")
compile("jetty-xml:jetty-xml:${jettyVersion}")
compile("jetty-servlet:jetty-servlet:${jettyVersion}")
compile("jetty-servlet:jetty-security:${jettyVersion}")
compile("jetty-servlet:jetty-util:${jettyVersion}")
compile("jetty-servlet:jetty-server:${jettyVersion}")
compile("jetty-servlet:jetty-http:${jettyVersion}")
compile("jetty-servlet:jetty-io:${jettyVersion}")
compile("jetty-servlet:jetty-schemas:${jettySchemasVersion}")
compile("apache-jsp:apache-jsp:${jettyVersion}")
compile("aopalliance:aopalliance:1.0")
compile("javax.annotation-api:javax.annotation-api:${annotationApiVersion}")
compile("asm:asm:${asmVersion}")
compile("asm-tree:asm-tree:${asmVersion}")
compile("asm-commons:asm-commons:${asmVersion}")
compile("jasper-apache-jsp:apache-jsp:${apacheJspVersion}")
compile("apache-el:apache-el:${apacheJspVersion}")
compile("ecj:ecj:${ecjVersion}")
compile("taglibs-standard-spec:taglibs-standard-spec:${taglibsStandardVersion}")
compile("taglibs-standard-impl:taglibs-standard-impl:${taglibsStandardVersion}")
}
1、jetty9内嵌到应用
核心类代码如下:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List; import org.apache.tomcat.InstanceManager;
import org.apache.tomcat.SimpleInstanceManager;
import org.eclipse.jetty.annotations.AnnotationConfiguration;
import org.eclipse.jetty.annotations.ClassInheritanceHandler;
import org.eclipse.jetty.annotations.ServletContainerInitializersStarter;
import org.eclipse.jetty.apache.jsp.JettyJasperInitializer;
import org.eclipse.jetty.jsp.JettyJspServlet;
import org.eclipse.jetty.plus.annotation.ContainerInitializer;
import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.NCSARequestLog;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.RequestLog;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.handler.RequestLogHandler;
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.ConcurrentHashSet;
import org.eclipse.jetty.util.log.JavaUtilLog;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.ThreadPool;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.MetaData;
import org.eclipse.jetty.webapp.WebAppContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.WebApplicationInitializer; import com.wangzhe.autojoin.wangfw.init.WebAppStrarUpInitializer;
import com.wangzhe.autojoin.wangfw.server.Common;
import com.wangzhe.autojoin.wangfw.server.ServerParam;
import com.wangzhe.autojoin.wangfw.server.jetty9.test.DateServlet;
import com.wangzhe.autojoin.wangfw.util.DateUtil;
import com.wangzhe.autojoin.wangfw.util.ObjectUtil;
import com.wangzhe.autojoin.wangfw.util.Pic2Char; /**
* Example of using JSP's with embedded jetty and not requiring all of the
* overhead of a WebAppContext
*/
public class JettyRunner {
private static final Logger LOG = LoggerFactory.getLogger(JettyRunner.class); // web容器相关参数
private static final ServerParam param = new ServerParam(); public static void main(String[] args) throws Exception {
printFrameWorkLog();
Common.initServerParam(args, param);
LoggingUtil.config();
Log.setLog(new JavaUtilLog());
JettyRunner main = new JettyRunner();
main.start();
printStartSuccess();
main.waitForInterrupt(); } private static void printFrameWorkLog() throws IOException {
String fileStr = new File("").getAbsolutePath()+"\\src\\main\\webapp\\pc\\aj.wangfw\\img\\wang_font.png";
Pic2Char.startPic2Char(fileStr);
}
private static void printStartSuccess() throws IOException {
String fileStr = new File("").getAbsolutePath()+"\\src\\main\\webapp\\pc\\aj.wangfw\\img\\startSuccess.png";
System.out.println();
Pic2Char.startPic2Char(fileStr);
} private Server server;
private URI serverURI; public JettyRunner() {
} public URI getServerURI() {
return serverURI;
} public void start() throws Exception {
server = new Server(createThreadPool());
NetworkConnector connector = createConnector();
server.addConnector(connector); URI baseUri = getWebRootResourceUri();
// Set JSP to use Standard JavaC always
System.setProperty("org.apache.jasper.compiler.disablejsr199", "false"); server.setHandler(getWebAppContext(baseUri, getScratchDir()));
server.addConnector(connector);
server.setStopAtShutdown(true);
// Start Server
server.start(); // Show server state
// if (LOG.isDebugEnabled())
String dump = server.dump();// 输出jetty部分dump信息
LOG.info(dump.substring(dump.indexOf("> sun.misc.Launcher$AppClassLoader")));
// } this.serverURI = getServerUri(connector);
} private NetworkConnector createConnector() {
ServerConnector connector = new ServerConnector(server);
connector.setPort(param.getPort());
connector.setHost(param.getHost());
return connector;
} private URI getWebRootResourceUri() throws FileNotFoundException, URISyntaxException {
URL indexUri = this.getClass().getResource("" + param.getWebDir());
if (indexUri == null) {
return null;
}
// Points to wherever /webroot/ (the resource) is
return indexUri.toURI();
} /**
* Establish Scratch directory for the servlet context (used by JSP
* compilation)
*/
private File getScratchDir() throws IOException {
File tempDir = new File(System.getProperty("java.io.tmpdir"));
File scratchDir = new File(tempDir.toString(), "embedded-jetty-jsp"); if (!scratchDir.exists()) {
if (!scratchDir.mkdirs()) {
throw new IOException("Unable to create scratch directory: " + scratchDir);
}
}
return scratchDir;
} /**
* Setup the basic application "context" for this application at "/" This is
* also known as the handler tree (in jetty speak)
*/
private HandlerCollection getWebAppContext(URI baseUri, File scratchDir) {
WebAppContext webappCtx = new WebAppContext();
webappCtx.setContextPath("/");
// webappCtx.setDescriptor(param.getWebDir()+"\\WEB-INF\\web.xml");
// webappCtx.setWar(param.getWebDir());//for war
webappCtx.setDisplayName("auto join");
webappCtx.setTempDirectory(new File(param.getTempDir()));
webappCtx.setWelcomeFiles(new String[] { param.getWebDir() + "\\index.html" });// 欢迎页面
webappCtx.setConfigurationDiscovered(true);
webappCtx.setParentLoaderPriority(true);
RequestLogHandler logHandler = new RequestLogHandler();
logHandler.setRequestLog(createRequestLog()); webappCtx.setAttribute("javax.servlet.context.tempdir", scratchDir);
webappCtx.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/.*taglibs.*\\.jar$");
if (ObjectUtil.isNotEmpty(baseUri)) {
webappCtx.setResourceBase(baseUri.toASCIIString());// for dir
} else {
webappCtx.setResourceBase(param.getWebDir());
} webappCtx.setAttribute("org.eclipse.jetty.containerInitializers", jspInitializers());
webappCtx.setAttribute(InstanceManager.class.getName(), new SimpleInstanceManager());
webappCtx.addBean(new ServletContainerInitializersStarter(webappCtx), true);
webappCtx.setClassLoader(getUrlClassLoader()); webappCtx.addServlet(jspServletHolder(), "*.jsp");
// Add Application Servlets
webappCtx.addServlet(DateServlet.class, "/date/");
webappCtx.addServlet(exampleJspFileMappedServletHolder(), "/test/foo/");
webappCtx.addServlet(defaultServletHolder(baseUri), "/"); setConfigurations(webappCtx); MetaData metaData = webappCtx.getMetaData();
Resource webappInitializer = Resource.newResource(WebAppStrarUpInitializer.class.getProtectionDomain().getCodeSource().getLocation());
metaData.addContainerResource(webappInitializer); HandlerCollection handlerCollection = new HandlerCollection();
GzipHandler gzipHandler = new GzipHandler();
handlerCollection.setHandlers(new Handler[] { webappCtx, logHandler, gzipHandler });
return handlerCollection;
} private void setConfigurations(WebAppContext webappCtx) {
webappCtx.setConfigurations(new Configuration[] {
new AnnotationConfiguration() {
@Override
public void preConfigure(WebAppContext context) throws Exception {
ClassInheritanceMap map = new ClassInheritanceMap();
ConcurrentHashSet<String> hashSet = new ConcurrentHashSet<String>();
hashSet.add(WebAppStrarUpInitializer.class.getName());
map.put(WebApplicationInitializer.class.getName(), hashSet);
context.setAttribute(CLASS_INHERITANCE_MAP, map);
_classInheritanceHandler = new ClassInheritanceHandler(map);
}
}
});
} /**
* Ensure the jsp engine is initialized correctly
*/
private List<ContainerInitializer> jspInitializers() {
JettyJasperInitializer sci = new JettyJasperInitializer();
ContainerInitializer initializer = new ContainerInitializer(sci, null);
List<ContainerInitializer> initializers = new ArrayList<ContainerInitializer>();
initializers.add(initializer);
return initializers;
} /**
* Set Classloader of Context to be sane (needed for JSTL) JSP requires a
* non-System classloader, this simply wraps the embedded System classloader
* in a way that makes it suitable for JSP to use
*/
private ClassLoader getUrlClassLoader() {
ClassLoader jspClassLoader = new URLClassLoader(new URL[0], this.getClass().getClassLoader());
// jspClassLoader=Thread.currentThread().getContextClassLoader();
// //也可以用这种方式
return jspClassLoader;
} /**
* Create JSP Servlet (must be named "jsp")
*/
private ServletHolder jspServletHolder() {
ServletHolder holderJsp = new ServletHolder("jsp", JettyJspServlet.class);
holderJsp.setInitOrder(0);
holderJsp.setInitParameter("logVerbosityLevel", "DEBUG");
holderJsp.setInitParameter("fork", "false");
holderJsp.setInitParameter("xpoweredBy", "false");
holderJsp.setInitParameter("compilerTargetVM", "1.7");
holderJsp.setInitParameter("compilerSourceVM", "1.7");
holderJsp.setInitParameter("keepgenerated", "true");
return holderJsp;
} /**
* Create Example of mapping jsp to path spec
*/
private ServletHolder exampleJspFileMappedServletHolder() {
ServletHolder holderAltMapping = new ServletHolder();
holderAltMapping.setName("foo.jsp");
holderAltMapping.setForcedPath("/test/foo/foo.jsp");
return holderAltMapping;
} /**
* Create Default Servlet (must be named "default")
*/
private ServletHolder defaultServletHolder(URI baseUri) {
ServletHolder holderDefault = new ServletHolder("default", DefaultServlet.class);
if (ObjectUtil.isNotEmpty(baseUri)) {
LOG.info("Base URI: " + baseUri);
holderDefault.setInitParameter("resourceBase", baseUri.toASCIIString());
} else {
holderDefault.setInitParameter("resourceBase", param.getWebDir());
} holderDefault.setInitParameter("dirAllowed", "true");
return holderDefault;
} /**
* Establish the Server URI
*/
private URI getServerUri(NetworkConnector connector) throws URISyntaxException {
String scheme = "http";
for (ConnectionFactory connectFactory : connector.getConnectionFactories()) {
if (connectFactory.getProtocol().equals("SSL-http")) {
scheme = "https";
}
}
String host = connector.getHost();
if (host == null) {
host = "localhost";
}
int port = connector.getLocalPort();
serverURI = new URI(String.format("%s://%s:%d/", scheme, host, port));
LOG.info("start sucess on Server URI: " + serverURI); return serverURI;
} public void stop() throws Exception {
server.stop();
} /**
* Cause server to keep running until it receives a Interrupt.
* <p>
* Interrupt Signal, or SIGINT (Unix Signal), is typically seen as a result
* of a kill -TERM {pid} or Ctrl+C
*
* @throws InterruptedException
* if interrupted
*/
public void waitForInterrupt() throws InterruptedException {
server.join();
} public static ServerParam getParam() {
return param;
} private RequestLog createRequestLog() {
// 记录访问日志的处理
NCSARequestLog requestLog = new NCSARequestLog();
requestLog.setFilename(param.getLogDir() + "/jetty_log" + DateUtil.formatDate(DateUtil.YYYYMMDD) + ".log");
requestLog.setRetainDays(90);
requestLog.setExtended(false);
requestLog.setAppend(true);
// requestLog.setLogTimeZone("GMT");
requestLog.setLogTimeZone("Asia/beijing");
requestLog.setLogDateFormat("yyyy-MM-dd HH:mm:ss");
requestLog.setLogLatency(true);
return requestLog;
} /**
* 设置线程池
*
* @return
*/
private ThreadPool createThreadPool() {
QueuedThreadPool threadPool = new QueuedThreadPool();
threadPool.setMinThreads(10);
threadPool.setMaxThreads(500);
return threadPool;
}
}
2、jetty9服务器启动时加载WebApplicationInitializer
下面代码是WebApplicationInitializer的一个实现类
@Order(Integer.MIN_VALUE) // 较低的值有更高的优先级 所以这个类的优先级是最高的
public class WebAppStrarUpInitializer implements WebApplicationInitializer{ public WebAppStrarUpInitializer() { } @Override
public void onStartup(ServletContext servletContext) throws ServletException {
System.out.println("hello WebAppStrarUpInitializer"); } }
下面代码是从上面第一部分的JettyRunner类中抽取的部分代码,即注册WebApplicationInitializer的地方
private void setConfigurations(WebAppContext webappCtx) {
webappCtx.setConfigurations(new Configuration[] {
new AnnotationConfiguration() {
@Override
public void preConfigure(WebAppContext context) throws Exception {
ClassInheritanceMap map = new ClassInheritanceMap();
ConcurrentHashSet<String> hashSet = new ConcurrentHashSet<String>();
hashSet.add(WebAppStrarUpInitializer.class.getName());//注册WebApplicationInitializer
map.put(WebApplicationInitializer.class.getName(), hashSet);
context.setAttribute(CLASS_INHERITANCE_MAP, map);
_classInheritanceHandler = new ClassInheritanceHandler(map);
}
}
});
}
完成代码编写后,请运行JettyRunner类的main方法,运行后请在浏览器输入localhost/index.jsp即可看到效果。如图:
参考:
https://github.com/orb15/embeddedjetty9-spring4
https://github.com/langtianya/embedded-jetty-jsp
https://github.com/yjmyzz/jetty-embed-demo
本文代码托管:https://github.com/langtianya/autojion/tree/master/module_project
jetty9内嵌到应用,并在启动后加载WebApplicationInitializer,可运行jsp的更多相关文章
- Pycharm启动后加载anaconda一直updating indices造成Pycharm闪退甚至电脑崩溃
可能跟anaconda文件夹有一定关系 网上找找解决方案,似乎很多人有同样的困扰! 知乎-pycharm启动后总是不停的updating indices...indexing? stackoverfl ...
- 【实战问题】【1】@PostConstruct 服务启动后加载两次的问题
@PostConstruct:在服务启动时触发操作(我是用来更新微信的access_token) 解决方法: tomcat文件夹→conf→server.xml→将appBase="weba ...
- Tomcat启动后加载两次web.xml的问题(因为spring定时任务执行了俩次,引出此问题)
http://www.linuxidc.com/Linux/2011-07/38779.htmhttp://jingyan.baidu.com/article/48206aeaf9422e216ad6 ...
- ElasticSearch 启动时加载 Analyzer 源码分析
ElasticSearch 启动时加载 Analyzer 源码分析 本文介绍 ElasticSearch启动时如何创建.加载Analyzer,主要的参考资料是Lucene中关于Analyzer官方文档 ...
- XV6学习笔记(1) : 启动与加载
XV6学习笔记(1) 1. 启动与加载 首先我们先来分析pc的启动.其实这个都是老生常谈了,但是还是很重要的(也不知道面试官考不考这玩意), 1. 启动的第一件事-bios 首先启动的第一件事就是运行 ...
- Servlet在启动时加载的tomcat源码(原创)
tomcat 8.0.36 知识点: 通过配置loadOnStartup可以设置Servlet是否在Tomcat启动时加载,以及按值大小进行有序加载,其最小有效值为0,最大有效值为Integer.MA ...
- 启动就加载(一)----注解方式实现的。static项目启动的时候就加载进来(一般用于常用参数)
一,案例 1.1,图片分析 1.2,代码 1.2.1,编写加载系统参数的servlet public class SysInitServlet extends HttpServlet { public ...
- SpringBoot启动如何加载application.yml配置文件
一.前言 在spring时代配置文件的加载都是通过web.xml配置加载的(Servlet3.0之前),可能配置方式有所不同,但是大多数都是通过指定路径的文件名的形式去告诉spring该加载哪个文件: ...
- Redis深入学习笔记(一)Redis启动数据加载流程
这两年使用Redis从单节点到主备,从主备到一主多从,再到现在使用集群,碰到很多坑,所以决定深入学习下Redis工作原理并予以记录. 本系列主要记录了Redis工作原理的一些要点,当然配置搭建和使用这 ...
随机推荐
- Java 加解密 AES DES TripleDes
package xxx.common.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.crypt ...
- EasyUI combobox
高度自适应 data-options="required:true,editable:false,panelHeight:'auto',panelMaxHeight:170" 加上 ...
- 2015-12-01 SQL查询语句基础
1.查询全体学生的学号与姓名select sno,snamefrom student;3.查询全体学生的详细信息select *from student;4.查询全体学生的姓名及其出生年份select ...
- 安卓android sharepreference数据存储,保存输入框里面的数据
Fragment 里面 使用轻量级的数据存储sharepreference ,代码思路清晰.保存输入框里面的数据,实现按钮保存. 个人项目中简单清晰代码: 赵存档 编写 ,可以参考: 类继承Fragm ...
- [转]Asp.Net Core 简单的使用加密的Cookie保存用户状态
本文转自:http://www.cnblogs.com/Joes/p/6023820.html 在以前的Asp.Net中可以用 FormsAuthentication 类的一系列方法来使用加密的Coo ...
- 用字体在网页中画Icon图标
第一步,下载.IcoMoon网站选择字体图标并下载,解压后将fonts文件夹放在工程目录下.fonts文件夹内有四种格式的字体文件: 注:由于浏览器对每种字体的支持程度不一致,要想在所有浏览器中都显示 ...
- Url重写——伪静态实现
简述: 在我们浏览网站的时候,很多都是以.html结尾的.难道这些都是静态网页么?其实不是的,它们很多是伪静态 那么什么是伪静态?顾名思义,就是假的静态页面.通过某种设置让你看成是静态的. Q:为何要 ...
- asp.net获取服务器绝对路径和相对路径
绝对路径 AppDomain.CurrentDomain.SetupInformation.ApplicationBase 相对路径 Server.MapPath("~/")表示当 ...
- 用vue.js学习es6(六):Iterator和for...of循环
一.Iterator (遍历器)的概念: 遍历器(Iterator)就是这样一种机制.它是一种接口,为各种不同的数据结构提供统一的访问机制.任何数据结构只 要部署Iterator接口,就可以完成遍历操 ...
- Redis中connect与pconnect区别?
1.首先先介绍下connect和pconnect的区别. connect:脚本结束之后连接就释放了. 2.pconnect:脚本结束之后连接不释放,连接保持在php-fpm进程中. 所以使用pconn ...