这两天在看Spark HistoryServer的代码,发现里面使用了Jetty,下面简单描述下Jetty的使用
有两个Servlet:HelloServlet和WorldServlet
package com.luogankun.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HelloServlet extends HttpServlet { private static final long serialVersionUID = 1L; private String msg = "hello"; public HelloServlet() { } public HelloServlet(String msg) { this.msg = "hello: "+ msg; } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().println(msg); } }
package com.luogankun.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class WorldServlet extends HttpServlet{ private static final long serialVersionUID = 1L; private String msg = "world"; public WorldServlet() { } public WorldServlet(String msg) { this.msg = "world: " + msg; } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().println(msg); } }
Jetty客户端测试:
package com.luogankun.jetty; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import com.luogankun.servlet.HelloServlet; import com.luogankun.servlet.WorldServlet; public class JettyServer { public static void main(String[] args) throws Exception { Server server = new Server(7798); //指定jettyserver的启动端口 ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); //设置访问路径 server.setHandler(context); // http://localhost:8080/hello context.addServlet(new ServletHolder(new HelloServlet()), "/hello"); //当访问/hello时执行HelloServlet() // http://localhost:8080/hello/luogankun context.addServlet(new ServletHolder(new HelloServlet("luogankun")),"/hello/luogankun"); //当执行/hello/luogankun时执行HelloServlet // http://localhost:8080/world context.addServlet(new ServletHolder(new WorldServlet()), "/world"); //当执行/world时执行WorldServlet // http://localhost:8080/world/luogankun context.addServlet(new ServletHolder(new WorldServlet("luogankun")), "/world/luogankun"); //当执行/world/luogankun时执行WorldServlet server.start(); server.join(); } }
总结:当request请求匹配到某个设定的路径时就执行某个指定的Servlet。
在浏览器中访问如下地址,注意观察执行结果
http://localhost:8080/hello
http://localhost:8080/hello/luogankun
http://localhost:8080/world
http://localhost:8080/world/luogankun
查看HistoryServer的代码
def initialize() { attachPage(new HistoryPage(this)) attachHandler(createStaticHandler(SparkUI.STATIC_RESOURCE_DIR, "/static")) val contextHandler = new ServletContextHandler contextHandler.setContextPath(HistoryServer.UI_PATH_PREFIX) //UI_PATH_PREFIX是history contextHandler.addServlet(new ServletHolder(loaderServlet), "/*") attachHandler(contextHandler) } private val loaderServlet = new HttpServlet { protected override def doGet(req: HttpServletRequest, res: HttpServletResponse): Unit = { val parts = Option(req.getPathInfo()).getOrElse("").split("/") if (parts.length < 2) { res.sendError(HttpServletResponse.SC_BAD_REQUEST, ......)}") return } val appId = parts(1) appCache.get(appId) res.sendRedirect(res.encodeRedirectURL(req.getRequestURI())) } }
可以看到当请求为: /history/*时交由loadServlet执行,该步骤在historyserver主页中点击查看某个app历史信息时触发;
此处的req.getPathInfo()的值为/app编号,形如:/app-20141105100235-0009
刚开始看代码时,不懂jetty,死活弄不明白怎么跳转过到具体的app信息页面的,了解下jetty后明白了是按照指定的请求路径进行转发的。
时间: 2024-10-20 16:21:25