ApacheFelixplusJasperJSP支持-如何以正确的方式实现?
事实上,问题是:如何正确地将tomcat jasper jsp支持添加到felix osgi容器中 我已经设法找到了一种方法,用最少的java自定义代码来完成它,但是我确信这不是最“干净”或“合适”的方法。这种方法仍有一些局限性,因此本文将展示我是如何做到这一点的,并询问如何“正确地”做到这一点。链接到使用eclipse的示例: 所以我所做的是:ApacheFelixplusJasperJSP支持-如何以正确的方式实现?,jsp,tomcat,osgi,Jsp,Tomcat,Osgi,事实上,问题是:如何正确地将tomcat jasper jsp支持添加到felix osgi容器中 我已经设法找到了一种方法,用最少的java自定义代码来完成它,但是我确信这不是最“干净”或“合适”的方法。这种方法仍有一些局限性,因此本文将展示我是如何做到这一点的,并询问如何“正确地”做到这一点。链接到使用eclipse的示例: 所以我所做的是: 在默认的http白板配置和webconsole支持中设置Felix(实际上不是必需的,但是……您可以使用它检查jsp servlet部署是否正常)。我
“inline”
,“*,对maven repos中发现的最新tomcat-jasper-8.0.32.jar(和依赖项)进行Bundelized;分辨率:=可选“
和“”*”
。是的,我知道,大“不不不”,但人们不能期望Jasper提前知道它将编译什么。没有DI-P可能值得一试。以后。重新绑定相同(但没有DI-P)的taglibs-standard-impl-1.2.5,因为虽然pom指定xalan依赖项为可选,但捆绑包清单没有。而且Delegate/recent java内置了xml解析,所以我也“优化”了它的依赖关系。无论如何,我希望tomcat有一天会osgi将它的JAR升级,并生成一个更加osgi友好的taglib标准implfelix.base
|-- bin
|-- felix.jar
|-- bundle
|-- ecj-4.4.2.jar
|-- javax.el-3.0.0.jar
|-- javax.servlet.jsp-api-2.3.1.jar
|-- javax.servlet.jsp.jstl-api-1.2.1.jar
|-- org.apache.felix.bundlerepository-2.0.6.jar
|-- org.apache.felix.configadmin-1.8.8.jar
|-- org.apache.felix.eventadmin-1.4.6.jar
|-- org.apache.felix.gogo.command-0.16.0.jar
|-- org.apache.felix.gogo.runtime-0.16.2.jar
|-- org.apache.felix.gogo.shell-0.10.0.jar
|-- org.apache.felix.http.api-3.0.0.jar
|-- org.apache.felix.http.base-3.0.6.jar
|-- org.apache.felix.http.jetty-3.1.6.jar
|-- org.apache.felix.http.servlet-api-1.1.2.jar
|-- org.apache.felix.webconsole-4.2.14-all.jar
|-- taglibs-standard-impl-1.2.5.jar
|-- tomcat-api-8.0.32.jar
|-- tomcat-jasper-8.0.32.jar
|-- tomcat-jasper-el-8.0.32.jar
|-- tomcat-juli-8.0.32.jar
|-- tomcat-util-8.0.32.jar
|-- tomcat-util-scan-8.0.32.jar
如果您正在查看附带的示例,那么上面描述的所有内容都是通过“launcher/pom.xml”完成的。现在,如果启动“launcher”(作为java应用程序运行),所有捆绑包都应该处于活动状态。到目前为止,还没有java编码,唯一的“定制”是tomcat JAR的邦德化和taglib标准impl的重新邦德化
现在来看“jsp魔术”:
public class Activator implements BundleActivator {
public static String CONTEXT = "dummy";
public static String BASE_URL = "/dummy";
private ServletContextHelper servletContextHelper = null;
private ServiceRegistration<?> schRegistration = null;
private ServiceRegistration<Servlet> jspServletRegistration = null;
public void start(BundleContext context) {
// http support
servletContextHelper = new ServletContextHelper() {
@Override
public URL getResource(String name) {
if (name.startsWith("file:")) {
// this is an absolute URL, so it is already rendered
try {
return new URL(name);
} catch (Exception e) {
return null;
}
}
// render it in the webcontet dir
return FrameworkUtil.getBundle(this.getClass()).getResource("/webcontent" + name);
}
@Override
public Set<String> getResourcePaths(String path) {
if ("/WEB-INF/lib/".equals(path)) {
// jasper scans for tag libraries so give him all bundles in the container
Set<String> jars = new HashSet<String>();
Bundle thisBundle = FrameworkUtil.getBundle(ServletContextHelper.class);
try {
// look in the location of current bundle (assume they're all in the same place)
File deployDir = new File(new URI(thisBundle.getLocation())).getParentFile();
File[] files = deployDir.listFiles();
for (File file : files)
jars.add(file.toURI().toURL().toExternalForm());
} catch (Exception e) {
e.printStackTrace();
}
return jars;
}
return super.getResourcePaths(path);
}
};
Hashtable<String, Object> httpContextProps = new Hashtable<String, Object>();
httpContextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, CONTEXT);
httpContextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, BASE_URL);
schRegistration = context.registerService(ServletContextHelper.class, servletContextHelper, httpContextProps);
@SuppressWarnings("serial")
JspServlet jspServlet = new JspServlet() {
@Override
public void init(ServletConfig config) throws ServletException {
JspFactory.setDefaultFactory(new JspFactoryImpl());
ClassLoader current = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(JspServlet.class.getClassLoader());
ServletContainerInitializer sci = new JasperInitializer();
sci.onStartup(null, config.getServletContext());
super.init(config);
Thread.currentThread().setContextClassLoader(current);
}
@Override
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ClassLoader current = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(JspServlet.class.getClassLoader());
super.service(req, resp);
Thread.currentThread().setContextClassLoader(current);
}
};
Hashtable<String, Object> jspProps = new Hashtable<String, Object>();
jspProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "JSP servlet");
jspProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "*.jsp");
jspProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(osgi.http.whiteboard.context.name=" + CONTEXT + ")");
jspServletRegistration = context.registerService(Servlet.class, jspServlet, jspProps);
}
public void stop(BundleContext context) {
jspServletRegistration.unregister();
schRegistration.unregister();
}
}
公共类激活器实现BundleActivator{
公共静态字符串CONTEXT=“dummy”;
公共静态字符串BASE_URL=“/dummy”;
私有ServletContextHelper ServletContextHelper=null;
private ServiceRegistration schRegistration=null;
private ServiceRegistration jspServletRegistration=null;
公共void开始(BundleContext){
//http支持
servletContextHelper=新的servletContextHelper(){
@凌驾
公共URL getResource(字符串名称){
if(name.startsWith(“文件:”){
//这是一个绝对URL,因此它已呈现
试一试{
返回新的URL(名称);
}捕获(例外e){
返回null;
}
}
//在WebContent目录中呈现它
返回FrameworkUtil.getBundle(this.getClass()).getResource(“/webcontent”+名称);
}
@凌驾
公共设置GetResourcePath(字符串路径){
如果(“/WEB-INF/lib/”。等于(路径)){
//jasper扫描标记库,所以将容器中的所有包都交给他
Set jars=newhashset();
Bundle thisBundle=FrameworkUtil.getBundle(ServletContextHelper.class);
试一试{
//查看当前捆绑包的位置(假设它们都在同一个位置)
File deployDir=新文件(新URI(thisBundle.getLocation()).getParentFile();
File[]files=deployDir.listFiles();
用于(文件:文件)
add(file.toURI().tour().toExternalForm());
}捕获(例外e){
e、 printStackTrace();
}
返回罐;
}
返回super.getResourcePath(路径);
}
};
Hashtable httpContextProps=新Hashtable();
httpContextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME,CONTEXT);
httpContextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH,BASE_URL);
schRegistration=context.registerService(ServletContextHelper.class、ServletContextHelper、httpContextProps);
@抑制警告(“串行”)
JspServlet JspServlet=新的JspServlet(){
@凌驾
public void init(ServletConfig config)抛出ServletException{
setDefaultFactory(新的JspFactoryImpl());
ClassLoader current=Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(JspServlet.class.getClassLoader());
ServletContainerInitializer sci=新的JasperiInitializer();
sci.onStartup(null,config.getServletContext());
super.init(config);
Thread.currentThread().setContextClassLoader(当前);
}
@凌驾
公共无效服务(HttpServletRequest-req、HttpServletResponse-resp)抛出ServletException、IOException{
ClassLoader current=Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(JspServlet.class.getClassLoader());
超级服务(请求、响应);
Thread.currentThread().setContextClassLoader(当前);
}
};
Hashtable jspProps=新的Hashtable();
put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME,“JSP SERVLET”);
put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_模式,“*.jsp”);
jspProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT)”(osgi.HTTP.WHITEBOARD.CONTEXT.name=“+CO
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>dummy.jsp</groupId>
<artifactId>dummy.jsp.osgi</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>dummy.jsp.osgi</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<osgi.version>6.0.0</osgi.version>
<osgi.http.whiteboard.version>1.0.0</osgi.http.whiteboard.version>
<javax.servlet-api.version>3.1.0</javax.servlet-api.version>
<javax.servlet.jsp-api.version>2.3.1</javax.servlet.jsp-api.version>
<javax.servlet.jsp.jstl-api.version>1.2.1</javax.servlet.jsp.jstl-api.version>
<javax.el-api.version>3.0.0</javax.el-api.version>
</properties>
<dependencies>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<version>${osgi.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.service.http.whiteboard</artifactId>
<version>${osgi.http.whiteboard.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${javax.servlet-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>${javax.servlet.jsp-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>javax.servlet.jsp.jstl-api</artifactId>
<version>${javax.servlet.jsp.jstl-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper</artifactId>
<version>8.0.32</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>3.0.1</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Bundle-Activator>dummy.jsp.osgi.Activator</Bundle-Activator>
<Export-Package>
dummy.jsp.osgi;version=${project.version},
</Export-Package>
<Import-Package>
*;resolution:=optional
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>