首页 > 代码库 > Spark HistoryServer之Jetty简单使用

Spark HistoryServer之Jetty简单使用

这两天在看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后明白了是按照指定的请求路径进行转发的。

 

Spark HistoryServer之Jetty简单使用