Wejście do klasy serwera można zrobić z trybu osadzonego, ale nie samodzielnym Jetty. Dzieje się tak, ponieważ WebAppClassloader izoluje dostęp do klasy org.eclipse.jetty.server.Server
na aplikacje internetowe.
Można jednak użyć faktu, że cały kontener serwletu musi mieć implementację serwletu default
, wystarczy użyć ServletContext, aby uzyskać dostęp do RequestDispatcher dla domyślnego serwletu i zwrócić uwagę na nazwę klasy implementacji. Wygląda na to, że działa dobrze zarówno na Jetty 8.1.10, jak i 9.0.3 podczas używania wbudowanego. (Spróbuje ponownie na samodzielny molo wkrótce)
Pełna klasy jako przykład:
package com.company.foo;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns = { "/detect" })
@SuppressWarnings("serial")
public class DetectServlet extends HttpServlet
{
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
resp.setContentType("text/plain");
PrintWriter out = resp.getWriter();
detect(out,"org.eclipse.jetty.server.Server");
detect(out,"/org/eclipse/jetty/server/Server.class");
detect(out,"org.eclipse.jetty.server.Request");
detect(out,"/org/eclipse/jetty/server/Request.class");
detect(out,"org.mortbay.jetty.Server");
detect(out,"/org/mortbay/jetty/Server.class");
detectDefaultServlet(out, req, "org.eclipse.jetty");
detectDefaultServlet(out, req, "org.apache.catalina");
String version = getReflectedMethodValue("org.eclipse.jetty.server.Server", "getVersion");
out.printf("Server.getVersion() = %s%n", version);
}
private void detectDefaultServlet(PrintWriter out, HttpServletRequest req, String keyword)
{
// Request the default servlet (its pretty safe to say it will always be there)
RequestDispatcher dispatcher = req.getServletContext().getNamedDispatcher("default");
if(dispatcher == null) {
out.printf("detectDefaultServlet(out, req, \"%s\") = <no default servlet>%n", keyword);
return;
}
// If the request dispatcher implementation contains the keyword, we can claim a match
boolean detected = dispatcher.getClass().getName().contains(keyword);
out.printf("detectDefaultServlet(out, req, \"%s\") = %b (%s)%n", keyword, detected, dispatcher.getClass().getName());
}
private String getReflectedMethodValue(String clazzName, String methodName)
{
ClassLoader loader = ClassLoader.getSystemClassLoader();
try
{
Class<?> clazz = Class.forName(clazzName,false,loader);
Class<?> parameterTypes[] = new Class<?>[0];
Method method = clazz.getDeclaredMethod(methodName,parameterTypes);
Object args[] = new Object[0];
return (String)method.invoke(clazz,args);
}
catch (ClassNotFoundException e)
{
return "<class-not-found>";
}
catch (Throwable t)
{
return "<" + t.getClass().getName() + ": " + t.getMessage() + ">";
}
}
private void detect(PrintWriter out, String resource)
{
out.printf("detect(\"%s\") = %b%n",resource,detected(resource));
}
private boolean detected(String clazz)
{
try
{
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
systemClassLoader.loadClass(clazz);
return true;
}
catch (ClassNotFoundException cnfe)
{
Class<?> classObj = getClass();
if (classObj.getResource(clazz) != null)
{
return true;
}
else
{
return false;
}
}
}
}
Który będzie następujący wynik na Jetty 8.1.10 wbudowanego
detect("org.eclipse.jetty.server.Server") = true
detect("/org/eclipse/jetty/server/Server.class") = true
detect("org.eclipse.jetty.server.Request") = true
detect("/org/eclipse/jetty/server/Request.class") = true
detect("org.mortbay.jetty.Server") = false
detect("/org/mortbay/jetty/Server.class") = false
detectDefaultServlet(out, req, "org.eclipse.jetty") = true (org.eclipse.jetty.server.Dispatcher)
detectDefaultServlet(out, req, "org.apache.catalina") = false (org.eclipse.jetty.server.Dispatcher)
Server.getVersion() = 8.1.10.v20130312
i podobne wyjście na Jetty 9.0.3 Wbudowany
detect("org.eclipse.jetty.server.Server") = true
detect("/org/eclipse/jetty/server/Server.class") = true
detect("org.eclipse.jetty.server.Request") = true
detect("/org/eclipse/jetty/server/Request.class") = true
detect("org.mortbay.jetty.Server") = false
detect("/org/mortbay/jetty/Server.class") = false
detectDefaultServlet(out, req, "org.eclipse.jetty") = true (org.eclipse.jetty.server.Dispatcher)
detectDefaultServlet(out, req, "org.apache.catalina") = false (org.eclipse.jetty.server.Dispatcher)
Server.getVersion() = 9.0.3.v20130506
Ale inna dla Jetty 9.0.3 Samodzielny
detect("org.eclipse.jetty.server.Server") = false
detect("/org/eclipse/jetty/server/Server.class") = false
detect("org.eclipse.jetty.server.Request") = false
detect("/org/eclipse/jetty/server/Request.class") = false
detect("org.mortbay.jetty.Server") = false
detect("/org/mortbay/jetty/Server.class") = false
detectDefaultServlet(out, req, "org.eclipse.jetty") = true (org.eclipse.jetty.server.Dispatcher)
detectDefaultServlet(out, req, "org.apache.catalina") = false (org.eclipse.jetty.server.Dispatcher)
Server.getVersion() = <class-not-found>
Przyjdź, aby myśleć o tym, można użyć dowolnego interfejsu Servlet i sprawdzić, czy nazwa klasy realizacja rozpoczyna się od '„org.eclipse.jetty.”' –
To działa. Dziękuję Ci bardzo! – DaSilva2010