使用 Spark Web 框架时如何使用原生 Servlet 过滤器?
Posted
技术标签:
【中文标题】使用 Spark Web 框架时如何使用原生 Servlet 过滤器?【英文标题】:How can a native Servlet Filter be used when using Spark web framework? 【发布时间】:2015-12-14 09:06:47 【问题描述】:我在玩Spark(Java Web 框架,而不是 Apache Spark)。
我发现定义路由和过滤器真的很好也很容易,但是我希望将本机 servlet 过滤器应用于我的路由,但似乎找不到方法。
更具体地说,我想使用Jetty's DoSFilter,它是一个 servlet 过滤器(与 Spark 过滤器定义相反)。由于 Spark 使用的是嵌入式 Jetty,我没有 web.xml 来注册 DoSFilter。但是,Spark 没有公开服务器实例,所以我也找不到一种以编程方式注册过滤器的优雅方法。
有没有办法将本机 servlet 过滤器应用于我的路由?
我曾想过将 DoSFilter 包装在我自己的 Spark 过滤器中,但这似乎是一个奇怪的想法。
【问题讨论】:
嘿,您找到在 spark 中使用 servlet 过滤器的方法了吗?或者至少如何初始化码头服务器并将火花添加为servlet? 我已经有一段时间没有看到它了,但是有一种方法可以反转控制并将 spark 嵌入到 web 应用程序中,而不是通过 spark 运行 Jetty - sparkjava.com/documentation.html#other-webserver。我记得看过源代码,它看起来很容易设置。希望对您有所帮助。 这可能是***.com/questions/14390577/…的副本? 【参考方案1】:你可以这样做:
public class App
private static Logger LOG = LoggerFactory.getLogger(App.class);
public static void main(String[] args) throws Exception
ServletContextHandler mainHandler = new ServletContextHandler();
mainHandler.setContextPath("/base/path");
Stream.of(
new FilterHolder(new MyServletFilter()),
new FilterHolder(new SparkFilter())
this.setInitParameter("applicationClass", SparkApp.class.getName());
).forEach(h -> mainHandler.addFilter(h, "*", null));
GzipHandler compression = new GzipHandler();
compression.setIncludedMethods("GET");
compression.setMinGzipSize(512);
compression.setHandler(mainHandler);
Server server = new Server(new ExecutorThreadPool(new ThreadPoolExecutor(10,200,60000,TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(200),
new CustomizableThreadFactory("jetty-pool-"))));
final ServerConnector serverConnector = new ServerConnector(server);
serverConnector.setPort(9290);
server.setConnectors(new Connector[] serverConnector );
server.setHandler(compression);
server.start();
hookToShutdownEvents(server);
server.join();
private static void hookToShutdownEvents(final Server server)
LOG.debug("Hooking to JVM shutdown events");
server.addLifeCycleListener(new AbstractLifeCycle.AbstractLifeCycleListener()
@Override
public void lifeCycleStopped(LifeCycle event)
LOG.info("Jetty Server has been stopped");
super.lifeCycleStopped(event);
);
Runtime.getRuntime().addShutdownHook(new Thread()
@Override
public void run()
LOG.info("About to stop Jetty Server due to JVM shutdown");
try
server.stop();
catch (Exception e)
LOG.error("Could not stop Jetty Server properly", e);
);
/**
* @implNote @link SparkFilter needs to access a public class
*/
@SuppressWarnings("WeakerAccess")
public static class SparkApp implements SparkApplication
@Override
public void init()
System.setProperty("spring.profiles.active", ApplicationProfile.readProfilesOrDefault("dev").stream().collect(Collectors.joining()));
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ModocContext.class);
ctx.registerShutdownHook();
【讨论】:
以上是关于使用 Spark Web 框架时如何使用原生 Servlet 过滤器?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 AWS Elastic Beanstalk 上安装/运行 Spark Java 框架?